COPASI API  4.16.103
CEvaluationNodeCall.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 <sbml/math/ASTNode.h>
16 
17 #include "copasi.h"
18 
19 #include "CEvaluationNode.h"
20 #include "CEvaluationTree.h"
21 #include "CFunction.h"
22 #include "CExpression.h"
23 #include "CFunctionDB.h"
25 #include "utilities/utility.h"
27 
29  CEvaluationNode(CEvaluationNode::INVALID, ""),
30  mpFunction(NULL),
31  mpExpression(NULL),
32  mCallNodes(),
33  mpCallParameters(NULL),
34  mQuotesRequired(false),
35  mBooleanRequired(false),
36  mRegisteredFunctionCN()
38 
40  const Data & data):
41  CEvaluationNode((Type)(CEvaluationNode::CALL | subType), data),
42  mpFunction(NULL),
43  mpExpression(NULL),
44  mCallNodes(),
45  mpCallParameters(NULL),
46  mQuotesRequired(false),
47  mBooleanRequired(false),
48  mRegisteredFunctionCN()
49 {
50  setData(data);
51  mData = unQuote(mData);
52 
53  // We force quoting if the round trip unquote, quote does not recover the original input
54  if (isKeyword(mData))
55  {
56  mQuotesRequired = true;
57  }
58 
59  if (mData != data && quote(mData) != data)
60  {
61  mQuotesRequired = true;
62  }
63 
64  switch (subType)
65  {
66  case FUNCTION:
67  case EXPRESSION:
68  break;
69 
70  default:
71  fatalError();
72  break;
73  }
74 
76 }
77 
79  CEvaluationNode(src),
80  mpFunction(src.mpFunction),
81  mpExpression(src.mpExpression),
82  mCallNodes(src.mCallNodes),
83  mpCallParameters(NULL),
84  mQuotesRequired(src.mQuotesRequired),
85  mBooleanRequired(src.mBooleanRequired),
86  mRegisteredFunctionCN(src.mRegisteredFunctionCN)
88 
90 
92 {
93  switch (mType & 0x00FFFFFF)
94  {
95  case FUNCTION:
97  break;
98 
99  case EXPRESSION:
101  break;
102 
103  default:
104  mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();
105  break;
106  }
107 }
108 
110 {
111  bool success = true;
113 
114  CObjectInterface * pObjectInterface = NULL;
115 
116  if (mRegisteredFunctionCN != "")
117  {
118  pObjectInterface = const_cast< CObjectInterface * >(CCopasiRootContainer::getRoot()->getObject(mRegisteredFunctionCN));
119  }
120 
121  switch (mType & 0x00FFFFFF)
122  {
123  case FUNCTION:
124 
125  if (pObjectInterface != NULL)
126  {
127  mpFunction = dynamic_cast< CFunction * >(pObjectInterface);
128  }
129  else
130  {
131  mpFunction =
133  }
134 
135  if (!mpFunction) return false;
136 
138 
139  // We need to check whether the provided arguments match the on needed by the
140  // function;
141  if (!verifyParameters(mCallNodes, mpFunction->getVariables())) return false;
142 
144  break;
145 
146  case EXPRESSION:
147 
148  if (pObjectInterface != NULL)
149  {
150  mpExpression = dynamic_cast<CExpression *>(pObjectInterface);
151  }
152  else
153  {
154  mpExpression =
156  }
157 
158  if (!mpExpression)
159  {
160  // We may have a function with no arguments the parser is not able to distinguish
161  // between that and an expression.
162  if (pObjectInterface != NULL)
163  {
164  mpFunction = dynamic_cast< CFunction * >(pObjectInterface);
165  }
166  else
167  {
168  mpFunction =
170  }
171 
172  if (!mpFunction) return false;
173 
175 
177  success = compile(pTree);
178  }
179  else
180  {
182 
183  success = mpExpression->compile(static_cast<const CExpression *>(pTree)->getListOfContainer());
184  }
185 
186  break;
187 
188  default:
189  success = false;
190  break;
191  }
192 
193  return success;
194 }
195 
196 bool CEvaluationNodeCall::calls(std::set< std::string > & list) const
197 {
198  if (list.count(mData)) return true;
199 
200  CEvaluationTree * pTree =
202 
203  if (pTree) return pTree->calls(list);
204 
205  return false;
206 }
207 
208 // virtual
210 {
211  // We determine whether quoting is required here since we can not be sure
212  // that the original infix is correct.
213 
214  std::string Data;
215 
216  if (isKeyword(mData))
217  {
218  mQuotesRequired = true;
219  }
220 
221  if (mpFunction != NULL)
222  {
223  Data = mpFunction->getObjectName();
225 
226  return mpFunction->getObjectName();
227  }
228 
229  if (mpExpression != NULL)
230  {
231  Data = mpExpression->getObjectName();
233 
234  return mpExpression->getObjectName();
235  }
236 
237  return mData;
238 }
239 
240 // virtual
242 {
243  mData = unQuote(data);
244 
245  // We force quoting if the round trip unquote, quote does not recover the original input
246  if (isKeyword(mData))
247  {
248  mQuotesRequired = true;
249  }
250 
251  if (mData != data && quote(mData) != data)
252  {
253  mQuotesRequired = true;
254  }
255 
256  mRegisteredFunctionCN = std::string("");
257 
258  return true;
259 }
260 
261 // virtual
262 std::string CEvaluationNodeCall::getInfix(const std::vector< std::string > & children) const
263 {
264  std::string Infix;
265 
266  //We use getData instead of mData since getData also detects whether quoting is needed.
267  const std::string & Data = getData();
268 
269  if (mQuotesRequired)
270  {
271  Infix = "\"" + quote(Data, "-+^*/%(){},\t\r\n\"") + "\"(";
272  }
273  else
274  {
275  Infix = quote(Data, "-+^*/%(){},\t\r\n") + "(";
276  }
277 
278  switch (mType & 0x00FFFFFF)
279  {
280  case FUNCTION:
281  {
282  std::vector< std::string >::const_iterator it = children.begin();
283  std::vector< std::string>::const_iterator end = children.end();
284 
285  if (it != end) Infix += *it++;
286 
287  for (; it != end; ++it)
288  Infix += "," + *it;
289  }
290 
291  break;
292 
293  case EXPRESSION:
294  break;
295 
296  default:
297  return "@";
298  break;
299  }
300 
301  return Infix + ")";
302 }
303 
304 // virtual
305 std::string CEvaluationNodeCall::getDisplayString(const std::vector< std::string > & children) const
306 {
307  std::string DisplayString;
308 
309  if (mQuotesRequired)
310  {
311  DisplayString = "\"" + quote(mData, "-+^*/%(){},\t\r\n\"") + "\"(";
312  }
313  else
314  {
315  DisplayString = quote(mData, "-+^*/%(){},\t\r\n") + "(";
316  }
317 
318  switch (mType & 0x00FFFFFF)
319  {
320  case FUNCTION:
321  {
322  std::vector< std::string >::const_iterator it = children.begin();
323  std::vector< std::string >::const_iterator end = children.end();
324 
325  if (it != end) DisplayString += *it++;
326 
327  for (; it != end; ++it)
328  DisplayString += "," + *it;
329  }
330 
331  break;
332 
333  case EXPRESSION:
334  break;
335 
336  default:
337  return "@";
338  break;
339  }
340 
341  return DisplayString + ")";
342 }
343 
344 // virtual
345 std::string CEvaluationNodeCall::getCCodeString(const std::vector< std::string > & children) const
346 {
347  std::string DisplayString;
348 
349  std::string Data;
350 
351  if (mData.empty())
352  Data = getData();
353  else
354  Data = mData;
355 
356  if (mQuotesRequired)
357  {
358  DisplayString = "\"" + quote(Data, "-+^*/%(){},\t\r\n\"") + "\"(";
359  }
360  else
361  {
362  DisplayString = quote(Data, "-+^*/%(){},\t\r\n") + "(";
363  }
364 
365  switch (mType & 0x00FFFFFF)
366  {
367  case FUNCTION:
368  {
369 
370  std::vector< std::string >::const_iterator it = children.begin();
371  std::vector< std::string >::const_iterator end = children.end();
372 
373  if (it != end) DisplayString += *it++;
374 
375  for (; it != end; ++it)
376  DisplayString += "," + *it;
377  }
378 
379  break;
380 
381  case EXPRESSION:
382  break;
383 
384  default:
385  return "@";
386  break;
387  }
388 
389  return DisplayString + ")";
390 }
391 
392 // virtual
393 std::string CEvaluationNodeCall::getBerkeleyMadonnaString(const std::vector< std::string > & /* children */) const
394 {
395  std::string DisplayString;
396 
397  if (mQuotesRequired)
398  {
399  DisplayString = "\"" + quote(mData, "-+^*/%(){},\t\r\n\"") + "\"(";
400  }
401  else
402  {
403  DisplayString = quote(mData, "-+^*/%(){},\t\r\n") + "(";
404  }
405 
406  return DisplayString;
407 }
408 
409 // virtual
410 std::string CEvaluationNodeCall::getXPPString(const std::vector< std::string > & /* children */) const
411 {
412  std::string DisplayString;
413 
414  if (mQuotesRequired)
415  {
416  DisplayString = "\"" + quote(mData, "-+^*/%(){},\t\r\n\"") + "\"(";
417  }
418  else
419  {
420  DisplayString = quote(mData, "-+^*/%(){},\t\r\n") + "(";
421  }
422 
423  return DisplayString;
424 }
425 
426 // static
427 CEvaluationNode * CEvaluationNodeCall::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
428 {
429  assert(pASTNode->getNumChildren() == children.size());
430 
432  std::string data = pASTNode->getName();
433 
434  CEvaluationNodeCall * pNode = new CEvaluationNodeCall(subType, data);
435 
436  pNode->addChildren(children);
437 
438  return pNode;
439 }
440 
441 ASTNode* CEvaluationNodeCall::toAST(const CCopasiDataModel* pDataModel) const
442 {
443  ASTNode* pNode = NULL;
444 
445  pNode = new ASTNode(AST_FUNCTION);
446  const std::string funName = this->getData();
448  assert(pFun != NULL);
449 
450  if (pFun == NULL || pFun->getSBMLId().empty()) fatalError();
451 
452  pNode->setName(pFun->getSBMLId().c_str());
453 
454  const CEvaluationNode* child = static_cast<const CEvaluationNode*>(this->getChild());
455 
456  while (child)
457  {
458  pNode->addChild(child->toAST(pDataModel));
459  child = static_cast<const CEvaluationNode*>(child->getSibling());
460  }
461 
462  return pNode;
463 }
464 
466  CCopasiNode< Data > * pAfter)
467 {
468  CCopasiNode< Data >::addChild(pChild, pAfter);
469 
470  if (pAfter == NULL)
471  {
472  mCallNodes.push_back(static_cast<CEvaluationNode *>(pChild));
473  return true;
474  }
475 
476  std::vector<CEvaluationNode *>::iterator it = mCallNodes.begin();
477 
478  if (pAfter != this)
479  {
480  std::vector<CEvaluationNode *>::iterator end = mCallNodes.end();
481 
482  while (it != end && *it != pAfter) ++it;
483  }
484 
485  mCallNodes.insert(it, static_cast<CEvaluationNode *>(pChild));
486 
487  return true;
488 }
489 
491 {
492  std::vector<CEvaluationNode *>::iterator it = mCallNodes.begin();
493  std::vector<CEvaluationNode *>::iterator end = mCallNodes.end();
494 
495  while (it != end && *it != pChild) ++it;
496 
497  if (it != end) mCallNodes.erase(it);
498 
499  return CCopasiNode< Data >::removeChild(pChild);
500 }
501 
503 CEvaluationNodeCall::buildParameters(const std::vector<CEvaluationNode *> & vector)
504 {
505  std::vector<CEvaluationNode *>::const_iterator it = vector.begin();
506  std::vector<CEvaluationNode *>::const_iterator end = vector.end();
507 
508  CCallParameters< C_FLOAT64 > * pCallParameters =
509  new CCallParameters< C_FLOAT64 >(vector.size());
510  size_t i;
511 
512  for (i = 0; it != end; ++it, i++)
513  {
514  if (type((*it)->getType()) == CEvaluationNode::VECTOR)
515  (*pCallParameters)[i].vector = buildParameters(static_cast<const CEvaluationNodeVector *>(*it)->getVector());
516  else
517  (*pCallParameters)[i].value = (*it)->getValuePointer();
518  }
519 
520  return pCallParameters;
521 }
522 
523 void
525  const std::vector<CEvaluationNode *> & vector)
526 {
527  if (!pCallParameters) return;
528 
529  std::vector<CEvaluationNode *>::const_iterator it = vector.begin();
530  std::vector<CEvaluationNode *>::const_iterator end = vector.end();
531 
532  size_t i;
533 
534  for (i = 0; it != end; ++it, i++)
535  {
536  if (type((*it)->getType()) == CEvaluationNode::VECTOR)
537  clearParameters((*pCallParameters)[i].vector,
538  static_cast<const CEvaluationNodeVector *>(*it)->getVector());
539  }
540 
541  delete pCallParameters;
542  return;
543 }
544 
545 bool
546 CEvaluationNodeCall::verifyParameters(const std::vector<CEvaluationNode *> & vector,
547  const CFunctionParameters & functionParameters)
548 {
549  if (vector.size() != functionParameters.size()) return false;
550 
551  std::vector<CEvaluationNode *>::const_iterator it = vector.begin();
552  std::vector<CEvaluationNode *>::const_iterator end = vector.end();
553 
554  size_t i;
555 
556  for (i = 0; it != end; ++it, i++)
557  {
558  if ((type((*it)->getType()) == CEvaluationNode::VECTOR &&
559  functionParameters[i]->getType() != CFunctionParameter::VFLOAT64) ||
560  functionParameters[i]->getType() == CFunctionParameter::VFLOAT64)
561  return false;
562  }
563 
564  return true;
565 }
566 
568 {
569  switch (mType & 0x00FFFFFF)
570  {
571  case FUNCTION:
572  case EXPRESSION:
574 
575  default:
576  return NULL;
577  }
578 }
579 
580 #include "utilities/copasimathml.h"
581 
582 // virtual
583 std::string CEvaluationNodeCall::getMMLString(const std::vector< std::string > & children,
584  bool expand,
585  const std::vector< std::vector< std::string > > & /* variables */) const
586 {
587  std::ostringstream out;
588 
589  std::vector< std::string >::const_iterator it = children.begin();
590  std::vector< std::string >::const_iterator end = children.end();
591 
592  switch (mType & 0x00FFFFFF)
593  {
594  case FUNCTION:
595  {
596 
597  if (!expand || !mpFunction)
598  {
599  out << "<mrow>" << std::endl;
600 
601  std::string Data = getData();
602 
603  if (mQuotesRequired)
604  {
605  Data = "\"" + quote(Data, "-+^*/%(){},\t\r\n\"") + "\"";
606  }
607 
608  out << "<mi>" << CMathMl::fixName(Data) << "</mi>" << std::endl;
609  out << "<mrow>" << std::endl;
610  out << "<mo>(</mo>" << std::endl;
611  out << "<mrow>" << std::endl;
612 
613  if (it != end)
614  {
615  out << *it++;
616  }
617 
618  for (; it != end; ++it)
619  {
620  out << "<mo> , </mo>" << std::endl;
621  out << *it;
622  }
623 
624  out << "</mrow>" << std::endl;
625  out << "<mo>) </mo>" << std::endl;
626 
627  out << "</mrow>" << std::endl;
628  out << "</mrow>" << std::endl;
629  }
630  else
631  {
632  std::vector< std::vector< std::string > > Variables;
633 
634  for (; it != end; ++it)
635  {
636  std::vector< std::string > Variable;
637  Variable.push_back(*it);
638  Variables.push_back(Variable);
639  }
640 
641  out << "<mfenced>" << std::endl;
642  out << mpFunction->writeMathML(Variables, expand, expand);
643  out << "</mfenced>" << std::endl;
644  }
645  }
646  break;
647 
648  case EXPRESSION:
649  break;
650 
651  default:
652  break;
653  }
654 
655  return out.str();
656 }
657 
658 void CEvaluationNodeCall::setBooleanRequired(const bool & booleanRequired)
659 {mBooleanRequired = booleanRequired;}
660 
662 {return mBooleanRequired;}
663 
664 // virtual
666 {
667  const CEvaluationTree * pEvaluationTree = getCalledTree();
668 
669  if (pEvaluationTree != NULL)
670  {
671  return pEvaluationTree->isBoolean();
672  }
673 
674  return false;
675 }
std::string unQuote(const std::string &name)
Definition: utility.cpp:120
Header file of class CExpression.
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
static void clearParameters(CCallParameters< C_FLOAT64 > *pCallParameters, const std::vector< CEvaluationNode * > &vector)
const CEvaluationTree * getCalledTree() const
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
virtual std::string getDisplayString(const std::vector< std::string > &children) const
static bool verifyParameters(const std::vector< CEvaluationNode * > &vector, const CFunctionParameters &functionParameters)
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
virtual std::string getBerkeleyMadonnaString(const std::vector< std::string > &children) const
virtual CCopasiObjectName getCN() const
const std::string & getObjectName() const
static CEvaluationNode * fromAST(const ASTNode *pASTNode, const std::vector< CEvaluationNode * > &children)
static CCallParameters< C_FLOAT64 > * buildParameters(const std::vector< CEvaluationNode * > &vector)
virtual bool compile(const CEvaluationTree *pTree)
bool calls(std::set< std::string > &list) const
static std::string fixName(const std::string &name)
Definition: copasimathml.h:33
#define fatalError()
const Type & getType() const
const bool & isBooleanRequired() const
virtual bool compile(std::vector< CCopasiContainer * > listOfContainer=CCopasiContainer::EmptyList)
Definition: CExpression.cpp:97
virtual std::string getCCodeString(const std::vector< std::string > &children) const
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
static bool isKeyword(const std::string &str)
virtual std::string getInfix(const std::vector< std::string > &children) const
void addChildren(const std::vector< CEvaluationNode * > &children)
static Type type(const Type &type)
#define PRECEDENCE_FUNCTION
virtual const Data & getData() const
virtual const C_FLOAT64 & calcValue()
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
CCallParameters< C_FLOAT64 > * mpCallParameters
virtual void writeMathML(std::ostream &out, size_t l=0) const
Definition: CFunction.cpp:389
void setBooleanRequired(const bool &booleanRequired)
virtual bool removeChild(CCopasiNode< Data > *pChild)
static CFunctionDB * getFunctionList()
virtual const C_FLOAT64 & calcValue(const CCallParameters< C_FLOAT64 > &callParameters)
Definition: CFunction.cpp:159
std::string quote(const std::string &name, const std::string &additionalEscapes)
Definition: utility.cpp:144
virtual bool setData(const Data &data)
static Type subType(const Type &type)
virtual std::string getMMLString(const std::vector< std::string > &children, bool expand, const std::vector< std::vector< std::string > > &variables) const
class CEvaluationNode::CPrecedence mPrecedence
const std::string & getSBMLId() const
Definition: CFunction.cpp:68
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
virtual bool removeChild(CCopasiNode< Data > *pChild)
Definition: CCopasiNode.h:181
virtual bool isBoolean() const
#define PRECEDENCE_NUMBER
virtual const CObjectInterface * getObject(const CCopasiObjectName &cn) const
virtual std::string getXPPString(const std::vector< std::string > &children) const
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
static const CCopasiContainer * getRoot()
bool calls(std::set< std::string > &list) const
CFunction * findFunction(const std::string &functionName)
bool isBoolean() const
CFunctionParameters & getVariables()
Definition: CFunction.cpp:148
CRegisteredObjectName mRegisteredFunctionCN
std::vector< CEvaluationNode * > mCallNodes