Subversion Repositories wimsdev

Rev

Rev 104 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "chemeq.h"
  2. #include <math.h>
  3. #include <sstream>
  4.  
  5. atome lesatomes[] ={
  6. {-1, "e"},
  7. {1, "H"},
  8. {2, "He"},
  9. {3, "Li"},
  10. {4, "Be"},
  11. {5, "B"},
  12. {6, "C"},
  13. {7, "N"},
  14. {8, "O"},
  15. {9, "F"},
  16. {10, "Ne"},
  17. {11, "Na"},
  18. {12, "Mg"},
  19. {13, "Al"},
  20. {14, "Si"},
  21. {15, "P"},
  22. {16, "S"},
  23. {17, "Cl"},
  24. {18, "Ar"},
  25. {19, "K"},
  26. {20, "Ca"},
  27. {21, "Sc"},
  28. {22, "Ti"},
  29. {23, "V"},
  30. {24, "Cr"},
  31. {25, "Mn"},
  32. {26, "Fe"},
  33. {27, "Co"},
  34. {28, "Ni"},
  35. {29, "Cu"},
  36. {30, "Zn"},
  37. {31, "Ga"},
  38. {32, "Ge"},
  39. {33, "As"},
  40. {34, "Se"},
  41. {35, "Br"},
  42. {36, "Kr"},
  43. {37, "Rb"},
  44. {38, "Sr"},
  45. {39, "Y"},
  46. {40, "Zr"},
  47. {41, "Nb"},
  48. {42, "Mo"},
  49. {43, "Tc"},
  50. {44, "Ru"},
  51. {45, "Rh"},
  52. {46, "Pd"},
  53. {47, "Ag"},
  54. {48, "Cd"},
  55. {49, "In"},
  56. {50, "Sn"},
  57. {51, "Sb"},
  58. {52, "Te"},
  59. {53, "I"},
  60. {54, "Xe"},
  61. {55, "Cs"},
  62. {56, "Ba"},
  63. {57, "La"},
  64. {58, "Ce"},
  65. {59, "Pr"},
  66. {60, "Nd"},
  67. {61, "Pm"},
  68. {62, "Sm"},
  69. {63, "Eu"},
  70. {64, "Gd"},
  71. {65, "Tb"},
  72. {66, "Dy"},
  73. {67, "Ho"},
  74. {68, "Er"},
  75. {69, "Tm"},
  76. {70, "Yb"},
  77. {71, "Lu"},
  78. {72, "Hf"},
  79. {73, "Ta"},
  80. {74, "W"},
  81. {75, "Re"},
  82. {76, "Os"},
  83. {77, "Ir"},
  84. {78, "Pt"},
  85. {79, "Au"},
  86. {80, "Hg"},
  87. {81, "Tl"},
  88. {82, "Pb"},
  89. {83, "Bi"},
  90. {84, "Po"},
  91. {85, "At"},
  92. {86, "Rn"},
  93. {87, "Fr"},
  94. {88, "Ra"},
  95. {89, "Ac"},
  96. {90, "Th"},
  97. {91, "Pa"},
  98. {92, "U"},
  99. {93, "Np"},
  100. {94, "Pu"},
  101. {95, "Am"},
  102. {96, "Cm"},
  103. {97, "Bk"},
  104. {98, "Cf"},
  105. {99, "Es"},
  106. {100, "Fm"},
  107. {101, "Md"},
  108. {102, "No"},
  109. {103, "Lr"},
  110. {104, "Rf"},
  111. {105, "Db"},
  112. {106, "Sg"},
  113. {107, "Bh"},
  114. {108, "Hs"},
  115. {109, "Mt"},
  116. {110, "Uun"},
  117. {111, "Uuu"},
  118. {112, "Uub"},
  119. {113, "Uut"},
  120. {114, "Uuq"},
  121. {115, "Uup"},
  122. {116, "Uuh"},
  123. {117, "Uus"},
  124. {118, "Uuo"},
  125. {0,"fin"}
  126. };
  127.  
  128. std::ostream & Compteur::operator << (std::ostream & o)const{
  129.   const_iterator i=begin();
  130.   while (i != end()){
  131.     o << i->first << " : " << i->second;
  132.     if (++i != end()) o << " ";
  133.   }
  134.   return o;
  135. }
  136.  
  137. std::ostream & operator << (std::ostream & o, const Compteur & c){
  138.   return c.operator << (o);
  139. }
  140.  
  141. double AtomeListe::weight(fraction mult)const{
  142.   const AtomeListe * al;
  143.   double w=0.0;
  144.   if(Zed!=0 && Zed!=-1 ){ /* cas où ce n'est pas un groupe ou un électron */
  145.     w=mendelweight(symb)*nb*mult.i/mult.d;
  146.     //debug(); std::cout << std::endl;
  147.   }
  148.   else if (Zed==0){ /* cas d'un groupe */
  149.     if (group) w+=group->weight(mult*nb);
  150.   }
  151.   if (suiv) w+=suiv->weight(mult);
  152.   return w;
  153. }
  154.  
  155. void AtomeListe::compte(Compteur &c, fraction mult)const{
  156.   const AtomeListe * al;
  157.   if(Zed!=0 && Zed!=-1 ){ /* cas où ce n'est pas un groupe ou un électron */
  158.     std::string key(symb);
  159.     c[key] +=1.0*nb*mult.i/mult.d;
  160.   }
  161.   else if (Zed==0){ /* cas d'un groupe */
  162.     if (group) group->compte(c,mult*nb);
  163.   }
  164.   if (suiv) suiv->compte(c,mult);
  165. }
  166.  
  167. void AtomeListe::numerote(int n){
  168.   if(Zed!=0){ /* cas où ce n'est pas un groupe */
  169.     no = n;
  170.   }
  171.   else if (Zed==0){ /* cas d'un groupe */
  172.     no = n;
  173.     if (group) group->numerote();
  174.   }
  175.   if (suiv) suiv->numerote(n+1);
  176. }
  177.  
  178. AtomeListe * AtomeListe::triage(AtomeListe * al){
  179.   AtomeListe * al1;
  180.   if(al->Z()!=0){ /* cas où ce n'est pas un groupe */
  181.     if (al->suiv){
  182.       al->suiv = triage(al->suiv);
  183.     }
  184.     while (al->suiv && al->suiv->Zed!=0 &&
  185.            strcmp(al->symbole(), al->suiv->symbole()) > 1){
  186.       al1=al; al=al->suiv; al1->suiv=al->suiv; al->suiv=triage(al1);
  187.     }
  188.   }
  189.   else{ /* cas d'un groupe */
  190.      if (al->groupe()) al->groupe(triage(al->groupe()));
  191.   }
  192.   return al;
  193. }
  194.  
  195. bool operator == (const AtomeListe & a1, const AtomeListe & a2){
  196.   std::stringstream s1, s2;
  197.   a1.printnorm(s1);
  198.   a2.printnorm(s2);
  199.   return s1 == s2;
  200. }
  201.  
  202. void AtomeListe::printcount(std::ostream & o, const fraction& n, int multiple=1) const{
  203.   if(Zed!=0){ /* cas où ce n'est pas un groupe */
  204.     o << symb;
  205.     o << ':' << n << '*' << multiple*nb;
  206.   }
  207.   else{ /* cas d'un groupe */
  208.     if (group) group->printcount(o,n,nb);
  209.   }  
  210.   if (suiv) {o << ' '; suiv->printcount(o,n,multiple);}
  211. }
  212.  
  213. void AtomeListe::printnorm(std::ostream & o) const{
  214.   if (sqbr) o << "[";
  215.   if(Zed!=0){ /* cas où ce n'est pas un groupe */
  216.     o << symb;
  217.     if (nb!=1) o << nb;
  218.   }
  219.   else{ /* cas d'un groupe */
  220.     o << "(";
  221.     if (group) group->printnorm(o);
  222.     o << ")" << nb;
  223.   }  
  224.   if (suiv) suiv->printnorm(o);
  225.   if (sqbr) o << "]";
  226. }
  227.  
  228. std::ostream & operator << (std::ostream & o, const AtomeListe & l){
  229.   int n;
  230.   const AtomeListe * al;
  231.   if (l.sq()) o << "[";
  232.   if(l.Z()>0 || l.Z()<-1){
  233.     o << l.symbole();
  234.   }
  235.   else if (l.Z()==-1){ // cas de l'électron
  236.     o << "e";
  237.   }
  238.   else{                // cas des groupes parenthésés
  239.     o << "(";
  240.     if((al=l.groupe())) o << *al;
  241.     o << ")";
  242.   }
  243.   if((n=l.getmolecularite())>1) o << "_{" << n << "}";
  244.   if((al=l.suivant())) o << *al;
  245.   if (l.sq()) o << "]";
  246.   return o;
  247. }
  248.  
  249. char* moltypeStr[] = { "aq", "g", "s" };
  250.  
  251. bool operator == (const Molec & m1, const Molec & m2){
  252.   return *(m1.al) == *(m2.al) && m1.ch == m2.ch;
  253. }
  254.  
  255. const std::string Molec::signature()const{
  256.   std::ostringstream o;
  257.   o << liste();
  258.   if (charge()){
  259.     o << "^{";
  260.     if(fabs(1.0*charge())!=1) o << fabs(1.0*charge());
  261.     if(charge()>0) o << "+}"; else o << "-}";
  262.   }
  263.   if (t != aqueous) o << moltypeStr[t];
  264.   return std::string (o.str());
  265. }
  266.  
  267. bool Molec::printcount(std::ostream & o, bool first) const{
  268.   if (!first) o << ", ";
  269.   first=false;
  270.   printnorm(o);
  271.   o << '|';
  272.   al-> printcount(o,nb);
  273.   return first;
  274. }
  275.  
  276. bool Molec::printelec(std::ostream & o, bool first) const{
  277.   if (!first) o << ", ";
  278.   first=false;
  279.   printnorm(o);
  280.   o << '|';
  281.   o << nb << '*' << ch;
  282.   return first;
  283. }
  284.  
  285. bool Molec::printspecies(std::ostream & o, bool first) const{
  286.   if (!first) o << ", ";
  287.   first=false;
  288.   printnorm(o);
  289.   return first;
  290. }
  291.  
  292. void Molec::printnorm(std::ostream & o)const{
  293.   if (nb!=1) o << nb << " ";
  294.   al-> printnorm(o);
  295.   if (ch) {
  296.     o << "^";
  297.     if(fabs(1.0*ch)!=1) o << fabs(1.0*ch);
  298.     if(ch>0) o << "+"; else o << "-";
  299.   }
  300.   if (!iswater()&&!iselectron()) o << "_" << moltypeStr[t];
  301. }
  302.  
  303. void Molec::coeff( fraction f){
  304.   nb.i *= f.i;
  305.   nb.d *= f.d;
  306.   nb.simplifie();
  307. }
  308.  
  309. bool Molec::printNernst(std::ostream & o, char * prefix){
  310.   switch(t){
  311.   case sol : return 0;
  312.   case aqueous :
  313.     if (iswater() || iselectron()) return 0;
  314.     o << prefix << "[" << *al;
  315.     if (ch){
  316.       o << "^{";
  317.       if(fabs(1.0*ch)!=1) o << fabs(1.0*ch);
  318.       if(ch>0) o << "+}"; else o << "-}";
  319.     }
  320.     if (t != aqueous) o << "_{" << moltypeStr[t] << "}";
  321.     o  <<"]";
  322.     if (nb!=1) {
  323.       o << "^{";
  324.       printNombre(o);
  325.       o << "}";
  326.     }
  327.     return 1;
  328.   case gas :
  329.     o << prefix << "P_{" << *al << "}";
  330.     if (nb!=1) {
  331.       o << "^{";
  332.       printNombre(o);
  333.       o << "}";
  334.     }
  335.     return 1;
  336.   }
  337. }
  338.  
  339. bool Molec::iswater()const{
  340.   if (t != aqueous) return 0;
  341.   if (signature()==std::string("H_{2}O") ||
  342.       signature()==std::string("OH_{2}")) return 1;
  343.   else return 0;
  344. }
  345.  
  346. bool Molec::iselectron()const{
  347.   return (signature()==std::string("e^{-}"));
  348. }
  349.  
  350. fraction Molec::nbelectron()const{
  351.   if (iselectron()) return nb;
  352.   else return fraction(0);
  353. }
  354.  
  355. void Molec::printNombre(std::ostream & o)const{
  356.   if (nb.d==1){
  357.     o << nb.i << "\\,";
  358.   }
  359.   else {
  360.     o << "\\frac{" << nb.i << "}{" << nb.d << "}\\,";
  361.   }
  362. }
  363.  
  364. std::ostream & operator << (std::ostream & o, const Molec & m){
  365.   if (m.nombre() != 1) m.printNombre(o);
  366.   o << m.liste();
  367.   if (m.charge()){
  368.     o << "^{";
  369.     if(fabs(1.0*m.charge())!=1) o << fabs(1.0*m.charge());
  370.     if(m.charge()>0) o << "+}"; else o << "-}";
  371.   }
  372.   if (m.typage() != aqueous) o << "_{" << moltypeStr[m.typage()] << "}";
  373.   return o;
  374. }
  375.  
  376. void Membre::compte(Compteur & c)const{
  377.   for(int i =0; i < size(); i++){
  378.     operator [] (i)->compte(c);
  379.   }
  380. }
  381.  
  382. void Membre::numerote(){
  383.   for (int i=0; i < size(); i++){
  384.     operator [](i)->numero(i);
  385.     operator [](i)->liste().numerote();
  386.   }
  387. }
  388.  
  389. void Membre::triage(){
  390.   int i,j;
  391.   for (i=0; i < size(); i++){
  392.     operator [](i)->triage();
  393.   }
  394.   for (i=0; i < size(); i++){
  395.     for (j=i+1; j < size(); j++){
  396.       if (operator [](i)->signature() > operator [](j)->signature()){
  397.         Molec * m = operator [](i);
  398.         operator [](i) = operator [](j);
  399.         operator [](j) = m;
  400.       }
  401.     }
  402.   }
  403. }
  404.  
  405. void Membre::printcount(std::ostream & o) const{
  406.   bool first=true;
  407.   for(int i=0; i < size(); i++){
  408.     first=operator[](i)->printcount(o,first);
  409.   }
  410. }
  411.  
  412. void Membre::printelec(std::ostream & o) const{
  413.   bool first=true;
  414.   for(int i=0; i < size(); i++){
  415.     first=operator[](i)->printelec(o,first);
  416.   }
  417. }
  418.  
  419. void Membre::printspecies(std::ostream & o) const{
  420.   bool first=true;
  421.   for(int i=0; i < size(); i++){
  422.     first=operator[](i)->printspecies(o,first);
  423.   }
  424. }
  425.  
  426. void Membre::printnorm(std::ostream & o) const{
  427.   for(int i=0; i < size(); i++){
  428.     operator[](i)->printnorm(o);
  429.     if (i < size()-1) o << " + ";
  430.   }
  431. }
  432.  
  433. void Membre::printweight(std::ostream & o) const{
  434.   for(int i=0; i < size(); i++){
  435.     o << operator[](i)->weight();
  436.     if (i < size()-1) o << " ";
  437.   }
  438. }
  439.  
  440. void Membre::coeff( fraction f){
  441.   for (int i=0; i<size(); i++) operator[](i)->coeff(f);
  442. }
  443.  
  444. int Membre::printableNernst(){
  445.   int result=0;
  446.   for (int i=0; i<size(); i++) {
  447.     if (operator[](i)->typage() != sol &&
  448.         !operator[](i)->iswater() &&
  449.         !operator[](i)->iselectron()) result =1;
  450.   }  
  451.   return result;
  452. }
  453.  
  454. bool Membre::redox()const{
  455.   for (int i=0; i<size(); i++){
  456.     if ((*this)[i]->iselectron()) /* c'est un électron */ return 1;
  457.   }
  458.   return 0;
  459. }
  460.  
  461. fraction  Membre::nbelectron()const{
  462.   fraction result(0);
  463.  
  464.   for(int i = 0; i<size(); i++) result=result+(*this)[i]->nbelectron();
  465.   return result;
  466. }
  467.  
  468. void Membre::printNernst(std::ostream & o){
  469.   bool printed = 0;
  470.   char * prefix="";
  471.   for (int i=0; i<size(); i++) {
  472.     if (i>0) prefix="\\,";
  473.     if (operator[](i)->printNernst(o, prefix)){
  474.       printed = 1;
  475.     }
  476.   }
  477.   if (!printed) o << "1";
  478. }
  479.  
  480. std::ostream & operator << (std::ostream & o, const Membre & m){
  481.   for(int i=0; i < m.size()-1; i++){
  482.     o << *m[i] << "\\,+\\,";
  483.   }
  484.   o << *m[m.size()-1];
  485.   return o;
  486. }
  487.  
  488. Membre operator & (Membre & m1, Membre & m2){
  489.   Membre result;
  490.   fraction min(1);
  491.   for(Membre::iterator i = m1.begin(); i < m1.end(); i++){
  492.     for(Membre::iterator j = m2.begin(); j < m2.end(); j++){
  493.       if (**i == **j){
  494.         Molec *m = new Molec(**i);
  495.         if ((*i)->nb > (*j)->nb){
  496.           min=(*j)->nb;
  497.         }else{
  498.           min=(*i)->nb;
  499.         }
  500.         m->nb=min;
  501.         result.push_back(m);
  502.       }
  503.     }
  504.   }
  505.   return result;
  506. }
  507.  
  508. Membre operator - (Membre & m1, Membre & m2){
  509.   Membre result;
  510.   fraction diff(1);
  511.   for(Membre::iterator i = m1.begin(); i < m1.end(); i++){
  512.     Molec *m = new Molec(**i);
  513.     for(Membre::iterator j = m2.begin(); j < m2.end(); j++){
  514.       if (**i == **j){
  515.         diff=(*i)->nb - (*j)->nb;
  516.         m->nb=diff;
  517.       }
  518.     }
  519.     result.push_back(m);
  520.   }
  521.   return result;
  522. }
  523.  
  524. void Chemeq::printnorm(std::ostream & o){
  525.   gauche->printnorm(o);
  526.   o << " -> ";
  527.   droit->printnorm(o);
  528.   if (val>=0){
  529.     o << " (";
  530.     if (cste!=std::string("")) o << cste << " = ";
  531.     o << val;
  532.     if (redox()) o << " V";
  533.     o << ")";
  534.   }
  535. }
  536.  
  537. void Chemeq::printcount(std::ostream & o) const {
  538.   gauche->printcount(o);
  539.   o << "; ";
  540.   droit->printcount(o);
  541. }
  542.  
  543. void Chemeq::printelec(std::ostream & o) const {
  544.   gauche->printelec(o);
  545.   o << "; ";
  546.   droit->printelec(o);
  547. }
  548.  
  549. void Chemeq::printspecies(std::ostream & o) const {
  550.   gauche->printspecies(o);
  551.   o << "; ";
  552.   droit->printspecies(o);
  553. }
  554.  
  555. void Chemeq::printweight(std::ostream & o) const{
  556.   gauche->printweight(o);
  557.   o << " ";
  558.   droit->printweight(o);
  559. }
  560.  
  561. std::string Chemeq::equilibre(){
  562.   std::ostringstream s;
  563.   Compteur cpg, cpd;
  564.   gauche->compte(cpg);
  565.   droit->compte(cpd);
  566.   if(cpg==cpd) s << "OK";
  567.   else s << "ERROR " << cpg << " / " << cpd;
  568.   return std::string(s.str());
  569. }
  570.  
  571. void Chemeq::coeff1(){
  572.   fraction mult = gauche->operator[](0)->nombre();
  573.   mult.inverse();
  574.   gauche->coeff(mult);
  575.   droit->coeff(mult);
  576.   Membre communs(*gauche & *droit);
  577.   if (communs.size()>0){
  578.     Membre * g, *d;
  579.     g= new Membre(*gauche - communs);
  580.     d= new Membre(*droit  - communs);
  581.     delete gauche;
  582.     delete droit;
  583.     gauche=g;
  584.     droit =d;
  585.   }
  586.   if (!redox()){
  587.     val = val*mult.i/mult.d;
  588.   }
  589. }
  590.  
  591. bool Chemeq::redox()const{
  592.   return gauche->redox() || droit->redox();
  593. }
  594.  
  595. void Chemeq::printNernst(std::ostream & o){
  596.   Membre * ga, * dr;
  597.   if (!redox()){
  598.     if (gauche->printableNernst()){
  599.       o << "\\frac{";
  600.       droit->printNernst(o);
  601.       o << "}{";
  602.       gauche->printNernst(o);
  603.       o << "}";
  604.     }
  605.     else {
  606.       droit->printNernst(o);
  607.     }
  608.     if (val >=0) {
  609.       o << "\\,=\\,";
  610.       if (cste!=std::string("")) o << cste << "\\,=\\,";
  611.       o << val;
  612.     }
  613.     else{
  614.       o << "\\,=\\,K";
  615.     }
  616.   }
  617.   else{ /* c'est une réaction redox */
  618.     o << "E\\,=\\,";
  619.     if (val >=0) {
  620.       o << val;
  621.     }
  622.     else{
  623.       o << "E_{0}";
  624.     }
  625.     o << "\\,+\\,\\frac{R\\,T}{";
  626.     o << gauche->nbelectron()+droit->nbelectron() << "\\,F}";
  627.     o << "\\log";
  628.     if (gauche->redox()){ /* c'est une réduction */
  629.       ga=gauche; dr=droit;
  630.     }
  631.     else{ /* c'est une oxydation */
  632.       ga=droit; dr=gauche;
  633.     }
  634.     if (dr->printableNernst()){
  635.         o << "\\frac{";
  636.         ga->printNernst(o);
  637.         o << "}{";
  638.         dr->printNernst(o);
  639.         o << "}";
  640.       }
  641.       else {
  642.         o << "(";
  643.         ga->printNernst(o);
  644.         o << ")";
  645.       }
  646.   }
  647. }
  648.  
  649. std::ostream & operator << (std::ostream & o, const Chemeq & c){
  650.   o << *c.membregauche() << "\\,\\rightarrow\\," << *c.membredroit();
  651.   if (c.valeur() >=0) {
  652.     o << "\\,(";
  653.     if (c.constante()!=std::string("")) o << c.constante() << "\\,=\\,";
  654.     o << c.valeur();
  655.     if (c.redox()) o << " V";
  656.     o << ")";
  657.   }
  658.   return o;
  659. }
  660.  
  661. std::ostream & operator << (std::ostream & o, fraction f){
  662.   o << f.i;
  663.   if (f.d!=1) o << '/' << f.d;
  664.   return o;
  665. }
  666.  
  667. fraction operator * (fraction f, int m){
  668.   fraction result = fraction(f.i*m, f.d);
  669.   result.simplifie();
  670.   return result;
  671. }
  672.  
  673. fraction operator * (int m, fraction f){
  674.   fraction result = fraction(f.i*m, f.d);
  675.   result.simplifie();
  676.   return result;
  677. }
  678.  
  679. fraction operator * (fraction f, fraction m)
  680. {
  681.   fraction result = fraction(f.i*m.i, f.d*m.d);
  682.   result.simplifie();
  683.   return result;
  684. }
  685.  
  686. fraction operator + (fraction f, fraction g){
  687.   fraction result = fraction(f.i*g.d+g.i*f.d, f.d*g.d);
  688.   result.simplifie();
  689.   return result;
  690. }
  691.  
  692. fraction operator - (fraction f, fraction g){
  693.   fraction result = fraction(f.i*g.d-g.i*f.d, f.d*g.d);
  694.   result.simplifie();
  695.   return result;
  696. }
  697.  
  698. void fraction::simplifie(){
  699.   int maxprem = 23;
  700.   int premiers[]={2,3,5,7,11,13,17,19,23,29};
  701.   int n;
  702.  
  703.   for (n=0; premiers[n]<= maxprem; n++){
  704.     while (i % premiers[n] == 0 && d % premiers[n] == 0){
  705.       i /= premiers[n]; d /= premiers[n];
  706.     }
  707.   }
  708. }
  709.  
  710. bool operator > (fraction f, int i){
  711.   return f.i > f.d*i;
  712. }
  713.  
  714. bool operator > (fraction f1, fraction f2){
  715.   return f1.i*f2.d > f1.d*f2.i;
  716. }
  717.  
  718. bool operator != (fraction f, int i){
  719.   return f.i != f.d*i;
  720. }
  721.  
  722. double mendelweight(int i){
  723.   if (i>=0) return strtod (table[i].info[WEIGHT],0); else return 0.0;
  724. }
  725.  
  726. int findmendel(const char * symb){
  727.   int i=0;
  728.   while (table[i].info[0] && strcmp(table[i].info[SYMBOL], symb) != 0) i++;
  729.   if (table[i].info[0]) return i; else return -1;
  730. }
  731.  
  732. double mendelweight(const char * symb){
  733.   int i;
  734.   i = findmendel(symb);
  735.   return mendelweight(i);
  736. }
  737.