1 /**
2  * @file    ASTNode.cpp
3  * @brief   Abstract Syntax Tree (AST) for representing formula trees.
4  * @author  Ben Bornstein
5  *
6  * <!--------------------------------------------------------------------------
7  * This file is part of libSBML.  Please visit http://sbml.org for more
8  * information about SBML, and the latest version of libSBML.
9  *
10  * Copyright (C) 2020 jointly by the following organizations:
11  *     1. California Institute of Technology, Pasadena, CA, USA
12  *     2. University of Heidelberg, Heidelberg, Germany
13  *     3. University College London, London, UK
14  *
15  * Copyright (C) 2019 jointly by the following organizations:
16  *     1. California Institute of Technology, Pasadena, CA, USA
17  *     2. University of Heidelberg, Heidelberg, Germany
18  *
19  * Copyright (C) 2013-2018 jointly by the following organizations:
20  *     1. California Institute of Technology, Pasadena, CA, USA
21  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
22  *     3. University of Heidelberg, Heidelberg, Germany
23  *
24  * Copyright (C) 2009-2013 jointly by the following organizations:
25  *     1. California Institute of Technology, Pasadena, CA, USA
26  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
27  *
28  * Copyright (C) 2006-2008 by the California Institute of Technology,
29  *     Pasadena, CA, USA
30  *
31  * Copyright (C) 2002-2005 jointly by the following organizations:
32  *     1. California Institute of Technology, Pasadena, CA, USA
33  *     2. Japan Science and Technology Agency, Japan
34  *
35  * This library is free software; you can redistribute it and/or modify it
36  * under the terms of the GNU Lesser General Public License as published by
37  * the Free Software Foundation.  A copy of the license agreement is provided
38  * in the file named "LICENSE.txt" included with this software distribution and
39  * also available online as http://sbml.org/software/libsbml/license.html
40  * ---------------------------------------------------------------------- -->*/
41 
42 #include <new>
43 #include <stdlib.h>
44 #include <limits.h>
45 
46 #include <sbml/common/common.h>
47 #include <sbml/util/List.h>
48 
49 #include <sbml/math/ASTNode.h>
50 #include <sbml/xml/XMLAttributes.h>
51 #include <sbml/xml/XMLNode.h>
52 #include <sbml/Model.h>
53 #include <sbml/util/IdList.h>
54 #include <sbml/extension/SBMLExtensionRegistry.h>
55 
56 /** @cond doxygenIgnored */
57 
58 using namespace std;
59 
60 /** @endcond */
61 
62 LIBSBML_CPP_NAMESPACE_BEGIN
63 
64 /**
65  * ASTNodeType predicate
66  */
67 #define ASTNodeType_isAvogadro(t) \
68   (t == AST_NAME_AVOGADRO)
69 
70 /**
71  * ASTNodeType predicate
72  */
73 #define ASTNodeType_isConstant(t) \
74   (((t >= AST_CONSTANT_E) && (t <= AST_CONSTANT_TRUE)) || t == AST_NAME_AVOGADRO)
75 
76 /**
77  * ASTNodeType predicate
78  */
79 #define ASTNodeType_isFunction(t) \
80   (((t >= AST_FUNCTION) && (t <= AST_FUNCTION_TANH)) || t == AST_CSYMBOL_FUNCTION)
81 
82 /**
83  * ASTNodeType predicate
84  */
85 #define ASTNodeType_isLambda(t) \
86   (t == AST_LAMBDA)
87 
88 /**
89  * ASTNodeType predicate
90  */
91 #define ASTNodeType_isLogical(t) \
92   (((t >= AST_LOGICAL_AND) && (t <= AST_LOGICAL_XOR)))
93 
94 /**
95  * ASTNodeType predicate
96  */
97 #define ASTNodeType_isName(t) \
98   ((t >= AST_NAME) && (t <= AST_NAME_TIME))
99 
100 /**
101  * ASTNodeType predicate
102  */
103 #define ASTNodeType_isRelational(t) \
104   ((t >= AST_RELATIONAL_EQ) && (t <= AST_RELATIONAL_NEQ))
105 
106 /**
107  * ASTNodeType predicate
108  */
109 #define ASTNodeType_isInteger(t) \
110   (t == AST_INTEGER)
111 
112 /**
113  * ASTNodeType predicate
114  */
115 #define ASTNodeType_isRational(t) \
116   (t == AST_RATIONAL)
117 
118 /**
119  * ASTNodeType predicate
120  */
121 #define ASTNodeType_isReal(t) \
122   ((t >= AST_REAL) && (t <= AST_RATIONAL))
123 
124 /**
125  * ASTNodeType predicate
126  */
127 #define ASTNodeType_isNumber(t) \
128   (ASTNodeType_isInteger(t) || ASTNodeType_isReal(t))
129 
130  /**
131  * ASTNodeType predicate
132  */
133 #define ASTNodeType_isConstantNumber(t) \
134   (t == AST_CONSTANT_E || t == AST_CONSTANT_PI || t == AST_NAME_AVOGADRO)
135  /**
136  * ASTNodeType predicate
137  */
138 #define ASTNodeType_isOperator(t) \
139   ( ( t == AST_PLUS   ) || \
140     ( t == AST_MINUS  ) || \
141     ( t == AST_TIMES  ) || \
142     ( t == AST_DIVIDE ) || \
143     ( t == AST_POWER  ) )
144 
145 /**
146  * ASTNodeType predicate
147  */
148 #define ASTNodeType_isUnknown(t) \
149   (t == AST_UNKNOWN)
150 
151 
152 /**
153  * String Constants
154  */
155 static const char *AST_LAMBDA_STRING = "lambda";
156 
157 static const char *AST_CONSTANT_STRINGS[] =
158 {
159     "exponentiale"
160   , "false"
161   , "pi"
162   , "true"
163   , "avogadro"
164 };
165 
166 static const char *AST_FUNCTION_STRINGS[] =
167 {
168     "abs"
169   , "arccos"
170   , "arccosh"
171   , "arccot"
172   , "arccoth"
173   , "arccsc"
174   , "arccsch"
175   , "arcsec"
176   , "arcsech"
177   , "arcsin"
178   , "arcsinh"
179   , "arctan"
180   , "arctanh"
181   , "ceiling"
182   , "cos"
183   , "cosh"
184   , "cot"
185   , "coth"
186   , "csc"
187   , "csch"
188   , "delay"
189   , "exp"
190   , "factorial"
191   , "floor"
192   , "ln"
193   , "log"
194   , "piecewise"
195   , "power"
196   , "root"
197   , "sec"
198   , "sech"
199   , "sin"
200   , "sinh"
201   , "tan"
202   , "tanh"
203 };
204 
205 static const char *AST_LOGICAL_STRINGS[] =
206 {
207     "and"
208   , "not"
209   , "or"
210   , "xor"
211 };
212 
213 
214 static const char *AST_RELATIONAL_STRINGS[] =
215 {
216     "eq"
217   , "geq"
218   , "gt"
219   , "leq"
220   , "lt"
221   , "neq"
222 };
223 
224 
225 static const char *AST_OPERATOR_STRINGS[] =
226 {
227     "divide"
228   , "minus"
229   , "plus"
230   , "times"
231   , "power"
232 };
233 
234 
235 #ifdef __cplusplus
236 
237 /*
238  * Creates a new ASTNode.
239  *
240  * By default, node will have a type of AST_UNKNOWN and should be set to
241  * something else as soon as possible.
242  */
243 LIBSBML_EXTERN
ASTNode(ASTNodeType_t type)244 ASTNode::ASTNode (ASTNodeType_t type)
245 {
246   unsetSemanticsFlag();
247   mDefinitionURL = new XMLAttributes();
248   mReal          = 0;
249   mExponent      = 0;
250   mType          = AST_UNKNOWN;
251   mChar          = 0;
252   mName          = NULL;
253   mInteger       = 0;
254   mDenominator   = 1;
255   mParentSBMLObject = NULL;
256   mUnits         = "";
257   mId			 = "";
258   mClass		 = "";
259   mStyle		 = "";
260   mIsBvar = false;
261   mUserData      = NULL;
262 
263   // move to after we have loaded plugins
264   //setType(type);
265 
266   mChildren             = new List;
267   mSemanticsAnnotations = new List;
268   // only load plugins when we need to
269   //if (type > AST_END_OF_CORE && type < AST_UNKNOWN)
270   //{
271   //  loadASTPlugins(NULL);
272   //  for (unsigned int i = 0; i < getNumPlugins(); i++)
273   //  {
274   //    getPlugin(i)->connectToParent(this);
275   //  }
276   //}
277 
278   setType(type);
279 }
280 
281 
282 /*
283  * Creates a new ASTNode from the given Token_t structure.
284  *
285  * The resulting ASTNode will contain the same data as the Token_t
286  * object.  Please refer to the documentation for Token_t to learn
287  * about the possible contents.
288  */
289 LIBSBML_EXTERN
ASTNode(Token_t * token)290 ASTNode::ASTNode (Token_t* token)
291 {
292   unsetSemanticsFlag();
293   mDefinitionURL = new XMLAttributes();
294   mReal          = 0;
295   mExponent      = 0;
296   mType          = AST_UNKNOWN;
297   mChar          = 0;
298   mName          = NULL;
299   mInteger       = 0;
300   mDenominator   = 1;
301   mParentSBMLObject = NULL;
302   mUnits         = "";
303   mId			 = "";
304   mClass		 = "";
305   mStyle		 = "";
306   mIsBvar = false;
307   mUserData      = NULL;
308 
309   mChildren             = new List;
310   mSemanticsAnnotations = new List;
311 
312   if (token != NULL)
313   {
314     if (token->type == TT_NAME)
315     {
316       setName(token->value.name);
317     }
318     else if (token->type == TT_INTEGER)
319     {
320       setValue(token->value.integer);
321     }
322     else if (token->type == TT_REAL)
323     {
324       setValue(token->value.real);
325     }
326     else if (token->type == TT_REAL_E)
327     {
328       setValue(token->value.real, token->exponent);
329     }
330     else
331     {
332       setCharacter(token->value.ch);
333     }
334   }
335   //loadASTPlugins(NULL);
336   //for (unsigned int i = 0; i < getNumPlugins(); i++)
337   //{
338   //  getPlugin(i)->connectToParent(this);
339   //}
340 }
341 
342 /*
343 * Used by the Copy Constructor to clone each item in mPlugins.
344 */
345 struct CloneASTPluginEntity : public unary_function<ASTBasePlugin*, ASTBasePlugin*>
346 {
operator ()CloneASTPluginEntity347   ASTBasePlugin* operator() (ASTBasePlugin* ast) {
348     if (!ast) return 0;
349     return ast->clone();
350   }
351 };
352 
353 
354 /*
355  *
356  * Copy constructor; Creates a deep copy of the given ASTNode
357  *
358  */
359 LIBSBML_EXTERN
ASTNode(const ASTNode & orig)360 ASTNode::ASTNode (const ASTNode& orig) :
361   mType                 ( orig.mType )
362  ,mChar                 ( orig.mChar )
363  ,mName                 ( NULL )
364  ,mInteger              ( orig.mInteger )
365  ,mReal                 ( orig.mReal )
366  ,mDenominator          ( orig.mDenominator )
367  ,mExponent             ( orig.mExponent )
368  ,mDefinitionURL        ( orig.mDefinitionURL->clone() )
369  ,hasSemantics          ( orig.hasSemantics )
370  ,mChildren             ( new List() )
371  ,mSemanticsAnnotations ( new List() )
372  ,mParentSBMLObject     ( orig.mParentSBMLObject )
373  ,mUnits                ( orig.mUnits)
374  ,mId                   ( orig.mId)
375  ,mClass                ( orig.mClass)
376  ,mStyle                ( orig.mStyle)
377  ,mIsBvar               ( orig.mIsBvar)
378  ,mUserData             ( orig.mUserData )
379 {
380   if (orig.mName)
381   {
382     mName = safe_strdup(orig.mName);
383   }
384 
385   for (unsigned int c = 0; c < orig.getNumChildren(); ++c)
386   {
387     addChild( orig.getChild(c)->deepCopy() );
388   }
389 
390   for (unsigned int c = 0; c < orig.getNumSemanticsAnnotations(); ++c)
391   {
392     addSemanticsAnnotation( orig.getSemanticsAnnotation(c)->clone() );
393   }
394   mPlugins.resize(orig.mPlugins.size());
395   transform(orig.mPlugins.begin(), orig.mPlugins.end(),
396     mPlugins.begin(), CloneASTPluginEntity());
397   for (size_t i = 0; i < mPlugins.size(); i++)
398   {
399     getPlugin((unsigned int)i)->connectToParent(this);
400   }
401 }
402 
403 /*
404  *
405  * assignment operator
406  *
407  */
408 LIBSBML_EXTERN
operator =(const ASTNode & rhs)409 ASTNode& ASTNode::operator=(const ASTNode& rhs)
410 {
411   if(&rhs!=this)
412   {
413     mType                 = rhs.mType;
414     mChar                 = rhs.mChar;
415     mInteger              = rhs.mInteger;
416     mReal                 = rhs.mReal;
417     mDenominator          = rhs.mDenominator;
418     mExponent             = rhs.mExponent;
419     hasSemantics          = rhs.hasSemantics;
420     mParentSBMLObject     = rhs.mParentSBMLObject;
421     mUnits                = rhs.mUnits;
422     mId                   = rhs.mId;
423     mClass                = rhs.mClass;
424     mStyle                = rhs.mStyle;
425     mIsBvar               = rhs.mIsBvar;
426     mUserData             = rhs.mUserData;
427     freeName();
428     if (rhs.mName)
429     {
430       mName = safe_strdup(rhs.mName);
431     }
432     else
433     {
434       mName = NULL;
435     }
436 
437     unsigned int size = mChildren->getSize();
438     while (size--) delete static_cast<ASTNode*>( mChildren->remove(0) );
439     delete mChildren;
440     mChildren = new List();
441 
442     for (unsigned int c = 0; c < rhs.getNumChildren(); ++c)
443     {
444       addChild( rhs.getChild(c)->deepCopy() );
445     }
446 
447     size = mSemanticsAnnotations->getSize();
448     while (size--)  delete static_cast<XMLNode*>(mSemanticsAnnotations->remove(0) );
449     delete mSemanticsAnnotations;
450     mSemanticsAnnotations = new List();
451 
452     for (unsigned int c = 0; c < rhs.getNumSemanticsAnnotations(); ++c)
453     {
454       addSemanticsAnnotation( rhs.getSemanticsAnnotation(c)->clone() );
455     }
456 
457     delete mDefinitionURL;
458     mDefinitionURL        = rhs.mDefinitionURL->clone();
459     clearPlugins();
460     mPlugins.resize(rhs.mPlugins.size());
461     transform(rhs.mPlugins.begin(), rhs.mPlugins.end(),
462       mPlugins.begin(), CloneASTPluginEntity());
463   }
464   return *this;
465 }
466 
467 /*
468  * Destroys this ASTNode including any child nodes.
469  */
470 LIBSBML_EXTERN
~ASTNode()471 ASTNode::~ASTNode ()
472 {
473   unsigned int size = getNumChildren();
474 
475 
476   while (size--) delete static_cast<ASTNode*>( mChildren->remove(0) );
477   delete mChildren;
478 
479   size = mSemanticsAnnotations->getSize();
480   while (size--)  delete static_cast<XMLNode*>(mSemanticsAnnotations->remove(0) );
481   delete mSemanticsAnnotations;
482 
483   delete mDefinitionURL;
484 
485   freeName();
486   clearPlugins();
487 
488 }
489 
490 
491 /*
492  * Frees the name of this ASTNode and sets it to NULL.
493  *
494  * This operation is only applicable to ASTNodes corresponding to
495  * operators, numbers, or AST_UNKNOWN.  This method will have no
496  * effect on other types of nodes.
497  */
498 int
freeName()499 ASTNode::freeName ()
500 {
501   if (mName != NULL)
502   {
503     safe_free(mName);
504     mName = NULL;
505     return LIBSBML_OPERATION_SUCCESS;
506   }
507   else
508   {
509     return LIBSBML_UNEXPECTED_ATTRIBUTE;
510   }
511 }
512 
513 
514 /*
515  * Attempts to convert this ASTNode to a canonical form and returns true if
516  * the conversion succeeded, false otherwise.
517  *
518  * The rules determining the canonical form conversion are as follows:
519  *
520  *   1. If the node type is AST_NAME and the node name matches
521  *   "ExponentialE", "Pi", "True" or "False" the node type is converted to
522  *   the corresponding AST_CONSTANT type.
523  *
524  *   2. If the node type is an AST_FUNCTION and the node name matches an L1
525  *   or L2 (MathML) function name, logical operator name, or relational
526  *   operator name, the node is converted to the correspnding AST_FUNCTION,
527  *   AST_LOGICAL or AST_CONSTANT type.
528  *
529  * L1 function names are searched first, so canonicalizing "log" will
530  * result in a node type of AST_FUNCTION_LN (see L1 Specification,
531  * Appendix C).
532  *
533  * Some canonicalizations result in a structural converion of the nodes (by
534  * adding a child).  For example, a node with L1 function name "sqr" and a
535  * single child node (the argument) will be transformed to a node of type
536  * AST_FUNCTION_POWER with two children.  The first child will remain
537  * unchanged, but the second child will be an ASTNode of type AST_INTEGER
538  * and a value of 2.  The function names that result in structural changes
539  * are: log10, sqr and sqrt.
540  */
541 LIBSBML_EXTERN
542 bool
canonicalize()543 ASTNode::canonicalize ()
544 {
545   bool found = false;
546 
547 
548   if (mType == AST_NAME)
549   {
550     found = canonicalizeConstant();
551   }
552 
553   if (!found && mType == AST_FUNCTION)
554   {
555     found = canonicalizeFunction();
556 
557     if (!found)
558     {
559       found = canonicalizeLogical();
560     }
561 
562     if (!found)
563     {
564       found = canonicalizeRelational();
565     }
566   }
567 
568   return found;
569 }
570 
571 /** @cond doxygenLibsbmlInternal */
572 /*
573  * Internal helper function for canonicalize().
574  */
575 bool
canonicalizeConstant()576 ASTNode::canonicalizeConstant ()
577 {
578   const int first = AST_CONSTANT_E;
579   const int last  = AST_CONSTANT_TRUE;
580   const int size  = last - first + 1;
581 
582   int  index;
583   bool found;
584 
585 
586   index = util_bsearchStringsI(AST_CONSTANT_STRINGS, mName, 0, size - 1);
587   found = (index < size);
588 
589   if (found)
590   {
591     setType( static_cast<ASTNodeType_t>(first + index) );
592   }
593 
594   return found;
595 }
596 /** @endcond */
597 
598 
599 /** @cond doxygenLibsbmlInternal */
600 /*
601  * Internal helper function for canonicalize().
602  */
603 bool
canonicalizeFunction()604 ASTNode::canonicalizeFunction ()
605 {
606   const int first = AST_FUNCTION_ABS;
607   const int last  = AST_FUNCTION_TANH;
608   const int size  = last - first + 1;
609 
610   int  index;
611   bool found;
612 
613 
614   /*
615    * Search for SBML Level 1 function names first.
616    */
617   found = canonicalizeFunctionL1();
618 
619   /*
620    * Now Lambda...
621    */
622   if (!found)
623   {
624     if ( (found = !strcmp_insensitive(mName, AST_LAMBDA_STRING)) )
625     {
626       setType(AST_LAMBDA);
627     }
628   }
629 
630   /*
631    * ... the L2 (MathML) function names.
632    */
633   if (!found)
634   {
635     index = util_bsearchStringsI(AST_FUNCTION_STRINGS, mName, 0, size - 1);
636     found = (index < size);
637 
638     if (found)
639     {
640       setType( static_cast<ASTNodeType_t>(first + index) );
641     }
642   }
643 
644   // and then the ones defined in packages/l3v2.
645   //if (!found)
646   //{
647   //  ASTNodeType_t type = mExtendedMathList->getASTNodeTypeForFunction(mName);
648   //  if (type != AST_UNKNOWN) {
649   //    found = true;
650   //    setType(type);
651   //  }
652   //}
653 
654 
655   return found;
656 }
657 /** @endcond */
658 
659 
660 /** @cond doxygenLibsbmlInternal */
661 /*
662  * Internal helper function for canonicalize().
663  */
664 bool
canonicalizeFunctionL1()665 ASTNode::canonicalizeFunctionL1 ()
666 {
667   ASTNode* child;
668 
669 
670   if ( !strcmp_insensitive(mName, "acos") )
671   {
672     setType(AST_FUNCTION_ARCCOS);
673   }
674   else if ( !strcmp_insensitive(mName, "asin") )
675   {
676     setType(AST_FUNCTION_ARCSIN);
677   }
678   else if ( !strcmp_insensitive(mName, "atan") )
679   {
680     setType(AST_FUNCTION_ARCTAN);
681   }
682   else if ( !strcmp_insensitive(mName, "ceil") )
683   {
684     setType(AST_FUNCTION_CEILING);
685   }
686 
687   /*
688    * "log(x)" in L1 is represented as "ln(x)" in L2.
689    *
690    * Notice, however, that the conversion is performed only if the number of
691    * arguments is 1.  Thus "log(5, x)" will still be "log(5, x) when passed
692    * through this filter.
693    */
694   else if ( !strcmp_insensitive(mName, "log") && (getNumChildren() == 1) )
695   {
696     setType(AST_FUNCTION_LN);
697   }
698 
699   /*
700    * "log10(x)" in L1 is represented as "log(10, x)" in L2.
701    */
702   else if ( !strcmp_insensitive(mName, "log10") && (getNumChildren() == 1) )
703   {
704     setType(AST_FUNCTION_LOG);
705 
706     child = new ASTNode;
707     child->setValue(10);
708 
709     prependChild(child);
710   }
711 
712   /*
713    * Here we set the type to AST_FUNCTION_POWER.  We could set it to
714    * AST_POWER, but then we would loose the idea that it was a function
715    * before it was canonicalized.
716    */
717   else if ( !strcmp_insensitive(mName, "pow") )
718   {
719     setType(AST_FUNCTION_POWER);
720   }
721 
722   /*
723    * "sqr(x)" in L1 is represented as "power(x, 2)" in L2.
724    */
725   else if ( !strcmp_insensitive(mName, "sqr") && (getNumChildren() == 1) )
726   {
727     setType(AST_FUNCTION_POWER);
728 
729     child = new ASTNode;
730     child->setValue(2);
731 
732     addChild(child);
733   }
734 
735   /*
736    * "sqrt(x) in L1 is represented as "root(2, x)" in L1.
737    */
738   else if ( !strcmp_insensitive(mName, "sqrt") && (getNumChildren() == 1) )
739   {
740     setType(AST_FUNCTION_ROOT);
741 
742     child = new ASTNode;
743     child->setValue(2);
744 
745     prependChild(child);
746   }
747 
748   /*
749    * Was a conversion performed?
750    */
751   return (mType != AST_FUNCTION);
752 }
753 /** @endcond */
754 
755 
756 /** @cond doxygenLibsbmlInternal */
757 /*
758  * Internal helper function for canonicalize().
759  */
760 bool
canonicalizeLogical()761 ASTNode::canonicalizeLogical ()
762 {
763   const int first = AST_LOGICAL_AND;
764   const int last  = AST_LOGICAL_XOR;
765   const int size  = last - first + 1;
766 
767   int  index = util_bsearchStringsI(AST_LOGICAL_STRINGS, mName, 0, size - 1);
768   bool found = (index < size);
769 
770   if (found)
771   {
772     setType( static_cast<ASTNodeType_t>(first + index) );
773   }
774 
775   //if (!found)
776   //{
777   //  ASTNodeType_t type = mExtendedMathList->getASTNodeTypeForFunction(mName);
778   //  if (type != AST_UNKNOWN) {
779   //    found = true;
780   //    setType( static_cast<ASTNodeType_t>(new_first + index) );
781   //  }
782   //}
783 
784   return found;
785 }
786 /** @endcond */
787 
788 
789 /** @cond doxygenLibsbmlInternal */
790 /*
791  * Internal helper function for canonicalize().
792  */
793 bool
canonicalizeRelational()794 ASTNode::canonicalizeRelational ()
795 {
796   const int first = AST_RELATIONAL_EQ;
797   const int last  = AST_RELATIONAL_NEQ;
798   const int size  = last - first + 1;
799 
800   int  index;
801   bool found;
802 
803 
804   index = util_bsearchStringsI(AST_RELATIONAL_STRINGS, mName, 0, size - 1);
805   found = (index < size);
806 
807   if (found)
808   {
809     setType( static_cast<ASTNodeType_t>(first + index) );
810   }
811 
812   return found;
813 }
814 /** @endcond */
815 
816 
817 /*
818  * Adds the given node as a child of this ASTNode.  Child nodes are added
819  * in-order from "left-to-right".
820  *
821  * @return integer value indicating success/failure of the
822  * function.  @if clike The value is drawn from the
823  * enumeration #OperationReturnValues_t. @endif@~ The possible values
824  * returned by this function are:
825  * @li LIBSBML_OPERATION_SUCCESS
826  * @li LIBSBML_OPERATION_FAILED
827  */
828 LIBSBML_EXTERN
829 int
addChild(ASTNode * child,bool inRead)830 ASTNode::addChild (ASTNode* child, bool inRead)
831 {
832 
833   unsigned int numBefore = getNumChildren();
834   mChildren->add(child);
835 
836   /* HACK to allow representsBVar function to be correct */
837   if (inRead == false && this->getType() == AST_LAMBDA
838     && numBefore > 0)
839   {
840     getChild(numBefore-1)->setBvar();
841   }
842 
843   if (getNumChildren() == numBefore + 1)
844   {
845     return LIBSBML_OPERATION_SUCCESS;
846   }
847   else
848   {
849     return LIBSBML_OPERATION_FAILED;
850   }
851 }
852 
853 /*
854  * Adds the given node as a child of this ASTNode.  This method adds child
855  * nodes from "right-to-left".
856  *
857  * @return integer value indicating success/failure of the
858  * function.  @if clike The value is drawn from the
859  * enumeration #OperationReturnValues_t. @endif@~ The possible values
860  * returned by this function are:
861  * @li LIBSBML_OPERATION_SUCCESS
862  * @li LIBSBML_OPERATION_FAILED
863  * @li LIBSBML_INVALID_OBJECT
864  */
865 LIBSBML_EXTERN
866 int
prependChild(ASTNode * child)867 ASTNode::prependChild (ASTNode* child)
868 {
869   if (child == NULL) return LIBSBML_INVALID_OBJECT;
870 
871   unsigned int numBefore = getNumChildren();
872   mChildren->prepend(child);
873 
874   if (getNumChildren() == numBefore + 1)
875   {
876     return LIBSBML_OPERATION_SUCCESS;
877   }
878   else
879   {
880     return LIBSBML_OPERATION_FAILED;
881   }
882 }
883 
884 
885 LIBSBML_EXTERN
886 int
removeChild(unsigned int n)887 ASTNode::removeChild(unsigned int n)
888 {
889   int removed = LIBSBML_INDEX_EXCEEDS_SIZE;
890   unsigned int size = getNumChildren();
891   if (n < size)
892   {
893     mChildren->remove(n);
894     if (getNumChildren() == size-1)
895     {
896       removed = LIBSBML_OPERATION_SUCCESS;
897     }
898   }
899 
900   return removed;
901 }
902 
903 LIBSBML_EXTERN
904 int
replaceChild(unsigned int n,ASTNode * newChild,bool delreplaced)905 ASTNode::replaceChild(unsigned int n, ASTNode *newChild, bool delreplaced)
906 {
907   if (newChild == NULL) return LIBSBML_INVALID_OBJECT;
908 
909   int replaced = LIBSBML_INDEX_EXCEEDS_SIZE;
910 
911   unsigned int size = getNumChildren();
912   if (n < size)
913   {
914     ASTNode* rep = static_cast<ASTNode*>(mChildren->remove(n));
915     if (delreplaced)
916     {
917       delete rep;
918     }
919     if (insertChild(n, newChild) == LIBSBML_OPERATION_SUCCESS)
920       replaced = LIBSBML_OPERATION_SUCCESS;
921   }
922 
923   return replaced;
924 }
925 
926 LIBSBML_EXTERN
927 int
insertChild(unsigned int n,ASTNode * newChild)928 ASTNode::insertChild(unsigned int n, ASTNode *newChild)
929 {
930   if (newChild == NULL) return LIBSBML_INVALID_OBJECT;
931 
932   int inserted = LIBSBML_INDEX_EXCEEDS_SIZE;
933 
934   unsigned int i, size = getNumChildren();
935   if (n == 0)
936   {
937     prependChild(newChild);
938     inserted = LIBSBML_OPERATION_SUCCESS;
939   }
940   else if (n <= size)
941   {
942     /* starting at the end take each child in the list and prepend it
943     * then remove it from the end
944     * at the insertion point prepend the newChild
945     * eg list: a, b, c
946     * inserting d at position 2
947     * list goes: c, a, b :  d, c, a, b : b, d, c, a : a, b, d, c
948     */
949     for (i = size-1; i >= n; i--)
950     {
951       prependChild(getChild(size-1));
952       mChildren->remove(size);
953     }
954 
955     prependChild(newChild);
956 
957     for (i = 0; i < n; i++)
958     {
959       prependChild(getChild(size));
960       mChildren->remove(size+1);
961     }
962 
963     if (getNumChildren() == size + 1)
964       inserted = LIBSBML_OPERATION_SUCCESS;
965   }
966 
967   /* HACK TO Make representBvar work */
968   // mark all but last child as bvar
969   // unless we have only inserted one
970   if (size > 1)
971   {
972     for (unsigned int c = 0; c < getNumChildren() - 1; c++)
973     {
974       getChild(c)->setBvar();
975     }
976   }
977 
978   return inserted;
979 }
980 
981 /*
982  * @return a copy of this ASTNode and all its children.  The caller owns
983  * the returned ASTNode and is reponsible for deleting it.
984  */
985 LIBSBML_EXTERN
986 ASTNode*
deepCopy() const987 ASTNode::deepCopy () const
988 {
989   return new ASTNode(*this);
990 }
991 
992 
993 /*
994  * @return the nth child of this ASTNode or NULL if this node has no nth
995  * child (n > getNumChildren() - 1).
996  */
997 LIBSBML_EXTERN
998 ASTNode*
getChild(unsigned int n) const999 ASTNode::getChild (unsigned int n) const
1000 {
1001   return static_cast<ASTNode*>( mChildren->get(n) );
1002 }
1003 
1004 
1005 /*
1006  * @return the left child of this ASTNode.  This is equivalent to
1007  * getChild(0);
1008  */
1009 LIBSBML_EXTERN
1010 ASTNode*
getLeftChild() const1011 ASTNode::getLeftChild () const
1012 {
1013   return static_cast<ASTNode*>( mChildren->get(0) );
1014 }
1015 
1016 
1017 /*
1018  * @return the right child of this ASTNode or NULL if this node has no
1019  * right child.  If getNumChildren() > 1, then this is equivalent to:
1020  *
1021  *   getChild( getNumChildren() - 1);
1022  */
1023 LIBSBML_EXTERN
1024 ASTNode*
getRightChild() const1025 ASTNode::getRightChild () const
1026 {
1027   unsigned int nc = getNumChildren();
1028 
1029 
1030   return (nc > 1) ? static_cast<ASTNode*>( mChildren->get(nc - 1) ): NULL;
1031 }
1032 
1033 
1034 /*
1035  * @return the number of children of this ASTNode or 0 is this node has no
1036  * children.
1037  */
1038 LIBSBML_EXTERN
1039 unsigned int
getNumChildren() const1040 ASTNode::getNumChildren () const
1041 {
1042   return mChildren->getSize();
1043 }
1044 
1045 
1046 /*
1047  * Adds the given xmlnode as an annotation of this ASTNode.
1048  */
1049 LIBSBML_EXTERN
1050 int
addSemanticsAnnotation(XMLNode * sAnnotation)1051 ASTNode::addSemanticsAnnotation (XMLNode* sAnnotation)
1052 {
1053   if (sAnnotation == NULL)
1054   {
1055     return LIBSBML_OPERATION_FAILED;
1056   }
1057   mSemanticsAnnotations->add(sAnnotation);
1058   return LIBSBML_OPERATION_SUCCESS;
1059 }
1060 
1061 
1062 /*
1063  * @return the number of annotations of this ASTNode.
1064  */
1065 LIBSBML_EXTERN
1066 unsigned int
getNumSemanticsAnnotations() const1067 ASTNode::getNumSemanticsAnnotations () const
1068 {
1069   return mSemanticsAnnotations->getSize();
1070 }
1071 
1072 
1073 /*
1074  * @return the nth annotation of this ASTNode or NULL if this node has no nth
1075  * annotation.
1076  */
1077 LIBSBML_EXTERN
1078 XMLNode*
getSemanticsAnnotation(unsigned int n) const1079 ASTNode::getSemanticsAnnotation (unsigned int n) const
1080 {
1081   return static_cast<XMLNode*>( mSemanticsAnnotations->get(n) );
1082 }
1083 
1084 /*
1085  * Performs a depth-first search (DFS) of the tree rooted at node and
1086  * returns the List of nodes where predicate(node) returns true.
1087  *
1088  * The typedef for ASTNodePredicate is:
1089  *
1090  *   int (*ASTNodePredicate) (const ASTNode_t *node);
1091  *
1092  * where a return value of nonzero represents true and zero represents
1093  * false.
1094  *
1095  * The List returned is owned by the caller and should be deleted.  The
1096  * ASTNodes in the list, however, are not owned by the caller (as they
1097  * still belong to the tree itself) and therefore should not be deleted.
1098  */
1099 LIBSBML_EXTERN
1100 List*
getListOfNodes(ASTNodePredicate predicate) const1101 ASTNode::getListOfNodes (ASTNodePredicate predicate) const
1102 {
1103   if (predicate == NULL) return NULL;
1104 
1105   List* lst = new List;
1106 
1107 
1108   fillListOfNodes(predicate, lst);
1109 
1110   return lst;
1111 }
1112 
1113 
1114 /*
1115  * This method is identical in functionality to getListOfNodes(), except
1116  * the List is passed-in by the caller.
1117  */
1118 LIBSBML_EXTERN
1119 void
fillListOfNodes(ASTNodePredicate predicate,List * lst) const1120 ASTNode::fillListOfNodes (ASTNodePredicate predicate, List* lst) const
1121 {
1122   if (lst == NULL || predicate == NULL) return;
1123 
1124   ASTNode*     child;
1125   unsigned int c;
1126   unsigned int numChildren = getNumChildren();
1127 
1128 
1129 
1130   if (predicate(this) != 0)
1131   {
1132     lst->add( const_cast<ASTNode*>(this) );
1133   }
1134 
1135   for (c = 0; c < numChildren; c++)
1136   {
1137     child = getChild(c);
1138     child->fillListOfNodes(predicate, lst);
1139   }
1140 }
1141 
1142 
1143 /*
1144  * @return the value of this ASTNode as a single character.  This function
1145  * should be called only when getType() is one of AST_PLUS, AST_MINUS,
1146  * AST_TIMES, AST_DIVIDE or AST_POWER.
1147  */
1148 LIBSBML_EXTERN
1149 char
getCharacter() const1150 ASTNode::getCharacter () const
1151 {
1152   return mChar;
1153 }
1154 
1155 
1156 /*
1157  * @return the value of this ASTNode as a (long) integer.  This function
1158  * should be called only when getType() == AST_INTEGER.
1159  */
1160 LIBSBML_EXTERN
1161 long
getInteger() const1162 ASTNode::getInteger () const
1163 {
1164   return mInteger;
1165 }
1166 
1167 
1168 /*
1169  * @return the value of this ASTNode as a string.  This function may be
1170  * called on nodes that are not operators (isOperator() == false)
1171  * or numbers (isNumber() == false).
1172  */
1173 LIBSBML_EXTERN
1174 const char*
getName() const1175 ASTNode::getName () const
1176 {
1177   const char* result = mName;
1178 
1179 
1180   /*
1181    * If the node does not have a name and is not a user-defined function
1182    * (type == AST_FUNCTION), use the default name for the builtin node
1183    * types.
1184    */
1185   if (mName == NULL && mType != AST_FUNCTION)
1186   {
1187     if ( isConstant() )
1188     {
1189       if (mType == AST_NAME_AVOGADRO)
1190       {
1191         result = AST_CONSTANT_STRINGS[4];
1192       }
1193       else
1194       {
1195         result = AST_CONSTANT_STRINGS[ mType - AST_CONSTANT_E ];
1196       }
1197     }
1198     else if ( isLambda() )
1199     {
1200       result = AST_LAMBDA_STRING;
1201     }
1202     else if ( isFunction() )
1203     {
1204       if (mType <= AST_FUNCTION_TANH && mType >= AST_FUNCTION_ABS)
1205       {
1206         result = AST_FUNCTION_STRINGS[ mType - AST_FUNCTION_ABS ];
1207       }
1208     }
1209     else if ( isLogical() )
1210     {
1211       if (mType <= AST_RELATIONAL_NEQ)
1212       {
1213         result = AST_LOGICAL_STRINGS[ mType - AST_LOGICAL_AND ];
1214       }
1215     }
1216     else if ( isRelational() )
1217     {
1218       result = AST_RELATIONAL_STRINGS[ mType - AST_RELATIONAL_EQ ];
1219     }
1220   }
1221   if (result == NULL && mType > AST_END_OF_CORE)
1222   {
1223     const ASTBasePlugin * baseplugin = getASTPlugin(mType);
1224     if (baseplugin != NULL)
1225     {
1226       result = baseplugin->getConstCharFor(mType);
1227     }
1228     //if (getNumPlugins() == 0)
1229     //{
1230     //  const_cast<ASTNode*>(this)->loadASTPlugins(NULL);
1231     //}
1232 
1233     //unsigned int i = 0;
1234     //while (result == NULL && i < getNumPlugins())
1235     //{
1236     //  result = getPlugin(i)->getConstCharFor(mType);
1237     //  i++;
1238     //}
1239   }
1240   //if (result == NULL && mExtendedMathList->defines(mType))
1241   //{
1242   //  result = mExtendedMathList->getConstCharFor(mType);
1243   //}
1244 
1245   return result;
1246 }
1247 
1248 
1249 LIBSBML_EXTERN
1250 const char*
getOperatorName() const1251 ASTNode::getOperatorName () const
1252 {
1253   switch(mType) {
1254   case AST_DIVIDE:
1255     return AST_OPERATOR_STRINGS[0];
1256   case AST_MINUS:
1257     return AST_OPERATOR_STRINGS[1];
1258   case AST_PLUS:
1259     return AST_OPERATOR_STRINGS[2];
1260   case AST_TIMES:
1261     return AST_OPERATOR_STRINGS[3];
1262   case AST_POWER:
1263     return AST_OPERATOR_STRINGS[4];
1264   default:
1265     return NULL;
1266   }
1267 }
1268 
1269 
1270 /*
1271  * @return the value of the numerator of this ASTNode.  This function
1272  * should be called only when getType() == AST_RATIONAL.
1273  */
1274 LIBSBML_EXTERN
1275 long
getNumerator() const1276 ASTNode::getNumerator () const
1277 {
1278   return mInteger;
1279 }
1280 
1281 
1282 /*
1283  * @return the value of the denominator of this ASTNode.  This function
1284  * should be called only when getType() == AST_RATIONAL.
1285  */
1286 LIBSBML_EXTERN
1287 long
getDenominator() const1288 ASTNode::getDenominator () const
1289 {
1290   return mDenominator;
1291 }
1292 
1293 
1294 /*
1295  * @return the value of this ASTNode as a real (double).  This function
1296  * should be called only when isReal() == true.
1297  *
1298  * This function performs the necessary arithmetic if the node type is
1299  * AST_REAL_E (mantissa * $10^exponent$) or AST_RATIONAL (numerator /
1300  * denominator).
1301  */
1302 LIBSBML_EXTERN
1303 double
getReal() const1304 ASTNode::getReal () const
1305 {
1306   double result = mReal;
1307 
1308 
1309   if (mType == AST_REAL_E)
1310   {
1311     result *= pow(10.0,  static_cast<double>(mExponent) );
1312   }
1313   else if (mType == AST_RATIONAL)
1314   {
1315     result = static_cast<double>(mInteger) / mDenominator;
1316   }
1317 
1318   return result;
1319 }
1320 
1321 
1322 /*
1323  * @return the value of the mantissa of this ASTNode.  This function should
1324  * be called only when getType() is AST_REAL_E or AST_REAL.  If AST_REAL,
1325  * this method is identical to getReal().
1326  */
1327 LIBSBML_EXTERN
1328 double
getMantissa() const1329 ASTNode::getMantissa () const
1330 {
1331   return mReal;
1332 }
1333 
1334 
1335 /*
1336  * @return the value of the exponent of this ASTNode.  This function should
1337  * be called only when getType() is AST_REAL_E or AST_REAL.
1338  */
1339 LIBSBML_EXTERN
1340 long
getExponent() const1341 ASTNode::getExponent () const
1342 {
1343   return mExponent;
1344 }
1345 
1346 
1347 LIBSBML_EXTERN
1348 double
getValue() const1349 ASTNode::getValue () const
1350 {
1351   double value = util_NaN();
1352 
1353   switch(mType)
1354   {
1355   case AST_CONSTANT_E:
1356     value = 2.71828182;
1357     break;
1358   case AST_CONSTANT_FALSE:
1359     value = 0;
1360     break;
1361   case AST_CONSTANT_PI:
1362     value = 3.14159292;
1363     break;
1364   case AST_CONSTANT_TRUE:
1365     value = 1;
1366     break;
1367   case AST_INTEGER:
1368     value = (double)(getInteger());
1369     break;
1370   case AST_NAME_AVOGADRO:
1371   case AST_RATIONAL:
1372   case AST_REAL:
1373   case AST_REAL_E:
1374     value = getReal();
1375     break;
1376   default:
1377     break;
1378   }
1379 
1380   return value;
1381 
1382 }
1383 
1384 /*
1385  * @return the precedence of this ASTNode (as defined in the SBML L1
1386  * specification).
1387  */
1388 LIBSBML_EXTERN
1389 int
getPrecedence() const1390 ASTNode::getPrecedence () const
1391 {
1392   int precedence = 6;
1393 
1394 
1395   if ( isUMinus() )
1396   {
1397     precedence = 5;
1398   }
1399   else
1400   {
1401     switch (mType)
1402     {
1403       case AST_PLUS:
1404       case AST_MINUS:
1405         precedence = 2;
1406         break;
1407 
1408       case AST_DIVIDE:
1409       case AST_TIMES:
1410         precedence = 3;
1411         break;
1412 
1413       case AST_POWER:
1414         precedence = 4;
1415         break;
1416 
1417       default:
1418         if (mType > AST_END_OF_CORE)
1419         {
1420           const ASTBasePlugin * baseplugin = getASTPlugin(mType);
1421           if (baseplugin != NULL)
1422           {
1423             precedence = baseplugin->getL3PackageInfixPrecedence();
1424           }
1425         }
1426         else
1427         {
1428           precedence = 6;
1429         }
1430         break;
1431     }
1432   }
1433 
1434   return precedence;
1435 }
1436 
1437 
1438 /*
1439  * @return the type of this ASTNode.
1440  */
1441 LIBSBML_EXTERN
1442 ASTNodeType_t
getType() const1443 ASTNode::getType () const
1444 {
1445   return mType;
1446 }
1447 
1448 LIBSBML_EXTERN
1449 std::string
getId() const1450 ASTNode::getId() const
1451 {
1452   return mId;
1453 }
1454 
1455 LIBSBML_EXTERN
1456 std::string
getClass() const1457 ASTNode::getClass() const
1458 {
1459   return mClass;
1460 }
1461 
1462 LIBSBML_EXTERN
1463 std::string
getStyle() const1464 ASTNode::getStyle() const
1465 {
1466   return mStyle;
1467 }
1468 
1469 LIBSBML_EXTERN
1470 std::string
getUnits() const1471 ASTNode::getUnits() const
1472 {
1473   return mUnits;
1474 }
1475 
1476 /** @cond doxygenLibsbmlInternal */
1477 LIBSBML_EXTERN
1478 bool
usesL3V2MathConstructs() const1479 ASTNode::usesL3V2MathConstructs() const
1480 {
1481   bool mathConstructs = false;
1482 
1483   ASTNodeType_t type = getType();
1484 
1485   if (type > AST_END_OF_CORE)
1486   {
1487     if (getASTPlugin(type) != NULL)
1488       mathConstructs = true;
1489   }
1490   unsigned int i = 0;
1491   while (!mathConstructs && i < getNumChildren())
1492   {
1493     mathConstructs = getChild(i)->usesL3V2MathConstructs();
1494     i++;
1495   }
1496 
1497   return mathConstructs;
1498 }
1499 /** @endcond */
1500 
1501 
1502 /** @cond doxygenLibsbmlInternal */
1503 LIBSBML_EXTERN
1504 bool
usesRateOf() const1505 ASTNode::usesRateOf() const
1506 {
1507   bool mathConstructs = false;
1508 
1509   if (getType() == AST_FUNCTION_RATE_OF)
1510       mathConstructs = true;
1511   unsigned int i = 0;
1512   while (!mathConstructs && i < getNumChildren())
1513   {
1514     mathConstructs = getChild(i)->usesRateOf();
1515     i++;
1516   }
1517 
1518   return mathConstructs;
1519 }
1520 /** @endcond */
1521 
1522 /*
1523  * @return true if this ASTNode is a boolean (a logical operator, a
1524  * relational operator, or the constants true or false), false otherwise.
1525  */
1526 LIBSBML_EXTERN
1527 bool
isAvogadro() const1528 ASTNode::isAvogadro () const
1529 {
1530   return ASTNodeType_isAvogadro(mType);
1531 }
1532 
1533 
1534 /*
1535  * @return true if this ASTNode is a boolean (a logical operator, a
1536  * relational operator, or the constants true or false), false otherwise.
1537  */
1538 LIBSBML_EXTERN
1539 bool
isBoolean() const1540 ASTNode::isBoolean () const
1541 {
1542   return
1543     isLogical   () ||
1544     isRelational() ||
1545     mType == AST_CONSTANT_TRUE ||
1546     mType == AST_CONSTANT_FALSE;
1547 }
1548 
1549 
1550 LIBSBML_EXTERN
1551 bool
returnsBoolean(const Model * givenModel) const1552 ASTNode::returnsBoolean (const Model* givenModel /*=NULL*/) const
1553 {
1554 
1555   if (isBoolean() == true)
1556   {
1557     return true;
1558   }
1559 
1560   const Model* model = givenModel;
1561   if (givenModel == NULL && getParentSBMLObject() != NULL)
1562   {
1563     model = getParentSBMLObject()->getModel();
1564   }
1565 
1566   if (getType() == AST_FUNCTION)
1567   {
1568     if (model == NULL)
1569     {
1570       return false;
1571     }
1572     else
1573     {
1574       const FunctionDefinition* fd = model->getFunctionDefinition( getName() );
1575 
1576       if (fd != NULL && fd->isSetMath())
1577       {
1578         return (fd->getBody() != NULL ?
1579           fd->getBody()->returnsBoolean() : false);
1580       }
1581       else
1582       {
1583         return false;
1584       }
1585     }
1586   }
1587 
1588   else if (getType() == AST_FUNCTION_PIECEWISE)
1589   {
1590     for (unsigned int c = 0; c < getNumChildren(); c += 2)
1591     {
1592       if ( getChild(c)->returnsBoolean() == false )
1593         return false;
1594     }
1595 
1596     return true;
1597   }
1598 
1599   // add explicit return value in case we overlooked something
1600   return false;
1601 }
1602 
1603 
1604 
1605 
1606 /*
1607  * @return true if this ASTNode is a MathML constant (true,
1608  * false, pi, exponentiale), false otherwise.
1609  */
1610 LIBSBML_EXTERN
1611 bool
isConstant() const1612 ASTNode::isConstant () const
1613 {
1614   return ASTNodeType_isConstant(mType);
1615 }
1616 
1617 /*
1618 * @return true if this ASTNode is a MathML constant number
1619 *(pi, exponentiale), false otherwise.
1620 */
1621 LIBSBML_EXTERN
1622 bool
isCiNumber() const1623 ASTNode::isCiNumber() const
1624 {
1625   return (mType == AST_NAME);
1626 }
1627 
1628 
1629 
1630 
1631 /*
1632  * @return true if this ASTNode is a MathML constant number
1633  *(pi, exponentiale), false otherwise.
1634  */
1635 LIBSBML_EXTERN
1636 bool
isConstantNumber() const1637 ASTNode::isConstantNumber() const
1638 {
1639   return ASTNodeType_isConstantNumber(mType);
1640 }
1641 
1642 
1643 /*
1644 * @return true if this ASTNode is a MathML constant number
1645 *(pi, exponentiale), false otherwise.
1646 */
1647 LIBSBML_EXTERN
1648 bool
isCSymbolFunction() const1649 ASTNode::isCSymbolFunction() const
1650 {
1651   if (mType == AST_FUNCTION_DELAY)
1652   {
1653     return true;
1654   }
1655   const ASTBasePlugin* baseplugin = getASTPlugin(mType);
1656   if (baseplugin != NULL)
1657   {
1658     const char* csymbol = baseplugin->getConstCharCsymbolURLFor(mType);
1659     return (csymbol != NULL && !((string)csymbol).empty() && baseplugin->isFunction(mType));
1660   }
1661   return false;
1662 }
1663 
1664 
1665 
1666 bool
isFunction() const1667 ASTNode::isFunction () const
1668 {
1669   if (ASTNodeType_isFunction(mType))
1670   {
1671     return true;
1672   }
1673   const ASTBasePlugin* baseplugin = getASTPlugin(mType);
1674   if (baseplugin != NULL)
1675   {
1676     if (baseplugin->isFunction(mType))
1677     {
1678       return true;
1679     }
1680   }
1681   return false;
1682 }
1683 
1684 
1685 /*
1686  * @return true if this ASTNode is the special IEEE 754 value infinity,
1687  * false otherwise.
1688  */
1689 LIBSBML_EXTERN
1690 bool
isInfinity() const1691 ASTNode::isInfinity () const
1692 {
1693   return isReal() ? util_isInf( getReal() ) > 0 : false;
1694 }
1695 
1696 
1697 /*
1698  * @return true if this ASTNode is of type AST_INTEGER, false otherwise.
1699  */
1700 LIBSBML_EXTERN
1701 bool
isInteger() const1702 ASTNode::isInteger () const
1703 {
1704   return ASTNodeType_isInteger(mType);
1705 }
1706 
1707 
1708 /*
1709  * @return true if this ASTNode is of type AST_LAMBDA, false otherwise.
1710  */
1711 LIBSBML_EXTERN
1712 bool
isLambda() const1713 ASTNode::isLambda () const
1714 {
1715   return ASTNodeType_isLambda(mType);
1716 }
1717 
1718 /*
1719  * @return true if the given ASTNode represents a log10() function, false
1720  * otherwise.
1721  *
1722  * More precisley, the node type is AST_FUNCTION_LOG with two children the
1723  * first of which is an AST_INTEGER equal to 10.
1724  */
1725 LIBSBML_EXTERN
1726 bool
isLog10() const1727 ASTNode::isLog10 () const
1728 {
1729   bool     result = false;
1730   ASTNode* c;
1731 
1732 
1733   if (mType == AST_FUNCTION_LOG)
1734   {
1735     if (getNumChildren() == 2)
1736     {
1737       c = getLeftChild();
1738 
1739       if ((c->mType == AST_INTEGER) && (c->mInteger == 10))
1740       {
1741         result = true;
1742       }
1743     }
1744   }
1745 
1746   return result;
1747 }
1748 
1749 
1750 /*
1751  * @return true if this ASTNode is a MathML logical operator (and, or, not,
1752  * xor), false otherwise.
1753  */
1754 LIBSBML_EXTERN
1755 bool
isLogical() const1756 ASTNode::isLogical () const
1757 {
1758   if (ASTNodeType_isLogical(mType))
1759   {
1760     return true;
1761   }
1762   const ASTBasePlugin* baseplugin = getASTPlugin(mType);
1763   if (baseplugin != NULL)
1764   {
1765     if (baseplugin->isLogical(mType))
1766     {
1767       return true;
1768     }
1769   }
1770   return false;
1771 }
1772 
1773 
1774 /*
1775  * @return true if this ASTNode is a user-defined variable name in SBML L1,
1776  * L2 (MathML) or the special symbols delay or time, false otherwise.
1777  */
1778 LIBSBML_EXTERN
1779 bool
isName() const1780 ASTNode::isName () const
1781 {
1782   return ASTNodeType_isName(mType);
1783 }
1784 
1785 
1786 /*
1787  * @return true if this ASTNode is the special IEEE 754 value not a
1788  * number, false otherwise.
1789  */
1790 LIBSBML_EXTERN
1791 bool
isNaN() const1792 ASTNode::isNaN () const
1793 {
1794   if ( isReal() )
1795   {
1796     double value = getReal();
1797     return (value != value);
1798   }
1799 
1800   return false;
1801 }
1802 
1803 
1804 /*
1805  * @return true if this ASTNode is the special IEEE 754 value negative
1806  * infinity, false otherwise.
1807  */
1808 LIBSBML_EXTERN
1809 bool
isNegInfinity() const1810 ASTNode::isNegInfinity () const
1811 {
1812   return isReal() ? util_isInf( getReal() ) < 0 : false;
1813 }
1814 
1815 
1816 /*
1817  * @return true if this ASTNode is a number, false otherwise.
1818  *
1819  * This is functionally equivalent to:
1820  *
1821  *   isInteger() || isReal().
1822  */
1823 LIBSBML_EXTERN
1824 bool
isNumber() const1825 ASTNode::isNumber () const
1826 {
1827   return ASTNodeType_isNumber(mType);
1828 }
1829 
1830 
1831 /*
1832  * @return true if this ASTNode is an operator, false otherwise.  Operators
1833  * are: +, -, *, / and \^ (power).
1834  */
1835 LIBSBML_EXTERN
1836 bool
isOperator() const1837 ASTNode::isOperator () const
1838 {
1839   return ASTNodeType_isOperator(mType);
1840 }
1841 
1842 
1843 /*
1844  * @return true if this ASTNode is a piecewise function, false otherwise.
1845  */
1846 LIBSBML_EXTERN
1847 bool
isPiecewise() const1848 ASTNode::isPiecewise () const
1849 {
1850   return (mType == AST_FUNCTION_PIECEWISE);
1851 }
1852 
1853 
1854 /*
1855  * @return true if this ASTNode is of type AST_RATIONAL, false otherwise.
1856  */
1857 LIBSBML_EXTERN
1858 bool
isRational() const1859 ASTNode::isRational () const
1860 {
1861   return ASTNodeType_isRational(mType);
1862 }
1863 
1864 
1865 /*
1866  * @return true if the value of this ASTNode can represented as a real
1867  * number, false otherwise.
1868  *
1869  * To be a represented as a real number, this node must be of one of the
1870  * following types: AST_REAL, AST_REAL_E or AST_RATIONAL.
1871  */
1872 LIBSBML_EXTERN
1873 bool
isReal() const1874 ASTNode::isReal () const
1875 {
1876   return ASTNodeType_isReal(mType);
1877 }
1878 
1879 
1880 /*
1881  * @return true if this ASTNode is a MathML relational operator (==, >=, >,
1882  * <=, < !=), false otherwise.
1883  */
1884 LIBSBML_EXTERN
1885 bool
isRelational() const1886 ASTNode::isRelational () const
1887 {
1888   return ASTNodeType_isRelational(mType);
1889 }
1890 
1891 
1892 /*
1893  * @return true if the given ASTNode represents a sqrt() function, false
1894  * otherwise.
1895  *
1896  * More precisley, the node type is AST_FUNCTION_ROOT with two children the
1897  * first of which is an AST_INTEGER equal to 2.
1898  */
1899 LIBSBML_EXTERN
1900 bool
isSqrt() const1901 ASTNode::isSqrt () const
1902 {
1903   int      result = false;
1904   ASTNode* c;
1905 
1906 
1907   if (mType == AST_FUNCTION_ROOT)
1908   {
1909     if (getNumChildren() == 2)
1910     {
1911       c = getLeftChild();
1912 
1913       if ((c->mType == AST_INTEGER) && (c->mInteger == 2))
1914       {
1915         result = true;
1916       }
1917     }
1918   }
1919 
1920   return result;
1921 }
1922 
1923 
1924 /*
1925  * @return true if this ASTNode is a unary minus, false otherwise.
1926  *
1927  * For numbers, unary minus nodes can be "collapsed" by negating the
1928  * number.  In fact, SBML_parseFormula() does this during its parse.
1929  * However, unary minus nodes for symbols (AST_NAMES) cannot be
1930  * "collapsed", so this predicate function is necessary.
1931  *
1932  * A node is defined as a unary minus node if it is of type AST_MINUS and
1933  * has exactly one child.
1934  */
1935 LIBSBML_EXTERN
1936 bool
isUMinus() const1937 ASTNode::isUMinus () const
1938 {
1939   bool uminus = false;
1940 
1941 
1942   if (mType == AST_MINUS)
1943   {
1944     if (getNumChildren() == 1)
1945     {
1946       uminus = true;
1947     }
1948   }
1949 
1950   return uminus;
1951 }
1952 
1953 LIBSBML_EXTERN
1954 bool
isUPlus() const1955 ASTNode::isUPlus () const
1956 {
1957   bool uplus = false;
1958 
1959 
1960   if (mType == AST_PLUS)
1961   {
1962     if (getNumChildren() == 1)
1963     {
1964       uplus = true;
1965     }
1966   }
1967 
1968   return uplus;
1969 }
1970 
1971 LIBSBML_EXTERN
1972 bool
isUserFunction() const1973 ASTNode::isUserFunction() const
1974 {
1975   return (mType == AST_FUNCTION);
1976 }
1977 
1978 LIBSBML_EXTERN
1979 int
hasTypeAndNumChildren(ASTNodeType_t type,unsigned int numchildren) const1980 ASTNode::hasTypeAndNumChildren(ASTNodeType_t type, unsigned int numchildren) const
1981 {
1982   return (mType == type && getNumChildren() == numchildren);
1983 }
1984 
1985 /*
1986  * @return true if this ASTNode is of type AST_UNKNOWN, false otherwise.
1987  */
1988 LIBSBML_EXTERN
1989 bool
isUnknown() const1990 ASTNode::isUnknown () const
1991 {
1992   return ASTNodeType_isUnknown(mType);
1993 }
1994 
1995 
1996 LIBSBML_EXTERN
1997 bool
isSetId() const1998 ASTNode::isSetId() const
1999 {
2000   return (mId.empty() == false);
2001 }
2002 
2003 LIBSBML_EXTERN
2004 bool
isSetClass() const2005 ASTNode::isSetClass() const
2006 {
2007   return (mClass.empty() == false);
2008 }
2009 
2010 LIBSBML_EXTERN
2011 bool
isSetStyle() const2012 ASTNode::isSetStyle() const
2013 {
2014   return (mStyle.empty() == false);
2015 }
2016 
2017 LIBSBML_EXTERN
2018 bool
isSetUnits() const2019 ASTNode::isSetUnits() const
2020 {
2021   return (mUnits.empty() == false);
2022 }
2023 
2024 
2025 LIBSBML_EXTERN
2026 bool
hasUnits() const2027 ASTNode::hasUnits() const
2028 {
2029   bool hasUnits = isSetUnits();
2030 
2031   unsigned int n = 0;
2032   while(!hasUnits && n < getNumChildren())
2033   {
2034     hasUnits = getChild(n)->hasUnits();
2035     n++;
2036   }
2037 
2038   return hasUnits;
2039 }
2040 
2041 
2042 /*
2043  * Sets the value of this ASTNode to the given character.  If character is
2044  * one of '+', '-', '*', '/' or '\^', the node type will be set
2045  * accordingly.  For all other characters, the node type will be set to
2046  * AST_UNKNOWN.
2047  */
2048 LIBSBML_EXTERN
2049 int
setCharacter(char value)2050 ASTNode::setCharacter (char value)
2051 {
2052   setType( static_cast<ASTNodeType_t>(value) );
2053   mChar = value;
2054   return LIBSBML_OPERATION_SUCCESS;
2055 }
2056 
2057 
2058 /*
2059  * Sets the value of this ASTNode to the given name.
2060  *
2061  * The node type will be set (to AST_NAME) ONLY IF the ASTNode was
2062  * previously an operator (isOperator(node) == true) or number
2063  * (isNumber(node) == true).  This allows names to be set for AST_FUNCTIONs
2064  * and the like.
2065  */
2066 LIBSBML_EXTERN
2067 int
setName(const char * name)2068 ASTNode::setName (const char *name)
2069 {
2070   if (getName() == name)
2071     return LIBSBML_OPERATION_SUCCESS;
2072 
2073   unsetUnits();
2074 
2075   if ( isOperator() || isNumber() || isUnknown() )
2076   {
2077     mType = AST_NAME;
2078   }
2079 
2080   freeName();
2081   mName = (name == NULL) ? NULL : safe_strdup(name);
2082   return LIBSBML_OPERATION_SUCCESS;
2083 }
2084 
2085 
2086 /*
2087  * Sets the value of this ASTNode to the given integer and sets the node
2088  * type to AST_INTEGER.
2089  */
2090 LIBSBML_EXTERN
2091 int
setValue(int value)2092 ASTNode::setValue (int value)
2093 {
2094   setType(AST_INTEGER);
2095   mInteger = value;
2096   return LIBSBML_OPERATION_SUCCESS;
2097 }
2098 
2099 
2100 /*
2101  * Sets the value of this ASTNode to the given (long) integer and sets the
2102  * node type to AST_INTEGER.
2103  */
2104 LIBSBML_EXTERN
2105 int
setValue(long value)2106 ASTNode::setValue (long value)
2107 {
2108   setType(AST_INTEGER);
2109   mInteger = value;
2110   return LIBSBML_OPERATION_SUCCESS;
2111 }
2112 
2113 
2114 /*
2115  * Sets the value of this ASTNode to the given rational in two parts:
2116  * the numerator and denominator.  The node type is set to AST_RATIONAL.
2117  */
2118 LIBSBML_EXTERN
2119 int
setValue(long numerator,long denominator)2120 ASTNode::setValue (long numerator, long denominator)
2121 {
2122   setType(AST_RATIONAL);
2123 
2124   mInteger     = numerator;
2125   mDenominator = denominator;
2126   return LIBSBML_OPERATION_SUCCESS;
2127 }
2128 
2129 
2130 /*
2131  * Sets the value of this ASTNode to the given real (double) and sets the
2132  * node type to AST_REAL.
2133  *
2134  * This is functionally equivalent to:
2135  *
2136  *   setValue(value, 0);
2137  */
2138 LIBSBML_EXTERN
2139 int
setValue(double value)2140 ASTNode::setValue (double value)
2141 {
2142   setType(AST_REAL);
2143 
2144   mReal     = value;
2145   mExponent = 0;
2146   return LIBSBML_OPERATION_SUCCESS;
2147 }
2148 
2149 
2150 /*
2151  * Sets the value of this ASTNode to the given real (double) in two parts:
2152  * the mantissa and the exponent.  The node type is set to AST_REAL_E.
2153  */
2154 LIBSBML_EXTERN
2155 int
setValue(double mantissa,long exponent)2156 ASTNode::setValue (double mantissa, long exponent)
2157 {
2158   setType(AST_REAL_E);
2159 
2160   mReal     = mantissa;
2161   mExponent = exponent;
2162   return LIBSBML_OPERATION_SUCCESS;
2163 }
2164 
2165 
2166 /*
2167  * Sets the type of this ASTNode to the given ASTNodeType.
2168  */
2169 LIBSBML_EXTERN
2170 int
setType(ASTNodeType_t type)2171 ASTNode::setType (ASTNodeType_t type)
2172 {
2173   if (mType == type)
2174   {
2175     return LIBSBML_OPERATION_SUCCESS;
2176   }
2177 
2178   if (isOperator() || isNumber())
2179   {
2180     mReal     = 0;
2181     mExponent = 0;
2182     mDenominator = 1;
2183     mInteger = 0;
2184   }
2185 
2186   /* if avogadro set value */
2187   if (type == AST_NAME_AVOGADRO)
2188   {
2189     /* this will free the name - which people may not want */
2190     /* this solution does not in fact work for all language bindings */
2191 
2192     //if (mName != NULL)
2193     //{
2194     //  char * name = mName;
2195     //  setValue(6.02214179e23);
2196     //  setName(name);
2197     //}
2198     //else
2199     //{
2200       mReal = 6.02214179e23;
2201     //}
2202     mDefinitionURL->clear();
2203     mDefinitionURL->add("definitionURL",
2204                         "http://www.sbml.org/sbml/symbols/avogadro");
2205   }
2206   else if (type == AST_NAME_TIME)
2207   {
2208     mDefinitionURL->clear();
2209     mDefinitionURL->add("definitionURL",
2210                         "http://www.sbml.org/sbml/symbols/time");
2211   }
2212   else if (type == AST_FUNCTION_DELAY)
2213   {
2214     mDefinitionURL->clear();
2215     mDefinitionURL->add("definitionURL",
2216                         "http://www.sbml.org/sbml/symbols/delay");
2217   }
2218 
2219   /*
2220    * Free name only if the ASTNodeType is being set to something that
2221    * cannot contain a string.
2222    *
2223    * Note: freeName() will only free value.name if there is something to be
2224    * freed.
2225    */
2226   if ( ASTNodeType_isOperator(type) || ASTNodeType_isNumber(type) )
2227   {
2228     freeName();
2229   }
2230 
2231   // if the new type is not a number unset the units
2232   if (ASTNodeType_isNumber(type) == 0)
2233   {
2234     unsetUnits();
2235   }
2236 
2237   bool clearDefinitionURL = true;
2238   if (ASTNodeType_isOperator(type))
2239   {
2240     mType = type;
2241     mChar = (char)type;
2242   }
2243   else if ((type >= AST_INTEGER) && (type < AST_END_OF_CORE))
2244   {
2245     mType = type;
2246     mChar = 0;
2247 
2248     // clear the definitionURL unless new type is csymbol
2249     // or a number or is a semantics
2250     switch (type)
2251     {
2252     case AST_NAME:
2253     case AST_NAME_TIME:
2254     case AST_NAME_AVOGADRO:
2255     case AST_FUNCTION_DELAY:
2256     case AST_FUNCTION:
2257       clearDefinitionURL = false;
2258       break;
2259     default:
2260       break;
2261     }
2262   }
2263   else if (type > AST_END_OF_CORE && type < AST_UNKNOWN)
2264   {
2265     mType = type;
2266     mChar = 0;
2267 
2268     const ASTBasePlugin* baseplugin = getASTPlugin(mType);
2269     if (baseplugin != NULL)
2270     {
2271       if (baseplugin->getConstCharCsymbolURLFor(type) != NULL)
2272       {
2273         clearDefinitionURL = false;
2274       }
2275     }
2276   }
2277   else
2278   {
2279     mType = AST_UNKNOWN;
2280     mChar = 0;
2281     mDefinitionURL->clear();
2282     return LIBSBML_INVALID_ATTRIBUTE_VALUE;
2283   }
2284 
2285   if (clearDefinitionURL == true && getSemanticsFlag() == false)
2286   {
2287     mDefinitionURL->clear();
2288   }
2289 
2290 
2291   return LIBSBML_OPERATION_SUCCESS;
2292 
2293 }
2294 
2295 LIBSBML_EXTERN
2296 int
setId(const std::string & id)2297 ASTNode::setId (const std::string& id)
2298 {
2299   mId     = id;
2300   return LIBSBML_OPERATION_SUCCESS;
2301 }
2302 
2303 LIBSBML_EXTERN
2304 int
setClass(const std::string & className)2305 ASTNode::setClass (const std::string& className)
2306 {
2307   mClass   = className;
2308   return LIBSBML_OPERATION_SUCCESS;
2309 }
2310 
2311 LIBSBML_EXTERN
2312 int
setStyle(const std::string & style)2313 ASTNode::setStyle (const std::string& style)
2314 {
2315   mStyle     = style;
2316   return LIBSBML_OPERATION_SUCCESS;
2317 }
2318 
2319 
2320 
2321 LIBSBML_EXTERN
2322 int
setUnits(const std::string & units)2323 ASTNode::setUnits (const std::string& units)
2324 {
2325   if (!isNumber())
2326     return LIBSBML_UNEXPECTED_ATTRIBUTE;
2327 
2328   if (!SyntaxChecker::isValidInternalUnitSId(units))
2329     return LIBSBML_INVALID_ATTRIBUTE_VALUE;
2330 
2331   mUnits     = units;
2332   return LIBSBML_OPERATION_SUCCESS;
2333 }
2334 
2335 
2336 /*
2337  * Swap the children of this ASTNode with the children of that ASTNode.
2338  */
2339 LIBSBML_EXTERN
2340 int
swapChildren(ASTNode * that)2341 ASTNode::swapChildren (ASTNode *that)
2342 {
2343   if (that == NULL)
2344     return LIBSBML_OPERATION_FAILED;
2345 
2346   List *temp      = this->mChildren;
2347   this->mChildren = that->mChildren;
2348   that->mChildren = temp;
2349   return LIBSBML_OPERATION_SUCCESS;
2350 }
2351 
2352 LIBSBML_EXTERN
2353 void
renameSIdRefs(const std::string & oldid,const std::string & newid)2354 ASTNode::renameSIdRefs(const std::string& oldid, const std::string& newid)
2355 {
2356   if (getType() == AST_NAME ||
2357       getType() == AST_FUNCTION ||
2358       getType() == AST_UNKNOWN) {
2359     if (getName() == oldid) {
2360       setName(newid.c_str());
2361     }
2362   }
2363   for (unsigned int child=0; child<getNumChildren(); child++) {
2364     getChild(child)->renameSIdRefs(oldid, newid);
2365   }
2366 }
2367 
2368 LIBSBML_EXTERN
2369 void
renameUnitSIdRefs(const std::string & oldid,const std::string & newid)2370 ASTNode::renameUnitSIdRefs(const std::string& oldid, const std::string& newid)
2371 {
2372   if (isSetUnits()) {
2373     if (getUnits() == oldid) {
2374       setUnits(newid);
2375     }
2376   }
2377   for (unsigned int child=0; child<getNumChildren(); child++) {
2378     getChild(child)->renameUnitSIdRefs(oldid, newid);
2379   }
2380 }
2381 
2382 
2383 /** @cond doxygenLibsbmlInternal */
2384 LIBSBML_EXTERN
2385 void
replaceIDWithFunction(const std::string & id,const ASTNode * function)2386 ASTNode::replaceIDWithFunction(const std::string& id, const ASTNode* function)
2387 {
2388   for (unsigned int i=0; i<getNumChildren(); i++) {
2389     ASTNode* child = getChild(i);
2390     if (child->getType() == AST_NAME &&
2391         child->getName() == id) {
2392       replaceChild(i, function->deepCopy(), true);
2393     }
2394     else {
2395       child->replaceIDWithFunction(id, function);
2396     }
2397   }
2398 }
2399 /** @endcond */
2400 
2401 
2402 /** @cond doxygenLibsbmlInternal */
2403 LIBSBML_EXTERN
multiplyTimeBy(const ASTNode * function)2404 void ASTNode::multiplyTimeBy(const ASTNode* function)
2405 {
2406   for (unsigned int i=0; i<getNumChildren(); i++) {
2407     getChild(i)->multiplyTimeBy(function);
2408   }
2409   if (getType() == AST_NAME_TIME) {
2410     setType(AST_TIMES);
2411     addChild(function->deepCopy());
2412     ASTNode* time = new ASTNode(AST_NAME_TIME);
2413     addChild(time);
2414   }
2415 }
2416 /** @endcond */
2417 
2418 LIBSBML_EXTERN
2419 int
unsetId()2420 ASTNode::unsetId ()
2421 {
2422   mId.erase();
2423 
2424   if (mId.empty())
2425   {
2426     return LIBSBML_OPERATION_SUCCESS;
2427   }
2428   else
2429   {
2430     return LIBSBML_OPERATION_FAILED;
2431   }
2432 }
2433 
2434 
2435 LIBSBML_EXTERN
2436 int
unsetClass()2437 ASTNode::unsetClass ()
2438 {
2439   mClass.erase();
2440 
2441   if (mClass.empty())
2442   {
2443     return LIBSBML_OPERATION_SUCCESS;
2444   }
2445   else
2446   {
2447     return LIBSBML_OPERATION_FAILED;
2448   }
2449 }
2450 
2451 LIBSBML_EXTERN
2452 int
unsetStyle()2453 ASTNode::unsetStyle ()
2454 {
2455   mStyle.erase();
2456 
2457   if (mStyle.empty())
2458   {
2459     return LIBSBML_OPERATION_SUCCESS;
2460   }
2461   else
2462   {
2463     return LIBSBML_OPERATION_FAILED;
2464   }
2465 }
2466 
2467 LIBSBML_EXTERN
2468 int
unsetUnits()2469 ASTNode::unsetUnits ()
2470 {
2471   if (!isNumber())
2472     return LIBSBML_UNEXPECTED_ATTRIBUTE;
2473 
2474   mUnits.erase();
2475 
2476   if (mUnits.empty())
2477   {
2478     return LIBSBML_OPERATION_SUCCESS;
2479   }
2480   else
2481   {
2482     return LIBSBML_OPERATION_FAILED;
2483   }
2484 }
2485 
2486 
2487 /** @cond doxygenLibsbmlInternal */
2488 /*
2489  * Sets the flag indicating that this ASTNode has semantics attached
2490  */
2491 int
setSemanticsFlag()2492 ASTNode::setSemanticsFlag()
2493 {
2494   hasSemantics = true;
2495   return LIBSBML_OPERATION_SUCCESS;
2496 }
2497 /** @endcond */
2498 
2499 
2500 /** @cond doxygenLibsbmlInternal */
2501 /*
2502   * Unsets the flag indicating that this ASTNode has semantics attached
2503   */
2504 int
unsetSemanticsFlag()2505 ASTNode::unsetSemanticsFlag()
2506 {
2507   hasSemantics = false;
2508 
2509   if (hasSemantics)
2510   {
2511     return LIBSBML_OPERATION_FAILED;
2512   }
2513   else
2514   {
2515     return LIBSBML_OPERATION_SUCCESS;
2516   }
2517 }
2518 /** @endcond */
2519 
2520 
2521 /** @cond doxygenLibsbmlInternal */
2522 /*
2523   * gets the flag indicating that this ASTNode has semantics attached
2524   */
2525 bool
getSemanticsFlag() const2526 ASTNode::getSemanticsFlag() const
2527 {
2528   return hasSemantics;
2529 }
2530 /** @endcond */
2531 
2532 
2533 /** @cond doxygenLibsbmlInternal */
2534 /*
2535   * sets the definitionURL attributes
2536   */
2537 int
setDefinitionURL(XMLAttributes url)2538 ASTNode::setDefinitionURL(XMLAttributes url)
2539 {
2540   delete mDefinitionURL;
2541   mDefinitionURL = static_cast<XMLAttributes *>(url.clone());
2542   return LIBSBML_OPERATION_SUCCESS;
2543 }
2544 
2545 
2546 /*
2547   * sets the definitionURL attributes
2548   */
2549 int
setDefinitionURL(const std::string & url)2550 ASTNode::setDefinitionURL(const std::string& url)
2551 {
2552   mDefinitionURL->clear();
2553   mDefinitionURL->add("definitionURL", url);
2554   return LIBSBML_OPERATION_SUCCESS;
2555 }
2556 
2557 LIBSBML_EXTERN
2558 bool
isBvar() const2559 ASTNode::isBvar() const
2560 {
2561   return mIsBvar;
2562 }
2563 
2564 
2565 LIBSBML_EXTERN
2566 bool
representsBvar() const2567 ASTNode::representsBvar() const
2568 {
2569   return mIsBvar;
2570 }
2571 
2572 
2573 LIBSBML_EXTERN
2574 void
setBvar()2575 ASTNode::setBvar()
2576 {
2577   mIsBvar = true;
2578 }
2579 
2580 
2581 LIBSBML_EXTERN
2582 bool
isQualifier() const2583 ASTNode::isQualifier() const
2584 {
2585   return false;
2586 }
2587 
2588 LIBSBML_EXTERN
2589 bool
isSemantics() const2590 ASTNode::isSemantics() const
2591 {
2592   return getSemanticsFlag();
2593 }
2594 
2595 LIBSBML_EXTERN
2596 unsigned int
getNumBvars() const2597 ASTNode::getNumBvars() const
2598 {
2599   unsigned int num = getNumChildren();
2600   if (num == 0)
2601     return num;
2602   if (getChild(num - 1)->isBvar())
2603     return num;
2604   else
2605     return num - 1;
2606 }
2607 
2608 
2609 bool
hasCorrectNumberArguments() const2610 ASTNode::hasCorrectNumberArguments() const
2611 {
2612   bool correctNum = true;
2613   ASTNodeType_t type = getType();
2614   unsigned int numChildren = getNumChildren();
2615 
2616   switch (type)
2617   {
2618   case AST_INTEGER:
2619   case AST_REAL:
2620   case AST_REAL_E:
2621   case AST_RATIONAL:
2622   case AST_NAME:
2623   case AST_NAME_AVOGADRO:
2624   case AST_NAME_TIME:
2625   case AST_CONSTANT_E:
2626   case AST_CONSTANT_FALSE:
2627   case AST_CONSTANT_PI:
2628   case AST_CONSTANT_TRUE:
2629 
2630     if (numChildren != 0) {
2631       correctNum = false;
2632     }
2633     break;
2634 
2635   case AST_FUNCTION_ABS:
2636   case AST_FUNCTION_ARCCOS:
2637   case AST_FUNCTION_ARCCOSH:
2638   case AST_FUNCTION_ARCCOT:
2639   case AST_FUNCTION_ARCCOTH:
2640   case AST_FUNCTION_ARCCSC:
2641   case AST_FUNCTION_ARCCSCH:
2642   case AST_FUNCTION_ARCSEC:
2643   case AST_FUNCTION_ARCSECH:
2644   case AST_FUNCTION_ARCSIN:
2645   case AST_FUNCTION_ARCSINH:
2646   case AST_FUNCTION_ARCTAN:
2647   case AST_FUNCTION_ARCTANH:
2648   case AST_FUNCTION_CEILING:
2649   case AST_FUNCTION_COS:
2650   case AST_FUNCTION_COSH:
2651   case AST_FUNCTION_COT:
2652   case AST_FUNCTION_COTH:
2653   case AST_FUNCTION_CSC:
2654   case AST_FUNCTION_CSCH:
2655   case AST_FUNCTION_EXP:
2656   case AST_FUNCTION_FACTORIAL:
2657   case AST_FUNCTION_FLOOR:
2658   case AST_FUNCTION_LN:
2659   case AST_FUNCTION_SEC:
2660   case AST_FUNCTION_SECH:
2661   case AST_FUNCTION_SIN:
2662   case AST_FUNCTION_SINH:
2663   case AST_FUNCTION_TAN:
2664   case AST_FUNCTION_TANH:
2665   case AST_LOGICAL_NOT:
2666 
2667     if (numChildren != 1) {
2668       correctNum = false;
2669     }
2670     break;
2671 
2672   case AST_DIVIDE:
2673   case AST_POWER:
2674   case AST_RELATIONAL_NEQ:
2675   case AST_FUNCTION_DELAY:
2676   case AST_FUNCTION_POWER:
2677   case AST_FUNCTION_LOG:       // a log ASTNode has a child for base
2678 
2679     if (numChildren != 2) {
2680       correctNum = false;
2681     }
2682     break;
2683 
2684   case AST_TIMES:
2685   case AST_PLUS:
2686   case AST_LOGICAL_AND:
2687   case AST_LOGICAL_OR:
2688   case AST_LOGICAL_XOR:
2689     correctNum = true;
2690     break;
2691 
2692   case AST_RELATIONAL_EQ:
2693   case AST_RELATIONAL_GEQ:
2694   case AST_RELATIONAL_GT:
2695   case AST_RELATIONAL_LEQ:
2696   case AST_RELATIONAL_LT:
2697 
2698     if (numChildren < 2) {
2699       correctNum = false;
2700     }
2701     break;
2702 
2703   case AST_FUNCTION_ROOT:
2704   case AST_MINUS:
2705 
2706     if (numChildren < 1 || numChildren > 2) {
2707       correctNum = false;
2708     }
2709     break;
2710 
2711   case AST_FUNCTION_PIECEWISE:
2712   case AST_LAMBDA:
2713 
2714     if (numChildren < 1) {
2715       correctNum = false;
2716     }
2717     break;
2718 
2719   case AST_FUNCTION:
2720     break;
2721 
2722   default:
2723     if (mType > AST_END_OF_CORE)
2724     {
2725       const ASTBasePlugin * baseplugin = getASTPlugin(mType);
2726       if (baseplugin != NULL)
2727       {
2728         correctNum = baseplugin->hasCorrectNumArguments(this);
2729       }
2730     }
2731     break;
2732 
2733   }
2734 
2735   return correctNum;
2736 }
2737 bool
isWellFormedASTNode() const2738 ASTNode::isWellFormedASTNode() const
2739 {
2740   bool valid = hasCorrectNumberArguments();
2741   unsigned int numChildren = getNumChildren();
2742   unsigned int i = 0;
2743 
2744   // check number of arguments
2745   while (valid && i < numChildren)
2746   {
2747     valid = getChild(i)->isWellFormedASTNode();
2748     i++;
2749   }
2750   return valid;
2751 }
2752 
2753 
2754 /** @endcond */
2755 
2756 
2757 LIBSBML_EXTERN
2758 void
replaceArgument(const std::string & bvar,ASTNode * arg)2759 ASTNode::replaceArgument(const std::string& bvar, ASTNode * arg)
2760 {
2761   if (arg == NULL)
2762     return;
2763   else if (getNumChildren() == 0)
2764   {
2765     if (this->isName() && this->getName() == bvar)
2766     {
2767       if (arg->isName())
2768       {
2769         this->setType(arg->getType());
2770         this->setName(arg->getName());
2771       }
2772       else if (arg->isReal())
2773       {
2774         this->setValue(arg->getReal());
2775         if (arg->isSetUnits())
2776         {
2777           this->setUnits(arg->getUnits());
2778         }
2779       }
2780       else if (arg->isInteger())
2781       {
2782         this->setValue(arg->getInteger());
2783         if (arg->isSetUnits())
2784         {
2785           this->setUnits(arg->getUnits());
2786         }
2787       }
2788       else if (arg->isConstant())
2789       {
2790         this->setType(arg->getType());
2791       }
2792       else
2793       {
2794         this->setType(arg->getType());
2795         this->setName(arg->getName());
2796         for (unsigned int c = 0; c < arg->getNumChildren(); c++)
2797         {
2798           this->addChild(arg->getChild(c)->deepCopy());
2799         }
2800       }
2801     }
2802   }
2803   for (unsigned int i = 0; i < getNumChildren(); i++)
2804   {
2805     if (getChild(i)->isName())
2806     {
2807       if (getChild(i)->getName() == bvar)
2808       {
2809         if (arg->isName())
2810         {
2811           getChild(i)->setType(arg->getType());
2812           getChild(i)->setName(arg->getName());
2813         }
2814         else if (arg->isReal())
2815         {
2816           getChild(i)->setValue(arg->getReal());
2817           if (arg->isSetUnits())
2818           {
2819             getChild(i)->setUnits(arg->getUnits());
2820           }
2821         }
2822         else if (arg->isInteger())
2823         {
2824           getChild(i)->setValue(arg->getInteger());
2825           if (arg->isSetUnits())
2826           {
2827             getChild(i)->setUnits(arg->getUnits());
2828           }
2829         }
2830         else if (arg->isConstant())
2831         {
2832           getChild(i)->setType(arg->getType());
2833         }
2834         else
2835         {
2836           getChild(i)->setType(arg->getType());
2837           getChild(i)->setName(arg->getName());
2838           for (unsigned int c = 0; c < arg->getNumChildren(); c++)
2839           {
2840             getChild(i)->addChild(arg->getChild(c)->deepCopy());
2841           }
2842         }
2843       }
2844     }
2845     else
2846     {
2847       getChild(i)->replaceArgument(bvar, arg);
2848     }
2849   }
2850 }
2851 
2852 LIBSBML_EXTERN
2853 void
reduceToBinary()2854 ASTNode::reduceToBinary()
2855 {
2856   unsigned int numChildren = getNumChildren();
2857   /* number of children should be greater than 2 */
2858   if (numChildren < 3)
2859     return;
2860 
2861   ASTNode* op = new ASTNode( getType() );
2862   ASTNode* op2 = new ASTNode( getType() );
2863 
2864   // add the first two children to the first node
2865   op->addChild(getChild(0));
2866   op->addChild(getChild(1));
2867 
2868   op2->addChild(op);
2869   for (unsigned int n = 2; n < numChildren; n++)
2870     op2->addChild(getChild(n));
2871 
2872   swapChildren(op2);
2873 
2874   // need to clean up memory but the children of op2
2875   // are now the children of this ASTNode
2876   // so remove them from op2 before deleting it
2877   // this is why removeChild does not delete the child
2878   unsigned int num = op2->getNumChildren();
2879   unsigned int i = 0;
2880   while(i < num)
2881   {
2882     op2->removeChild(0);
2883     i++;
2884   }
2885   delete op2;
2886 
2887   reduceToBinary();
2888 }
2889 
2890 
2891 /** @cond doxygenLibsbmlInternal */
2892 LIBSBML_EXTERN
2893 void
setParentSBMLObject(SBase * sb)2894 ASTNode::setParentSBMLObject(SBase * sb)
2895 {
2896   mParentSBMLObject = sb;
2897 }
2898 
2899 LIBSBML_EXTERN
2900 int
unsetParentSBMLObject()2901 ASTNode::unsetParentSBMLObject()
2902 {
2903   mParentSBMLObject = NULL;
2904   return LIBSBML_OPERATION_SUCCESS;
2905 }
2906 
2907 
2908 LIBSBML_EXTERN
2909 bool
isSetParentSBMLObject() const2910 ASTNode::isSetParentSBMLObject() const
2911 {
2912   return (mParentSBMLObject != NULL);
2913 }
2914 /** @endcond */
2915 
2916 
2917 LIBSBML_EXTERN
2918 SBase *
getParentSBMLObject() const2919 ASTNode::getParentSBMLObject() const
2920 {
2921   return mParentSBMLObject;
2922 }
2923 
2924 
2925 /*
2926   * gets the definitionURL attributes
2927   */
2928 LIBSBML_EXTERN
2929 XMLAttributes*
getDefinitionURL() const2930 ASTNode::getDefinitionURL() const
2931 {
2932   return mDefinitionURL;
2933 }
2934 
2935 
2936 
2937 LIBSBML_EXTERN
2938 std::string
getDefinitionURLString() const2939 ASTNode::getDefinitionURLString() const
2940 {
2941   if (mDefinitionURL == NULL)
2942   {
2943     return "";
2944   }
2945   else
2946   {
2947     return mDefinitionURL->getValue("definitionURL");
2948   }
2949 }
2950 
2951 LIBSBML_EXTERN
2952 void *
getUserData() const2953 ASTNode::getUserData() const
2954 {
2955   return this->mUserData;
2956 }
2957 
2958 
2959 LIBSBML_EXTERN
2960 int
setUserData(void * userData)2961 ASTNode::setUserData(void *userData)
2962 {
2963   this->mUserData = userData;
2964 
2965   // allow userData to be set to NULL
2966   if (userData == NULL)
2967   {
2968     if (mUserData != NULL)
2969     {
2970       return LIBSBML_OPERATION_FAILED;
2971     }
2972     else
2973     {
2974       return LIBSBML_OPERATION_SUCCESS;
2975     }
2976   }
2977 
2978   if (mUserData != NULL)
2979   {
2980     return LIBSBML_OPERATION_SUCCESS;
2981   }
2982   else
2983   {
2984     return LIBSBML_OPERATION_FAILED;
2985   }
2986 }
2987 
2988 
2989 LIBSBML_EXTERN
2990 int
unsetUserData()2991 ASTNode::unsetUserData()
2992 {
2993   mUserData = NULL;
2994 
2995   if (mUserData == NULL)
2996   {
2997     return LIBSBML_OPERATION_SUCCESS;
2998   }
2999   else
3000   {
3001     return LIBSBML_OPERATION_FAILED;
3002   }
3003 }
3004 
3005 
3006 LIBSBML_EXTERN
3007 bool
isSetUserData() const3008 ASTNode::isSetUserData() const
3009 {
3010   return (mUserData != NULL);
3011 }
3012 
3013 
3014 /** @cond doxygenLibsbmlInternal */
3015 LIBSBML_EXTERN
containsVariable(const std::string & id) const3016 bool ASTNode::containsVariable(const std::string& id) const
3017 {
3018   bool found = false;
3019 
3020   List * nodes = this->getListOfNodes( ASTNode_isName );
3021   if (nodes == NULL) return false;
3022 
3023   unsigned int i = 0;
3024   while (found == false && i < nodes->getSize())
3025   {
3026     ASTNode* node = static_cast<ASTNode*>( nodes->get(i) );
3027     string   name = node->getName() ? node->getName() : "";
3028     if (name == id)
3029     {
3030       found = true;
3031     }
3032     i++;
3033   }
3034 
3035   delete nodes;
3036 
3037   return found;
3038 }
3039 /** @endcond */
3040 
3041 /** @cond doxygenLibsbmlInternal */
3042 LIBSBML_EXTERN
getNumVariablesWithUndeclaredUnits(Model * m) const3043 unsigned int ASTNode::getNumVariablesWithUndeclaredUnits(Model * m) const
3044 {
3045   unsigned int number = 0;
3046 
3047   if (m == NULL)
3048   {
3049     if (this->getParentSBMLObject() != NULL)
3050     {
3051       m = static_cast <Model *>(this->getParentSBMLObject()
3052                                      ->getAncestorOfType(SBML_MODEL));
3053     }
3054   }
3055 
3056   // we are possibly in a kineticLaw where parameters might
3057   // have local ids
3058   KineticLaw* kl = NULL;
3059 
3060   if (this->getParentSBMLObject() != NULL &&
3061     this->getParentSBMLObject()->getTypeCode() == SBML_KINETIC_LAW)
3062   {
3063     kl = static_cast<KineticLaw*>(this->getParentSBMLObject());
3064   }
3065 
3066   // create a list of variables in the math
3067   List * nodes = this->getListOfNodes( ASTNode_isName );
3068   IdList * variables = new IdList();
3069   if (nodes != NULL)
3070   {
3071     for (unsigned int i = 0; i < nodes->getSize(); i++)
3072     {
3073       ASTNode* node = static_cast<ASTNode*>( nodes->get(i) );
3074       string   name = node->getName() ? node->getName() : "";
3075       if (name.empty() == false)
3076       {
3077         if (variables->contains(name) == false)
3078         {
3079           variables->append(name);
3080         }
3081       }
3082     }
3083     delete nodes;
3084   }
3085 
3086   if ( m == NULL)
3087   {
3088     // there is no model so we have no units
3089     number = variables->size();
3090   }
3091   else
3092   {
3093     // should we look for reactions or speciesreferences in the math
3094     bool allowReactionId = true;
3095     //bool allowSpeciesRef = false;
3096 
3097     if ( (m->getLevel() < 2)
3098      || ((m->getLevel() == 2) && (m->getVersion() == 1)) )
3099     {
3100       allowReactionId = false;
3101     }
3102 
3103     //if (m->getLevel() > 2)
3104     //{
3105     //  allowSpeciesRef = true;
3106     //}
3107 
3108     // loop through the list and check the unit status of each variable
3109     for (unsigned int v = 0; v < variables->size(); v++)
3110     {
3111       string id = variables->at(v);
3112 
3113 
3114       if (m->getParameter(id) != NULL)
3115       {
3116         if (m->getParameter(id)->isSetUnits() == false)
3117         {
3118           number++;
3119         }
3120       }
3121       else if (m->getSpecies(id) != NULL)
3122       {
3123         if (m->getSpecies(id)->getDerivedUnitDefinition()->getNumUnits() == 0)
3124         {
3125           number++;
3126         }
3127       }
3128       else if (m->getCompartment(id) != NULL)
3129       {
3130          if (m->getCompartment(id)->getDerivedUnitDefinition()
3131                                                          ->getNumUnits() == 0)
3132         {
3133           number++;
3134         }
3135       }
3136       else if (kl != NULL && kl->getParameter(id) != NULL)
3137       {
3138         if (kl->getParameter(id)->getDerivedUnitDefinition() == NULL ||
3139           kl->getParameter(id)->getDerivedUnitDefinition()->getNumUnits() == 0)
3140         {
3141           number++;
3142         }
3143       }
3144       else if (allowReactionId == true
3145          && m->getReaction(id) != NULL
3146          && m->getReaction(id)->getKineticLaw() != NULL)
3147       {
3148          if (m->getReaction(id)->getKineticLaw()->getDerivedUnitDefinition()
3149                                                          ->getNumUnits() == 0)
3150         {
3151           number++;
3152         }
3153       }
3154       /* actually these always are considered to be dimensionless */
3155       //else if (allowSpeciesRef == true && m->getSpeciesReference(id) != NULL)
3156       //{
3157       //}
3158     }
3159   }
3160 
3161 
3162   variables->clear();
3163   delete variables;
3164 
3165   return number;
3166 }
3167 /** @endcond */
3168 
3169 /** @cond doxygenLibsbmlInternal */
3170 
3171 LIBSBML_EXTERN
3172 ASTBasePlugin *
getASTPlugin(const SBMLNamespaces * sbmlns)3173 ASTNode::getASTPlugin(const SBMLNamespaces * sbmlns)
3174 {
3175   if (sbmlns)
3176   {
3177     const XMLNamespaces *xmlns = sbmlns->getNamespaces();
3178 
3179     if (xmlns)
3180     {
3181       int numxmlns = xmlns->getLength();
3182       for (int i = 0; i < numxmlns; i++)
3183       {
3184         const std::string &uri = xmlns->getURI(i);
3185         const SBMLExtension* sbmlext = SBMLExtensionRegistry::getInstance().getExtensionInternal(uri);
3186 
3187         if (sbmlext && sbmlext->isEnabled())
3188         {
3189           const ASTBasePlugin* astPlugin = sbmlext->getASTBasePlugin();
3190           if (astPlugin != NULL)
3191           {
3192             return const_cast<ASTBasePlugin*>(astPlugin);
3193           }
3194         }
3195       }
3196     }
3197   }
3198   return NULL;
3199 }
3200 
3201 LIBSBML_EXTERN
3202 ASTBasePlugin *
getASTPlugin(ASTNodeType_t type)3203 ASTNode::getASTPlugin(ASTNodeType_t type)
3204 {
3205   unsigned int numPkgs = SBMLExtensionRegistry::getInstance().getNumASTPlugins();
3206 
3207   for (unsigned int i = 0; i < numPkgs; i++)
3208   {
3209     const ASTBasePlugin* baseplugin = SBMLExtensionRegistry::getInstance().getASTPlugin(i);
3210     if (baseplugin->defines(type))
3211     {
3212       return const_cast<ASTBasePlugin*>(baseplugin);
3213     }
3214   }
3215   return NULL;
3216 }
3217 
3218 LIBSBML_EXTERN
3219 ASTBasePlugin *
getASTPlugin(const std::string & name,bool isCsymbol,bool strCmpIsCaseSensitive)3220 ASTNode::getASTPlugin(const std::string& name, bool isCsymbol, bool strCmpIsCaseSensitive)
3221 {
3222   unsigned int numPkgs = SBMLExtensionRegistry::getInstance().getNumASTPlugins();
3223 
3224   for (unsigned int i = 0; i < numPkgs; i++)
3225   {
3226     const ASTBasePlugin* baseplugin = SBMLExtensionRegistry::getInstance().getASTPlugin(i);
3227     if (isCsymbol)
3228     {
3229       if (baseplugin->getASTNodeTypeForCSymbolURL(name) != AST_UNKNOWN)
3230       {
3231         return const_cast<ASTBasePlugin*>(baseplugin);
3232       }
3233     }
3234     else
3235     {
3236       if (baseplugin->defines(name, strCmpIsCaseSensitive))
3237       {
3238         return const_cast<ASTBasePlugin*>(baseplugin);
3239       }
3240     }
3241   }
3242   return NULL;
3243 }
3244 
3245 
3246 LIBSBML_EXTERN
3247 const ASTBasePlugin *
getASTPlugin(const SBMLNamespaces * sbmlns) const3248 ASTNode::getASTPlugin(const SBMLNamespaces * sbmlns) const
3249 {
3250   if (sbmlns)
3251   {
3252     const XMLNamespaces *xmlns = sbmlns->getNamespaces();
3253 
3254     if (xmlns)
3255     {
3256       int numxmlns = xmlns->getLength();
3257       for (int i = 0; i < numxmlns; i++)
3258       {
3259         const std::string &uri = xmlns->getURI(i);
3260         const SBMLExtension* sbmlext = SBMLExtensionRegistry::getInstance().getExtensionInternal(uri);
3261 
3262         if (sbmlext && sbmlext->isEnabled())
3263         {
3264           const ASTBasePlugin* astPlugin = sbmlext->getASTBasePlugin();
3265           if (astPlugin != NULL)
3266           {
3267             return astPlugin;
3268           }
3269         }
3270       }
3271     }
3272   }
3273   return NULL;
3274 }
3275 
3276 LIBSBML_EXTERN
3277 const ASTBasePlugin *
getASTPlugin(ASTNodeType_t type) const3278 ASTNode::getASTPlugin(ASTNodeType_t type) const
3279 {
3280   unsigned int numPkgs = SBMLExtensionRegistry::getInstance().getNumASTPlugins();
3281 
3282   for (unsigned int i = 0; i < numPkgs; i++)
3283   {
3284     const ASTBasePlugin* baseplugin = SBMLExtensionRegistry::getInstance().getASTPlugin(i);
3285     if (baseplugin->defines(type))
3286     {
3287       return baseplugin;
3288     }
3289   }
3290   return NULL;
3291 }
3292 
3293 LIBSBML_EXTERN
3294 const ASTBasePlugin *
getASTPlugin(const std::string & name,bool isCsymbol,bool strCmpIsCaseSensitive) const3295 ASTNode::getASTPlugin(const std::string& name, bool isCsymbol, bool strCmpIsCaseSensitive) const
3296 {
3297   unsigned int numPkgs = SBMLExtensionRegistry::getInstance().getNumASTPlugins();
3298 
3299   for (unsigned int i = 0; i < numPkgs; i++)
3300   {
3301     const ASTBasePlugin* baseplugin = SBMLExtensionRegistry::getInstance().getASTPlugin(i);
3302     if (isCsymbol)
3303     {
3304       if (baseplugin->getASTNodeTypeForCSymbolURL(name) != AST_UNKNOWN)
3305       {
3306         return baseplugin;
3307       }
3308     }
3309     else
3310     {
3311       if (baseplugin->defines(name, strCmpIsCaseSensitive))
3312       {
3313         return const_cast<ASTBasePlugin*>(baseplugin);
3314       }
3315     }
3316   }
3317   return NULL;
3318 }
3319 
3320 
3321 
3322 LIBSBML_EXTERN
3323 void
loadASTPlugin(const std::string & pkgName)3324 ASTNode::loadASTPlugin(const std::string& pkgName)
3325 {
3326   unsigned int numPkgs = SBMLExtensionRegistry::getInstance().getNumASTPlugins();
3327 
3328   for (unsigned int i = 0; i < numPkgs; i++)
3329   {
3330     const ASTBasePlugin* baseplugin = SBMLExtensionRegistry::getInstance().getASTPlugin(i);
3331     if (baseplugin->getPackageName() == pkgName)
3332     {
3333       ASTBasePlugin* myastPlugin = baseplugin->clone();
3334       myastPlugin->setPrefix(pkgName);
3335       myastPlugin->connectToParent(this);
3336       mPlugins.push_back(myastPlugin);
3337     }
3338   }
3339 }
3340 
3341 
3342 LIBSBML_EXTERN
3343 void
loadASTPlugins(const SBMLNamespaces * sbmlns)3344 ASTNode::loadASTPlugins(const SBMLNamespaces * sbmlns)
3345 {
3346   if (sbmlns == NULL)
3347   {
3348     const std::vector<std::string>& names = SBMLExtensionRegistry::getAllRegisteredPackageNames();
3349     unsigned int numPkgs = (unsigned int)names.size();
3350 
3351     for (unsigned int i = 0; i < numPkgs; i++)
3352     {
3353       const std::string& uri = names[i];
3354       const SBMLExtension* sbmlext = SBMLExtensionRegistry::getInstance().getExtensionInternal(uri);
3355 
3356       if (sbmlext && sbmlext->isEnabled())
3357       {
3358 
3359         //const std::string &prefix = xmlns->getPrefix(i);
3360         const ASTBasePlugin* astPlugin = sbmlext->getASTBasePlugin();
3361         if (astPlugin != NULL)
3362         {
3363           ASTBasePlugin* myastPlugin = astPlugin->clone();
3364           myastPlugin->setSBMLExtension(sbmlext);
3365           myastPlugin->setPrefix(uri);
3366           myastPlugin->connectToParent(this);
3367           mPlugins.push_back(myastPlugin);
3368         }
3369 
3370       }
3371     }
3372   }
3373   else
3374   {
3375     const XMLNamespaces *xmlns = sbmlns->getNamespaces();
3376 
3377     if (xmlns)
3378     {
3379       int numxmlns = xmlns->getLength();
3380       for (int i = 0; i < numxmlns; i++)
3381       {
3382         const std::string &uri = xmlns->getURI(i);
3383         const SBMLExtension* sbmlext = SBMLExtensionRegistry::getInstance().getExtensionInternal(uri);
3384 
3385         if (sbmlext && sbmlext->isEnabled())
3386         {
3387           const ASTBasePlugin* astPlugin = sbmlext->getASTBasePlugin();
3388           if (astPlugin != NULL)
3389           {
3390             ASTBasePlugin* myastPlugin = astPlugin->clone();
3391             myastPlugin->setSBMLExtension(sbmlext);
3392             myastPlugin->setPrefix(xmlns->getPrefix(i));
3393             myastPlugin->connectToParent(this);
3394             mPlugins.push_back(myastPlugin);
3395           }
3396         }
3397       }
3398     }
3399   }
3400 }
3401 
3402 LIBSBML_EXTERN
3403 void
addPlugin(ASTBasePlugin * plugin)3404 ASTNode::addPlugin(ASTBasePlugin* plugin)
3405 {
3406   mPlugins.push_back(plugin);
3407 }
3408 
3409 
3410 /** @endcond */
3411 
3412 /** @cond doxygenLibsbmlInternal */
3413 
3414 LIBSBML_EXTERN
3415 ASTBasePlugin*
getPlugin(const std::string & package)3416 ASTNode::getPlugin(const std::string& package)
3417 {
3418   ASTBasePlugin * astPlugin = NULL;
3419   if (getNumPlugins() == 0)
3420   {
3421     loadASTPlugin(package);
3422   }
3423   for (size_t i = 0; i < mPlugins.size(); i++)
3424   {
3425     std::string uri = mPlugins[i]->getURI();
3426     const SBMLExtension* sbmlext = SBMLExtensionRegistry::getInstance().getExtensionInternal(uri);
3427     if (uri == package)
3428     {
3429       astPlugin = mPlugins[i];
3430       break;
3431     }
3432     else if (sbmlext && (sbmlext->getName() == package))
3433     {
3434       astPlugin = mPlugins[i];
3435       break;
3436     }
3437   }
3438 
3439   return astPlugin;
3440 }
3441 
3442 /** @endcond */
3443 
3444 /** @cond doxygenLibsbmlInternal */
3445 
3446 LIBSBML_EXTERN
3447 const ASTBasePlugin*
getPlugin(const std::string & package) const3448 ASTNode::getPlugin(const std::string& package) const
3449 {
3450   return const_cast<ASTNode*>(this)->getPlugin(package);
3451 }
3452 
3453 /** @endcond */
3454 
3455 /** @cond doxygenLibsbmlInternal */
3456 
3457 
3458 LIBSBML_EXTERN
3459 ASTBasePlugin*
getPlugin(unsigned int n)3460 ASTNode::getPlugin(unsigned int n)
3461 {
3462   if (n >= getNumPlugins())
3463     return NULL;
3464   return mPlugins[n];
3465 }
3466 
3467 /** @endcond */
3468 
3469 /** @cond doxygenLibsbmlInternal */
3470 
3471 LIBSBML_EXTERN
3472 const ASTBasePlugin*
getPlugin(unsigned int n) const3473 ASTNode::getPlugin(unsigned int n) const
3474 {
3475   return const_cast<ASTNode*>(this)->getPlugin(n);
3476 }
3477 
3478 /** @endcond */
3479 
3480 /** @cond doxygenLibsbmlInternal */
3481 
3482 LIBSBML_EXTERN
3483 unsigned int
getNumPlugins() const3484 ASTNode::getNumPlugins() const
3485 {
3486   return (unsigned int)mPlugins.size();
3487 }
3488 
3489 
3490 /** @endcond */
3491 
3492 struct DeleteASTPluginEntity : public unary_function<ASTBasePlugin*, void>
3493 {
operator ()DeleteASTPluginEntity3494   void operator() (ASTBasePlugin* ast) { delete ast; }
3495 };
3496 
clearPlugins()3497 void ASTNode::clearPlugins()
3498 {
3499   for_each(mPlugins.begin(), mPlugins.end(), DeleteASTPluginEntity());
3500   mPlugins.clear();
3501 }
3502 
3503 
3504 #endif /* __cplusplus */
3505 
3506 
3507 /** @cond doxygenIgnored */
3508 
3509 LIBSBML_EXTERN
3510 ASTNode_t *
ASTNode_create(void)3511 ASTNode_create (void)
3512 {
3513   return new(nothrow) ASTNode;
3514 }
3515 
3516 
3517 LIBSBML_EXTERN
3518 ASTNode_t *
ASTNode_createWithType(ASTNodeType_t type)3519 ASTNode_createWithType (ASTNodeType_t type)
3520 {
3521   return new(nothrow) ASTNode(type);
3522 }
3523 
3524 
3525 LIBSBML_EXTERN
3526 ASTNode_t *
ASTNode_createFromToken(Token_t * token)3527 ASTNode_createFromToken (Token_t *token)
3528 {
3529   if (token == NULL) return NULL;
3530   return new(nothrow) ASTNode(token);
3531 }
3532 
3533 
3534 LIBSBML_EXTERN
3535 void
ASTNode_free(ASTNode_t * node)3536 ASTNode_free (ASTNode_t *node)
3537 {
3538   if (node == NULL) return;
3539 
3540   delete static_cast<ASTNode*>(node);
3541 }
3542 
3543 
3544 LIBSBML_EXTERN
3545 int
ASTNode_freeName(ASTNode_t * node)3546 ASTNode_freeName (ASTNode_t *node)
3547 {
3548   if (node == NULL) return LIBSBML_INVALID_OBJECT;
3549   return static_cast<ASTNode*>(node)->freeName();
3550 }
3551 
3552 
3553 LIBSBML_EXTERN
3554 int
ASTNode_canonicalize(ASTNode_t * node)3555 ASTNode_canonicalize (ASTNode_t *node)
3556 {
3557   if (node == NULL) return (int)false;
3558   return (int) static_cast<ASTNode*>(node)->canonicalize();
3559 }
3560 
3561 
3562 LIBSBML_EXTERN
3563 int
ASTNode_addChild(ASTNode_t * node,ASTNode_t * child)3564 ASTNode_addChild (ASTNode_t *node, ASTNode_t *child)
3565 {
3566   if (node == NULL) return LIBSBML_INVALID_OBJECT;
3567   return static_cast<ASTNode*>(node)->addChild
3568                                     ( static_cast<ASTNode*>(child) );
3569 }
3570 
3571 
3572 LIBSBML_EXTERN
3573 int
ASTNode_prependChild(ASTNode_t * node,ASTNode_t * child)3574 ASTNode_prependChild (ASTNode_t *node, ASTNode_t *child)
3575 {
3576   if (node == NULL) return LIBSBML_INVALID_OBJECT;
3577   return static_cast<ASTNode*>(node)->prependChild
3578                                     ( static_cast<ASTNode*>(child) );
3579 }
3580 
3581 
3582 LIBSBML_EXTERN
3583 ASTNode_t *
ASTNode_deepCopy(const ASTNode_t * node)3584 ASTNode_deepCopy (const ASTNode_t *node)
3585 {
3586   if ( node == NULL ) return NULL;
3587   return
3588     static_cast<ASTNode_t *>( static_cast<const ASTNode*>(node)->deepCopy() );
3589 }
3590 
3591 
3592 LIBSBML_EXTERN
3593 ASTNode_t *
ASTNode_getChild(const ASTNode_t * node,unsigned int n)3594 ASTNode_getChild (const ASTNode_t *node, unsigned int n)
3595 {
3596   if (node == NULL) return NULL;
3597   return static_cast<const ASTNode*>(node)->getChild(n);
3598 }
3599 
3600 
3601 LIBSBML_EXTERN
3602 ASTNode_t *
ASTNode_getLeftChild(const ASTNode_t * node)3603 ASTNode_getLeftChild (const ASTNode_t *node)
3604 {
3605   if (node == NULL) return NULL;
3606   return static_cast<const ASTNode*>(node)->getLeftChild();
3607 }
3608 
3609 
3610 LIBSBML_EXTERN
3611 ASTNode_t *
ASTNode_getRightChild(const ASTNode_t * node)3612 ASTNode_getRightChild (const ASTNode_t *node)
3613 {
3614   if (node == NULL) return NULL;
3615   return static_cast<const ASTNode*>(node)->getRightChild();
3616 }
3617 
3618 
3619 LIBSBML_EXTERN
3620 unsigned int
ASTNode_getNumChildren(const ASTNode_t * node)3621 ASTNode_getNumChildren (const ASTNode_t *node)
3622 {
3623   if (node == NULL) return 0;
3624   return static_cast<const ASTNode*>(node)->getNumChildren();
3625 }
3626 
3627 
3628 LIBSBML_EXTERN
3629 List_t *
ASTNode_getListOfNodes(const ASTNode_t * node,ASTNodePredicate predicate)3630 ASTNode_getListOfNodes (const ASTNode_t *node, ASTNodePredicate predicate)
3631 {
3632   if (node == NULL) return NULL;
3633   return static_cast<const ASTNode*>(node)->getListOfNodes(predicate);
3634 }
3635 
3636 
3637 LIBSBML_EXTERN
3638 void
ASTNode_fillListOfNodes(const ASTNode_t * node,ASTNodePredicate predicate,List_t * lst)3639 ASTNode_fillListOfNodes ( const ASTNode_t  *node,
3640                           ASTNodePredicate predicate,
3641                           List_t           *lst )
3642 {
3643   if (node == NULL) return;
3644 
3645   List* x = static_cast<List*>(lst);
3646 
3647   static_cast<const ASTNode*>(node)->fillListOfNodes(predicate, x);
3648 }
3649 
3650 
3651 LIBSBML_EXTERN
3652 char
ASTNode_getCharacter(const ASTNode_t * node)3653 ASTNode_getCharacter (const ASTNode_t *node)
3654 {
3655   if (node == NULL) return CHAR_MAX;
3656   return static_cast<const ASTNode*>(node)->getCharacter();
3657 }
3658 
3659 
3660 LIBSBML_EXTERN
3661 long
ASTNode_getInteger(const ASTNode_t * node)3662 ASTNode_getInteger (const ASTNode_t *node)
3663 {
3664   if (node == NULL) return LONG_MAX;
3665   return static_cast<const ASTNode*>(node)->getInteger();
3666 }
3667 
3668 
3669 LIBSBML_EXTERN
3670 const char *
ASTNode_getName(const ASTNode_t * node)3671 ASTNode_getName (const ASTNode_t *node)
3672 {
3673   if (node == NULL) return NULL;
3674   return static_cast<const ASTNode*>(node)->getName();
3675 }
3676 
3677 
3678 LIBSBML_EXTERN
3679 long
ASTNode_getNumerator(const ASTNode_t * node)3680 ASTNode_getNumerator (const ASTNode_t *node)
3681 {
3682   if (node == NULL) return LONG_MAX;
3683   return static_cast<const ASTNode*>(node)->getNumerator();
3684 }
3685 
3686 
3687 LIBSBML_EXTERN
3688 long
ASTNode_getDenominator(const ASTNode_t * node)3689 ASTNode_getDenominator (const ASTNode_t *node)
3690 {
3691   if (node == NULL) return LONG_MAX;
3692   return static_cast<const ASTNode*>(node)->getDenominator();
3693 }
3694 
3695 
3696 LIBSBML_EXTERN
3697 double
ASTNode_getReal(const ASTNode_t * node)3698 ASTNode_getReal (const ASTNode_t *node)
3699 {
3700   if (node == NULL) return util_NaN();
3701   return static_cast<const ASTNode*>(node)->getReal();
3702 }
3703 
3704 
3705 LIBSBML_EXTERN
3706 double
ASTNode_getMantissa(const ASTNode_t * node)3707 ASTNode_getMantissa (const ASTNode_t *node)
3708 {
3709   if (node == NULL) return numeric_limits<double>::quiet_NaN();
3710   return static_cast<const ASTNode*>(node)->getMantissa();
3711 }
3712 
3713 
3714 LIBSBML_EXTERN
3715 long
ASTNode_getExponent(const ASTNode_t * node)3716 ASTNode_getExponent (const ASTNode_t *node)
3717 {
3718   if (node == NULL) return LONG_MAX;
3719   return static_cast<const ASTNode*>(node)->getExponent();
3720 }
3721 
3722 
3723 LIBSBML_EXTERN
3724 double
ASTNode_getValue(const ASTNode_t * node)3725 ASTNode_getValue (const ASTNode_t *node)
3726 {
3727   if (node == NULL) return util_NaN();
3728   return static_cast<const ASTNode*>(node)->getValue();
3729 }
3730 
3731 
3732 LIBSBML_EXTERN
3733 int
ASTNode_getPrecedence(const ASTNode_t * node)3734 ASTNode_getPrecedence (const ASTNode_t *node)
3735 {
3736   if (node == NULL) return 6; // default precedence
3737   return static_cast<const ASTNode*>(node)->getPrecedence();
3738 }
3739 
3740 
3741 LIBSBML_EXTERN
3742 ASTNodeType_t
ASTNode_getType(const ASTNode_t * node)3743 ASTNode_getType (const ASTNode_t *node)
3744 {
3745   if (node == NULL) return AST_UNKNOWN;
3746   return static_cast<const ASTNode*>(node)->getType();
3747 }
3748 
3749 LIBSBML_EXTERN
3750 char *
ASTNode_getId(const ASTNode_t * node)3751 ASTNode_getId(const ASTNode_t * node)
3752 {
3753   if (node == NULL)
3754     return NULL;
3755 
3756   return safe_strdup(node->getId().c_str());
3757 }
3758 
3759 LIBSBML_EXTERN
3760 char *
ASTNode_getClass(const ASTNode_t * node)3761 ASTNode_getClass(const ASTNode_t * node)
3762 {
3763   if (node == NULL)
3764     return NULL;
3765 
3766   return safe_strdup(node->getClass().c_str());
3767 }
3768 
3769 LIBSBML_EXTERN
3770 char *
ASTNode_getStyle(const ASTNode_t * node)3771 ASTNode_getStyle(const ASTNode_t * node)
3772 {
3773   if (node == NULL)
3774     return NULL;
3775 
3776   return safe_strdup(node->getStyle().c_str());
3777 }
3778 
3779 
3780 LIBSBML_EXTERN
3781 char *
ASTNode_getUnits(const ASTNode_t * node)3782 ASTNode_getUnits(const ASTNode_t * node)
3783 {
3784   if (node == NULL) return NULL;
3785   return safe_strdup(node->getUnits().c_str());
3786 }
3787 
3788 
3789 LIBSBML_EXTERN
3790 int
ASTNode_isAvogadro(const ASTNode_t * node)3791 ASTNode_isAvogadro (const ASTNode_t *node)
3792 {
3793   if (node == NULL) return (int) false;
3794   return (int) static_cast<const ASTNode*>(node)->isAvogadro();
3795 }
3796 
3797 
3798 LIBSBML_EXTERN
3799 int
ASTNode_isBoolean(const ASTNode_t * node)3800 ASTNode_isBoolean (const ASTNode_t *node)
3801 {
3802   if (node == NULL) return (int) false;
3803   return (int) static_cast<const ASTNode*>(node)->isBoolean();
3804 }
3805 
3806 
3807 LIBSBML_EXTERN
3808 int
ASTNode_returnsBoolean(const ASTNode_t * node)3809 ASTNode_returnsBoolean (const ASTNode_t *node)
3810 {
3811   if (node == NULL) return (int) false;
3812   return (int) static_cast<const ASTNode*>(node)->returnsBoolean();
3813 }
3814 
3815 
3816 LIBSBML_EXTERN
3817 int
ASTNode_returnsBooleanForModel(const ASTNode_t * node,const Model_t * model)3818 ASTNode_returnsBooleanForModel (const ASTNode_t *node, const Model_t* model)
3819 {
3820   if (node == NULL) return (int) false;
3821   return (int) static_cast<const ASTNode*>(node)->returnsBoolean(model);
3822 }
3823 
3824 
3825 LIBSBML_EXTERN
3826 int
ASTNode_isConstant(const ASTNode_t * node)3827 ASTNode_isConstant (const ASTNode_t *node)
3828 {
3829   if (node == NULL) return (int) false;
3830   return (int) static_cast<const ASTNode*>(node)->isConstant();
3831 }
3832 
3833 
3834 LIBSBML_EXTERN
3835 int
ASTNode_isConstantNumber(const ASTNode_t * node)3836 ASTNode_isConstantNumber(const ASTNode_t *node)
3837 {
3838   if (node == NULL) return (int)false;
3839   return (int) static_cast<const ASTNode*>(node)->isConstantNumber();
3840 }
3841 
3842 
3843 LIBSBML_EXTERN
3844 int
ASTNode_isFunction(const ASTNode_t * node)3845 ASTNode_isFunction (const ASTNode_t *node)
3846 {
3847   if (node == NULL) return (int) false;
3848   return (int) static_cast<const ASTNode*>(node)->isFunction();
3849 }
3850 
3851 
3852 LIBSBML_EXTERN
3853 int
ASTNode_isInfinity(const ASTNode_t * node)3854 ASTNode_isInfinity (const ASTNode_t *node)
3855 {
3856   if (node == NULL) return (int) false;
3857   return static_cast<int>( node->isInfinity() );
3858 }
3859 
3860 
3861 LIBSBML_EXTERN
3862 int
ASTNode_isInteger(const ASTNode_t * node)3863 ASTNode_isInteger (const ASTNode_t *node)
3864 {
3865   if (node == NULL) return (int) false;
3866   return (int) static_cast<const ASTNode*>(node)->isInteger();
3867 }
3868 
3869 
3870 LIBSBML_EXTERN
3871 int
ASTNode_isLambda(const ASTNode_t * node)3872 ASTNode_isLambda (const ASTNode_t *node)
3873 {
3874   if (node == NULL) return (int) false;
3875   return (int) static_cast<const ASTNode*>(node)->isLambda();
3876 }
3877 
3878 
3879 LIBSBML_EXTERN
3880 int
ASTNode_isLog10(const ASTNode_t * node)3881 ASTNode_isLog10 (const ASTNode_t *node)
3882 {
3883   if (node == NULL) return (int) false;
3884   return (int) static_cast<const ASTNode*>(node)->isLog10();
3885 }
3886 
3887 
3888 LIBSBML_EXTERN
3889 int
ASTNode_isLogical(const ASTNode_t * node)3890 ASTNode_isLogical (const ASTNode_t *node)
3891 {
3892   if (node == NULL) return (int) false;
3893   return (int) static_cast<const ASTNode*>(node)->isLogical();
3894 }
3895 
3896 
3897 LIBSBML_EXTERN
3898 int
ASTNode_isName(const ASTNode_t * node)3899 ASTNode_isName (const ASTNode_t *node)
3900 {
3901   if (node == NULL) return (int) false;
3902   return (int) static_cast<const ASTNode*>(node)->isName();
3903 }
3904 
3905 
3906 LIBSBML_EXTERN
3907 int
ASTNode_isNaN(const ASTNode_t * node)3908 ASTNode_isNaN (const ASTNode_t *node)
3909 {
3910   if (node == NULL) return (int) false;
3911   return static_cast<int>( node->isNaN() );
3912 }
3913 
3914 
3915 LIBSBML_EXTERN
3916 int
ASTNode_isNegInfinity(const ASTNode_t * node)3917 ASTNode_isNegInfinity (const ASTNode_t *node)
3918 {
3919   if (node == NULL) return (int) false;
3920   return static_cast<int>( node->isNegInfinity() );
3921 }
3922 
3923 
3924 LIBSBML_EXTERN
3925 int
ASTNode_isNumber(const ASTNode_t * node)3926 ASTNode_isNumber (const ASTNode_t *node)
3927 {
3928   if (node == NULL) return (int) false;
3929   return (int) static_cast<const ASTNode*>(node)->isNumber();
3930 }
3931 
3932 
3933 LIBSBML_EXTERN
3934 int
ASTNode_isOperator(const ASTNode_t * node)3935 ASTNode_isOperator (const ASTNode_t *node)
3936 {
3937   if (node == NULL) return (int) false;
3938   return (int) static_cast<const ASTNode*>(node)->isOperator();
3939 }
3940 
3941 
3942 LIBSBML_EXTERN
3943 int
ASTNode_isPiecewise(const ASTNode_t * node)3944 ASTNode_isPiecewise (const ASTNode_t *node)
3945 {
3946   if (node == NULL) return (int) false;
3947   return static_cast<int>( node->isPiecewise() );
3948 }
3949 
3950 
3951 LIBSBML_EXTERN
3952 int
ASTNode_isRational(const ASTNode_t * node)3953 ASTNode_isRational (const ASTNode_t *node)
3954 {
3955   if (node == NULL) return (int) false;
3956   return (int) static_cast<const ASTNode*>(node)->isRational();
3957 }
3958 
3959 
3960 LIBSBML_EXTERN
3961 int
ASTNode_isReal(const ASTNode_t * node)3962 ASTNode_isReal (const ASTNode_t *node)
3963 {
3964   if (node == NULL) return (int) false;
3965   return (int) static_cast<const ASTNode*>(node)->isReal();
3966 }
3967 
3968 
3969 LIBSBML_EXTERN
3970 int
ASTNode_isRelational(const ASTNode_t * node)3971 ASTNode_isRelational (const ASTNode_t *node)
3972 {
3973   if (node == NULL) return (int) false;
3974   return (int) static_cast<const ASTNode*>(node)->isRelational();
3975 }
3976 
3977 
3978 LIBSBML_EXTERN
3979 int
ASTNode_isSqrt(const ASTNode_t * node)3980 ASTNode_isSqrt (const ASTNode_t *node)
3981 {
3982   if (node == NULL) return (int) false;
3983   return (int) static_cast<const ASTNode*>(node)->isSqrt();
3984 }
3985 
3986 
3987 LIBSBML_EXTERN
3988 int
ASTNode_isUMinus(const ASTNode_t * node)3989 ASTNode_isUMinus (const ASTNode_t *node)
3990 {
3991   if (node == NULL) return (int) false;
3992   return (int) static_cast<const ASTNode*>(node)->isUMinus();
3993 }
3994 
3995 LIBSBML_EXTERN
3996 int
ASTNode_isUPlus(const ASTNode_t * node)3997 ASTNode_isUPlus (const ASTNode_t *node)
3998 {
3999   if (node == NULL) return (int) false;
4000   return (int) static_cast<const ASTNode*>(node)->isUPlus();
4001 }
4002 
4003 LIBSBML_EXTERN
4004 int
ASTNode_hasTypeAndNumChildren(const ASTNode_t * node,ASTNodeType_t type,unsigned int numchildren)4005 ASTNode_hasTypeAndNumChildren(const ASTNode_t *node, ASTNodeType_t type, unsigned int numchildren)
4006 {
4007   if (node==NULL) return (int) false;
4008   return node->hasTypeAndNumChildren(type, numchildren);
4009 }
4010 
4011 
4012 LIBSBML_EXTERN
4013 int
ASTNode_isUnknown(const ASTNode_t * node)4014 ASTNode_isUnknown (const ASTNode_t *node)
4015 {
4016   if (node == NULL) return (int) false;
4017   return (int) static_cast<const ASTNode*>(node)->isUnknown();
4018 }
4019 
4020 
4021 LIBSBML_EXTERN
4022 int
ASTNode_isSetId(const ASTNode_t * node)4023 ASTNode_isSetId (const ASTNode_t *node)
4024 {
4025   return static_cast<int>(node->isSetId());
4026 }
4027 
4028 
4029 LIBSBML_EXTERN
4030 int
ASTNode_isSetClass(const ASTNode_t * node)4031 ASTNode_isSetClass (const ASTNode_t *node)
4032 {
4033   return static_cast<int>(node->isSetClass());
4034 }
4035 
4036 
4037 LIBSBML_EXTERN
4038 int
ASTNode_isSetStyle(const ASTNode_t * node)4039 ASTNode_isSetStyle (const ASTNode_t *node)
4040 {
4041   return static_cast<int>(node->isSetStyle());
4042 }
4043 
4044 
4045 LIBSBML_EXTERN
4046 int
ASTNode_isSetUnits(const ASTNode_t * node)4047 ASTNode_isSetUnits (const ASTNode_t *node)
4048 {
4049   if (node == NULL) return (int) false;
4050   return static_cast<int>(node->isSetUnits());
4051 }
4052 
4053 
4054 LIBSBML_EXTERN
4055 int
ASTNode_hasUnits(const ASTNode_t * node)4056 ASTNode_hasUnits (const ASTNode_t *node)
4057 {
4058   if (node == NULL) return (int)false;
4059   return static_cast<int>(node->hasUnits());
4060 }
4061 
4062 
4063 LIBSBML_EXTERN
4064 int
ASTNode_setCharacter(ASTNode_t * node,char value)4065 ASTNode_setCharacter (ASTNode_t *node, char value)
4066 {
4067   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4068   return static_cast<ASTNode*>(node)->setCharacter(value);
4069 }
4070 
4071 
4072 LIBSBML_EXTERN
4073 int
ASTNode_setName(ASTNode_t * node,const char * name)4074 ASTNode_setName (ASTNode_t *node, const char *name)
4075 {
4076   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4077   return static_cast<ASTNode*>(node)->setName(name);
4078 }
4079 
4080 
4081 LIBSBML_EXTERN
4082 int
ASTNode_setInteger(ASTNode_t * node,long value)4083 ASTNode_setInteger (ASTNode_t *node, long value)
4084 {
4085   if(node == NULL) return LIBSBML_INVALID_OBJECT;
4086   return static_cast<ASTNode*>(node)->setValue(value);
4087 }
4088 
4089 
4090 LIBSBML_EXTERN
4091 int
ASTNode_setRational(ASTNode_t * node,long numerator,long denominator)4092 ASTNode_setRational (ASTNode_t *node, long numerator, long denominator)
4093 {
4094   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4095   return static_cast<ASTNode*>(node)->setValue(numerator, denominator);
4096 }
4097 
4098 
4099 LIBSBML_EXTERN
4100 int
ASTNode_setReal(ASTNode_t * node,double value)4101 ASTNode_setReal (ASTNode_t *node, double value)
4102 {
4103   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4104   return static_cast<ASTNode*>(node)->setValue(value);
4105 }
4106 
4107 
4108 LIBSBML_EXTERN
4109 int
ASTNode_setRealWithExponent(ASTNode_t * node,double mantissa,long exponent)4110 ASTNode_setRealWithExponent (ASTNode_t *node, double mantissa, long exponent)
4111 {
4112   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4113   return static_cast<ASTNode*>(node)->setValue(mantissa, exponent);
4114 }
4115 
4116 
4117 LIBSBML_EXTERN
4118 int
ASTNode_setType(ASTNode_t * node,ASTNodeType_t type)4119 ASTNode_setType (ASTNode_t *node, ASTNodeType_t type)
4120 {
4121   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4122   return static_cast<ASTNode*>(node)->setType(type);
4123 }
4124 
4125 
4126 LIBSBML_EXTERN
4127 int
ASTNode_setId(ASTNode_t * node,const char * id)4128 ASTNode_setId (ASTNode_t *node, const char *id)
4129 {
4130   return static_cast<ASTNode*>(node)->setId(id);
4131 }
4132 
4133 
4134 LIBSBML_EXTERN
4135 int
ASTNode_setClass(ASTNode_t * node,const char * className)4136 ASTNode_setClass (ASTNode_t *node, const char *className)
4137 {
4138   return static_cast<ASTNode*>(node)->setClass(className);
4139 }
4140 
4141 
4142 LIBSBML_EXTERN
4143 int
ASTNode_setStyle(ASTNode_t * node,const char * style)4144 ASTNode_setStyle (ASTNode_t *node, const char *style)
4145 {
4146   return static_cast<ASTNode*>(node)->setStyle(style);
4147 }
4148 
4149 
4150 LIBSBML_EXTERN
4151 int
ASTNode_setUnits(ASTNode_t * node,const char * units)4152 ASTNode_setUnits (ASTNode_t *node, const char *units)
4153 {
4154   if (node == NULL ) return LIBSBML_INVALID_OBJECT;
4155   return static_cast<ASTNode*>(node)->setUnits(units);
4156 }
4157 
4158 
4159 LIBSBML_EXTERN
4160 int
ASTNode_swapChildren(ASTNode_t * node,ASTNode_t * that)4161 ASTNode_swapChildren (ASTNode_t *node, ASTNode_t *that)
4162 {
4163   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4164   return static_cast<ASTNode*>(node)
4165                          ->swapChildren( static_cast<ASTNode*>(that) );
4166 }
4167 
4168 
4169 LIBSBML_EXTERN
4170 int
ASTNode_unsetId(ASTNode_t * node)4171 ASTNode_unsetId (ASTNode_t *node)
4172 {
4173   return static_cast<ASTNode*>(node)->unsetId();
4174 }
4175 
4176 
4177 LIBSBML_EXTERN
4178 int
ASTNode_unsetClass(ASTNode_t * node)4179 ASTNode_unsetClass (ASTNode_t *node)
4180 {
4181   return static_cast<ASTNode*>(node)->unsetClass();
4182 }
4183 
4184 
4185 LIBSBML_EXTERN
4186 int
ASTNode_unsetStyle(ASTNode_t * node)4187 ASTNode_unsetStyle (ASTNode_t *node)
4188 {
4189   return static_cast<ASTNode*>(node)->unsetStyle();
4190 }
4191 
4192 
4193 LIBSBML_EXTERN
4194 int
ASTNode_unsetUnits(ASTNode_t * node)4195 ASTNode_unsetUnits (ASTNode_t *node)
4196 {
4197   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4198   return static_cast<ASTNode*>(node)->unsetUnits();
4199 }
4200 
4201 
4202 LIBSBML_EXTERN
4203 void
ASTNode_replaceArgument(ASTNode_t * node,const char * bvar,ASTNode_t * arg)4204 ASTNode_replaceArgument(ASTNode_t* node, const char * bvar, ASTNode_t* arg)
4205 {
4206   if (node == NULL) return ;
4207   static_cast<ASTNode*>(node)->replaceArgument(bvar,
4208                                                   static_cast<ASTNode*>(arg));
4209 }
4210 
4211 
4212 LIBSBML_EXTERN
4213 void
ASTNode_reduceToBinary(ASTNode_t * node)4214 ASTNode_reduceToBinary(ASTNode_t* node)
4215 {
4216   if (node == NULL) return;
4217   static_cast<ASTNode*>(node)->reduceToBinary();
4218 }
4219 
4220 
4221 LIBSBML_EXTERN
4222 SBase_t *
ASTNode_getParentSBMLObject(ASTNode_t * node)4223 ASTNode_getParentSBMLObject(ASTNode_t* node)
4224 {
4225   if (node == NULL) return NULL;
4226   return node->getParentSBMLObject();
4227 }
4228 
4229 
4230 
4231 LIBSBML_EXTERN
4232 void
ASTNode_setParentSBMLObject(ASTNode_t * node,SBase_t * sb)4233 ASTNode_setParentSBMLObject(ASTNode_t* node, SBase_t * sb)
4234 {
4235   if (node == NULL) return;
4236   node->setParentSBMLObject(sb);
4237 }
4238 
4239 
4240 LIBSBML_EXTERN
4241 int
ASTNode_unsetParentSBMLObject(ASTNode_t * node)4242 ASTNode_unsetParentSBMLObject(ASTNode_t* node)
4243 {
4244   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4245   return node->unsetParentSBMLObject();
4246 }
4247 
4248 
4249 LIBSBML_EXTERN
4250 int
ASTNode_isSetParentSBMLObject(ASTNode_t * node)4251 ASTNode_isSetParentSBMLObject(ASTNode_t* node)
4252 {
4253   if (node == NULL) return (int) false;
4254   return static_cast<int>(node->isSetParentSBMLObject());
4255 }
4256 
4257 
4258 
4259 LIBSBML_EXTERN
4260 int
ASTNode_removeChild(ASTNode_t * node,unsigned int n)4261 ASTNode_removeChild(ASTNode_t* node, unsigned int n)
4262 {
4263   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4264   return node->removeChild(n);
4265 }
4266 
4267 
4268 LIBSBML_EXTERN
4269 int
ASTNode_replaceChild(ASTNode_t * node,unsigned int n,ASTNode_t * newChild)4270 ASTNode_replaceChild(ASTNode_t* node, unsigned int n, ASTNode_t * newChild)
4271 {
4272   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4273   return node->replaceChild(n, newChild, false);
4274 }
4275 
4276 
4277 LIBSBML_EXTERN
4278 int
ASTNode_replaceAndDeleteChild(ASTNode_t * node,unsigned int n,ASTNode_t * newChild)4279 ASTNode_replaceAndDeleteChild(ASTNode_t* node, unsigned int n, ASTNode_t * newChild)
4280 {
4281   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4282   return node->replaceChild(n, newChild, true);
4283 }
4284 
4285 
4286 LIBSBML_EXTERN
4287 int
ASTNode_insertChild(ASTNode_t * node,unsigned int n,ASTNode_t * newChild)4288 ASTNode_insertChild(ASTNode_t* node, unsigned int n, ASTNode_t * newChild)
4289 {
4290   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4291   return node->insertChild(n, newChild);
4292 }
4293 
4294 
4295 LIBSBML_EXTERN
4296 int
ASTNode_addSemanticsAnnotation(ASTNode_t * node,XMLNode_t * annotation)4297 ASTNode_addSemanticsAnnotation(ASTNode_t* node, XMLNode_t * annotation)
4298 {
4299   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4300   return node->addSemanticsAnnotation(annotation);
4301 }
4302 
4303 
4304 LIBSBML_EXTERN
4305 unsigned int
ASTNode_getNumSemanticsAnnotations(ASTNode_t * node)4306 ASTNode_getNumSemanticsAnnotations(ASTNode_t* node)
4307 {
4308   if (node == NULL) return 0;
4309   return node->getNumSemanticsAnnotations();
4310 }
4311 
4312 
4313 LIBSBML_EXTERN
4314 XMLNode_t *
ASTNode_getSemanticsAnnotation(ASTNode_t * node,unsigned int n)4315 ASTNode_getSemanticsAnnotation(ASTNode_t* node, unsigned int n)
4316 {
4317   if (node == NULL) return NULL;
4318   return node->getSemanticsAnnotation(n);
4319 }
4320 
4321 
4322 LIBSBML_EXTERN
4323 int
ASTNode_setUserData(ASTNode_t * node,void * userData)4324 ASTNode_setUserData(ASTNode_t* node, void *userData)
4325 {
4326   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4327   return node->setUserData(userData);
4328 }
4329 
4330 
4331 LIBSBML_EXTERN
4332 void *
ASTNode_getUserData(const ASTNode_t * node)4333 ASTNode_getUserData(const ASTNode_t* node)
4334 {
4335   if (node == NULL) return NULL;
4336   return node->getUserData();
4337 }
4338 
4339 
4340 LIBSBML_EXTERN
4341 int
ASTNode_unsetUserData(ASTNode_t * node)4342 ASTNode_unsetUserData(ASTNode_t* node)
4343 {
4344   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4345   return node->unsetUserData();
4346 }
4347 
4348 
4349 LIBSBML_EXTERN
4350 int
ASTNode_isSetUserData(const ASTNode_t * node)4351 ASTNode_isSetUserData(const ASTNode_t* node)
4352 {
4353   if (node == NULL) return (int) false;
4354   return static_cast<int>(node->isSetUserData());
4355 }
4356 
4357 
4358 LIBSBML_EXTERN
4359 int
ASTNode_hasCorrectNumberArguments(ASTNode_t * node)4360 ASTNode_hasCorrectNumberArguments(ASTNode_t* node)
4361 {
4362   if (node == NULL) return (int)false;
4363   return static_cast <int> (node->hasCorrectNumberArguments());
4364 }
4365 
4366 LIBSBML_EXTERN
4367 int
ASTNode_isWellFormedASTNode(ASTNode_t * node)4368 ASTNode_isWellFormedASTNode(ASTNode_t* node)
4369 {
4370   if (node == NULL) return (int) false;
4371   return static_cast <int> (node->isWellFormedASTNode());
4372 }
4373 
4374 
4375 LIBSBML_EXTERN
4376 XMLAttributes_t *
ASTNode_getDefinitionURL(ASTNode_t * node)4377 ASTNode_getDefinitionURL(ASTNode_t* node)
4378 {
4379   if (node == NULL) return NULL;
4380   return node->getDefinitionURL();
4381 }
4382 
4383 
4384 LIBSBML_EXTERN
4385 int
ASTNode_setDefinitionURL(ASTNode_t * node,XMLAttributes_t defnURL)4386 ASTNode_setDefinitionURL(ASTNode_t* node, XMLAttributes_t defnURL)
4387 {
4388   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4389   return node->setDefinitionURL(defnURL);
4390 }
4391 
4392 
4393 LIBSBML_EXTERN
4394 char *
ASTNode_getDefinitionURLString(ASTNode_t * node)4395 ASTNode_getDefinitionURLString(ASTNode_t* node)
4396 {
4397   if (node == NULL) return safe_strdup("");
4398   return safe_strdup(node->getDefinitionURLString().c_str());
4399 }
4400 
4401 
4402 
4403 LIBSBML_EXTERN
4404 int
ASTNode_setDefinitionURLString(ASTNode_t * node,const char * defnURL)4405 ASTNode_setDefinitionURLString(ASTNode_t* node, const char * defnURL)
4406 {
4407   if (node == NULL) return LIBSBML_INVALID_OBJECT;
4408   XMLAttributes_t *att = XMLAttributes_create();
4409   XMLAttributes_add(att, "definitionURL", defnURL);
4410   int ret = node->setDefinitionURL(*(att));
4411   XMLAttributes_free(att);
4412   return ret;
4413 }
4414 
4415 
4416 /** @cond doxygenLibsbmlInternal */
4417 /*
4418  * Internal utility function used in some language binding code.
4419  */
4420 LIBSBML_EXTERN
4421 int
ASTNode_true(const ASTNode * node)4422 ASTNode_true(const ASTNode *node)
4423 {
4424   return 1;
4425 }
4426 /** @endcond */
4427 
4428 
4429 /** @endcond */
4430 
4431 LIBSBML_CPP_NAMESPACE_END
4432