1 /**
2 * @file KineticLaw.cpp
3 * @brief Implementation of KineticLaw.
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 <sbml/xml/XMLNode.h>
43 #include <sbml/xml/XMLAttributes.h>
44 #include <sbml/xml/XMLInputStream.h>
45 #include <sbml/xml/XMLOutputStream.h>
46
47 #include <sbml/math/FormulaFormatter.h>
48 #include <sbml/math/FormulaParser.h>
49 #include <sbml/math/MathML.h>
50 #include <sbml/math/ASTNode.h>
51
52 #include <sbml/SBO.h>
53 #include <sbml/SBMLVisitor.h>
54 #include <sbml/SBMLDocument.h>
55 #include <sbml/SBMLError.h>
56 #include <sbml/Model.h>
57 #include <sbml/Parameter.h>
58 #include <sbml/KineticLaw.h>
59
60 #include <sbml/util/ElementFilter.h>
61
62 /** @cond doxygenIgnored */
63 using namespace std;
64 /** @endcond */
65
66 LIBSBML_CPP_NAMESPACE_BEGIN
67 #ifdef __cplusplus
68
KineticLaw(unsigned int level,unsigned int version)69 KineticLaw::KineticLaw (unsigned int level, unsigned int version) :
70 SBase ( level, version )
71 , mMath ( NULL )
72 , mParameters (level, version)
73 , mLocalParameters (level, version)
74 , mTimeUnits ("")
75 , mSubstanceUnits ("")
76 , mInternalId ("")
77
78 {
79 if (!hasValidLevelVersionNamespaceCombination())
80 throw SBMLConstructorException();
81
82 connectToChild();
83 }
84
85
KineticLaw(SBMLNamespaces * sbmlns)86 KineticLaw::KineticLaw (SBMLNamespaces * sbmlns) :
87 SBase (sbmlns )
88 , mMath ( NULL )
89 , mParameters (sbmlns)
90 , mLocalParameters (sbmlns)
91 , mTimeUnits ("")
92 , mSubstanceUnits ("")
93 , mInternalId ("")
94
95 {
96 if (!hasValidLevelVersionNamespaceCombination())
97 {
98 throw SBMLConstructorException(getElementName(), sbmlns);
99 }
100
101 connectToChild();
102 loadPlugins(sbmlns);
103 }
104
105
106 /*
107 * Destroys this KineticLaw.
108 */
~KineticLaw()109 KineticLaw::~KineticLaw ()
110 {
111 delete mMath;
112 }
113
114
115 /*
116 * Copy constructor. Creates a copy of this KineticLaw.
117 */
KineticLaw(const KineticLaw & orig)118 KineticLaw::KineticLaw (const KineticLaw& orig) :
119 SBase ( orig )
120 , mFormula ( orig.mFormula )
121 , mMath ( NULL )
122 , mParameters ( orig.mParameters )
123 , mLocalParameters ( orig.mLocalParameters )
124 , mTimeUnits ( orig.mTimeUnits )
125 , mSubstanceUnits ( orig.mSubstanceUnits )
126 , mInternalId ( orig.mInternalId )
127 {
128
129 if (orig.mMath != NULL)
130 {
131 mMath = orig.mMath->deepCopy();
132 mMath->setParentSBMLObject(this);
133 }
134
135 connectToChild();
136 }
137
138
139 /*
140 * Assignment operator
141 */
operator =(const KineticLaw & rhs)142 KineticLaw& KineticLaw::operator=(const KineticLaw& rhs)
143 {
144 if(&rhs!=this)
145 {
146 this->SBase::operator =(rhs);
147 mFormula = rhs.mFormula ;
148 mTimeUnits = rhs.mTimeUnits ;
149 mSubstanceUnits = rhs.mSubstanceUnits ;
150 mParameters = rhs.mParameters ;
151 mLocalParameters = rhs.mLocalParameters ;
152 mInternalId = rhs.mInternalId ;
153
154 delete mMath;
155 if (rhs.mMath != NULL)
156 {
157 mMath = rhs.mMath->deepCopy();
158 mMath->setParentSBMLObject(this);
159 }
160 else
161 {
162 mMath = NULL;
163 }
164 }
165
166 connectToChild();
167
168 return *this;
169 }
170
171
172 /** @cond doxygenLibsbmlInternal */
173 bool
accept(SBMLVisitor & v) const174 KineticLaw::accept (SBMLVisitor& v) const
175 {
176 v.visit(*this);
177 if (getLevel() > 2)
178 mLocalParameters.accept(v);
179 else
180 mParameters.accept(v);
181 v.leave(*this);
182
183 return true;
184 }
185 /** @endcond */
186
187
188 /*
189 * @return a (deep) copy of this KineticLaw.
190 */
191 KineticLaw*
clone() const192 KineticLaw::clone () const
193 {
194 return new KineticLaw(*this);
195 }
196
197
198 SBase*
getElementBySId(const std::string & id)199 KineticLaw::getElementBySId(const std::string& id)
200 {
201 if (id.empty()) return NULL;
202 //Don't look in mParameters--they're only for L1, so their IDs are not appropriate, and they won't have L3 plugins on them. We can't rely on ListOfParameters being overridden, either, as we can for ListOfLocalParameters.
203 SBase* obj = mLocalParameters.getElementBySId(id);
204 if (obj != NULL) return obj;
205
206 return getElementFromPluginsBySId(id);
207 }
208
209
210 SBase*
getElementByMetaId(const std::string & metaid)211 KineticLaw::getElementByMetaId(const std::string& metaid)
212 {
213 if (metaid.empty()) return NULL;
214 //Go ahead and check mParameters, since metaIDs are global.
215 if (mParameters.getMetaId() == metaid) return &mParameters;
216 if (mLocalParameters.getMetaId() == metaid) return &mLocalParameters;
217
218 SBase* obj = mLocalParameters.getElementByMetaId(metaid);
219 if (obj != NULL) return obj;
220 obj = mParameters.getElementByMetaId(metaid);
221 if (obj != NULL) return obj;
222
223 return getElementFromPluginsByMetaId(metaid);
224 }
225
226
227 List*
getAllElements(ElementFilter * filter)228 KineticLaw::getAllElements(ElementFilter *filter)
229 {
230 List* ret = new List();
231 List* sublist = NULL;
232
233 ADD_FILTERED_LIST(ret, sublist, mParameters, filter);
234 ADD_FILTERED_LIST(ret, sublist, mLocalParameters, filter);
235
236 ADD_FILTERED_FROM_PLUGIN(ret, sublist, filter);
237
238 return ret;
239 }
240
241 /*
242 * @return the formula of this KineticLaw.
243 */
244 const string&
getFormula() const245 KineticLaw::getFormula () const
246 {
247 if (mFormula.empty() == true && mMath != NULL)
248 {
249 char* s = SBML_formulaToString(mMath);
250 mFormula = s;
251
252 free(s);
253 }
254
255 return mFormula;
256 }
257
258
259 /*
260 * @return the math of this KineticLaw.
261 */
262 const ASTNode*
getMath() const263 KineticLaw::getMath () const
264 {
265 if (mMath == NULL && mFormula.empty() == false)
266 {
267 mMath = SBML_parseFormula( mFormula.c_str() );
268 }
269
270 return mMath;
271 }
272
273
274 /*
275 * @return the timeUnits of this KineticLaw.
276 */
277 const string&
getTimeUnits() const278 KineticLaw::getTimeUnits () const
279 {
280 return mTimeUnits;
281 }
282
283
284 /*
285 * @return the substanceUnits of this KineticLaw.
286 */
287 const string&
getSubstanceUnits() const288 KineticLaw::getSubstanceUnits () const
289 {
290 return mSubstanceUnits;
291 }
292
293
294 /*
295 * @return @c true if the formula (or equivalently the math) of this
296 * KineticLaw is set, false otherwise.
297 */
298 bool
isSetFormula() const299 KineticLaw::isSetFormula () const
300 {
301 return (mFormula.empty() == false) || (mMath != NULL);
302 }
303
304
305 /*
306 * @return @c true if the math (or equivalently the formula) of this
307 * KineticLaw is set, false otherwise.
308 */
309 bool
isSetMath() const310 KineticLaw::isSetMath () const
311 {
312 /* if the formula has been set but it is not a correct formula
313 * it cannot be correctly transferred to an ASTNode so in fact
314 * getMath will return @c NULL
315 *
316 * this function needs to test for this
317 */
318 bool formula = isSetFormula();
319
320 if (formula)
321 {
322 const ASTNode *temp = getMath();
323 if (temp == NULL)
324 formula = false;
325 }
326
327 return formula;
328 }
329
330
331 /*
332 * @return @c true if the timeUnits of this KineticLaw is set, false
333 * otherwise.
334 */
335 bool
isSetTimeUnits() const336 KineticLaw::isSetTimeUnits () const
337 {
338 return (mTimeUnits.empty() == false);
339 }
340
341
342 /*
343 * @return @c true if the substanceUnits of this KineticLaw is set,
344 * false otherwise.
345 */
346 bool
isSetSubstanceUnits() const347 KineticLaw::isSetSubstanceUnits () const
348 {
349 return (mSubstanceUnits.empty() == false);
350 }
351
352
353 /*
354 * Sets the formula of this KineticLaw to a copy of formula.
355 */
356 int
setFormula(const std::string & formula)357 KineticLaw::setFormula (const std::string& formula)
358 {
359 if (formula == "")
360 {
361 mFormula.erase();
362 delete mMath;
363 mMath = NULL;
364 return LIBSBML_OPERATION_SUCCESS;
365 }
366 ASTNode * math = SBML_parseFormula(formula.c_str());
367 if (math == NULL || !(math->isWellFormedASTNode()))
368 {
369 delete math;
370 return LIBSBML_INVALID_OBJECT;
371 }
372 else
373 {
374 mFormula = formula;
375
376 if (mMath != NULL)
377 {
378 delete mMath;
379 mMath = NULL;
380 }
381 delete math;
382 return LIBSBML_OPERATION_SUCCESS;
383 }
384
385 }
386
387
388 /*
389 * Sets the math of this KineticLaw to a copy of the given ASTNode.
390 */
391 int
setMath(const ASTNode * math)392 KineticLaw::setMath (const ASTNode* math)
393 {
394 if (mMath == math)
395 {
396 return LIBSBML_OPERATION_SUCCESS;
397 }
398 else if (math == NULL)
399 {
400 delete mMath;
401 mMath = NULL;
402 mFormula.erase();
403 return LIBSBML_OPERATION_SUCCESS;
404 }
405 else if (!(math->isWellFormedASTNode()))
406 {
407 return LIBSBML_INVALID_OBJECT;
408 }
409 else
410 {
411 delete mMath;
412 mMath = (math != NULL) ? math->deepCopy() : NULL;
413 if (mMath != NULL) mMath->setParentSBMLObject(this);
414 mFormula.erase();
415 return LIBSBML_OPERATION_SUCCESS;
416 }
417 }
418
419
420 /*
421 * Sets the timeUnits of this KineticLaw to a copy of @p sid.
422 */
423 int
setTimeUnits(const std::string & sid)424 KineticLaw::setTimeUnits (const std::string& sid)
425 {
426 /* only in L1 and L2V1 */
427 if ((getLevel() == 2 && getVersion() > 1)
428 || getLevel() > 2)
429 {
430 return LIBSBML_UNEXPECTED_ATTRIBUTE;
431 }
432 else if (!(SyntaxChecker::isValidInternalSId(sid)))
433 {
434 return LIBSBML_INVALID_ATTRIBUTE_VALUE;
435 }
436 else
437 {
438 mTimeUnits = sid;
439 return LIBSBML_OPERATION_SUCCESS;
440 }
441 }
442
443
444 /*
445 * Sets the substanceUnits of this KineticLaw to a copy of @p sid.
446 */
447 int
setSubstanceUnits(const std::string & sid)448 KineticLaw::setSubstanceUnits (const std::string& sid)
449 {
450 /* only in L1 and L2V1 */
451 if ((getLevel() == 2 && getVersion() > 1)
452 || getLevel() > 2)
453 {
454 return LIBSBML_UNEXPECTED_ATTRIBUTE;
455 }
456 else if (!(SyntaxChecker::isValidInternalSId(sid)))
457 {
458 return LIBSBML_INVALID_ATTRIBUTE_VALUE;
459 }
460 else
461 {
462 mSubstanceUnits = sid;
463 return LIBSBML_OPERATION_SUCCESS;
464 }
465 }
466
467
468 /*
469 * Unsets the timeUnits of this KineticLaw.
470 */
471 int
unsetTimeUnits()472 KineticLaw::unsetTimeUnits ()
473 {
474 /* only in L1 and L2V1 */
475 if ((getLevel() == 2 && getVersion() > 1)
476 || getLevel() > 2)
477 {
478 return LIBSBML_UNEXPECTED_ATTRIBUTE;
479 }
480
481 mTimeUnits.erase();
482
483 if (mTimeUnits.empty())
484 {
485 return LIBSBML_OPERATION_SUCCESS;
486 }
487 else
488 {
489 return LIBSBML_OPERATION_FAILED;
490 }
491 }
492
493
494 /*
495 * Unsets the substanceUnits of this KineticLaw.
496 */
497 int
unsetSubstanceUnits()498 KineticLaw::unsetSubstanceUnits ()
499 {
500 /* only in L1 and L2V1 */
501 if ((getLevel() == 2 && getVersion() > 1)
502 || getLevel() > 2)
503 {
504 return LIBSBML_UNEXPECTED_ATTRIBUTE;
505 }
506
507 mSubstanceUnits.erase();
508
509 if (mSubstanceUnits.empty())
510 {
511 return LIBSBML_OPERATION_SUCCESS;
512 }
513 else
514 {
515 return LIBSBML_OPERATION_FAILED;
516 }
517 }
518
519
520 /*
521 * Adds a copy of the given Parameter to this KineticLaw.
522 */
523 int
addParameter(const Parameter * p)524 KineticLaw::addParameter (const Parameter* p)
525 {
526 if (p == NULL)
527 {
528 return LIBSBML_OPERATION_FAILED;
529 }
530 else if (!(p->hasRequiredAttributes()) || !(p->hasRequiredElements())
531 || p->getTypeCode() == SBML_LOCAL_PARAMETER)
532 {
533 /*
534 * in an attempt to make existing code work with the new localParameter
535 * class this requires a further check
536 */
537 if (getLevel() < 3)
538 {
539 return LIBSBML_INVALID_OBJECT;
540 }
541 else
542 {
543 /* hack so this will deal with local parameters */
544 LocalParameter lp(*p);
545
546 if (!(lp.hasRequiredAttributes()) || !(lp.hasRequiredElements()))
547 {
548 return LIBSBML_INVALID_OBJECT;
549 }
550 else if (getLocalParameter(lp.getId()) != NULL)
551 {
552 // an parameter with this id already exists
553 return LIBSBML_DUPLICATE_OBJECT_ID;
554 }
555 else
556 {
557 return mLocalParameters.append(&lp);
558 }
559 }
560 }
561 else if (getLevel() != p->getLevel())
562 {
563 return LIBSBML_LEVEL_MISMATCH;
564 }
565 else if (getVersion() != p->getVersion())
566 {
567 return LIBSBML_VERSION_MISMATCH;
568 }
569 else if (matchesRequiredSBMLNamespacesForAddition(static_cast<const SBase *>(p)) == false)
570 {
571 return LIBSBML_NAMESPACES_MISMATCH;
572 }
573 else if (getParameter(p->getId()) != NULL)
574 {
575 // an parameter with this id already exists
576 return LIBSBML_DUPLICATE_OBJECT_ID;
577 }
578 else
579 {
580 return mParameters.append(p);
581 }
582 }
583
584
585 /*
586 * Adds a copy of the given LocalParameter to this KineticLaw.
587 */
588 int
addLocalParameter(const LocalParameter * p)589 KineticLaw::addLocalParameter (const LocalParameter* p)
590 {
591 int returnValue = checkCompatibility(static_cast<const SBase *>(p));
592 if (returnValue != LIBSBML_OPERATION_SUCCESS)
593 {
594 return returnValue;
595 }
596 else if (getLocalParameter(p->getId()) != NULL)
597 {
598 // an parameter with this id already exists
599 return LIBSBML_DUPLICATE_OBJECT_ID;
600 }
601 else
602 {
603 return mLocalParameters.append(p);
604 }
605 }
606
607
608 /*
609 * Creates a new Parameter, adds it to this KineticLaw's list of
610 * parameters and returns it.
611 */
612 Parameter*
createParameter()613 KineticLaw::createParameter ()
614 {
615 if (getLevel() < 3)
616 {
617 Parameter* p = NULL;
618
619 try
620 {
621 p = new Parameter(getSBMLNamespaces());
622 }
623 catch (...)
624 {
625 /* here we do not create a default object as the level/version must
626 * match the parent object
627 *
628 * so do nothing
629 */
630 return NULL;
631 }
632
633 if (p) mParameters.appendAndOwn(p);
634
635 return p;
636 }
637 else
638 {
639 LocalParameter *p = NULL;
640 try
641 {
642 p = new LocalParameter(getSBMLNamespaces());
643 }
644 catch (...)
645 {
646 /* here we do not create a default object as the level/version must
647 * match the parent object
648 *
649 * so do nothing
650 */
651 return NULL;
652 }
653
654 if (p != NULL) mLocalParameters.appendAndOwn(p);
655
656 return static_cast <Parameter *> (p);
657 }
658 }
659
660
661 /*
662 * Creates a new LocalParameter, adds it to this KineticLaw's list of
663 * parameters and returns it.
664 */
665 LocalParameter*
createLocalParameter()666 KineticLaw::createLocalParameter ()
667 {
668 LocalParameter* p = NULL;
669
670 try
671 {
672 p = new LocalParameter(getSBMLNamespaces());
673 }
674 catch (...)
675 {
676 /* here we do not create a default object as the level/version must
677 * match the parent object
678 *
679 * so do nothing
680 */
681 return NULL;
682 }
683
684 if (p != NULL) mLocalParameters.appendAndOwn(p);
685
686 return p;
687 }
688
689
690 /*
691 * @return the list of Parameters for this KineticLaw.
692 */
693 const ListOfParameters*
getListOfParameters() const694 KineticLaw::getListOfParameters () const
695 {
696 if (getLevel() < 3)
697 return &mParameters;
698 else
699 return static_cast <const ListOfParameters *> (&mLocalParameters);
700 }
701
702
703 /*
704 * @return the list of Parameters for this KineticLaw.
705 */
706 ListOfParameters*
getListOfParameters()707 KineticLaw::getListOfParameters ()
708 {
709 if (getLevel() < 3)
710 return &mParameters;
711 else
712 return static_cast <ListOfParameters *> (&mLocalParameters);
713 }
714
715
716 /*
717 * @return the list of LocalParameters for this KineticLaw.
718 */
719 const ListOfLocalParameters*
getListOfLocalParameters() const720 KineticLaw::getListOfLocalParameters () const
721 {
722 return &mLocalParameters;
723 }
724
725
726 /*
727 * @return the list of LocalParameters for this KineticLaw.
728 */
729 ListOfLocalParameters*
getListOfLocalParameters()730 KineticLaw::getListOfLocalParameters ()
731 {
732 return &mLocalParameters;
733 }
734
735
736 /*
737 * @return the nth Parameter of this KineticLaw.
738 */
739 const Parameter*
getParameter(unsigned int n) const740 KineticLaw::getParameter (unsigned int n) const
741 {
742 if (getLevel() < 3)
743 return static_cast<const Parameter*>( mParameters.get(n) );
744 else
745 return static_cast<const Parameter*>( mLocalParameters.get(n) );
746
747 }
748
749
750 /*
751 * @return the nth Parameter of this KineticLaw.
752 */
753 Parameter*
getParameter(unsigned int n)754 KineticLaw::getParameter (unsigned int n)
755 {
756 if (getLevel() < 3)
757 return static_cast<Parameter*>( mParameters.get(n) );
758 else
759 return static_cast<Parameter*>( mLocalParameters.get(n) );
760 }
761
762
763 /*
764 * @return the nth LocalParameter of this KineticLaw.
765 */
766 const LocalParameter*
getLocalParameter(unsigned int n) const767 KineticLaw::getLocalParameter (unsigned int n) const
768 {
769 return static_cast<const LocalParameter*>( mLocalParameters.get(n) );
770 }
771
772
773 /*
774 * @return the nth LocalParameter of this KineticLaw.
775 */
776 LocalParameter*
getLocalParameter(unsigned int n)777 KineticLaw::getLocalParameter (unsigned int n)
778 {
779 return static_cast<LocalParameter*>( mLocalParameters.get(n) );
780 }
781
782
783 /*
784 * @return the Parameter in this kineticLaw with the given @p id or @c NULL if
785 * no such Parameter exists.
786 */
787 const Parameter*
getParameter(const std::string & sid) const788 KineticLaw::getParameter (const std::string& sid) const
789 {
790 if (getLevel() < 3)
791 return static_cast<const Parameter*>( mParameters.get(sid) );
792 else
793 return static_cast<const Parameter*>( mLocalParameters.get(sid) );
794 }
795
796
797 /*
798 * @return the Parameter in this kineticLaw with the given @p id or @c NULL if
799 * no such Parameter exists.
800 */
801 Parameter*
getParameter(const std::string & sid)802 KineticLaw::getParameter (const std::string& sid)
803 {
804 if (getLevel() < 3)
805 return static_cast<Parameter*>( mParameters.get(sid) );
806 else
807 return static_cast<Parameter*>( mLocalParameters.get(sid) );
808 }
809
810
811 /*
812 * @return the LocalParameter in this kineticLaw with the given @p id or @c NULL if
813 * no such LocalParameter exists.
814 */
815 const LocalParameter*
getLocalParameter(const std::string & sid) const816 KineticLaw::getLocalParameter (const std::string& sid) const
817 {
818 return static_cast<const LocalParameter*>( mLocalParameters.get(sid) );
819 }
820
821
822 /*
823 * @return the LocalParameter in this kineticLaw with the given @p id or @c NULL if
824 * no such LocalParameter exists.
825 */
826 LocalParameter*
getLocalParameter(const std::string & sid)827 KineticLaw::getLocalParameter (const std::string& sid)
828 {
829 return static_cast<LocalParameter*>( mLocalParameters.get(sid) );
830 }
831
832
833 /*
834 * @return the number of Parameters in this KineticLaw.
835 */
836 unsigned int
getNumParameters() const837 KineticLaw::getNumParameters () const
838 {
839 if (getLevel() < 3)
840 return mParameters.size();
841 else
842 return mLocalParameters.size();
843 }
844
845 /*
846 * @return the number of LocalParameters in this KineticLaw.
847 */
848 unsigned int
getNumLocalParameters() const849 KineticLaw::getNumLocalParameters () const
850 {
851 return mLocalParameters.size();
852 }
853
854 /*
855 * Calculates and returns a UnitDefinition that expresses the units
856 * returned by the math expression of this KineticLaw.
857 */
858 UnitDefinition *
getDerivedUnitDefinition()859 KineticLaw::getDerivedUnitDefinition()
860 {
861 if (!isSetMath())
862 return NULL;
863 /* if we have the whole model but it is not in a document
864 * it is still possible to determine the units
865 */
866
867 /* VERY NASTY HACK THAT WILL WORK IF WE DONT KNOW ABOUT COMP
868 * but will identify if the parent model is a ModelDefinition
869 */
870 Model * m = NULL;
871
872 if (this->isPackageEnabled("comp"))
873 {
874 m = static_cast <Model *> (getAncestorOfType(251, "comp"));
875 }
876
877 if (m == NULL)
878 {
879 m = static_cast <Model *> (getAncestorOfType(SBML_MODEL));
880 }
881
882 /* we should have a model by this point
883 * OR the object is not yet a child of a model
884 */
885
886 if (m != NULL)
887 {
888 if (!m->isPopulatedListFormulaUnitsData())
889 {
890 m->populateListFormulaUnitsData();
891 }
892
893 FormulaUnitsData *fud = m->getFormulaUnitsData(getInternalId(), getTypeCode());
894 if (fud != NULL)
895 {
896 return fud->getUnitDefinition();
897 }
898 else
899 {
900 return NULL;
901 }
902 }
903 else
904 {
905 return NULL;
906 }
907 }
908
909
910 /*
911 * Constructs and returns a UnitDefinition that expresses the units of this
912 * Compartment.
913 */
914 const UnitDefinition *
getDerivedUnitDefinition() const915 KineticLaw::getDerivedUnitDefinition() const
916 {
917 return const_cast <KineticLaw *> (this)->getDerivedUnitDefinition();
918 }
919
920
921 /** @cond doxygenLibsbmlInternal */
922 /*
923 * Predicate returning @c true if
924 * the math expression of this KineticLaw contains
925 * parameters/numbers with undeclared units that cannot be ignored.
926 */
927 bool
containsUndeclaredUnits()928 KineticLaw::containsUndeclaredUnits()
929 {
930 if (!isSetMath())
931 return false;
932 /* if we have the whole model but it is not in a document
933 * it is still possible to determine the units
934 */
935
936 /* VERY NASTY HACK THAT WILL WORK IF WE DONT KNOW ABOUT COMP
937 * but will identify if the parent model is a ModelDefinition
938 */
939 Model * m = NULL;
940
941 if (this->isPackageEnabled("comp"))
942 {
943 m = static_cast <Model *> (getAncestorOfType(251, "comp"));
944 }
945
946 if (m == NULL)
947 {
948 m = static_cast <Model *> (getAncestorOfType(SBML_MODEL));
949 }
950
951 /* we should have a model by this point
952 * OR the object is not yet a child of a model
953 */
954
955
956 if (m != NULL)
957 {
958 if (!m->isPopulatedListFormulaUnitsData())
959 {
960 m->populateListFormulaUnitsData();
961 }
962
963 FormulaUnitsData *fud = m->getFormulaUnitsData(getInternalId(), getTypeCode());
964 if (fud != NULL)
965 {
966 return fud->getContainsUndeclaredUnits();
967 }
968 else
969 {
970 return false;
971 }
972 }
973 else
974 {
975 return false;
976 }
977 }
978 /** @endcond */
979
980
981 /** @cond doxygenLibsbmlInternal */
982 bool
containsUndeclaredUnits() const983 KineticLaw::containsUndeclaredUnits() const
984 {
985 return const_cast<KineticLaw *> (this)->containsUndeclaredUnits();
986 }
987 /** @endcond */
988
989 /**
990 * Removes the nth Parameter object in the list of local parameters
991 * in this KineticLaw instance.
992 */
993 Parameter*
removeParameter(unsigned int n)994 KineticLaw::removeParameter (unsigned int n)
995 {
996 return mParameters.remove(n);
997 }
998
999
1000 /**
1001 * Removes the nth LocalParameter object in the list of local parameters
1002 * in this KineticLaw instance.
1003 */
1004 LocalParameter*
removeLocalParameter(unsigned int n)1005 KineticLaw::removeLocalParameter (unsigned int n)
1006 {
1007 return mLocalParameters.remove(n);
1008 }
1009
1010
1011 /**
1012 * Removes a Parameter object with the given identifier in the list of
1013 * local parameters in this KineticLaw instance.
1014 */
1015 Parameter*
removeParameter(const std::string & sid)1016 KineticLaw::removeParameter (const std::string& sid)
1017 {
1018 return mParameters.remove(sid);
1019 }
1020
1021
1022 /**
1023 * Removes a LocalParameter object with the given identifier in the list of
1024 * local parameters in this KineticLaw instance.
1025 */
1026 LocalParameter*
removeLocalParameter(const std::string & sid)1027 KineticLaw::removeLocalParameter (const std::string& sid)
1028 {
1029 return mLocalParameters.remove(sid);
1030 }
1031
1032
1033 /** @cond doxygenLibsbmlInternal */
1034 /*
1035 * Sets the parent SBMLDocument of this SBML object.
1036 */
1037 void
setSBMLDocument(SBMLDocument * d)1038 KineticLaw::setSBMLDocument (SBMLDocument* d)
1039 {
1040 SBase::setSBMLDocument(d);
1041
1042 //if (getLevel() < 3)
1043 //{
1044 mParameters.setSBMLDocument(d);
1045 //}
1046 //else
1047 //{
1048 mLocalParameters.setSBMLDocument(d);
1049 //}
1050 }
1051
1052
1053 /*
1054 * Sets this SBML object to child SBML objects (if any).
1055 * (Creates a child-parent relationship by the parent)
1056 */
1057 void
connectToChild()1058 KineticLaw::connectToChild()
1059 {
1060 SBase::connectToChild();
1061 mParameters.connectToParent(this);
1062 mLocalParameters.connectToParent(this);
1063 }
1064
1065
1066 /**
1067 * Enables/Disables the given package with this element and child
1068 * elements (if any).
1069 * (This is an internal implementation for enablePackage function)
1070 */
1071 void
enablePackageInternal(const std::string & pkgURI,const std::string & pkgPrefix,bool flag)1072 KineticLaw::enablePackageInternal(const std::string& pkgURI,
1073 const std::string& pkgPrefix, bool flag)
1074 {
1075 SBase::enablePackageInternal(pkgURI,pkgPrefix,flag);
1076
1077 if (getLevel() < 3)
1078 {
1079 mParameters.enablePackageInternal(pkgURI,pkgPrefix,flag);
1080 }
1081 else
1082 {
1083 mLocalParameters.enablePackageInternal(pkgURI,pkgPrefix,flag);
1084 }
1085 }
1086
1087 void
updateSBMLNamespace(const std::string & pkg,unsigned int level,unsigned int version)1088 KineticLaw::updateSBMLNamespace(const std::string& pkg, unsigned int level,
1089 unsigned int version)
1090 {
1091 SBase::updateSBMLNamespace(pkg, level, version);
1092
1093 if (getLevel() < 3)
1094 {
1095 mParameters.updateSBMLNamespace(pkg, level, version);
1096 }
1097 else
1098 {
1099 mLocalParameters.updateSBMLNamespace(pkg, level, version);
1100 }
1101 }
1102 /** @endcond */
1103
1104 /*
1105 * @return the typecode (int) of this SBML object or SBML_UNKNOWN
1106 * (default).
1107 *
1108 * @see getElementName()
1109 */
1110 int
getTypeCode() const1111 KineticLaw::getTypeCode () const
1112 {
1113 return SBML_KINETIC_LAW;
1114 }
1115
1116
1117 /*
1118 * @return the name of this element ie "kineticLaw".
1119 */
1120 const string&
getElementName() const1121 KineticLaw::getElementName () const
1122 {
1123 static const string name = "kineticLaw";
1124 return name;
1125 }
1126
1127
1128 bool
hasRequiredAttributes() const1129 KineticLaw::hasRequiredAttributes() const
1130 {
1131 bool allPresent = true;
1132
1133 /* required attributes for kineticLaw: formula (L1 only) */
1134
1135 if (getLevel() == 1 && !isSetFormula())
1136 allPresent = false;
1137
1138 return allPresent;
1139 }
1140
1141
1142 bool
hasRequiredElements() const1143 KineticLaw::hasRequiredElements() const
1144 {
1145 bool allPresent = true;
1146
1147 /* required attributes for kineticlaw: math */
1148 /* l3v2 removed that requirement */
1149
1150 if ((getLevel() < 3 ) || (getLevel() == 3 && getVersion() == 1))
1151 {
1152 if (!isSetMath())
1153 allPresent = false;
1154 }
1155
1156 return allPresent;
1157 }
1158
removeFromParentAndDelete()1159 int KineticLaw::removeFromParentAndDelete()
1160 {
1161 if (mHasBeenDeleted) return LIBSBML_OPERATION_SUCCESS;
1162 SBase* parent = getParentSBMLObject();
1163 if (parent==NULL) return LIBSBML_OPERATION_FAILED;
1164 Reaction* parentReaction = static_cast<Reaction*>(parent);
1165 if (parentReaction== NULL) return LIBSBML_OPERATION_FAILED;
1166 return parentReaction->unsetKineticLaw();
1167 }
1168
1169
1170
1171
1172
1173
1174 /** @cond doxygenLibsbmlInternal */
1175
1176 /*
1177 * Returns the value of the "attributeName" attribute of this KineticLaw.
1178 */
1179 int
getAttribute(const std::string & attributeName,bool & value) const1180 KineticLaw::getAttribute(const std::string& attributeName, bool& value) const
1181 {
1182 int return_value = SBase::getAttribute(attributeName, value);
1183
1184 return return_value;
1185 }
1186
1187 /** @endcond */
1188
1189
1190
1191 /** @cond doxygenLibsbmlInternal */
1192
1193 /*
1194 * Returns the value of the "attributeName" attribute of this KineticLaw.
1195 */
1196 int
getAttribute(const std::string & attributeName,int & value) const1197 KineticLaw::getAttribute(const std::string& attributeName, int& value) const
1198 {
1199 int return_value = SBase::getAttribute(attributeName, value);
1200
1201 return return_value;
1202 }
1203
1204 /** @endcond */
1205
1206
1207
1208 /** @cond doxygenLibsbmlInternal */
1209
1210 /*
1211 * Returns the value of the "attributeName" attribute of this KineticLaw.
1212 */
1213 int
getAttribute(const std::string & attributeName,double & value) const1214 KineticLaw::getAttribute(const std::string& attributeName,
1215 double& value) const
1216 {
1217 int return_value = SBase::getAttribute(attributeName, value);
1218
1219 return return_value;
1220 }
1221
1222 /** @endcond */
1223
1224
1225
1226 /** @cond doxygenLibsbmlInternal */
1227
1228 /*
1229 * Returns the value of the "attributeName" attribute of this KineticLaw.
1230 */
1231 int
getAttribute(const std::string & attributeName,unsigned int & value) const1232 KineticLaw::getAttribute(const std::string& attributeName,
1233 unsigned int& value) const
1234 {
1235 int return_value = SBase::getAttribute(attributeName, value);
1236
1237 return return_value;
1238 }
1239
1240 /** @endcond */
1241
1242
1243
1244 /** @cond doxygenLibsbmlInternal */
1245
1246 /*
1247 * Returns the value of the "attributeName" attribute of this KineticLaw.
1248 */
1249 int
getAttribute(const std::string & attributeName,std::string & value) const1250 KineticLaw::getAttribute(const std::string& attributeName,
1251 std::string& value) const
1252 {
1253 int return_value = SBase::getAttribute(attributeName, value);
1254
1255 if (return_value == LIBSBML_OPERATION_SUCCESS)
1256 {
1257 return return_value;
1258 }
1259
1260 if (attributeName == "timeUnits")
1261 {
1262 value = getTimeUnits();
1263 return_value = LIBSBML_OPERATION_SUCCESS;
1264 }
1265 else if (attributeName == "substanceUnits")
1266 {
1267 value = getSubstanceUnits();
1268 return_value = LIBSBML_OPERATION_SUCCESS;
1269 }
1270
1271 return return_value;
1272 }
1273
1274 /** @endcond */
1275
1276
1277
1278 /** @cond doxygenLibsbmlInternal */
1279
1280 /*
1281 * Returns the value of the "attributeName" attribute of this KineticLaw.
1282 */
1283 //int
1284 //KineticLaw::getAttribute(const std::string& attributeName,
1285 // const char* value) const
1286 //{
1287 // int return_value = SBase::getAttribute(attributeName, value);
1288 //
1289 // if (return_value == LIBSBML_OPERATION_SUCCESS)
1290 // {
1291 // return return_value;
1292 // }
1293 //
1294 // if (attributeName == "timeUnits")
1295 // {
1296 // value = getTimeUnits().c_str();
1297 // return_value = LIBSBML_OPERATION_SUCCESS;
1298 // }
1299 // else if (attributeName == "substanceUnits")
1300 // {
1301 // value = getSubstanceUnits().c_str();
1302 // return_value = LIBSBML_OPERATION_SUCCESS;
1303 // }
1304 //
1305 // return return_value;
1306 //}
1307
1308 /** @endcond */
1309
1310
1311
1312 /** @cond doxygenLibsbmlInternal */
1313
1314 /*
1315 * Predicate returning @c true if this KineticLaw's attribute "attributeName"
1316 * is set.
1317 */
1318 bool
isSetAttribute(const std::string & attributeName) const1319 KineticLaw::isSetAttribute(const std::string& attributeName) const
1320 {
1321 bool value = SBase::isSetAttribute(attributeName);
1322
1323 if (attributeName == "timeUnits")
1324 {
1325 value = isSetTimeUnits();
1326 }
1327 else if (attributeName == "substanceUnits")
1328 {
1329 value = isSetSubstanceUnits();
1330 }
1331
1332 return value;
1333 }
1334
1335 /** @endcond */
1336
1337
1338
1339 /** @cond doxygenLibsbmlInternal */
1340
1341 /*
1342 * Sets the value of the "attributeName" attribute of this KineticLaw.
1343 */
1344 int
setAttribute(const std::string & attributeName,bool value)1345 KineticLaw::setAttribute(const std::string& attributeName, bool value)
1346 {
1347 int return_value = SBase::setAttribute(attributeName, value);
1348
1349 return return_value;
1350 }
1351
1352 /** @endcond */
1353
1354
1355
1356 /** @cond doxygenLibsbmlInternal */
1357
1358 /*
1359 * Sets the value of the "attributeName" attribute of this KineticLaw.
1360 */
1361 int
setAttribute(const std::string & attributeName,int value)1362 KineticLaw::setAttribute(const std::string& attributeName, int value)
1363 {
1364 int return_value = SBase::setAttribute(attributeName, value);
1365
1366 return return_value;
1367 }
1368
1369 /** @endcond */
1370
1371
1372
1373 /** @cond doxygenLibsbmlInternal */
1374
1375 /*
1376 * Sets the value of the "attributeName" attribute of this KineticLaw.
1377 */
1378 int
setAttribute(const std::string & attributeName,double value)1379 KineticLaw::setAttribute(const std::string& attributeName, double value)
1380 {
1381 int return_value = SBase::setAttribute(attributeName, value);
1382
1383 return return_value;
1384 }
1385
1386 /** @endcond */
1387
1388
1389
1390 /** @cond doxygenLibsbmlInternal */
1391
1392 /*
1393 * Sets the value of the "attributeName" attribute of this KineticLaw.
1394 */
1395 int
setAttribute(const std::string & attributeName,unsigned int value)1396 KineticLaw::setAttribute(const std::string& attributeName, unsigned int value)
1397 {
1398 int return_value = SBase::setAttribute(attributeName, value);
1399
1400 return return_value;
1401 }
1402
1403 /** @endcond */
1404
1405
1406
1407 /** @cond doxygenLibsbmlInternal */
1408
1409 /*
1410 * Sets the value of the "attributeName" attribute of this KineticLaw.
1411 */
1412 int
setAttribute(const std::string & attributeName,const std::string & value)1413 KineticLaw::setAttribute(const std::string& attributeName,
1414 const std::string& value)
1415 {
1416 int return_value = SBase::setAttribute(attributeName, value);
1417
1418 if (attributeName == "timeUnits")
1419 {
1420 return_value = setTimeUnits(value);
1421 }
1422 else if (attributeName == "substanceUnits")
1423 {
1424 return_value = setSubstanceUnits(value);
1425 }
1426
1427 return return_value;
1428 }
1429
1430 /** @endcond */
1431
1432
1433
1434 /** @cond doxygenLibsbmlInternal */
1435
1436 /*
1437 * Sets the value of the "attributeName" attribute of this KineticLaw.
1438 */
1439 //int
1440 //KineticLaw::setAttribute(const std::string& attributeName, const char* value)
1441 //{
1442 // int return_value = SBase::setAttribute(attributeName, value);
1443 //
1444 // if (attributeName == "timeUnits")
1445 // {
1446 // return_value = setTimeUnits(value);
1447 // }
1448 // else if (attributeName == "substanceUnits")
1449 // {
1450 // return_value = setSubstanceUnits(value);
1451 // }
1452 //
1453 // return return_value;
1454 //}
1455
1456 /** @endcond */
1457
1458
1459
1460 /** @cond doxygenLibsbmlInternal */
1461
1462 /*
1463 * Unsets the value of the "attributeName" attribute of this KineticLaw.
1464 */
1465 int
unsetAttribute(const std::string & attributeName)1466 KineticLaw::unsetAttribute(const std::string& attributeName)
1467 {
1468 int value = SBase::unsetAttribute(attributeName);
1469
1470 if (attributeName == "timeUnits")
1471 {
1472 value = unsetTimeUnits();
1473 }
1474 else if (attributeName == "substanceUnits")
1475 {
1476 value = unsetSubstanceUnits();
1477 }
1478
1479 return value;
1480 }
1481
1482 /** @endcond */
1483
1484
1485
1486 /** @cond doxygenLibsbmlInternal */
1487
1488 /*
1489 * Creates and returns an new "elementName" object in this KineticLaw.
1490 */
1491 SBase*
createChildObject(const std::string & elementName)1492 KineticLaw::createChildObject(const std::string& elementName)
1493 {
1494 SBase* obj = NULL;
1495
1496 if (elementName == "localParameter")
1497 {
1498 return createLocalParameter();
1499 }
1500 else if (elementName == "parameter")
1501 {
1502 return createParameter();
1503 }
1504
1505
1506 return obj;
1507 }
1508
1509 /** @endcond */
1510
1511
1512 /** @cond doxygenLibsbmlInternal */
1513
1514 /*
1515 * Adds an new "elementName" object in this KineticLaw.
1516 */
1517 int
addChildObject(const std::string & elementName,const SBase * element)1518 KineticLaw::addChildObject(const std::string& elementName, const SBase* element)
1519 {
1520 if (elementName == "localParameter" && element->getTypeCode() == SBML_LOCAL_PARAMETER)
1521 {
1522 return addLocalParameter((const LocalParameter*)(element));
1523 }
1524 else if (elementName == "parameter" && element->getTypeCode() == SBML_PARAMETER)
1525 {
1526 return addParameter((const Parameter*)(element));
1527 }
1528
1529 return LIBSBML_OPERATION_FAILED;
1530 }
1531
1532 /** @endcond */
1533
1534
1535 /** @cond doxygenLibsbmlInternal */
1536
1537 /*
1538 * Adds an new "elementName" object in this KineticLaw.
1539 */
1540 SBase*
removeChildObject(const std::string & elementName,const std::string & id)1541 KineticLaw::removeChildObject(const std::string& elementName, const std::string& id)
1542 {
1543 if (elementName == "localParameter")
1544 {
1545 return removeLocalParameter(id);
1546 }
1547 else if (elementName == "parameter")
1548 {
1549 return removeParameter(id);
1550 }
1551
1552 return NULL;
1553 }
1554
1555 /** @endcond */
1556
1557 /** @cond doxygenLibsbmlInternal */
1558
1559 /*
1560 * Returns the number of "elementName" in this KineticLaw.
1561 */
1562 unsigned int
getNumObjects(const std::string & elementName)1563 KineticLaw::getNumObjects(const std::string& elementName)
1564 {
1565 unsigned int n = 0;
1566
1567 if (elementName == "localParameter")
1568 {
1569 return getNumLocalParameters();
1570 }
1571 else if (elementName == "parameter")
1572 {
1573 return getNumParameters();
1574 }
1575
1576
1577 return n;
1578 }
1579
1580 /** @endcond */
1581
1582
1583
1584 /** @cond doxygenLibsbmlInternal */
1585
1586 /*
1587 * Returns the nth object of "objectName" in this KineticLaw.
1588 */
1589 SBase*
getObject(const std::string & elementName,unsigned int index)1590 KineticLaw::getObject(const std::string& elementName, unsigned int index)
1591 {
1592 SBase* obj = NULL;
1593
1594 if (elementName == "localParameter")
1595 {
1596 return getLocalParameter(index);
1597 }
1598 else if (elementName == "parameter")
1599 {
1600 return getParameter(index);
1601 }
1602
1603 return obj;
1604 }
1605
1606 /** @endcond */
1607
1608
1609 void
renameSIdRefs(const std::string & oldid,const std::string & newid)1610 KineticLaw::renameSIdRefs(const std::string& oldid, const std::string& newid)
1611 {
1612 SBase::renameSIdRefs(oldid, newid);
1613 //If the oldid is actually a local parameter, we should not rename it.
1614 if (getParameter(oldid) != NULL) return;
1615 if (getLocalParameter(oldid) != NULL) return;
1616 if (isSetMath()) {
1617 mMath->renameSIdRefs(oldid, newid);
1618 }
1619 }
1620
1621 void
renameUnitSIdRefs(const std::string & oldid,const std::string & newid)1622 KineticLaw::renameUnitSIdRefs(const std::string& oldid, const std::string& newid)
1623 {
1624 SBase::renameUnitSIdRefs(oldid, newid);
1625 if (isSetMath()) {
1626 mMath->renameUnitSIdRefs(oldid, newid);
1627 }
1628 if (mTimeUnits == oldid) mTimeUnits = newid;
1629 if (mSubstanceUnits == oldid) mSubstanceUnits = newid;
1630 }
1631
1632 /** @cond doxygenLibsbmlInternal */
1633 void
replaceSIDWithFunction(const std::string & id,const ASTNode * function)1634 KineticLaw::replaceSIDWithFunction(const std::string& id, const ASTNode* function)
1635 {
1636 if (isSetMath()) {
1637 if (mMath->getType() == AST_NAME && mMath->getName() == id) {
1638 delete mMath;
1639 mMath = function->deepCopy();
1640 }
1641 else {
1642 mMath->replaceIDWithFunction(id, function);
1643 }
1644 }
1645 }
1646 /** @endcond */
1647
1648 /** @cond doxygenLibsbmlInternal */
1649 void
divideAssignmentsToSIdByFunction(const std::string & id,const ASTNode * function)1650 KineticLaw::divideAssignmentsToSIdByFunction(const std::string& id, const ASTNode* function)
1651 {
1652 SBase* parentrxn = getParentSBMLObject();
1653 if (parentrxn==NULL) return;
1654 if (parentrxn->getId() == id && isSetMath()) {
1655 ASTNode* temp = mMath;
1656 mMath = new ASTNode(AST_DIVIDE);
1657 mMath->addChild(temp);
1658 mMath->addChild(function->deepCopy());
1659 }
1660 }
1661 /** @endcond */
1662
1663 /** @cond doxygenLibsbmlInternal */
1664 void
multiplyAssignmentsToSIdByFunction(const std::string & id,const ASTNode * function)1665 KineticLaw::multiplyAssignmentsToSIdByFunction(const std::string& id, const ASTNode* function)
1666 {
1667 SBase* parentrxn = getParentSBMLObject();
1668 if (parentrxn==NULL) return;
1669 if (parentrxn->getId() == id && isSetMath()) {
1670 ASTNode* temp = mMath;
1671 mMath = new ASTNode(AST_TIMES);
1672 mMath->addChild(temp);
1673 mMath->addChild(function->deepCopy());
1674 }
1675 }
1676 /** @endcond */
1677
1678
1679 /** @cond doxygenLibsbmlInternal */
1680 /*
1681 * @return the ordinal position of the element with respect to its siblings
1682 * or -1 (default) to indicate the position is not significant.
1683 */
1684 int
getElementPosition() const1685 KineticLaw::getElementPosition () const
1686 {
1687 return 4;
1688 }
1689 /** @endcond */
1690
1691
1692 /** @cond doxygenLibsbmlInternal */
1693 /*
1694 * Subclasses should override this method to write out their contained
1695 * SBML objects as XML elements. Be sure to call your parent's
1696 * implementation of this method as well.
1697 */
1698 void
writeElements(XMLOutputStream & stream) const1699 KineticLaw::writeElements (XMLOutputStream& stream) const
1700 {
1701 SBase::writeElements(stream);
1702
1703 if ( getLevel() > 1 && isSetMath() )
1704 {
1705 writeMathML(getMath(), stream, getSBMLNamespaces());
1706 }
1707
1708 if ( getLevel() < 3 && getNumParameters() > 0 )
1709 {
1710 mParameters.write(stream);
1711 }
1712 else if (getLevel() == 3)
1713 {
1714 if ( getVersion() == 1 && getNumLocalParameters() > 0)
1715 {
1716 mLocalParameters.write(stream);
1717 }
1718 else if (getVersion() > 1)
1719 {
1720 if (mLocalParameters.hasOptionalElements() == true ||
1721 mLocalParameters.hasOptionalAttributes() == true ||
1722 mLocalParameters.isExplicitlyListed())
1723 {
1724 mLocalParameters.write(stream);
1725 }
1726 }
1727 }
1728
1729 //
1730 // (EXTENSION)
1731 //
1732 SBase::writeExtensionElements(stream);
1733 }
1734 /** @endcond */
1735
1736
1737 /** @cond doxygenLibsbmlInternal */
1738 /*
1739 * @return the SBML object corresponding to next XMLToken in the
1740 * XMLInputStream or @c NULL if the token was not recognized.
1741 */
1742 SBase*
createObject(XMLInputStream & stream)1743 KineticLaw::createObject (XMLInputStream& stream)
1744 {
1745 SBase* object = NULL;
1746
1747 const string& name = stream.peek().getName();
1748
1749 if (name == "listOfParameters")
1750 {
1751 if (mParameters.size() != 0)
1752 {
1753 logError(NotSchemaConformant, getLevel(), getVersion(),
1754 "Only one <listOfParameters> elements is permitted "
1755 "in a given <kineticLaw> element.");
1756 }
1757 object = &mParameters;
1758 }
1759 else if (name == "listOfLocalParameters" && getLevel() > 2)
1760 {
1761 if (mLocalParameters.size() != 0)
1762 {
1763 logError(OneListOfPerKineticLaw, getLevel(), getVersion());
1764 }
1765 mLocalParameters.setExplicitlyListed();
1766 object = &mLocalParameters;
1767 }
1768
1769 return object;
1770 }
1771 /** @endcond */
1772
1773
1774 /** @cond doxygenLibsbmlInternal */
1775 /*
1776 * Subclasses should override this method to read (and store) XHTML,
1777 * MathML, etc. directly from the XMLInputStream.
1778 *
1779 * @return @c true if the subclass read from the stream, false otherwise.
1780 */
1781 bool
readOtherXML(XMLInputStream & stream)1782 KineticLaw::readOtherXML (XMLInputStream& stream)
1783 {
1784 bool read = false;
1785 const string& name = stream.peek().getName();
1786
1787 if (name == "math")
1788 {
1789 // if this is level 1 there shouldnt be any math!!!
1790 if (getLevel() == 1)
1791 {
1792 logError(NotSchemaConformant, getLevel(), getVersion(),
1793 "SBML Level 1 does not support MathML.");
1794 delete mMath;
1795 return false;
1796 }
1797 if (mMath != NULL)
1798 {
1799 if (getLevel() < 3)
1800 {
1801 logError(NotSchemaConformant, getLevel(), getVersion(),
1802 "Only one <math> element is permitted inside a "
1803 "particular containing element.");
1804 }
1805 else
1806 {
1807 logError(OneMathPerKineticLaw, getLevel(), getVersion(),
1808 "The <kineticLaw> contains more than one <math> element.");
1809 }
1810 }
1811
1812 if (getNumParameters() > 0 && getLevel() < 3)
1813 logError(IncorrectOrderInKineticLaw);
1814
1815 /* check for MathML namespace
1816 * this may be explicitly declared here
1817 * or implicitly declared on the whole document
1818 */
1819 const XMLToken elem = stream.peek();
1820 const std::string prefix = checkMathMLNamespace(elem);
1821
1822 // the following assumes that the SBML Namespaces object is valid
1823 if (stream.getSBMLNamespaces() == NULL)
1824 {
1825 SBMLNamespaces sbmlns(getLevel(), getVersion());
1826 stream.setSBMLNamespaces(&sbmlns);
1827 }
1828
1829 delete mMath;
1830 mMath = readMathML(stream, prefix);
1831 if (mMath != NULL) mMath->setParentSBMLObject(this);
1832 read = true;
1833 }
1834
1835 /* ------------------------------
1836 *
1837 * (EXTENSION)
1838 *
1839 * ------------------------------ */
1840 if ( SBase::readOtherXML(stream) )
1841 read = true;
1842
1843 return read;
1844 }
1845 /** @endcond */
1846
1847
1848 /** @cond doxygenLibsbmlInternal */
1849 /**
1850 * Subclasses should override this method to get the list of
1851 * expected attributes.
1852 * This function is invoked from corresponding readAttributes()
1853 * function.
1854 */
1855 void
addExpectedAttributes(ExpectedAttributes & attributes)1856 KineticLaw::addExpectedAttributes(ExpectedAttributes& attributes)
1857 {
1858 SBase::addExpectedAttributes(attributes);
1859
1860 const unsigned int level = getLevel ();
1861 const unsigned int version = getVersion();
1862
1863 switch (level)
1864 {
1865 case 1:
1866 attributes.add("formula");
1867 attributes.add("timeUnits");
1868 attributes.add("substanceUnits");
1869 break;
1870 case 2:
1871 if (version == 1)
1872 {
1873 attributes.add("timeUnits");
1874 attributes.add("substanceUnits");
1875 }
1876 if (version == 2)
1877 {
1878 attributes.add("sboTerm");
1879 }
1880 break;
1881 case 3:
1882 default:
1883 break;
1884 }
1885 }
1886
1887 /*
1888 * Subclasses should override this method to read values from the given
1889 * XMLAttributes set into their specific fields. Be sure to call your
1890 * parent's implementation of this method as well.
1891 */
1892 void
readAttributes(const XMLAttributes & attributes,const ExpectedAttributes & expectedAttributes)1893 KineticLaw::readAttributes (const XMLAttributes& attributes,
1894 const ExpectedAttributes& expectedAttributes)
1895 {
1896 const unsigned int level = getLevel ();
1897
1898 SBase::readAttributes(attributes, expectedAttributes);
1899
1900 switch (level)
1901 {
1902 case 1:
1903 readL1Attributes(attributes);
1904 break;
1905 case 2:
1906 readL2Attributes(attributes);
1907 break;
1908 case 3:
1909 default:
1910 readL3Attributes(attributes);
1911 break;
1912 }
1913 }
1914 /** @endcond */
1915
1916
1917 /** @cond doxygenLibsbmlInternal */
1918 /*
1919 * Subclasses should override this method to read values from the given
1920 * XMLAttributes set into their specific fields. Be sure to call your
1921 * parent's implementation of this method as well.
1922 */
1923 void
readL1Attributes(const XMLAttributes & attributes)1924 KineticLaw::readL1Attributes (const XMLAttributes& attributes)
1925 {
1926 //
1927 // formula: string { use="required" } (L1v1->)
1928 //
1929 attributes.readInto("formula", mFormula, getErrorLog(), true, getLine(), getColumn());
1930
1931 //
1932 // timeUnits { use="optional" } (L1v1, L1v2, L2v1, L2v2)
1933 //
1934 attributes.readInto("timeUnits", mTimeUnits, getErrorLog(), false, getLine(), getColumn());
1935
1936 //
1937 // substanceUnits { use="optional" } (L1v1, L1v2, L2v1, L2v2)
1938 //
1939 attributes.readInto("substanceUnits", mSubstanceUnits, getErrorLog(), false, getLine(), getColumn());
1940
1941 }
1942 /** @endcond */
1943
1944
1945 /** @cond doxygenLibsbmlInternal */
1946 /*
1947 * Subclasses should override this method to read values from the given
1948 * XMLAttributes set into their specific fields. Be sure to call your
1949 * parent's implementation of this method as well.
1950 */
1951 void
readL2Attributes(const XMLAttributes & attributes)1952 KineticLaw::readL2Attributes (const XMLAttributes& attributes)
1953 {
1954 const unsigned int level = getLevel ();
1955 const unsigned int version = getVersion();
1956
1957 if (version == 1)
1958 {
1959 //
1960 // timeUnits { use="optional" } (L1v1, L1v2, L2v1)
1961 //
1962 attributes.readInto("timeUnits", mTimeUnits, getErrorLog(), false, getLine(), getColumn());
1963
1964 //
1965 // substanceUnits { use="optional" } (L1v1, L1v2, L2v1)
1966 //
1967 attributes.readInto("substanceUnits", mSubstanceUnits, getErrorLog(), false, getLine(), getColumn());
1968 }
1969
1970 //
1971 // sboTerm: SBOTerm { use="optional" } (L2v2 ->)
1972 //
1973 if (version == 2)
1974 mSBOTerm = SBO::readTerm(attributes, this->getErrorLog(), level, version,
1975 getLine(), getColumn());
1976 }
1977 /** @endcond */
1978
1979
1980 /** @cond doxygenLibsbmlInternal */
1981 /*
1982 * Subclasses should override this method to read values from the given
1983 * XMLAttributes set into their specific fields. Be sure to call your
1984 * parent's implementation of this method as well.
1985 */
1986 void
readL3Attributes(const XMLAttributes &)1987 KineticLaw::readL3Attributes (const XMLAttributes&)
1988 {
1989 }
1990 /** @endcond */
1991
1992
1993 /** @cond doxygenLibsbmlInternal */
1994 /*
1995 * Subclasses should override this method to write their XML attributes
1996 * to the XMLOutputStream. Be sure to call your parent's implementation
1997 * of this method as well.
1998 */
1999 void
writeAttributes(XMLOutputStream & stream) const2000 KineticLaw::writeAttributes (XMLOutputStream& stream) const
2001 {
2002 SBase::writeAttributes(stream);
2003
2004 const unsigned int level = getLevel ();
2005 const unsigned int version = getVersion();
2006
2007 //
2008 // formula: string { use="required" } (L1v1, L1v2)
2009 //
2010 if (level == 1)
2011 {
2012 //
2013 // formula: string { use="required" } (L1v1, L1v2)
2014 //
2015 stream.writeAttribute("formula", getFormula());
2016
2017 //
2018 // timeUnits { use="optional" } (L1v1, L1v2, L2v1)
2019 // removed in l2v2
2020 //
2021 stream.writeAttribute("timeUnits", mTimeUnits);
2022
2023 //
2024 // substanceUnits { use="optional" } (L1v1, L1v2, L2v1)
2025 // removed in l2v2
2026 //
2027 stream.writeAttribute("substanceUnits", mSubstanceUnits);
2028 }
2029 else
2030 {
2031 //
2032 // sboTerm: SBOTerm { use="optional" } (L2v2 ->)
2033 //
2034 // sboTerm for L2V3 or later is written in SBase::writeAttributes()
2035 //
2036 if ( (level == 2) && (version == 2) )
2037 {
2038 SBO::writeTerm(stream, mSBOTerm);
2039 }
2040
2041 if (level == 2 && version == 1)
2042 {
2043 //
2044 // timeUnits { use="optional" } (L1v1, L1v2, L2v1)
2045 // removed in l2v2
2046 //
2047 stream.writeAttribute("timeUnits", mTimeUnits);
2048
2049 //
2050 // substanceUnits { use="optional" } (L1v1, L1v2, L2v1)
2051 // removed in l2v2
2052 //
2053 stream.writeAttribute("substanceUnits", mSubstanceUnits);
2054 }
2055 }
2056
2057 //
2058 // (EXTENSION)
2059 //
2060 SBase::writeExtensionAttributes(stream);
2061 }
2062 /** @endcond */
2063
2064
2065 #endif /* __cplusplus */
2066 /** @cond doxygenIgnored */
2067 LIBSBML_EXTERN
2068 KineticLaw_t *
KineticLaw_create(unsigned int level,unsigned int version)2069 KineticLaw_create (unsigned int level, unsigned int version)
2070 {
2071 try
2072 {
2073 KineticLaw* obj = new KineticLaw(level,version);
2074 return obj;
2075 }
2076 catch (SBMLConstructorException)
2077 {
2078 return NULL;
2079 }
2080 }
2081
2082
2083 LIBSBML_EXTERN
2084 KineticLaw_t *
KineticLaw_createWithNS(SBMLNamespaces_t * sbmlns)2085 KineticLaw_createWithNS (SBMLNamespaces_t* sbmlns)
2086 {
2087 try
2088 {
2089 KineticLaw* obj = new KineticLaw(sbmlns);
2090 return obj;
2091 }
2092 catch (SBMLConstructorException)
2093 {
2094 return NULL;
2095 }
2096 }
2097
2098
2099 LIBSBML_EXTERN
2100 void
KineticLaw_free(KineticLaw_t * kl)2101 KineticLaw_free (KineticLaw_t *kl)
2102 {
2103 if (kl != NULL)
2104 delete kl;
2105 }
2106
2107
2108 LIBSBML_EXTERN
2109 KineticLaw_t *
KineticLaw_clone(const KineticLaw_t * kl)2110 KineticLaw_clone (const KineticLaw_t *kl)
2111 {
2112 return (kl != NULL) ? kl->clone() : NULL;
2113 }
2114
2115
2116 LIBSBML_EXTERN
2117 const XMLNamespaces_t *
KineticLaw_getNamespaces(KineticLaw_t * kl)2118 KineticLaw_getNamespaces(KineticLaw_t *kl)
2119 {
2120 return (kl != NULL) ? kl->getNamespaces() : NULL;
2121 }
2122
2123 LIBSBML_EXTERN
2124 const char *
KineticLaw_getFormula(const KineticLaw_t * kl)2125 KineticLaw_getFormula (const KineticLaw_t *kl)
2126 {
2127 return (kl != NULL && kl->isSetFormula()) ? kl->getFormula().c_str() : NULL;
2128 }
2129
2130
2131 LIBSBML_EXTERN
2132 const ASTNode_t *
KineticLaw_getMath(const KineticLaw_t * kl)2133 KineticLaw_getMath (const KineticLaw_t *kl)
2134 {
2135 return (kl != NULL) ? kl->getMath() : NULL;
2136 }
2137
2138
2139 LIBSBML_EXTERN
2140 const char *
KineticLaw_getTimeUnits(const KineticLaw_t * kl)2141 KineticLaw_getTimeUnits (const KineticLaw_t *kl)
2142 {
2143 return (kl != NULL && kl->isSetTimeUnits()) ?
2144 kl->getTimeUnits().c_str() : NULL;
2145 }
2146
2147
2148 LIBSBML_EXTERN
2149 const char *
KineticLaw_getSubstanceUnits(const KineticLaw_t * kl)2150 KineticLaw_getSubstanceUnits (const KineticLaw_t *kl)
2151 {
2152 return (kl != NULL && kl->isSetSubstanceUnits()) ?
2153 kl->getSubstanceUnits().c_str() : NULL;
2154 }
2155
2156
2157 LIBSBML_EXTERN
2158 int
KineticLaw_isSetFormula(const KineticLaw_t * kl)2159 KineticLaw_isSetFormula (const KineticLaw_t *kl)
2160 {
2161 return (kl != NULL) ? static_cast<int>( kl->isSetFormula() ) : 0;
2162 }
2163
2164
2165 LIBSBML_EXTERN
2166 int
KineticLaw_isSetMath(const KineticLaw_t * kl)2167 KineticLaw_isSetMath (const KineticLaw_t *kl)
2168 {
2169 return (kl != NULL) ? static_cast<int>( kl->isSetMath() ) : 0;
2170 }
2171
2172
2173 LIBSBML_EXTERN
2174 int
KineticLaw_isSetTimeUnits(const KineticLaw_t * kl)2175 KineticLaw_isSetTimeUnits (const KineticLaw_t *kl)
2176 {
2177 return (kl != NULL) ? static_cast<int>( kl->isSetTimeUnits() ) : 0;
2178 }
2179
2180
2181 LIBSBML_EXTERN
2182 int
KineticLaw_isSetSubstanceUnits(const KineticLaw_t * kl)2183 KineticLaw_isSetSubstanceUnits (const KineticLaw_t *kl)
2184 {
2185 return (kl != NULL) ? static_cast<int>( kl->isSetSubstanceUnits() ) : 0;
2186 }
2187
2188
2189 LIBSBML_EXTERN
2190 int
KineticLaw_setFormula(KineticLaw_t * kl,const char * formula)2191 KineticLaw_setFormula (KineticLaw_t *kl, const char *formula)
2192 {
2193 if (kl != NULL)
2194 return kl->setFormula((formula != NULL) ? formula : "");
2195 else
2196 return LIBSBML_INVALID_OBJECT;
2197 }
2198
2199
2200 LIBSBML_EXTERN
2201 int
KineticLaw_setMath(KineticLaw_t * kl,const ASTNode_t * math)2202 KineticLaw_setMath (KineticLaw_t *kl, const ASTNode_t *math)
2203 {
2204 if (kl != NULL)
2205 return kl->setMath(math);
2206 else
2207 return LIBSBML_INVALID_OBJECT;
2208 }
2209
2210
2211 LIBSBML_EXTERN
2212 int
KineticLaw_setTimeUnits(KineticLaw_t * kl,const char * sid)2213 KineticLaw_setTimeUnits (KineticLaw_t *kl, const char *sid)
2214 {
2215 if (kl != NULL)
2216 return (sid == NULL) ? kl->unsetTimeUnits() : kl->setTimeUnits(sid);
2217 else
2218 return LIBSBML_INVALID_OBJECT;
2219 }
2220
2221
2222 LIBSBML_EXTERN
2223 int
KineticLaw_setSubstanceUnits(KineticLaw_t * kl,const char * sid)2224 KineticLaw_setSubstanceUnits (KineticLaw_t *kl, const char *sid)
2225 {
2226 if (kl != NULL)
2227 return (sid == NULL) ?
2228 kl->unsetSubstanceUnits() : kl->setSubstanceUnits(sid);
2229 else
2230 return LIBSBML_INVALID_OBJECT;
2231 }
2232
2233
2234 LIBSBML_EXTERN
2235 int
KineticLaw_unsetTimeUnits(KineticLaw_t * kl)2236 KineticLaw_unsetTimeUnits (KineticLaw_t *kl)
2237 {
2238 if (kl != NULL)
2239 return kl->unsetTimeUnits();
2240 else
2241 return LIBSBML_INVALID_OBJECT;
2242 }
2243
2244
2245 LIBSBML_EXTERN
2246 int
KineticLaw_unsetSubstanceUnits(KineticLaw_t * kl)2247 KineticLaw_unsetSubstanceUnits (KineticLaw_t *kl)
2248 {
2249 if (kl != NULL)
2250 return kl->unsetSubstanceUnits();
2251 else
2252 return LIBSBML_INVALID_OBJECT;
2253 }
2254
2255
2256 LIBSBML_EXTERN
2257 int
KineticLaw_addParameter(KineticLaw_t * kl,const Parameter_t * p)2258 KineticLaw_addParameter (KineticLaw_t *kl, const Parameter_t *p)
2259 {
2260 if (kl != NULL)
2261 return kl->addParameter(p);
2262 else
2263 return LIBSBML_INVALID_OBJECT;
2264 }
2265
2266
2267 LIBSBML_EXTERN
2268 int
KineticLaw_addLocalParameter(KineticLaw_t * kl,const LocalParameter_t * p)2269 KineticLaw_addLocalParameter (KineticLaw_t *kl, const LocalParameter_t *p)
2270 {
2271 if (kl != NULL)
2272 return kl->addLocalParameter(p);
2273 else
2274 return LIBSBML_INVALID_OBJECT;
2275 }
2276
2277
2278 LIBSBML_EXTERN
2279 Parameter_t *
KineticLaw_createParameter(KineticLaw_t * kl)2280 KineticLaw_createParameter (KineticLaw_t *kl)
2281 {
2282 return (kl != NULL) ? kl->createParameter() : NULL;
2283 }
2284
2285
2286 LIBSBML_EXTERN
2287 LocalParameter_t *
KineticLaw_createLocalParameter(KineticLaw_t * kl)2288 KineticLaw_createLocalParameter (KineticLaw_t *kl)
2289 {
2290 return (kl != NULL) ? kl->createLocalParameter() : NULL;
2291 }
2292
2293
2294 LIBSBML_EXTERN
2295 ListOf_t *
KineticLaw_getListOfParameters(KineticLaw_t * kl)2296 KineticLaw_getListOfParameters (KineticLaw_t *kl)
2297 {
2298 return (kl != NULL) ? kl->getListOfParameters() : NULL;
2299 }
2300
2301
2302 LIBSBML_EXTERN
2303 ListOf_t *
KineticLaw_getListOfLocalParameters(KineticLaw_t * kl)2304 KineticLaw_getListOfLocalParameters (KineticLaw_t *kl)
2305 {
2306 return (kl != NULL) ? kl->getListOfLocalParameters() : 0;
2307 }
2308
2309
2310 LIBSBML_EXTERN
2311 Parameter_t *
KineticLaw_getParameter(KineticLaw_t * kl,unsigned int n)2312 KineticLaw_getParameter (KineticLaw_t *kl, unsigned int n)
2313 {
2314 return (kl != NULL) ? kl->getParameter(n) : NULL;
2315 }
2316
2317
2318 LIBSBML_EXTERN
2319 LocalParameter_t *
KineticLaw_getLocalParameter(KineticLaw_t * kl,unsigned int n)2320 KineticLaw_getLocalParameter (KineticLaw_t *kl, unsigned int n)
2321 {
2322 return (kl != NULL) ? kl->getLocalParameter(n) : NULL;
2323 }
2324
2325
2326 LIBSBML_EXTERN
2327 Parameter_t *
KineticLaw_getParameterById(KineticLaw_t * kl,const char * sid)2328 KineticLaw_getParameterById (KineticLaw_t *kl, const char *sid)
2329 {
2330 return (kl != NULL && sid != NULL) ? kl->getParameter(sid) : NULL;
2331 }
2332
2333
2334 LIBSBML_EXTERN
2335 LocalParameter_t *
KineticLaw_getLocalParameterById(KineticLaw_t * kl,const char * sid)2336 KineticLaw_getLocalParameterById (KineticLaw_t *kl, const char *sid)
2337 {
2338 return (kl != NULL && sid != NULL) ? kl->getLocalParameter(sid) : NULL;
2339 }
2340
2341
2342 LIBSBML_EXTERN
2343 unsigned int
KineticLaw_getNumParameters(const KineticLaw_t * kl)2344 KineticLaw_getNumParameters (const KineticLaw_t *kl)
2345 {
2346 return (kl != NULL) ? kl->getNumParameters() : SBML_INT_MAX;
2347 }
2348
2349
2350 LIBSBML_EXTERN
2351 unsigned int
KineticLaw_getNumLocalParameters(const KineticLaw_t * kl)2352 KineticLaw_getNumLocalParameters (const KineticLaw_t *kl)
2353 {
2354 return (kl != NULL) ? kl->getNumLocalParameters() : SBML_INT_MAX;
2355 }
2356
2357 LIBSBML_EXTERN
2358 UnitDefinition_t *
KineticLaw_getDerivedUnitDefinition(KineticLaw_t * kl)2359 KineticLaw_getDerivedUnitDefinition(KineticLaw_t *kl)
2360 {
2361 return (kl != NULL) ? kl->getDerivedUnitDefinition() : NULL;
2362 }
2363
2364
2365 LIBSBML_EXTERN
2366 int
KineticLaw_containsUndeclaredUnits(KineticLaw_t * kl)2367 KineticLaw_containsUndeclaredUnits(KineticLaw_t *kl)
2368 {
2369 return (kl != NULL) ? static_cast<int>(kl->containsUndeclaredUnits()) : 0;
2370 }
2371
2372
2373 LIBSBML_EXTERN
2374 Parameter_t *
KineticLaw_removeParameter(KineticLaw_t * kl,unsigned int n)2375 KineticLaw_removeParameter (KineticLaw_t *kl, unsigned int n)
2376 {
2377 return (kl != NULL) ? kl->removeParameter(n) : NULL;
2378 }
2379
2380
2381 LIBSBML_EXTERN
2382 LocalParameter_t *
KineticLaw_removeLocalParameter(KineticLaw_t * kl,unsigned int n)2383 KineticLaw_removeLocalParameter (KineticLaw_t *kl, unsigned int n)
2384 {
2385 return (kl != NULL) ? kl->removeLocalParameter(n) : NULL;
2386 }
2387
2388
2389 LIBSBML_EXTERN
2390 Parameter_t *
KineticLaw_removeParameterById(KineticLaw_t * kl,const char * sid)2391 KineticLaw_removeParameterById (KineticLaw_t *kl, const char *sid)
2392 {
2393 if (kl != NULL)
2394 return sid != NULL ? kl->removeParameter(sid) : NULL;
2395 else
2396 return NULL;
2397 }
2398
2399
2400 LIBSBML_EXTERN
2401 LocalParameter_t *
KineticLaw_removeLocalParameterById(KineticLaw_t * kl,const char * sid)2402 KineticLaw_removeLocalParameterById (KineticLaw_t *kl, const char *sid)
2403 {
2404 if (kl != NULL)
2405 return sid != NULL ? kl->removeLocalParameter(sid) : NULL;
2406 else
2407 return NULL;
2408 }
2409 /** @endcond */
2410
2411 LIBSBML_CPP_NAMESPACE_END
2412
2413
2414