COPASI API  4.16.103
CEvaluationNodeLogical.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include "copasi.h"
16 #include "CEvaluationNode.h"
17 #include "CEvaluationTree.h"
18 
19 #include "sbml/math/ASTNode.h"
20 
22  CEvaluationNode(CEvaluationNode::INVALID, ""),
23  mpLeft(NULL),
24  mpRight(NULL)
25 {}
26 
28  const Data & data):
29  CEvaluationNode((Type)(CEvaluationNode::LOGICAL | subType), data),
30  mpLeft(NULL),
31  mpRight(NULL)
32 {
33  switch (mType & 0x00FFFFFF)
34  {
35  case OR:
37  break;
38 
39  case XOR:
41  break;
42 
43  case AND:
45  break;
46 
47  case EQ:
49  break;
50 
51  case NE:
53  break;
54 
55  case GT:
57  break;
58 
59  case GE:
61  break;
62 
63  case LT:
65  break;
66 
67  case LE:
69  break;
70  }
71 }
72 
74  CEvaluationNode(src),
75  mpLeft(NULL),
76  mpRight(NULL)
77 {}
78 
80 
82 {
83  mpLeft = static_cast<CEvaluationNode *>(getChild());
84 
85  if (mpLeft == NULL) return false;
86 
87  mpRight = static_cast<CEvaluationNode *>(mpLeft->getSibling());
88 
89  if (mpRight == NULL) return false;
90 
91  return (mpRight->getSibling() == NULL); // We must have exactly two children
92 }
93 
94 // virtual
95 std::string CEvaluationNodeLogical::getInfix(const std::vector< std::string > & children) const
96 {
97  if (const_cast<CEvaluationNodeLogical *>(this)->compile(NULL))
98  {
99  Data Infix;
100 
101  if (*mpLeft < * (CEvaluationNode *)this)
102  Infix = "(" + children[0] + ")";
103  else
104  Infix = children[0];
105 
106  Infix += " " + mData + " ";
107 
108  if (!(*(CEvaluationNode *)this < *mpRight))
109  Infix += "(" + children[1] + ")";
110  else
111  Infix += children[1];
112 
113  return Infix;
114  }
115  else
116  return "@";
117 }
118 
119 // virtual
120 std::string CEvaluationNodeLogical::getDisplayString(const std::vector< std::string > & children) const
121 {
122  if (const_cast<CEvaluationNodeLogical *>(this)->compile(NULL))
123  {
124  Data DisplayString;
125 
126  if (*mpLeft < * (CEvaluationNode *)this)
127  DisplayString = "(" + children[0] + ")";
128  else
129  DisplayString = children[0] + " ";
130 
131  DisplayString += mData;
132 
133  if (!(*(CEvaluationNode *)this < *mpRight))
134  DisplayString += "(" + children[1] + ")";
135  else
136  DisplayString += " " + children[1];
137 
138  return DisplayString;
139  }
140  else
141  return "@";
142 }
143 
144 // virtual
145 std::string CEvaluationNodeLogical::getCCodeString(const std::vector< std::string > & children) const
146 {
147  if (const_cast<CEvaluationNodeLogical *>(this)->compile(NULL))
148  {
149  Data DisplayString;
150  Data data;
151  bool isXor = false;
152 
153  switch ((SubType)CEvaluationNode::subType(this->getType()))
154  {
155  case AND:
156  data = "&&";
157  break;
158 
159  case OR:
160  data = "||";
161  break;
162 
163  case EQ:
164  data = "==";
165  break;
166 
167  case GE:
168  data = ">=";
169  break;
170 
171  case GT:
172  data = ">";
173  break;
174 
175  case LE:
176  data = "<=";
177  break;
178 
179  case LT:
180  data = "<";
181  break;
182 
183  case NE:
184  data = "!=";
185  break;
186 
187  default:
188  /*
189  * case XOR:
190  */
191  data = "!=";
192  isXor = true;
193  break;
194  }
195 
196  if (isXor)
197  DisplayString = " !";
198  else
199  DisplayString = "";
200 
201  if (*mpLeft < * (CEvaluationNode *)this)
202  DisplayString += "(" + children[0] + ")";
203  else
204  DisplayString += children[0] + " ";
205 
206  DisplayString += data;
207 
208  if (isXor)
209  DisplayString += " !";
210 
211  if (!(*(CEvaluationNode *)this < *mpRight))
212  DisplayString += "(" + children[1] + ")";
213  else
214  DisplayString += " " + children[1];
215 
216  return DisplayString;
217  }
218  else
219  return "@";
220 }
221 
222 // virtual
223 std::string CEvaluationNodeLogical::getBerkeleyMadonnaString(const std::vector< std::string > & children) const
224 {
225  if (const_cast<CEvaluationNodeLogical *>(this)->compile(NULL))
226  {
227  Data DisplayString;
228  Data data;
229 
230  switch ((SubType)CEvaluationNode::subType(this->getType()))
231  {
232  case AND:
233  data = "AND";
234  break;
235 
236  case OR:
237  data = "OR";
238  break;
239 
240  /* case XOR:
241  break; */
242  case EQ:
243  data = "=";
244  break;
245 
246  case GE:
247  data = ">=";
248  break;
249 
250  case GT:
251  data = ">";
252  break;
253 
254  case LE:
255  data = "<=";
256  break;
257 
258  case LT:
259  data = "<";
260  break;
261 
262  case NE:
263  data = "<>";
264  break;
265 
266  default:
267  data = "@";
268  break;
269  }
270 
271  if (*mpLeft < * (CEvaluationNode *)this)
272  DisplayString = "(" + children[0] + ")";
273  else
274  DisplayString = children[0] + " ";
275 
276  DisplayString += data;
277 
278  if (!(*(CEvaluationNode *)this < *mpRight))
279  DisplayString += "(" + children[1] + ")";
280  else
281  DisplayString += " " + children[1];
282 
283  return DisplayString;
284  }
285  else
286  return "@";
287 }
288 
289 // virtual
290 std::string CEvaluationNodeLogical::getXPPString(const std::vector< std::string > & children) const
291 {
292  if (const_cast<CEvaluationNodeLogical *>(this)->compile(NULL))
293  {
294  Data DisplayString;
295  Data data;
296 
297  switch ((SubType)CEvaluationNode::subType(this->getType()))
298  {
299  case AND:
300  data = "&";
301  break;
302 
303  case OR:
304  data = "|";
305  break;
306 
307  case EQ:
308  data = "==";
309  break;
310 
311  case GE:
312  data = ">=";
313  break;
314 
315  case GT:
316  data = ">";
317  break;
318 
319  case LE:
320  data = "<=";
321  break;
322 
323  case LT:
324  data = "<";
325  break;
326 
327  case NE:
328  data = "!=";
329  break;
330 
331  default:
332  /* case XOR: */
334  data = "@"; //TODO
335  break;
336  }
337 
338  if (*mpLeft < * (CEvaluationNode *)this)
339  DisplayString = "(" + children[0] + ")";
340  else
341  DisplayString = children[0] + " ";
342 
343  DisplayString += data;
344 
345  if (!(*(CEvaluationNode *)this < *mpRight))
346  DisplayString += "(" + children[1] + ")";
347  else
348  DisplayString += " " + children[1];
349 
350  return DisplayString;
351  }
352  else
353  return "@"; //TODO
354 }
355 
356 // static
357 CEvaluationNode * CEvaluationNodeLogical::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
358 {
359  assert(pASTNode->getNumChildren() == children.size());
360 
361  size_t i = 0;
362  size_t iMax = children.size();
363 
365  std::string data = "";
366 
367  switch (pASTNode->getType())
368  {
369  case AST_LOGICAL_AND:
370  subType = AND;
371  data = "and";
372  break;
373 
374  case AST_LOGICAL_OR:
375  subType = OR;
376  data = "or";
377  break;
378 
379  case AST_LOGICAL_XOR:
380  subType = XOR;
381  data = "xor";
382  break;
383 
384  case AST_RELATIONAL_EQ:
385  subType = EQ;
386  data = "eq";
387  break;
388 
389  case AST_RELATIONAL_GEQ:
390  subType = GE;
391  data = "ge";
392  break;
393 
394  case AST_RELATIONAL_GT:
395  subType = GT;
396  data = "gt";
397  break;
398 
399  case AST_RELATIONAL_LEQ:
400  subType = LE;
401  data = "le";
402  break;
403 
404  case AST_RELATIONAL_LT:
405  subType = LT;
406  data = "lt";
407  break;
408 
409  case AST_RELATIONAL_NEQ:
410  subType = NE;
411  data = "ne";
412  break;
413 
414  default:
415  subType = INVALID;
416  break;
417  }
418 
419  CEvaluationNode* pNode = NULL;
420  // convert the two children
421 
422  switch (subType)
423  {
424  case AND:
425  case OR:
426  case XOR:
427 
428  // The number of chidren may vary
429  switch (iMax)
430  {
431  case 0:
432 
433  if (subType == AND)
435  else
437 
438  break;
439 
440  case 1:
441  pNode = children[0];
442  break;
443 
444  default:
445  {
446  pNode = new CEvaluationNodeLogical(subType, data);
447  CEvaluationNode * pCurrent = pNode;
448 
449  // We have at least 2 children
450  while (i < iMax - 1)
451  {
452  // add the first value
453  pCurrent->addChild(children[i++]);
454 
455  switch (iMax - i)
456  {
457  case 1:
458  // We have only 1 more child
459  pCurrent->addChild(children[i++]);
460  break;
461 
462  default:
463  // We have at least 2 more children
464  {
465  // create a new node with the same operator
466  CEvaluationNode * pTmp = new CEvaluationNodeLogical(subType, data);
467  pCurrent->addChild(pTmp);
468  pCurrent = pTmp;
469  }
470  break;
471  }
472  }
473  }
474  break;
475  }
476 
477  break;
478 
479  case EQ:
480  case NE:
481  case GE:
482  case GT:
483  case LE:
484  case LT:
485  // all these are binary
486  assert(iMax == 2);
487  pNode = new CEvaluationNodeLogical(subType, data);
488  pNode->addChild(children[0]);
489  pNode->addChild(children[1]);
490  break;
491 
492  case INVALID:
493  // do nothing
494  break;
495  }
496 
497  return pNode;
498 }
499 
500 // virtual
502 {return true;}
503 
504 ASTNode* CEvaluationNodeLogical::toAST(const CCopasiDataModel* pDataModel) const
505 {
507  ASTNode* node = new ASTNode();
508 
509  switch (subType)
510  {
511  case AND:
512  node->setType(AST_LOGICAL_AND);
513  break;
514 
515  case OR:
516  node->setType(AST_LOGICAL_OR);
517  break;
518 
519  case XOR:
520  node->setType(AST_LOGICAL_XOR);
521  break;
522 
523  case EQ:
524  node->setType(AST_RELATIONAL_EQ);
525  break;
526 
527  case NE:
528  node->setType(AST_RELATIONAL_NEQ);
529  break;
530 
531  case GT:
532  node->setType(AST_RELATIONAL_GT);
533  break;
534 
535  case GE:
536  node->setType(AST_RELATIONAL_GEQ);
537  break;
538 
539  case LT:
540  node->setType(AST_RELATIONAL_LT);
541  break;
542 
543  case LE:
544  node->setType(AST_RELATIONAL_LEQ);
545  break;
546 
547  case INVALID:
548  break;
549 
550  default:
551  subType = INVALID;
552  break;
553  }
554 
555  if (subType != INVALID)
556  {
557  const CEvaluationNode* child1 = dynamic_cast<const CEvaluationNode*>(this->getChild());
558  const CEvaluationNode* child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
559  node->addChild(child1->toAST(pDataModel));
560  node->addChild(child2->toAST(pDataModel));
561  }
562 
563  return node;
564 }
565 
566 #include "utilities/copasimathml.h"
567 
568 // virtual
569 std::string CEvaluationNodeLogical::getMMLString(const std::vector< std::string > & children,
570  bool /* expand */,
571  const std::vector< std::vector< std::string > > & /* variables */) const
572 {
573  std::ostringstream out;
574 
575  if (const_cast<CEvaluationNodeLogical *>(this)->compile(NULL))
576  {
577  std::string data = "";
578  bool flag = false;
579 
580  switch ((SubType)CEvaluationNode::subType(this->getType()))
581  {
582  case AND:
583  data = " and ";
584  break;
585 
586  case OR:
587  data = " or ";
588  break;
589 
590  case XOR:
591  data = " xor ";
592  break;
593 
594  case EQ:
595  data = "=";
596  break;
597 
598  case GE:
599  data = "&gt;=";
600  break;
601 
602  case GT:
603  data = "&gt;";
604  break;
605 
606  case LE:
607  data = "&lt;=";
608  break;
609 
610  case LT:
611  data = "&lt;";
612  break;
613 
614  case NE:
615  data = "&NotEqual;";
616  break;
617 
618  default:
619  /*
620  *
621  */
622  data = "@";
623  break;
624  }
625 
626  out << "<mrow>" << std::endl;
627 
628  flag = ((*mpLeft < * (CEvaluationNode *)this));
629 
630  if (flag) out << "<mfenced>" << std::endl;
631 
632  out << children[0];
633 
634  if (flag) out << "</mfenced>" << std::endl;
635 
636  out << "<mo>" << data << "</mo>" << std::endl;
637 
638  flag = ((*(CEvaluationNode *)this < *mpRight));
639 
640  if (!flag) out << "<mfenced>" << std::endl;
641 
642  out << children[1];
643 
644  if (!flag) out << "</mfenced>" << std::endl;
645 
646  out << "</mrow>" << std::endl;
647  }
648 
649  return out.str();
650 }
#define PRECEDENCE_LOGIG_AND
#define PRECEDENCE_LOGIG_XOR
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
#define PRECEDENCE_LOGIG_OR
virtual std::string getXPPString(const std::vector< std::string > &children) const
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
#define PRECEDENCE_LOGIG_LE
#define PRECEDENCE_LOGIG_NE
#define PRECEDENCE_LOGIG_LT
virtual std::string getBerkeleyMadonnaString(const std::vector< std::string > &children) const
const Type & getType() const
static CEvaluationNode * fromAST(const ASTNode *pASTNode, const std::vector< CEvaluationNode * > &children)
virtual std::string getDisplayString(const std::vector< std::string > &children) const
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
virtual std::string getCCodeString(const std::vector< std::string > &children) const
#define PRECEDENCE_LOGIG_EQ
virtual std::string getMMLString(const std::vector< std::string > &children, bool expand, const std::vector< std::vector< std::string > > &variables) const
virtual bool compile(const CEvaluationTree *pTree)
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
virtual bool isBoolean() const
long int flag
Definition: f2c.h:52
static Type subType(const Type &type)
class CEvaluationNode::CPrecedence mPrecedence
virtual std::string getInfix(const std::vector< std::string > &children) const
#define PRECEDENCE_LOGIG_GE
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
#define PRECEDENCE_LOGIG_GT