1 /**
2  * @file    FunctionDefinition.cpp
3  * @brief   Implementation of FunctionDefinition and ListOfFunctionDefinitions.
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
39  * and also available online as http://sbml.org/software/libsbml/license.html
40  * ---------------------------------------------------------------------- -->*/
41 
42 #include <cstring>
43 
44 #include <sbml/xml/XMLNode.h>
45 #include <sbml/xml/XMLAttributes.h>
46 #include <sbml/xml/XMLInputStream.h>
47 #include <sbml/xml/XMLOutputStream.h>
48 
49 #include <sbml/math/FormulaParser.h>
50 #include <sbml/math/ASTNode.h>
51 #include <sbml/math/MathML.h>
52 
53 #include <sbml/SBO.h>
54 #include <sbml/SBMLVisitor.h>
55 #include <sbml/SBMLError.h>
56 #include <sbml/FunctionDefinition.h>
57 #include <sbml/SBMLDocument.h>
58 #include <sbml/Model.h>
59 
60 /** @cond doxygenIgnored */
61 using namespace std;
62 /** @endcond */
63 
64 LIBSBML_CPP_NAMESPACE_BEGIN
65 #ifdef __cplusplus
66 
FunctionDefinition(unsigned int level,unsigned int version)67 FunctionDefinition::FunctionDefinition (unsigned int level, unsigned int version) :
68    SBase ( level, version )
69  , mMath ( NULL  )
70 {
71   if (!hasValidLevelVersionNamespaceCombination())
72     throw SBMLConstructorException();
73 }
74 
75 
FunctionDefinition(SBMLNamespaces * sbmlns)76 FunctionDefinition::FunctionDefinition (SBMLNamespaces * sbmlns) :
77    SBase ( sbmlns )
78  , mMath ( NULL  )
79 {
80   if (!hasValidLevelVersionNamespaceCombination())
81   {
82     throw SBMLConstructorException(getElementName(), sbmlns);
83   }
84 
85   loadPlugins(sbmlns);
86 }
87 
88 
89 /*
90  * Destroys this FunctionDefinition.
91  */
~FunctionDefinition()92 FunctionDefinition::~FunctionDefinition ()
93 {
94   delete mMath;
95 }
96 
97 
98 /*
99  * Copy constructor. Creates a copy of this FunctionDefinition.
100  */
FunctionDefinition(const FunctionDefinition & orig)101 FunctionDefinition::FunctionDefinition (const FunctionDefinition& orig) :
102    SBase             ( orig         )
103  , mMath             ( NULL            )
104 {
105 
106   if (orig.mMath != NULL)
107   {
108     mMath = orig.mMath->deepCopy();
109     mMath->setParentSBMLObject(this);
110   }
111 }
112 
113 
114 /*
115  * Assignment operator
116  */
operator =(const FunctionDefinition & rhs)117 FunctionDefinition& FunctionDefinition::operator=(const FunctionDefinition& rhs)
118 {
119   if(&rhs!=this)
120   {
121     this->SBase::operator =(rhs);
122 
123     delete mMath;
124     if (rhs.mMath != NULL)
125     {
126       mMath = rhs.mMath->deepCopy();
127       mMath->setParentSBMLObject(this);
128     }
129     else
130     {
131       mMath = NULL;
132     }
133   }
134 
135   return *this;
136 }
137 
138 
139 /** @cond doxygenLibsbmlInternal */
140 bool
accept(SBMLVisitor & v) const141 FunctionDefinition::accept (SBMLVisitor& v) const
142 {
143   return v.visit(*this);
144 }
145 /** @endcond */
146 
147 
148 /*
149  * @return a (deep) copy of this FunctionDefinition.
150  */
151 FunctionDefinition*
clone() const152 FunctionDefinition::clone () const
153 {
154   return new FunctionDefinition(*this);
155 }
156 
157 
158 /*
159  * @return the id of this SBML object.
160  */
161 const string&
getId() const162 FunctionDefinition::getId () const
163 {
164   return mId;
165 }
166 
167 
168 /*
169  * @return the name of this SBML object.
170  */
171 const string&
getName() const172 FunctionDefinition::getName () const
173 {
174   return (getLevel() == 1) ? mId : mName;
175 }
176 
177 
178 /*
179  * @return the math of this FunctionDefinition.
180  */
181 const ASTNode*
getMath() const182 FunctionDefinition::getMath () const
183 {
184   return mMath;
185 }
186 
187 
188 /*
189  * @return @c true if the id of this SBML object is set, false
190  * otherwise.
191  */
192 bool
isSetId() const193 FunctionDefinition::isSetId () const
194 {
195   return (mId.empty() == false);
196 }
197 
198 
199 /*
200  * @return @c true if the name of this SBML object is set, false
201  * otherwise.
202  */
203 bool
isSetName() const204 FunctionDefinition::isSetName () const
205 {
206   return (getLevel() == 1) ? (mId.empty() == false) :
207                             (mName.empty() == false);
208 }
209 
210 
211 /*
212  * @return @c true if the math of this FunctionDefinition is set, false
213  * otherwise.
214  */
215 bool
isSetMath() const216 FunctionDefinition::isSetMath () const
217 {
218   return (mMath != NULL);
219 }
220 
221 /*
222  * Sets the id of this SBML object to a copy of @p sid.
223  */
224 int
setId(const std::string & sid)225 FunctionDefinition::setId (const std::string& sid)
226 {
227   /* since the setId function has been used as an
228    * alias for setName we cant require it to only
229    * be used on a L2 model
230    */
231 /*  if (getLevel() == 1)
232   {
233     return LIBSBML_UNEXPECTED_ATTRIBUTE;
234   }
235 */
236   if (!(SyntaxChecker::isValidInternalSId(sid)))
237   {
238     return LIBSBML_INVALID_ATTRIBUTE_VALUE;
239   }
240   else
241   {
242     mId = sid;
243     return LIBSBML_OPERATION_SUCCESS;
244   }
245 }
246 
247 
248 /*
249  * Sets the name of this SBML object to a copy of name.
250  */
251 int
setName(const std::string & name)252 FunctionDefinition::setName (const std::string& name)
253 {
254   /* if this is setting an L2 name the type is string
255    * whereas if it is setting an L1 name its type is SId
256    */
257   if (getLevel() == 1)
258   {
259     if (!(SyntaxChecker::isValidInternalSId(name)))
260     {
261       return LIBSBML_INVALID_ATTRIBUTE_VALUE;
262     }
263     else
264     {
265       mId = name;
266       return LIBSBML_OPERATION_SUCCESS;
267     }
268   }
269   else
270   {
271     mName = name;
272     return LIBSBML_OPERATION_SUCCESS;
273   }
274 }
275 
276 
277 /*
278  * Sets the math of this FunctionDefinition to the given ASTNode.
279  */
280 int
setMath(const ASTNode * math)281 FunctionDefinition::setMath (const ASTNode* math)
282 {
283   if (mMath == math)
284   {
285     return LIBSBML_OPERATION_SUCCESS;
286   }
287   else if (math == NULL)
288   {
289     delete mMath;
290     mMath = NULL;
291     return LIBSBML_OPERATION_SUCCESS;
292   }
293   else if (!(math->isWellFormedASTNode()))
294   {
295     return LIBSBML_INVALID_OBJECT;
296   }
297   else
298   {
299     delete mMath;
300     mMath = (math != NULL) ? math->deepCopy() : NULL;
301     if (mMath != NULL) mMath->setParentSBMLObject(this);
302     return LIBSBML_OPERATION_SUCCESS;
303   }
304 }
305 
306 
307 /*
308  * Unsets the name of this SBML object.
309  */
310 int
unsetName()311 FunctionDefinition::unsetName ()
312 {
313   if (getLevel() == 1)
314   {
315     mId.erase();
316   }
317   else
318   {
319     mName.erase();
320   }
321 
322   if (getLevel() == 1 && mId.empty())
323   {
324     return LIBSBML_OPERATION_SUCCESS;
325   }
326   else if (mName.empty())
327   {
328     return LIBSBML_OPERATION_SUCCESS;
329   }
330   else
331   {
332     return LIBSBML_OPERATION_FAILED;
333   }
334 }
335 
336 
337 /*
338  * @return the nth argument (bound variable) passed to this
339  * FunctionDefinition.
340  */
341 const ASTNode*
getArgument(unsigned int n) const342 FunctionDefinition::getArgument (unsigned int n) const
343 {
344   if (mMath == NULL) return NULL;
345 
346   /* if the math is not a lambda this function can cause issues
347    * elsewhere, technically if the math is not a lambda
348    * function the body is NULL
349    */
350   ASTNode * lambda = NULL;
351 
352   if (mMath->isLambda() == true)
353   {
354     lambda = mMath;
355   }
356   else
357   {
358     if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
359     {
360       if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
361         && mMath->getChild(0)->isLambda() == true)
362       {
363         lambda = mMath->getChild(0);
364       }
365     }
366   }
367 
368   if (lambda == NULL)
369   {
370     return NULL;
371   }
372   else if (n < getNumArguments())
373   {
374     return lambda->getChild(n);
375   }
376   else
377   {
378     return NULL;
379   }
380 }
381 
382 
383 /*
384  * @return the argument (bound variable) in this FunctionDefinition with
385  * the given name or @c NULL if no such argument exists.
386  */
387 const ASTNode*
getArgument(const std::string & name) const388 FunctionDefinition::getArgument (const std::string& name) const
389 {
390   const char*    cname = name.c_str();
391   const ASTNode* found = NULL;
392 
393 
394   for (unsigned int n = 0; n < getNumArguments(); ++n)
395   {
396     const ASTNode* node = getArgument(n);
397 
398     if (node != NULL && node->isName() && !strcmp(node->getName(), cname))
399     {
400       found = node;
401       break;
402     }
403   }
404 
405   return found;
406 }
407 
408 
409 /*
410  * @return the body of this FunctionDefinition, or @c NULL if no body is
411  * defined.
412  */
413 const ASTNode*
getBody() const414 FunctionDefinition::getBody () const
415 {
416   if (mMath == NULL) return NULL;
417 
418   /* if the math is not a lambda this function can cause issues
419    * elsewhere, technically if the math is not a lambda
420    * function the body is NULL
421    */
422   ASTNode * lambda = NULL;
423 
424   if (mMath->isLambda() == true)
425   {
426     lambda = mMath;
427   }
428   else
429   {
430     if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
431     {
432       if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
433         && mMath->getChild(0)->isLambda() == true)
434       {
435         lambda = mMath->getChild(0);
436       }
437     }
438   }
439 
440   if (lambda == NULL)
441   {
442     return NULL;
443   }
444 
445 
446   unsigned int nc = lambda->getNumChildren();
447   /* here we do actually need to look at whether something is a bvar
448    * and not just assume that the last child is a function body
449    * it should be BUT it might not be
450    */
451 
452   if (nc > 0 && lambda->getNumBvars() < nc)
453   {
454     return lambda->getChild(nc-1);
455   }
456   else
457   {
458     return NULL;
459   }
460 }
461 
462 
463 /*
464  * @return the body of this FunctionDefinition, or @c NULL if no body is
465  * defined.
466  */
467 ASTNode*
getBody()468 FunctionDefinition::getBody ()
469 {
470   if (mMath == NULL) return NULL;
471 
472   /* if the math is not a lambda this function can cause issues
473    * elsewhere, technically if the math is not a lambda
474    * function the body is NULL
475    */
476   ASTNode * lambda = NULL;
477 
478   if (mMath->isLambda() == true)
479   {
480     lambda = mMath;
481   }
482   else
483   {
484     if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
485     {
486       if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
487         && mMath->getChild(0)->isLambda() == true)
488       {
489         lambda = mMath->getChild(0);
490       }
491     }
492   }
493 
494   if (lambda == NULL)
495   {
496     return NULL;
497   }
498 
499 
500   unsigned int nc = lambda->getNumChildren();
501   /* here we do actually need to look at whether something is a bvar
502    * and not just assume that the last child is a function body
503    * it should be BUT it might not be
504    */
505 
506   if (nc > 0 && lambda->getNumBvars() < nc)
507   {
508     return lambda->getChild(nc-1);
509   }
510   else
511   {
512     return NULL;
513   }
514 }
515 
516 
517 /*
518  * @return the true if the body of this FunctionDefinition is set
519  */
520 bool
isSetBody() const521 FunctionDefinition::isSetBody () const
522 {
523   return (getBody() == NULL) ? false : true;
524 }
525 
526 
527 /*
528  * @return the number of arguments (bound variables) that must be passed
529  * to this FunctionDefinition.
530  */
531 unsigned int
getNumArguments() const532 FunctionDefinition::getNumArguments () const
533 {
534   if (isSetMath() == false)
535   {
536     return 0;
537   }
538 
539   /* if the math is not a lambda this function can cause issues
540    * elsewhere, technically if the math is not a lambda
541    * function there are no arguments
542    */
543   ASTNode * lambda = NULL;
544 
545   if (mMath->isLambda() == true)
546   {
547     lambda = mMath;
548   }
549   else
550   {
551     if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
552     {
553       if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
554         && mMath->getChild(0)->isLambda() == true)
555       {
556         lambda = mMath->getChild(0);
557       }
558     }
559   }
560 
561   if ( lambda == NULL)
562   {
563     return 0;
564   }
565   else
566   {
567     return lambda->getNumBvars();
568   }
569 }
570 
571 
572 /*
573  * @return the typecode (int) of this SBML object or SBML_UNKNOWN
574  * (default).
575  *
576  * @see getElementName()
577  */
578 int
getTypeCode() const579 FunctionDefinition::getTypeCode () const
580 {
581   return SBML_FUNCTION_DEFINITION;
582 }
583 
584 
585 /*
586  * @return the name of this element ie "functionDefinition".
587  */
588 const string&
getElementName() const589 FunctionDefinition::getElementName () const
590 {
591   static const string name = "functionDefinition";
592   return name;
593 }
594 
595 
596 bool
hasRequiredAttributes() const597 FunctionDefinition::hasRequiredAttributes() const
598 {
599   bool allPresent = true;
600 
601   /* required attributes for functionDefinition: id */
602 
603   if (!isSetId())
604     allPresent = false;
605 
606   return allPresent;
607 }
608 
609 
610 bool
hasRequiredElements() const611 FunctionDefinition::hasRequiredElements() const
612 {
613   bool allPresent = true;
614 
615   /* required attributes for functionDefinition: math */
616   /* l3v2 removed that requirement */
617 
618   if ((getLevel() < 3 ) || (getLevel() == 3 && getVersion() == 1))
619   {
620     if (!isSetMath())
621       allPresent = false;
622   }
623 
624   return allPresent;
625 }
626 
627 void
renameUnitSIdRefs(const std::string & oldid,const std::string & newid)628 FunctionDefinition::renameUnitSIdRefs(const std::string& oldid, const std::string& newid)
629 {
630   SBase::renameUnitSIdRefs(oldid, newid);
631   if (isSetMath()) {
632     mMath->renameUnitSIdRefs(oldid, newid);
633   }
634 }
635 
636 /** @cond doxygenLibsbmlInternal */
637 
638 /*
639  * Returns the value of the "attributeName" attribute of this FunctionDefinition.
640  */
641 int
getAttribute(const std::string & attributeName,bool & value) const642 FunctionDefinition::getAttribute(const std::string& attributeName,
643                                  bool& value) const
644 {
645   int return_value = SBase::getAttribute(attributeName, value);
646 
647   return return_value;
648 }
649 
650 /** @endcond */
651 
652 
653 
654 /** @cond doxygenLibsbmlInternal */
655 
656 /*
657  * Returns the value of the "attributeName" attribute of this FunctionDefinition.
658  */
659 int
getAttribute(const std::string & attributeName,int & value) const660 FunctionDefinition::getAttribute(const std::string& attributeName,
661                                  int& value) const
662 {
663   int return_value = SBase::getAttribute(attributeName, value);
664 
665   return return_value;
666 }
667 
668 /** @endcond */
669 
670 
671 
672 /** @cond doxygenLibsbmlInternal */
673 
674 /*
675  * Returns the value of the "attributeName" attribute of this FunctionDefinition.
676  */
677 int
getAttribute(const std::string & attributeName,double & value) const678 FunctionDefinition::getAttribute(const std::string& attributeName,
679                                  double& value) const
680 {
681   int return_value = SBase::getAttribute(attributeName, value);
682 
683   return return_value;
684 }
685 
686 /** @endcond */
687 
688 
689 
690 /** @cond doxygenLibsbmlInternal */
691 
692 /*
693  * Returns the value of the "attributeName" attribute of this FunctionDefinition.
694  */
695 int
getAttribute(const std::string & attributeName,unsigned int & value) const696 FunctionDefinition::getAttribute(const std::string& attributeName,
697                                  unsigned int& value) const
698 {
699   int return_value = SBase::getAttribute(attributeName, value);
700 
701   return return_value;
702 }
703 
704 /** @endcond */
705 
706 
707 
708 /** @cond doxygenLibsbmlInternal */
709 
710 /*
711  * Returns the value of the "attributeName" attribute of this FunctionDefinition.
712  */
713 int
getAttribute(const std::string & attributeName,std::string & value) const714 FunctionDefinition::getAttribute(const std::string& attributeName,
715                                  std::string& value) const
716 {
717   int return_value = SBase::getAttribute(attributeName, value);
718 
719   return return_value;
720 }
721 
722 /** @endcond */
723 
724 
725 
726 /** @cond doxygenLibsbmlInternal */
727 
728 /*
729  * Returns the value of the "attributeName" attribute of this FunctionDefinition.
730  */
731 //int
732 //FunctionDefinition::getAttribute(const std::string& attributeName,
733 //                                 const char* value) const
734 //{
735 //  int return_value = SBase::getAttribute(attributeName, value);
736 //
737 //  return return_value;
738 //}
739 
740 /** @endcond */
741 
742 
743 
744 /** @cond doxygenLibsbmlInternal */
745 
746 /*
747  * Predicate returning @c true if this FunctionDefinition's attribute
748  * "attributeName" is set.
749  */
750 bool
isSetAttribute(const std::string & attributeName) const751 FunctionDefinition::isSetAttribute(const std::string& attributeName) const
752 {
753   bool value = SBase::isSetAttribute(attributeName);
754 
755   return value;
756 }
757 
758 /** @endcond */
759 
760 
761 
762 /** @cond doxygenLibsbmlInternal */
763 
764 /*
765  * Sets the value of the "attributeName" attribute of this FunctionDefinition.
766  */
767 int
setAttribute(const std::string & attributeName,bool value)768 FunctionDefinition::setAttribute(const std::string& attributeName, bool value)
769 {
770   int return_value = SBase::setAttribute(attributeName, value);
771 
772   return return_value;
773 }
774 
775 /** @endcond */
776 
777 
778 
779 /** @cond doxygenLibsbmlInternal */
780 
781 /*
782  * Sets the value of the "attributeName" attribute of this FunctionDefinition.
783  */
784 int
setAttribute(const std::string & attributeName,int value)785 FunctionDefinition::setAttribute(const std::string& attributeName, int value)
786 {
787   int return_value = SBase::setAttribute(attributeName, value);
788 
789   return return_value;
790 }
791 
792 /** @endcond */
793 
794 
795 
796 /** @cond doxygenLibsbmlInternal */
797 
798 /*
799  * Sets the value of the "attributeName" attribute of this FunctionDefinition.
800  */
801 int
setAttribute(const std::string & attributeName,double value)802 FunctionDefinition::setAttribute(const std::string& attributeName,
803                                  double value)
804 {
805   int return_value = SBase::setAttribute(attributeName, value);
806 
807   return return_value;
808 }
809 
810 /** @endcond */
811 
812 
813 
814 /** @cond doxygenLibsbmlInternal */
815 
816 /*
817  * Sets the value of the "attributeName" attribute of this FunctionDefinition.
818  */
819 int
setAttribute(const std::string & attributeName,unsigned int value)820 FunctionDefinition::setAttribute(const std::string& attributeName,
821                                  unsigned int value)
822 {
823   int return_value = SBase::setAttribute(attributeName, value);
824 
825   return return_value;
826 }
827 
828 /** @endcond */
829 
830 
831 
832 /** @cond doxygenLibsbmlInternal */
833 
834 /*
835  * Sets the value of the "attributeName" attribute of this FunctionDefinition.
836  */
837 int
setAttribute(const std::string & attributeName,const std::string & value)838 FunctionDefinition::setAttribute(const std::string& attributeName,
839                                  const std::string& value)
840 {
841   int return_value = SBase::setAttribute(attributeName, value);
842 
843   return return_value;
844 }
845 
846 /** @endcond */
847 
848 
849 
850 /** @cond doxygenLibsbmlInternal */
851 
852 /*
853  * Sets the value of the "attributeName" attribute of this FunctionDefinition.
854  */
855 //int
856 //FunctionDefinition::setAttribute(const std::string& attributeName,
857 //                                 const char* value)
858 //{
859 //  int return_value = SBase::setAttribute(attributeName, value);
860 //
861 //  return return_value;
862 //}
863 
864 /** @endcond */
865 
866 
867 
868 /** @cond doxygenLibsbmlInternal */
869 
870 /*
871  * Unsets the value of the "attributeName" attribute of this
872  * FunctionDefinition.
873  */
874 int
unsetAttribute(const std::string & attributeName)875 FunctionDefinition::unsetAttribute(const std::string& attributeName)
876 {
877   int value = SBase::unsetAttribute(attributeName);
878 
879   return value;
880 }
881 
882 /** @endcond */
883 
884 
885 
886 /** @cond doxygenLibsbmlInternal */
887 /*
888  * Subclasses should override this method to read (and store) XHTML,
889  * MathML, etc. directly from the XMLInputStream.
890  *
891  * @return @c true if the subclass read from the stream, false otherwise.
892  */
893 bool
readOtherXML(XMLInputStream & stream)894 FunctionDefinition::readOtherXML (XMLInputStream& stream)
895 {
896   bool          read = false;
897   const string& name = stream.peek().getName();
898 
899   if (name == "math")
900   {
901     // if this is level 1 there shouldnt be any math!!!
902     if (getLevel() == 1)
903     {
904       logError(NotSchemaConformant, getLevel(), getVersion(),
905 	       "SBML Level 1 does not support MathML.");
906       delete mMath;
907       return false;
908     }
909 
910 
911     if (mMath != NULL)
912     {
913       if (getLevel() < 3)
914       {
915         logError(NotSchemaConformant, getLevel(), getVersion(),
916 	        "Only one <math> element is permitted inside a "
917 	        "particular containing element.");
918       }
919       else
920       {
921         logError(OneMathElementPerFunc, getLevel(), getVersion(),
922           "The <functionDefinition> with id '" + getId() + "' contains "
923           "more than one <math> element.");
924       }
925     }
926     /* check for MathML namespace
927      * this may be explicitly declared here
928      * or implicitly declared on the whole document
929      */
930     const XMLToken elem = stream.peek();
931     const std::string prefix = checkMathMLNamespace(elem);
932 
933     delete mMath;
934     mMath = readMathML(stream, prefix);
935     if (mMath != NULL) mMath->setParentSBMLObject(this);
936     read  = true;
937   }
938 
939   /* ------------------------------
940    *
941    *   (EXTENSION)
942    *
943    * ------------------------------ */
944   if ( SBase::readOtherXML(stream) )
945     read = true;
946 
947   return read;
948 }
949 /** @endcond */
950 
951 
952 /** @cond doxygenLibsbmlInternal */
953 /**
954  * Subclasses should override this method to get the list of
955  * expected attributes.
956  * This function is invoked from corresponding readAttributes()
957  * function.
958  */
959 void
addExpectedAttributes(ExpectedAttributes & attributes)960 FunctionDefinition::addExpectedAttributes(ExpectedAttributes& attributes)
961 {
962   SBase::addExpectedAttributes(attributes);
963 
964   attributes.add("name");
965   attributes.add("id");
966 
967   const unsigned int level = getLevel();
968   const unsigned int version = getVersion();
969 
970   if (level == 2 && version == 2)
971   {
972     attributes.add("sboTerm");
973   }
974 
975 }
976 
977 /*
978  * Subclasses should override this method to read values from the given
979  * XMLAttributes set into their specific fields.  Be sure to call your
980  * parent's implementation of this method as well.
981  */
982 void
readAttributes(const XMLAttributes & attributes,const ExpectedAttributes & expectedAttributes)983 FunctionDefinition::readAttributes (const XMLAttributes& attributes,
984                                     const ExpectedAttributes& expectedAttributes)
985 {
986   const unsigned int level   = getLevel  ();
987   const unsigned int version = getVersion();
988 
989   SBase::readAttributes(attributes, expectedAttributes);
990 
991   switch (level)
992   {
993   case 1:
994     logError(NotSchemaConformant, level, version,
995 	      "FunctionDefinition is not a valid component for this level/version.");
996     break;
997   case 2:
998     readL2Attributes(attributes);
999     break;
1000   case 3:
1001   default:
1002     readL3Attributes(attributes);
1003     break;
1004   }
1005 }
1006 /** @endcond */
1007 
1008 
1009 /** @cond doxygenLibsbmlInternal */
1010 /*
1011  * Subclasses should override this method to read values from the given
1012  * XMLAttributes set into their specific fields.  Be sure to call your
1013  * parent's implementation of this method as well.
1014  */
1015 void
readL2Attributes(const XMLAttributes & attributes)1016 FunctionDefinition::readL2Attributes (const XMLAttributes& attributes)
1017 {
1018   const unsigned int level = getLevel();
1019   const unsigned int version = getVersion();
1020 
1021   //
1022   // id: SId  { use="required" }  (L2v1 ->)
1023   //
1024   bool assigned;
1025   assigned = attributes.readInto("id", mId, getErrorLog(), true, getLine(), getColumn());
1026   if (assigned && mId.size() == 0)
1027   {
1028     logEmptyString("id", level, version, "<functionDefinition>");
1029   }
1030   if (!SyntaxChecker::isValidInternalSId(mId))
1031     logError(InvalidIdSyntax, level, version, "The id '" + mId + "' does not conform to the syntax.");
1032 
1033   //
1034   // name: string  { use="optional" }  (L2v1 ->)
1035   //
1036   attributes.readInto("name", mName, getErrorLog(), false, getLine(), getColumn());
1037 
1038   //
1039   // sboTerm: SBOTerm { use="optional" }  (L2v2 ->)
1040   //
1041   if (version == 2)
1042     mSBOTerm = SBO::readTerm(attributes, this->getErrorLog(), level, version,
1043 				getLine(), getColumn());
1044 
1045 }
1046 /** @endcond */
1047 
1048 
1049 /** @cond doxygenLibsbmlInternal */
1050 /*
1051  * Subclasses should override this method to read values from the given
1052  * XMLAttributes set into their specific fields.  Be sure to call your
1053  * parent's implementation of this method as well.
1054  */
1055 void
readL3Attributes(const XMLAttributes & attributes)1056 FunctionDefinition::readL3Attributes (const XMLAttributes& attributes)
1057 {
1058   const unsigned int level = getLevel();
1059   const unsigned int version = getVersion();
1060 
1061   //
1062   // id: SId  { use="required" }  (L2v1 ->)
1063   //
1064   bool assigned;
1065   // for l3v2 sbase will read this as generically optional
1066   // we want to log errors relating to the specific object
1067   if (version == 1)
1068   {
1069     assigned = attributes.readInto("id", mId, getErrorLog(), false, getLine(), getColumn());
1070     if (!assigned)
1071     {
1072       logError(AllowedAttributesOnFunc, level, version,
1073         "The required attribute 'id' is missing.");
1074     }
1075     if (assigned && mId.size() == 0)
1076     {
1077       logEmptyString("id", level, version, "<functionDefinition>");
1078     }
1079     if (!SyntaxChecker::isValidInternalSId(mId))
1080       logError(InvalidIdSyntax, level, version, "The id '" + mId + "' does not conform to the syntax.");
1081   }
1082   else
1083   {
1084     // need to check that id was present
1085     // it has already been read and checked for syntax/emptyness
1086     if (attributes.hasAttribute("id") == false)
1087     {
1088       logError(AllowedAttributesOnFunc, level, version,
1089         "The required attribute 'id' is missing.");
1090     }
1091   }
1092 
1093   //
1094   // name: string  { use="optional" }  (L2v1 ->)
1095   //
1096   // for l3v2 sbase will read this
1097   if (version == 1)
1098   {
1099     attributes.readInto("name", mName, getErrorLog(), false,
1100                                        getLine(), getColumn());
1101   }
1102 }
1103 /** @endcond */
1104 
1105 
1106 /** @cond doxygenLibsbmlInternal */
1107 /*
1108  * Subclasses should override this method to write their XML attributes
1109  * to the XMLOutputStream.  Be sure to call your parent's implementation
1110  * of this method as well.
1111  */
1112 void
writeAttributes(XMLOutputStream & stream) const1113 FunctionDefinition::writeAttributes (XMLOutputStream& stream) const
1114 {
1115   const unsigned int level = getLevel();
1116   const unsigned int version = getVersion();
1117 
1118   /* invalid level/version */
1119   if (level < 2)
1120   {
1121     return;
1122   }
1123 
1124   SBase::writeAttributes(stream);
1125 
1126   //
1127   // sboTerm: SBOTerm { use="optional" }  (L2v2 ->)
1128   //
1129   // sboTerm for L2V3 or later is written in SBase::writeAttributes()
1130   //
1131   if ( (level == 2) && (version == 2) )
1132   {
1133     SBO::writeTerm(stream, mSBOTerm);
1134   }
1135 
1136   // for L3V2 and above SBase will write this out
1137   if (level < 3 || (level == 3 && version == 1))
1138   {
1139     //
1140     // id: SId  { use="required" }  (L2v1 ->)
1141     //
1142     stream.writeAttribute("id", mId);
1143 
1144     //
1145     // name: string  { use="optional" }  (L2v1 ->)
1146     //
1147     stream.writeAttribute("name", mName);
1148   }
1149 
1150   //
1151   // (EXTENSION)
1152   //
1153   SBase::writeExtensionAttributes(stream);
1154 
1155 }
1156 /** @endcond */
1157 
1158 
1159 /** @cond doxygenLibsbmlInternal */
1160 /*
1161  * Subclasses should override this method to write out their contained
1162  * SBML objects as XML elements.  Be sure to call your parent's
1163  * implementation of this method as well.
1164  */
1165 void
writeElements(XMLOutputStream & stream) const1166 FunctionDefinition::writeElements (XMLOutputStream& stream) const
1167 {
1168   SBase::writeElements(stream);
1169 
1170   if (mMath) writeMathML(mMath, stream, getSBMLNamespaces());
1171 
1172   //
1173   // (EXTENSION)
1174   //
1175   SBase::writeExtensionElements(stream);
1176 }
1177 /** @endcond */
1178 
1179 
1180 /*
1181  * Creates a new ListOfFunctionDefinitions items.
1182  */
ListOfFunctionDefinitions(unsigned int level,unsigned int version)1183 ListOfFunctionDefinitions::ListOfFunctionDefinitions (unsigned int level, unsigned int version)
1184 : ListOf(level,version)
1185 {
1186 }
1187 
1188 
1189 /*
1190  * Creates a new ListOfFunctionDefinitions items.
1191  */
ListOfFunctionDefinitions(SBMLNamespaces * sbmlns)1192 ListOfFunctionDefinitions::ListOfFunctionDefinitions (SBMLNamespaces* sbmlns)
1193 : ListOf(sbmlns)
1194 {
1195   loadPlugins(sbmlns);
1196 }
1197 
1198 
1199 /*
1200  * @return a (deep) copy of this ListOfFunctionDefinitions.
1201  */
1202 ListOfFunctionDefinitions*
clone() const1203 ListOfFunctionDefinitions::clone () const
1204 {
1205   return new ListOfFunctionDefinitions(*this);
1206 }
1207 
1208 
1209 /*
1210  * @return the typecode (int) of SBML objects contained in this ListOf or
1211  * SBML_UNKNOWN (default).
1212  */
1213 int
getItemTypeCode() const1214 ListOfFunctionDefinitions::getItemTypeCode () const
1215 {
1216   return SBML_FUNCTION_DEFINITION;
1217 }
1218 
1219 
1220 /*
1221  * @return the name of this element ie "listOfFunctionDefinitions".
1222  */
1223 const string&
getElementName() const1224 ListOfFunctionDefinitions::getElementName () const
1225 {
1226   static const string name = "listOfFunctionDefinitions";
1227   return name;
1228 }
1229 
1230 
1231 /* return nth item in list */
1232 FunctionDefinition *
get(unsigned int n)1233 ListOfFunctionDefinitions::get(unsigned int n)
1234 {
1235   return static_cast<FunctionDefinition*>(ListOf::get(n));
1236 }
1237 
1238 
1239 /* return nth item in list */
1240 const FunctionDefinition *
get(unsigned int n) const1241 ListOfFunctionDefinitions::get(unsigned int n) const
1242 {
1243   return static_cast<const FunctionDefinition*>(ListOf::get(n));
1244 }
1245 
1246 
1247 /**
1248  * Used by ListOf::get() to lookup an SBase based by its id.
1249  */
1250 struct IdEqFD : public unary_function<SBase*, bool>
1251 {
1252   const string& mId;
1253 
IdEqFDIdEqFD1254   IdEqFD (const string& id) : mId(id) { }
operator ()IdEqFD1255   bool operator() (SBase* sb)
1256        { return static_cast <FunctionDefinition *> (sb)->getId() == mId; }
1257 };
1258 
1259 
1260 /* return item by id */
1261 FunctionDefinition*
get(const std::string & sid)1262 ListOfFunctionDefinitions::get (const std::string& sid)
1263 {
1264   return const_cast<FunctionDefinition*>(
1265     static_cast<const ListOfFunctionDefinitions&>(*this).get(sid) );
1266 }
1267 
1268 
1269 /* return item by id */
1270 const FunctionDefinition*
get(const std::string & sid) const1271 ListOfFunctionDefinitions::get (const std::string& sid) const
1272 {
1273   vector<SBase*>::const_iterator result;
1274 
1275   result = find_if( mItems.begin(), mItems.end(), IdEqFD(sid) );
1276   return (result == mItems.end()) ? NULL :
1277                              static_cast <FunctionDefinition*> (*result);
1278 
1279 }
1280 
1281 
1282 /* Removes the nth item from this list */
1283 FunctionDefinition*
remove(unsigned int n)1284 ListOfFunctionDefinitions::remove (unsigned int n)
1285 {
1286    return static_cast<FunctionDefinition*>(ListOf::remove(n));
1287 }
1288 
1289 
1290 /* Removes item in this list by id */
1291 FunctionDefinition*
remove(const std::string & sid)1292 ListOfFunctionDefinitions::remove (const std::string& sid)
1293 {
1294   SBase* item = NULL;
1295   vector<SBase*>::iterator result;
1296 
1297   result = find_if( mItems.begin(), mItems.end(), IdEqFD(sid) );
1298 
1299   if (result != mItems.end())
1300   {
1301     item = *result;
1302     mItems.erase(result);
1303   }
1304 
1305   return static_cast <FunctionDefinition*> (item);
1306 }
1307 
1308 
1309 /** @cond doxygenLibsbmlInternal */
1310 /*
1311  * @return the ordinal position of the element with respect to its siblings
1312  * or -1 (default) to indicate the position is not significant.
1313  */
1314 int
getElementPosition() const1315 ListOfFunctionDefinitions::getElementPosition () const
1316 {
1317   return 1;
1318 }
1319 /** @endcond */
1320 
1321 
1322 /** @cond doxygenLibsbmlInternal */
1323 /*
1324  * @return the SBML object corresponding to next XMLToken in the
1325  * XMLInputStream or @c NULL if the token was not recognized.
1326  */
1327 SBase*
createObject(XMLInputStream & stream)1328 ListOfFunctionDefinitions::createObject (XMLInputStream& stream)
1329 {
1330   const string& name   = stream.peek().getName();
1331   SBase*        object = NULL;
1332 
1333 
1334   if (name == "functionDefinition")
1335   {
1336     try
1337     {
1338       object = new FunctionDefinition(getSBMLNamespaces());
1339     }
1340     catch (SBMLConstructorException*)
1341     {
1342       object = new FunctionDefinition(SBMLDocument::getDefaultLevel(),
1343         SBMLDocument::getDefaultVersion());
1344     }
1345     catch ( ... )
1346     {
1347       object = new FunctionDefinition(SBMLDocument::getDefaultLevel(),
1348         SBMLDocument::getDefaultVersion());
1349     }
1350 
1351     if (object != NULL) mItems.push_back(object);
1352   }
1353 
1354   return object;
1355 }
1356 /** @endcond */
1357 
1358 
1359 #endif /* __cplusplus */
1360 /** @cond doxygenIgnored */
1361 LIBSBML_EXTERN
1362 FunctionDefinition_t *
FunctionDefinition_create(unsigned int level,unsigned int version)1363 FunctionDefinition_create (unsigned int level, unsigned int version)
1364 {
1365   try
1366   {
1367     FunctionDefinition* obj = new FunctionDefinition(level,version);
1368     return obj;
1369   }
1370   catch (SBMLConstructorException)
1371   {
1372     return NULL;
1373   }
1374 }
1375 
1376 
1377 LIBSBML_EXTERN
1378 FunctionDefinition_t *
FunctionDefinition_createWithNS(SBMLNamespaces_t * sbmlns)1379 FunctionDefinition_createWithNS (SBMLNamespaces_t* sbmlns)
1380 {
1381   try
1382   {
1383     FunctionDefinition* obj = new FunctionDefinition(sbmlns);
1384     return obj;
1385   }
1386   catch (SBMLConstructorException)
1387   {
1388     return NULL;
1389   }
1390 }
1391 
1392 
1393 LIBSBML_EXTERN
1394 void
FunctionDefinition_free(FunctionDefinition_t * fd)1395 FunctionDefinition_free (FunctionDefinition_t *fd)
1396 {
1397   if (fd != NULL)
1398   delete fd;
1399 }
1400 
1401 
1402 LIBSBML_EXTERN
1403 FunctionDefinition_t *
FunctionDefinition_clone(const FunctionDefinition_t * fd)1404 FunctionDefinition_clone (const FunctionDefinition_t* fd)
1405 {
1406   return (fd != NULL) ? static_cast<FunctionDefinition*>( fd->clone() ) : NULL;
1407 }
1408 
1409 
1410 LIBSBML_EXTERN
1411 const XMLNamespaces_t *
FunctionDefinition_getNamespaces(FunctionDefinition_t * fd)1412 FunctionDefinition_getNamespaces(FunctionDefinition_t *fd)
1413 {
1414   return (fd != NULL) ? fd->getNamespaces() : NULL;
1415 }
1416 
1417 
1418 LIBSBML_EXTERN
1419 const char *
FunctionDefinition_getId(const FunctionDefinition_t * fd)1420 FunctionDefinition_getId (const FunctionDefinition_t *fd)
1421 {
1422   return (fd != NULL && fd->isSetId()) ? fd->getId().c_str() : NULL;
1423 }
1424 
1425 
1426 LIBSBML_EXTERN
1427 const char *
FunctionDefinition_getName(const FunctionDefinition_t * fd)1428 FunctionDefinition_getName (const FunctionDefinition_t *fd)
1429 {
1430   return (fd != NULL && fd->isSetName()) ? fd->getName().c_str() : NULL;
1431 }
1432 
1433 
1434 LIBSBML_EXTERN
1435 const ASTNode_t *
FunctionDefinition_getMath(const FunctionDefinition_t * fd)1436 FunctionDefinition_getMath (const FunctionDefinition_t *fd)
1437 {
1438   return (fd != NULL) ? fd->getMath() : NULL;
1439 }
1440 
1441 
1442 LIBSBML_EXTERN
1443 int
FunctionDefinition_isSetId(const FunctionDefinition_t * fd)1444 FunctionDefinition_isSetId (const FunctionDefinition_t *fd)
1445 {
1446   return (fd != NULL) ? static_cast<int>( fd->isSetId() ) : 0;
1447 }
1448 
1449 
1450 LIBSBML_EXTERN
1451 int
FunctionDefinition_isSetName(const FunctionDefinition_t * fd)1452 FunctionDefinition_isSetName (const FunctionDefinition_t *fd)
1453 {
1454   return (fd != NULL) ? static_cast<int>( fd->isSetName() ) : 0;
1455 }
1456 
1457 
1458 LIBSBML_EXTERN
1459 int
FunctionDefinition_isSetMath(const FunctionDefinition_t * fd)1460 FunctionDefinition_isSetMath (const FunctionDefinition_t *fd)
1461 {
1462   return (fd != NULL) ? static_cast<int>( fd->isSetMath() ) : 0;
1463 }
1464 
1465 
1466 LIBSBML_EXTERN
1467 int
FunctionDefinition_setId(FunctionDefinition_t * fd,const char * sid)1468 FunctionDefinition_setId (FunctionDefinition_t *fd, const char *sid)
1469 {
1470   if (fd != NULL)
1471     return (sid == NULL) ? fd->setId("") : fd->setId(sid);
1472   else
1473     return LIBSBML_INVALID_OBJECT;
1474 }
1475 
1476 
1477 LIBSBML_EXTERN
1478 int
FunctionDefinition_setName(FunctionDefinition_t * fd,const char * name)1479 FunctionDefinition_setName (FunctionDefinition_t *fd, const char *name)
1480 {
1481   if (fd != NULL)
1482     return (name == NULL) ? fd->unsetName() : fd->setName(name);
1483   else
1484     return LIBSBML_INVALID_OBJECT;
1485 }
1486 
1487 
1488 LIBSBML_EXTERN
1489 int
FunctionDefinition_setMath(FunctionDefinition_t * fd,const ASTNode_t * math)1490 FunctionDefinition_setMath (FunctionDefinition_t *fd, const ASTNode_t *math)
1491 {
1492   if (fd != NULL)
1493     return fd->setMath(math);
1494   else
1495     return LIBSBML_INVALID_OBJECT;
1496 }
1497 
1498 
1499 LIBSBML_EXTERN
1500 int
FunctionDefinition_unsetName(FunctionDefinition_t * fd)1501 FunctionDefinition_unsetName (FunctionDefinition_t *fd)
1502 {
1503   if (fd != NULL)
1504     return fd->unsetName();
1505   else
1506     return LIBSBML_INVALID_OBJECT;
1507 }
1508 
1509 
1510 LIBSBML_EXTERN
1511 const ASTNode_t *
FunctionDefinition_getArgument(const FunctionDefinition_t * fd,unsigned int n)1512 FunctionDefinition_getArgument (const FunctionDefinition_t *fd, unsigned int n)
1513 {
1514   return (fd != NULL) ? fd->getArgument(n) : NULL;
1515 }
1516 
1517 
1518 LIBSBML_EXTERN
1519 const ASTNode_t *
FunctionDefinition_getArgumentByName(FunctionDefinition_t * fd,const char * name)1520 FunctionDefinition_getArgumentByName ( FunctionDefinition_t *fd,
1521                                        const char *name )
1522 {
1523   return (fd != NULL) ? fd->getArgument(name != NULL ? name : "") : NULL;
1524 }
1525 
1526 
1527 LIBSBML_EXTERN
1528 const ASTNode_t *
FunctionDefinition_getBody(const FunctionDefinition_t * fd)1529 FunctionDefinition_getBody (const FunctionDefinition_t *fd)
1530 {
1531   return (fd != NULL) ? fd->getBody() : NULL;
1532 }
1533 
1534 
1535 LIBSBML_EXTERN
1536 int
FunctionDefinition_isSetBody(const FunctionDefinition_t * fd)1537 FunctionDefinition_isSetBody (const FunctionDefinition_t *fd)
1538 {
1539   return (fd != NULL) ? static_cast<int>( fd->isSetBody() ) : 0;
1540 }
1541 
1542 
1543 LIBSBML_EXTERN
1544 unsigned int
FunctionDefinition_getNumArguments(const FunctionDefinition_t * fd)1545 FunctionDefinition_getNumArguments (const FunctionDefinition_t *fd)
1546 {
1547   return (fd != NULL) ? fd->getNumArguments() : SBML_INT_MAX;
1548 }
1549 
1550 
1551 
1552 LIBSBML_EXTERN
1553 FunctionDefinition_t *
ListOfFunctionDefinitions_getById(ListOf_t * lo,const char * sid)1554 ListOfFunctionDefinitions_getById (ListOf_t *lo, const char *sid)
1555 {
1556   if (lo != NULL)
1557     return (sid != NULL) ?
1558       static_cast <ListOfFunctionDefinitions *> (lo)->get(sid) : NULL;
1559   else
1560     return NULL;
1561 }
1562 
1563 
1564 LIBSBML_EXTERN
1565 FunctionDefinition_t *
ListOfFunctionDefinitions_removeById(ListOf_t * lo,const char * sid)1566 ListOfFunctionDefinitions_removeById (ListOf_t *lo, const char *sid)
1567 {
1568   if (lo != NULL)
1569     return (sid != NULL) ?
1570       static_cast <ListOfFunctionDefinitions *> (lo)->remove(sid) : NULL;
1571   else
1572     return NULL;
1573 }
1574 /** @endcond */
1575 
1576 LIBSBML_CPP_NAMESPACE_END
1577 
1578