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