COPASI API  4.16.103
CEvaluationNodeNormalizer.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/compareExpressions/CEvaluationNodeNormalizer.cpp,v $
3 // $Revision: 1.14 $
4 // $Name: $
5 // $Author: shoops $
6 // $Date: 2012/05/15 15:56:22 $
7 // End CVS Header
8 
9 // Copyright (C) 2012 - 2010 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., University of Heidelberg, and The University
11 // of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
16 // and The University of Manchester.
17 // All rights reserved.
18 
19 // Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
20 // Properties, Inc. and EML Research, gGmbH.
21 // All rights reserved.
22 
24 
25 #include <sstream>
26 #include <algorithm>
27 #include <cmath>
28 
29 #include "copasi.h"
30 #include "utilities/CCopasiNode.h"
42 
43 const double CEvaluationNodeNormalizer::ZERO = 1e-100;
44 
46 {
47 
48  CEvaluationNode* pResult = NULL;
49 
50  if (pNode != NULL)
51  {
52  switch (CEvaluationNode::type(pNode->getType()))
53  {
55  break;
57  pResult = normalizeCEvaluationNodeNumber(dynamic_cast<const CEvaluationNodeNumber*>(pNode));
58  break;
60  pResult = normalizeCEvaluationNodeConstant(dynamic_cast<const CEvaluationNodeConstant*>(pNode));
61  break;
63  pResult = normalizeCEvaluationNodeDelay(dynamic_cast<const CEvaluationNodeDelay*>(pNode));
64  break;
66  pResult = normalizeCEvaluationNodeOperator(dynamic_cast<const CEvaluationNodeOperator*>(pNode));
67  break;
69  pResult = normalizeCEvaluationNodeObject(dynamic_cast<const CEvaluationNodeObject*>(pNode));
70  break;
72  pResult = normalizeCEvaluationNodeFunction(dynamic_cast<const CEvaluationNodeFunction*>(pNode));
73  break;
75  pResult = normalizeCEvaluationNodeCall(dynamic_cast<const CEvaluationNodeCall*>(pNode));
76  break;
78  pResult = normalizeCEvaluationNodeStructure(dynamic_cast<const CEvaluationNodeStructure*>(pNode));
79  break;
81  pResult = normalizeCEvaluationNodeChoice(dynamic_cast<const CEvaluationNodeChoice*>(pNode));
82  break;
84  pResult = normalizeCEvaluationNodeVariable(dynamic_cast<const CEvaluationNodeVariable*>(pNode));
85  break;
87  pResult = normalizeCEvaluationNodeWhiteSpace(dynamic_cast<const CEvaluationNodeWhiteSpace*>(pNode));
88  break;
90  pResult = normalizeCEvaluationNodeLogical(dynamic_cast<const CEvaluationNodeLogical*>(pNode));
91  break;
93  break;
95  pResult = normalizeCEvaluationNodeVector(dynamic_cast<const CEvaluationNodeVector*>(pNode));
96  break;
97  }
98 
99  if (pResult == NULL) pResult = pNode->copyBranch();
100  }
101 
102  return pResult;
103 }
104 
106 {
107  CEvaluationNode* pResult = NULL;
108 
109  if (pNode != NULL)
110  {
111  // copy the node
112  pResult = pNode->copyBranch();
113  }
114 
115  return pResult;
116 }
117 
119 {
120  CEvaluationNode* pResult = NULL;
121 
122  if (pNode != NULL)
123  {
124  // copy the node
125  pResult = pNode->copyBranch();
126  }
127 
128  return pResult;
129 }
130 
132 {
133  CEvaluationNode* pResult = NULL;
134 
135  if (pNode != NULL)
136  {
138  {
140  break;
143  break;
146  break;
149  break;
152  break;
155  break;
158  break;
159  }
160 
161  if (pResult == NULL) pResult = pNode->copyBranch();
162  }
163 
164  return pResult;
165 }
166 
168 {
169  CEvaluationNode* pResult = NULL;
170 
171  if (pNode != NULL)
172  {
173  // copy the node
174  pResult = pNode->copyBranch();
175  }
176 
177  return pResult;
178 }
179 
181 {
182  CEvaluationNode* pResult = NULL;
183 
184  if (pNode != NULL)
185  {
186  CEvaluationNode* pTmpResult;
187 
189  {
191  break;
227  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
228 
229  if (pTmpResult != NULL)
230  {
231  pResult->addChild(pTmpResult);
232  }
233  else
234  {
235  delete pResult;
236  pResult = NULL;
237  }
238 
239  break;
242  //case CEvaluationNodeFunction::DELAY:
243  // normalize all children
245  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
246 
247  if (pTmpResult != NULL)
248  {
249  pResult->addChild(pTmpResult);
250  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
251 
252  if (pTmpResult != NULL)
253  {
254  pResult->addChild(pTmpResult);
255  }
256  else
257  {
258  delete pResult;
259  pResult = NULL;
260  }
261  }
262  else
263  {
264  delete pResult;
265  pResult = NULL;
266  }
267 
268  break;
269  /*
270  case CEvaluationNodeFunction::MINUS:
271  // relace the - by a multiplication with -1
272  // !!! Maybe this is not possible since CEvaluationNodeNumber
273  // elements can not hold negative numbers.
274  pResult=new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY,"");
275  */
277  // eliminate the plus
278  pResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
279  break;
280  }
281 
282  if (pResult == NULL) pResult = pNode->copyBranch();
283  }
284 
285  return pResult;
286 }
287 
289 {
291 
292  if (pNode != NULL)
293  {
294  CEvaluationNode* pTmpResult = NULL;
295 
297  {
299  break;
302  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
303 
304  if (pTmpResult != NULL)
305  {
306  pResult->addChild(pTmpResult);
307  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
308 
309  if (pTmpResult != NULL)
310  {
311  pResult->addChild(pTmpResult);
312  }
313  else
314  {
315  delete pResult;
316  pResult = NULL;
317  }
318  }
319  else
320  {
321  delete pResult;
322  pResult = NULL;
323  }
324 
325  break;
326  }
327 
328  if (pResult == NULL)
329  {
330  pResult = static_cast<CEvaluationNodeDelay*>(pNode->copyBranch());
331  }
332  }
333 
334  return pResult;
335 }
336 
338 {
340 
341  if (pNode != NULL)
342  {
343  CEvaluationNode* pTmpResult = NULL;
344  CCopasiNode<std::string>* pTmpNode = NULL;
345 
347  {
349  break;
352  pResult = dynamic_cast<CEvaluationNodeCall*>(CEvaluationNode::create(pNode->getType(), pNode->getData()));
353  // add normalized call nodes
354  const std::vector<CEvaluationNode*>& callNodes = pNode->getListOfChildNodes();
355  std::vector<CEvaluationNode*>::const_iterator it = callNodes.begin(), endit = callNodes.end();
356 
357  while (it != endit)
358  {
359  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(*it));
360 
361  if (pTmpResult != NULL)
362  {
363  pResult->addChild(pTmpResult);
364  }
365  else
366  {
367  // delete all newly created call nodes
368  while (!pResult->getListOfChildNodes().empty())
369  {
370  pTmpNode = pResult->getChild();
371  pResult->removeChild(pTmpNode);
372  delete pTmpNode;
373  }
374 
375  delete pResult;
376  pResult = NULL;
377  break;
378  }
379 
380  ++it;
381  }
382 
383  break;
384  }
385 
386  if (pResult == NULL) pResult = static_cast<CEvaluationNodeCall*>(pNode->copyBranch());
387  }
388 
389  return pResult;
390 }
391 
393 {
394  CEvaluationNode* pResult = NULL;
395 
396  if (pNode != NULL)
397  {
398  // copy the node
399  pResult = pNode->copyBranch();
400  }
401 
402  return pResult;
403 }
404 
406 {
408  CEvaluationNode* pTmpResult;
409 
410  if (pNode != NULL)
411  {
413  {
415  break;
417  // create a new choice node with normalized if, true and false
418  // elements
420  // if element
421  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
422 
423  if (pTmpResult != NULL)
424  {
425  pResult->addChild(pTmpResult);
426  // true element
427  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
428 
429  if (pTmpResult != NULL)
430  {
431  pResult->addChild(pTmpResult);
432  // false element
433  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()->getSibling()));
434 
435  if (pTmpResult != NULL)
436  {
437  pResult->addChild(pTmpResult);
438  }
439  else
440  {
441  delete pResult;
442  pResult = NULL;
443  }
444  }
445  else
446  {
447  delete pResult;
448  pResult = NULL;
449  }
450  }
451  else
452  {
453  delete pResult;
454  pResult = NULL;
455  }
456  }
457 
458  if (pResult == NULL) pResult = static_cast<CEvaluationNodeChoice*>(pNode->copyBranch());
459  }
460 
461  return pResult;
462 }
463 
465 {
466  CEvaluationNode* pResult = NULL;
467 
468  if (pNode != NULL)
469  {
470  // copy the node
471  pResult = pNode->copyBranch();
472  }
473 
474  return pResult;
475 }
476 
478 {
480  CEvaluationNode* pTmpResult = NULL;
481 
482  if (pNode != NULL)
483  {
485  {
487  break;
496  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
497 
498  if (pTmpResult != NULL)
499  {
500  pResult->addChild(pTmpResult);
501  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
502 
503  if (pTmpResult != NULL)
504  {
505  pResult->addChild(pTmpResult);
506  }
507  else
508  {
509  delete pResult;
510  pResult = NULL;
511  }
512  }
513  else
514  {
515  delete pResult;
516  pResult = NULL;
517  }
518 
519  break;
521  // turn the order of the operands and change to LT
523  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
524 
525  if (pTmpResult != NULL)
526  {
527  pResult->addChild(pTmpResult);
528  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
529 
530  if (pTmpResult != NULL)
531  {
532  pResult->addChild(pTmpResult);
533  }
534  else
535  {
536  delete pResult;
537  pResult = NULL;
538  }
539  }
540  else
541  {
542  delete pResult;
543  pResult = NULL;
544  }
545 
546  break;
548  // turn the order of the operands and change to LE
550  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
551 
552  if (pTmpResult != NULL)
553  {
554  pResult->addChild(pTmpResult);
555  pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
556 
557  if (pTmpResult != NULL)
558  {
559  pResult->addChild(pTmpResult);
560  }
561  else
562  {
563  delete pResult;
564  pResult = NULL;
565  }
566  }
567  else
568  {
569  delete pResult;
570  pResult = NULL;
571  }
572 
573  break;
574  }
575 
576  if (pResult == NULL) pResult = static_cast<CEvaluationNodeLogical*>(pNode->copyBranch());
577  }
578 
579  return pResult;
580 }
581 
583 {
584  CEvaluationNode* pResult = NULL;
585 
586  if (pNode != NULL)
587  {
588  // copy node
589  pResult = pNode->copyBranch();
590  }
591 
592  return pResult;
593 }
594 
596 {
598  CEvaluationNode* pTmpResult;
599 
600  if (pNode != NULL)
601  {
602  const std::vector<CEvaluationNode*>* pItems;
603  std::vector<CEvaluationNode*>::const_iterator it, endit;
604 
606  {
608  // create a new vector with normalized forms of all children
609  pResult = new CEvaluationNodeVector();
610  pItems = &pNode->getVector();
611  it = pItems->begin();
612  endit = pItems->end();
613 
614  while (it != endit)
615  {
616  pTmpResult = CEvaluationNodeNormalizer::normalize(*it);
617 
618  if (pTmpResult != NULL)
619  {
620  if (!pResult->addChild(pTmpResult))
621  {
622  delete pResult;
623  pResult = NULL;
624  break;
625  }
626  }
627  else
628  {
629  delete pResult;
630  pResult = NULL;
631  break;
632  }
633 
634  ++it;
635  }
636 
637  break;
639  break;
640  }
641 
642  if (pResult == NULL) pResult = static_cast<CEvaluationNodeVector*>(pNode->copyBranch());
643  }
644 
645  return pResult;
646 }
647 
649 {
650  CEvaluationNode* pResult = NULL;
651 
652  if (pNode != NULL)
653  {
654  CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
655 
656  if (pChild1 != NULL)
657  {
658  CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
659 
660  if (pChild2 != NULL)
661  {
663  {
664  if (pChild2->getValue() - 1.0 < ZERO)
665  {
666  // replace it with the first child
667  pResult = pChild1;
668  delete pChild2;
669  pChild2 = NULL;
670  }
671  else if (pChild2->getValue() < ZERO)
672  {
673  // replace it by a number node of 1
675  delete pChild1;
676  delete pChild2;
677  pChild1 = NULL;
678  pChild2 = NULL;
679  }
680  }
681  else
682  {
684  pResult->addChild(pChild1);
685  pResult->addChild(pChild2);
686  }
687  }
688  }
689 
690  if (pResult == NULL) pResult = pNode->copyBranch();
691  }
692 
693  return pResult;
694 }
695 
697 {
698  CEvaluationNode* pResult = NULL;
699 
700  if (pNode != NULL)
701  {
702  CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
703 
704  if (pChild1 != NULL)
705  {
706  CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
707 
708  if (pChild2 != NULL)
709  {
710  // if one of the child nodes is zero, replace the node with a number
711  // node of value 0
712 
713  // if one of the nodes is a number node of 1, replace the node by the
714  // other child
716  {
717  if (fabs(pChild1->getValue() - 1.0) < ZERO)
718  {
719  pResult = pChild2;
720  delete pChild1;
721  pChild1 = NULL;
722  pChild2 = NULL;
723  }
724  else if (fabs(pChild1->getValue()) < ZERO)
725  {
727  // we are done
728  delete pChild1;
729  delete pChild2;
730  pChild1 = NULL;
731  pChild2 = NULL;
732  }
733  }
734 
735  if (pChild2 && CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
736  {
737  if (fabs(pChild2->getValue() - 1.0) < ZERO)
738  {
739  pResult = pChild1;
740  delete pChild2;
741  pChild2 = NULL;
742  pChild1 = NULL;
743  }
744  else if (fabs(pChild2->getValue()) < ZERO)
745  {
747  // we are done
748  delete pChild1;
749  delete pChild2;
750  pChild1 = NULL;
751  pChild2 = NULL;
752  }
753  }
754 
755  if (!pResult)
756  {
758  pResult->addChild(pChild1);
759  pResult->addChild(pChild2);
760  }
761 
762  if (pResult->getType() == CEvaluationNode::OPERATOR)
763  {
764  // multiply all number nodes in a multiplication chain
765  std::vector<CEvaluationNode*> chainNodes;
766  findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pResult), chainNodes);
768  // replace multiplication of identical items by a power node with the
769  // correct power
771  // reorder nodes again
773  // rebuild pResult;
775  delete pResult;
776  pResult = CEvaluationNodeNormalizer::buildOperatorBranchFromChain(subType, chainNodes);
777  }
778  }
779  }
780 
781  if (pResult == NULL) pResult = pNode->copyBranch();
782  }
783 
784  return pResult;
785 }
786 
788 {
789  CEvaluationNode* pResult = NULL;
790 
791  if (pNode != NULL)
792  {
793  CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
794 
795  if (pChild1 != NULL)
796  {
797  CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
798 
799  if (pChild2 != NULL)
800  {
801  // if one of the nodes is a number node of 0, replace the node by the
802  // other child
804  {
805  if (fabs(pChild1->getValue()) < ZERO)
806  {
807  pResult = pChild2;
808  delete pChild1;
809  pChild1 = NULL;
810  pChild2 = NULL;
811  }
812  }
813 
814  if (pChild2 != NULL && CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
815  {
816  if (fabs(pChild2->getValue()) < ZERO)
817  {
818  if (pChild2 != pResult)
819  {
820  pResult = pChild1;
821  delete pChild2;
822  }
823 
824  pChild1 = NULL;
825  pChild2 = NULL;
826  }
827  }
828 
829  if (!pResult)
830  {
832  pResult->addChild(pChild1);
833  pResult->addChild(pChild2);
834  }
835 
836  if (pResult->getType() == CEvaluationNode::OPERATOR)
837  {
838  // add all number nodes in a summation chain
839  std::vector<CEvaluationNode*> chainNodes;
840  findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pResult), chainNodes);
842  // replace addition of identical items by a multiplication node with the
843  // correct number
845  // reorder nodes again
847  // rebuild pResult;
849  delete pResult;
850  pResult = CEvaluationNodeNormalizer::buildOperatorBranchFromChain(subType, chainNodes);
851  }
852  }
853  else
854  {
855  delete pChild1;
856  pChild1 = NULL;
857  }
858  }
859 
860  if (pResult == NULL) pResult = pNode->copyBranch();
861  }
862 
863  return pResult;
864 }
865 
867 {
868  CEvaluationNode* pResult = NULL;
869 
870  if (pNode != NULL)
871  {
872  CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
873 
874  if (pChild1 != NULL)
875  {
876  CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
877 
878  if (pChild2 != NULL)
879  {
881  {
882  // eliminate divisions by 1
883  if (fabs(pChild2->getValue() - 1.0) < ZERO)
884  {
885  pResult = pChild1;
886  delete pChild2;
887  pChild2 = NULL;
888  }
889  else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER)
890  {
891  // if both children are numbers, do the calculation
892  std::ostringstream os;
893  os << pChild1->getValue() / pChild2->getValue();
894  pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, os.str());
895  delete pChild1;
896  delete pChild2;
897  pChild1 = NULL;
898  pChild2 = NULL;
899  }
900  }
901  else
902  {
903  // try to shorten numerator and denominator
904  // TODO find out if a factor is involved
905  if (*pChild1 == *pChild2)
906  {
908  delete pChild1;
909  delete pChild2;
910  pChild1 = NULL;
911  pChild2 = NULL;
912  }
913  }
914 
915  if (pResult == NULL)
916  {
918  pResult->addChild(pChild1);
919  pResult->addChild(pChild2);
920  }
921  }
922  else
923  {
924  delete pChild1;
925  pChild1 = NULL;
926  }
927  }
928 
929  if (pResult == NULL) pResult = pNode->copyBranch();
930  }
931 
932  return pResult;
933 }
934 
936 {
937  CEvaluationNode* pResult = NULL;
938 
939  if (pNode != NULL)
940  {
941  CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
942 
943  if (pChild1 != NULL)
944  {
945  CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
946 
947  if (pChild2 != NULL)
948  {
950  {
951  // eliminate modulus 1
952  if (fabs(pChild2->getValue() - 1.0) < ZERO)
953  {
955  delete pChild1;
956  delete pChild2;
957  pChild1 = NULL;
958  pChild2 = NULL;
959  }
960  else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER &&
963  {
964  // if both children are numbers, do the calculation
965  std::ostringstream os;
966  os << (long)pChild1->getValue() % (long)pChild2->getValue();
967  pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, os.str());
968  delete pChild1;
969  delete pChild2;
970  pChild1 = NULL;
971  pChild2 = NULL;
972  }
973  }
974  else
975  {
976  // try to shorten numerator and denominator
977  // TODO find out if a factor is involved
978  if (*pChild1 == *pChild2)
979  {
981  delete pChild1;
982  delete pChild2;
983  pChild1 = NULL;
984  pChild2 = NULL;
985  }
986  }
987 
988  if (pResult == NULL)
989  {
991  pResult->addChild(pChild1);
992  pResult->addChild(pChild2);
993  }
994  }
995  else
996  {
997  delete pChild1;
998  pChild1 = NULL;
999  }
1000  }
1001 
1002  if (pResult == NULL) pResult = pNode->copyBranch();
1003  }
1004 
1005  return pResult;
1006 }
1007 
1009 {
1010  CEvaluationNode* pResult = NULL;
1011 
1012  if (pNode != NULL)
1013  {
1014  CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
1015 
1016  if (pChild1 != NULL)
1017  {
1018  CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));
1019 
1020  if (pChild2 != NULL)
1021  {
1023  {
1024  // eliminate subtraction of 0
1025  if (fabs(pChild2->getValue()) < ZERO)
1026  {
1027  pResult = pChild1;
1028  delete pChild2;
1029  pChild1 = NULL;
1030  pChild2 = NULL;
1031  }
1032  else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER)
1033  {
1034  // if both children are numbers, do the calculation
1035  std::ostringstream os;
1036  os << pChild1->getValue() - pChild2->getValue();
1037  pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, os.str());
1038  delete pChild1;
1039  delete pChild2;
1040  pChild1 = NULL;
1041  pChild2 = NULL;
1042  }
1043  }
1044  else
1045  {
1046  // TODO find out if a factor is involved
1047  if (*pChild1 == *pChild2)
1048  {
1050  delete pChild1;
1051  delete pChild2;
1052  pChild1 = NULL;
1053  pChild2 = NULL;
1054  }
1055  }
1056 
1057  if (pResult == NULL)
1058  {
1060  pResult->addChild(pChild1);
1061  pResult->addChild(pChild2);
1062  }
1063  }
1064  else
1065  {
1066  delete pChild1;
1067  pChild1 = NULL;
1068  }
1069  }
1070 
1071  if (pResult == NULL) pResult = pNode->copyBranch();
1072  }
1073 
1074  return pResult;
1075 }
1076 
1077 bool CEvaluationNodeNormalizer::eliminateMultipleNumbers(CEvaluationNodeOperator::SubType subType, std::vector<CEvaluationNode*>& chainNodes)
1078 {
1079  // check if there are several numerical values in the operator chain and
1080  // evaluate those operations
1081  bool changed = false;
1082 
1083  if (chainNodes.size() > 1)
1084  {
1085  std::vector<CEvaluationNode*>::iterator it = chainNodes.begin(), endit = chainNodes.end();
1086 
1088  {
1089 
1090  double value = (subType == CEvaluationNodeOperator::MULTIPLY) ? 1.0 : 0.0;
1091  CEvaluationNodeNumber* pNumberNode = NULL;
1092  std::vector<CEvaluationNode*> numbers;
1093 
1094  while (it != endit)
1095  {
1096  pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(*it);
1097 
1098  if (pNumberNode != NULL)
1099  {
1100  numbers.push_back(pNumberNode);
1101 
1102  if (subType == CEvaluationNodeOperator::MULTIPLY)
1103  {
1104  value *= pNumberNode->getValue();
1105  }
1106  else
1107  {
1108  value += pNumberNode->getValue();
1109  }
1110  }
1111 
1112  ++it;
1113  }
1114 
1115  if (numbers.size() > 1)
1116  {
1117  changed = true;
1118  it = numbers.begin(), endit = numbers.end();
1119  // don't delete the last one since we reset it's value
1120  --endit;
1121 
1122  while (it != endit)
1123  {
1124  chainNodes.erase(std::find(chainNodes.begin(), chainNodes.end(), *it));
1125  delete *it;
1126  ++it;
1127  }
1128 
1129  std::ostringstream os;
1130  os << value;
1131  (*it)->setData(os.str());
1132  }
1133  }
1134  }
1135 
1136  return changed;
1137 }
1138 
1139 void CEvaluationNodeNormalizer::findChainNodes(CEvaluationNodeOperator* pNode, std::vector<CEvaluationNode*>& nodes)
1140 {
1142  CEvaluationNode* pChild1 = dynamic_cast<CEvaluationNode*>(pNode->getChild());
1143 
1144  if (pChild1 != NULL)
1145  {
1146  CEvaluationNode* pChild2 = dynamic_cast<CEvaluationNode*>(pChild1->getSibling());
1147 
1148  if (pChild2 != NULL)
1149  {
1151  {
1152  findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pChild1), nodes);
1153  }
1154  else
1155  {
1156  nodes.push_back(pChild1->copyBranch());
1157  }
1158 
1160  {
1161  findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pChild2), nodes);
1162  }
1163  else
1164  {
1165  nodes.push_back(pChild2->copyBranch());
1166  }
1167  }
1168  }
1169 }
1170 
1172 {
1174  std::string data;
1175 
1176  switch (subType)
1177  {
1179  data = "^";
1180  break;
1182  data = "*";
1183  break;
1185  data = "/";
1186  break;
1188  data = "%";
1189  break;
1191  data = "+";
1192  break;
1194  data = "-";
1195  break;
1196  default:
1197  fatalError();
1198  break;
1199  }
1200 
1201  if (chainNodes.size() > 1)
1202  {
1203  std::vector<CEvaluationNode*>::const_reverse_iterator it = chainNodes.rbegin(), endit = chainNodes.rend();
1204  CEvaluationNodeOperator* pTmpOperator = new CEvaluationNodeOperator(subType, data);
1205  // add the first child
1206  pTmpOperator->addChild(*it);
1207  ++it;
1208  --endit;
1209 
1210  while (it != endit)
1211  {
1212  pTmpOperator->addChild(*it);
1213  pResult = new CEvaluationNodeOperator(subType, data);
1214  pResult->addChild(pTmpOperator);
1215  pTmpOperator = pResult;
1216  ++it;
1217  }
1218 
1219  // add the last child
1220  pResult->addChild(*it);
1221  }
1222 
1223  return pResult;
1224 }
1225 
1226 bool CEvaluationNodeNormalizer::collectIdenticalBranches(CEvaluationNodeOperator::SubType subType, std::vector<CEvaluationNode*>& chainNodes)
1227 {
1228  bool changed = false;
1229 
1230  if (chainNodes.size() > 1)
1231  {
1232  // what is done depends on the subtype
1233  // if it is an additon we replace identical nodes with a multiplication of
1234  // the node with the number of occurences
1235  // for a multiplication it's the same, but we use a power instead of a
1236  // multiplication
1238  {
1240  std::vector<CEvaluationNode*>::iterator it = chainNodes.begin(), endit = chainNodes.end();
1241  std::map<CEvaluationNode, unsigned int> occurenceMap;
1242 
1243  while (it != endit)
1244  {
1245  std::map<CEvaluationNode, unsigned int>::iterator pos = occurenceMap.find(**it);
1246 
1247  if (pos == occurenceMap.end())
1248  {
1249  occurenceMap[**it] = 1;
1250  }
1251  else
1252  {
1253  ++(pos->second);
1254  changed = true;
1255  }
1256 
1257  // delete the node
1258  delete(*it);
1259  ++it;
1260  }
1261 
1262  chainNodes.clear();
1263  // convert the contents of the occurenceMap to new nodes
1264  std::map<CEvaluationNode, unsigned int>::const_iterator mapIt = occurenceMap.begin(), mapEndit = occurenceMap.end();
1265  std::ostringstream os;
1266 
1267  while (mapIt != mapEndit)
1268  {
1269  os << mapIt->second;
1271  CEvaluationNodeOperator* pNewOperator = dynamic_cast<CEvaluationNodeOperator*>(CEvaluationNode::create(pOperation->getType(), pOperation->getData()));
1272  pNewOperator->addChild(pNumberNode);
1273  pNewOperator->addChild(mapIt->first.copyBranch());
1274  chainNodes.push_back(pNewOperator);
1275  os.str("");
1276  ++mapIt;
1277  }
1278 
1279  delete pOperation;
1280  }
1281  }
1282 
1283  return changed;
1284 }
1285 
1286 bool CEvaluationNodeNormalizer::reorderNodes(std::vector<CEvaluationNode*>& chainNodes)
1287 {
1288  std::sort(chainNodes.begin(), chainNodes.end(), lessCEvaluationNodes());
1289  return true;
1290 }
static CEvaluationNode * normalizePowerNode(const CEvaluationNodeOperator *pNode)
static CEvaluationNodeOperator * buildOperatorBranchFromChain(CEvaluationNodeOperator::SubType subType, const std::vector< CEvaluationNode * > &chainNodes)
CEvaluationNode * copyBranch() const
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
static CEvaluationNode * normalizeCEvaluationNodeCall(const CEvaluationNodeCall *pNode)
static CEvaluationNode * normalizeCEvaluationNodeChoice(const CEvaluationNodeChoice *pNode)
static void findChainNodes(CEvaluationNodeOperator *pNode, std::vector< CEvaluationNode * > &nodes)
const C_FLOAT64 & getValue() const
static CEvaluationNode * normalizeCEvaluationNodeDelay(const CEvaluationNodeDelay *pNode)
#define fatalError()
const Type & getType() const
static CEvaluationNode * normalizeCEvaluationNodeVector(const CEvaluationNodeVector *pNode)
static CEvaluationNode * create(const Type &type, const Data &data)
static CEvaluationNode * normalizeCEvaluationNodeVariable(const CEvaluationNodeVariable *pNode)
const std::vector< CEvaluationNode * > & getVector() const
static CEvaluationNode * normalizeDivideNode(const CEvaluationNodeOperator *pNode)
const std::vector< CEvaluationNode * > getListOfChildNodes() const
static CEvaluationNode * normalizeModulusNode(const CEvaluationNodeOperator *pNode)
static CEvaluationNode * normalizeCEvaluationNodeObject(const CEvaluationNodeObject *pNode)
static CEvaluationNode * normalizeMultiplyNode(const CEvaluationNodeOperator *pNode)
bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
static Type type(const Type &type)
virtual const Data & getData() const
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
virtual bool removeChild(CCopasiNode< Data > *pChild)
static CEvaluationNode * normalizeCEvaluationNodeWhiteSpace(const CEvaluationNodeWhiteSpace *pNode)
static CEvaluationNode * normalizeCEvaluationNodeOperator(const CEvaluationNodeOperator *pNode)
static bool eliminateMultipleNumbers(CEvaluationNodeOperator::SubType subType, std::vector< CEvaluationNode * > &chainNodes)
static CEvaluationNode * normalizeCEvaluationNodeStructure(const CEvaluationNodeStructure *pNode)
const CArrayAnnotation * pResult
static Type subType(const Type &type)
static bool reorderNodes(std::vector< CEvaluationNode * > &chainNodes)
static CEvaluationNode * normalize(const CEvaluationNode *node)
static bool collectIdenticalBranches(CEvaluationNodeOperator::SubType subType, std::vector< CEvaluationNode * > &chainNodes)
static CEvaluationNode * normalizeMinusNode(const CEvaluationNodeOperator *pNode)
virtual const Data & getData() const
Definition: CCopasiNode.h:118
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
static CEvaluationNode * normalizeCEvaluationNodeFunction(const CEvaluationNodeFunction *pNode)
static CEvaluationNode * normalizeCEvaluationNodeLogical(const CEvaluationNodeLogical *pNode)
static CEvaluationNode * normalizeCEvaluationNodeConstant(const CEvaluationNodeConstant *pNode)
static CEvaluationNode * normalizePlusNode(const CEvaluationNodeOperator *pNode)
static CEvaluationNode * normalizeCEvaluationNodeNumber(const CEvaluationNodeNumber *pNode)