1 /**
2  * @cond doxygenLibsbmlInternal
3  *
4  * @file    L2v2CompatibilityConstraints.cpp
5  * @brief   L1 compatibility for conversion from L2
6  * @author  Sarah Keating
7  *
8  * <!--------------------------------------------------------------------------
9  * This file is part of libSBML.  Please visit http://sbml.org for more
10  * information about SBML, and the latest version of libSBML.
11  *
12  * Copyright (C) 2020 jointly by the following organizations:
13  *     1. California Institute of Technology, Pasadena, CA, USA
14  *     2. University of Heidelberg, Heidelberg, Germany
15  *     3. University College London, London, UK
16  *
17  * Copyright (C) 2019 jointly by the following organizations:
18  *     1. California Institute of Technology, Pasadena, CA, USA
19  *     2. University of Heidelberg, Heidelberg, Germany
20  *
21  * Copyright (C) 2013-2018 jointly by the following organizations:
22  *     1. California Institute of Technology, Pasadena, CA, USA
23  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
24  *     3. University of Heidelberg, Heidelberg, Germany
25  *
26  * Copyright (C) 2009-2013 jointly by the following organizations:
27  *     1. California Institute of Technology, Pasadena, CA, USA
28  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
29  *
30  * Copyright (C) 2006-2008 by the California Institute of Technology,
31  *     Pasadena, CA, USA
32  *
33  * Copyright (C) 2002-2005 jointly by the following organizations:
34  *     1. California Institute of Technology, Pasadena, CA, USA
35  *     2. Japan Science and Technology Agency, Japan
36  *
37  * This library is free software; you can redistribute it and/or modify it
38  * under the terms of the GNU Lesser General Public License as published by
39  * the Free Software Foundation.  A copy of the license agreement is provided
40  * in the file named "LICENSE.txt" included with this software distribution
41  * and also available online as http://sbml.org/software/libsbml/license.html
42  * ---------------------------------------------------------------------- -->*/
43 
44 #ifndef AddingConstraintsToValidator
45 #include <sbml/SBase.h>
46 #include <sbml/AssignmentRule.h>
47 #include <sbml/RateRule.h>
48 #include <sbml/AlgebraicRule.h>
49 #include <sbml/validator/VConstraint.h>
50 #include <math.h>
51 #include "DuplicateTopLevelAnnotation.h"
52 #include "CompatibilityConstraints.cxx"
53 #endif
54 
55 
56 #include <sbml/validator/ConstraintMacros.h>
57 
58 /** @cond doxygenIgnored */
59 using namespace std;
60 /** @endcond */
61 
62 
63 START_CONSTRAINT (93001, UnitDefinition, ud)
64 {
65   //msg =
66   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
67   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
68   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
69   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
70 
71   inv( ud.getSBOTerm() == -1 );
72 }
73 END_CONSTRAINT
74 
75 
76 START_CONSTRAINT (93001, Unit, u)
77 {
78   //msg =
79   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
80   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
81   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
82   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
83 
84   inv( u.getSBOTerm() == -1 );
85 }
86 END_CONSTRAINT
87 
88 
89 START_CONSTRAINT (93001, CompartmentType, ct)
90 {
91   //msg =
92   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
93   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
94   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
95   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
96 
97   inv( ct.getSBOTerm() == -1 );
98 }
99 END_CONSTRAINT
100 
101 
102 START_CONSTRAINT (93001, SpeciesType, st)
103 {
104   //msg =
105   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
106   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
107   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
108   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
109 
110   inv( st.getSBOTerm() == -1 );
111 }
112 END_CONSTRAINT
113 
114 
115 START_CONSTRAINT (93001, Compartment, c)
116 {
117   //msg =
118   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
119   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
120   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
121   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
122 
123   inv( c.getSBOTerm() == -1 );
124 }
125 END_CONSTRAINT
126 
127 
128 START_CONSTRAINT (93001, Species, s)
129 {
130   //msg =
131   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
132   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
133   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
134   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
135 
136   inv( s.getSBOTerm() == -1 );
137 }
138 END_CONSTRAINT
139 
140 
141 START_CONSTRAINT (93001, Trigger, t)
142 {
143   //msg =
144   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
145   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
146   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
147   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
148 
149   inv( t.getSBOTerm() == -1 );
150 }
151 END_CONSTRAINT
152 
153 
154 START_CONSTRAINT (93001, Delay, d)
155 {
156   //msg =
157   //  "In SBML Level 2 Version 2, an 'sboTerm' attribute is only permitted on "
158   //  "the following elements: <model>, <functionDefinition>, <parameter>, "
159   //  "<initialAssignment>, <rule>, <constraint>, <reaction>, "
160   //  "<speciesReference>, <kineticLaw>, <event> and <eventAssignment>.";
161 
162   inv( d.getSBOTerm() == -1 );
163 }
164 END_CONSTRAINT
165 
166 
167 START_CONSTRAINT (93002, Unit, u)
168 {
169   //msg =
170   //  "The 'offset' attribute on <unit> previously available in SBML Level 2 "
171   //  "Version 1, has been removed as of SBML Level 2 Version 2. (References: "
172   //  "L2V2 Section 4.4.)";
173 
174   inv( u.getOffset() == 0.0 );
175 }
176 END_CONSTRAINT
177 
178 START_CONSTRAINT (93003, KineticLaw, kl)
179 {
180   //msg =
181   //  "The 'timeUnits' attribute on <kineticLaw>, previously available in SBML "
182   //  "Level 1 and Level 2 Version 1, has been removed as of SBML Level 2 "
183   //  "Version 2. In SBML Level 2 Version 2, the time units of a reaction rate "
184   //  "expression are those of the global 'time' units of the model. "
185   //  "(References: L2V2 Section 4.13.5.)";
186 
187   inv( kl.isSetTimeUnits() == false );
188 }
189 END_CONSTRAINT
190 
191 START_CONSTRAINT (93004, KineticLaw, kl)
192 {
193   //msg =
194   //  "The 'substanceUnits' attribute on <kineticLaw>, previously available in "
195   //  "SBML Level 1 and Level 2 Version 1, has been removed as of SBML Level 2 "
196   //  "Version 2. In SBML Level 2 Version 2, the substance units of a reaction "
197   //  "rate expression are those of the global 'substance' units of the model. "
198   //  "(References: L2V2 Section 4.13.5.)";
199 
200   inv( kl.isSetSubstanceUnits() == false );
201 }
202 END_CONSTRAINT
203 
204 
205 START_CONSTRAINT (93005, Event, e)
206 {
207   inv( e.getUseValuesFromTriggerTime() == true);
208 }
209 END_CONSTRAINT
210 
211 START_CONSTRAINT (93006, Model, m1)
212 {
213   // if the model was L2V4 or above the model sbo term will not
214   // be valid in l2v2
215   pre( m1.getLevel() >1 );
216   if (m1.getLevel() == 2)
217   {
218     pre( m1.getVersion() > 3);
219   }
220 
221   inv( !m1.isSetSBOTerm());
222 }
223 END_CONSTRAINT
224 
225 EXTERN_CONSTRAINT(93009, DuplicateTopLevelAnnotation)
226 
227 START_CONSTRAINT (92009, Compartment, c)
228 {
229   inv_or( c.getSpatialDimensions() == 3 );
230   inv_or( c.getSpatialDimensions() == 2 );
231   inv_or( c.getSpatialDimensions() == 1 );
232   inv_or( c.getSpatialDimensionsAsDouble() == 0.0 );
233 }
234 END_CONSTRAINT
235 
236 
237 START_CONSTRAINT (92010, SpeciesReference, sr)
238 {
239   //msg =
240   //  "A <speciesReference> containing a non-integer or non-rational "
241   //  "<stoichiometryMath> subelement cannot be represented in SBML Level 1.";
242 
243   /* doesnt apply if the SpeciesReference is a modifier */
244   pre(!sr.isModifier());
245 
246   if (sr.getLevel() > 2)
247   {
248     inv( sr.getConstant());
249   }
250 }
251 END_CONSTRAINT
252 
253 
254 START_CONSTRAINT (91015, Model, x)
255 {
256   pre (m.getLevel() > 2);
257   inv( !m.isSetConversionFactor() );
258 }
259 END_CONSTRAINT
260 
261 
262 START_CONSTRAINT (91015, Species, s)
263 {
264   pre (s.getLevel() > 2);
265   inv( !s.isSetConversionFactor() );
266 }
267 END_CONSTRAINT
268 
269 
270 START_CONSTRAINT (91016, Reaction, r)
271 {
272   pre (r.getLevel() > 2);
273   inv( !r.isSetCompartment() );
274 }
275 END_CONSTRAINT
276 
277 
278 START_CONSTRAINT (91017, Model, x)
279 {
280   pre (m.getLevel() > 2);
281   pre (m.isSetExtentUnits());
282 
283   std::string extent = m.getExtentUnits();
284   const UnitDefinition * ud = m.getUnitDefinition(extent);
285   if (ud != NULL)
286   {
287     UnitDefinition ud1(m.getSBMLNamespaces());
288     for (unsigned int i = 0; i < ud->getNumUnits(); i++)
289     {
290       Unit u(m.getSBMLNamespaces());
291       u.setKind(ud->getUnit(i)->getKind());
292       u.setScale(ud->getUnit(i)->getScale());
293       u.setExponent(ud->getUnit(i)->getExponent());
294       u.setMultiplier(ud->getUnit(i)->getMultiplier());
295       ud1.addUnit(&u);
296     }
297 
298     inv( ud1.isVariantOfSubstance());
299   }
300   else
301   {
302     inv_or( extent == "mole" );
303     inv_or( extent == "item" );
304   }
305 }
306 END_CONSTRAINT
307 
308 
309 START_CONSTRAINT (91018, Model, x)
310 {
311   pre (m.getLevel() > 2);
312 
313   std::string units;
314   bool allCorrect = true;
315 
316   if (m.isSetExtentUnits() == true)
317   {
318     units = m.getExtentUnits();
319     if (UnitKind_isValidUnitKindString(units.c_str(),
320                                        m.getLevel(), m.getVersion()) == 0)
321     {
322       const UnitDefinition * ud = m.getUnitDefinition(units);
323       if (ud != NULL)
324       {
325         if (ud->hasRequiredElements() == false)
326         {
327           allCorrect = false;
328         }
329       }
330       else
331       {
332         allCorrect = false;
333       }
334     }
335   }
336   if (m.isSetTimeUnits() == true)
337   {
338     units = m.getTimeUnits();
339     if (UnitKind_isValidUnitKindString(units.c_str(),
340                                        m.getLevel(), m.getVersion()) == 0)
341     {
342       const UnitDefinition * ud = m.getUnitDefinition(units);
343       if (ud != NULL)
344       {
345         if (ud->hasRequiredElements() == false)
346         {
347           allCorrect = false;
348         }
349       }
350       else
351       {
352         allCorrect = false;
353       }
354     }
355   }
356   if (m.isSetSubstanceUnits() == true)
357   {
358     units = m.getSubstanceUnits();
359     if (UnitKind_isValidUnitKindString(units.c_str(),
360                                        m.getLevel(), m.getVersion()) == 0)
361     {
362       const UnitDefinition * ud = m.getUnitDefinition(units);
363       if (ud != NULL)
364       {
365         if (ud->hasRequiredElements() == false)
366         {
367           allCorrect = false;
368         }
369       }
370       else
371       {
372         allCorrect = false;
373       }
374     }
375   }
376   if (m.isSetVolumeUnits() == true)
377   {
378     units = m.getVolumeUnits();
379     if (UnitKind_isValidUnitKindString(units.c_str(),
380                                        m.getLevel(), m.getVersion()) == 0)
381     {
382       const UnitDefinition * ud = m.getUnitDefinition(units);
383       if (ud != NULL)
384       {
385         if (ud->hasRequiredElements() == false)
386         {
387           allCorrect = false;
388         }
389       }
390       else
391       {
392         allCorrect = false;
393       }
394     }
395   }
396   if (m.isSetAreaUnits() == true)
397   {
398     units = m.getAreaUnits();
399     if (UnitKind_isValidUnitKindString(units.c_str(),
400                                        m.getLevel(), m.getVersion()) == 0)
401     {
402       const UnitDefinition * ud = m.getUnitDefinition(units);
403       if (ud != NULL)
404       {
405         if (ud->hasRequiredElements() == false)
406         {
407           allCorrect = false;
408         }
409       }
410       else
411       {
412         allCorrect = false;
413       }
414     }
415   }
416   if (m.isSetLengthUnits() == true)
417   {
418     units = m.getLengthUnits();
419     if (UnitKind_isValidUnitKindString(units.c_str(),
420                                        m.getLevel(), m.getVersion()) == 0)
421     {
422       const UnitDefinition * ud = m.getUnitDefinition(units);
423       if (ud != NULL)
424       {
425         if (ud->hasRequiredElements() == false)
426         {
427           allCorrect = false;
428         }
429       }
430       else
431       {
432         allCorrect = false;
433       }
434     }
435   }
436 
437   inv (allCorrect == true);
438 }
439 END_CONSTRAINT
440 
441 
442 START_CONSTRAINT (92012, Event, e)
443 {
444   pre (e.getLevel() > 2);
445   pre (e.isSetTrigger());
446 
447   inv( e.getTrigger()->getPersistent() == true );
448 }
449 END_CONSTRAINT
450 
451 
452 START_CONSTRAINT (92013, Event, e)
453 {
454   pre (e.getLevel() > 2);
455   pre (e.isSetTrigger());
456 
457   inv( e.getTrigger()->getInitialValue() == true );
458 }
459 END_CONSTRAINT
460 
461 
462 START_CONSTRAINT (99926, Compartment, c)
463 {
464   pre (c.getLevel() > 2);
465 
466   inv( c.isSetSpatialDimensions() == true );
467 }
468 END_CONSTRAINT
469 
470 
471 START_CONSTRAINT (91020, Reaction, r)
472 {
473   pre (r.isSetKineticLaw() == true);
474   pre (r.getKineticLaw()->isSetMath() == true);
475 
476   List * names = r.getKineticLaw()->getMath()
477                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
478 
479   unsigned int size = names->getSize();
480   delete names;
481   inv( size == 0 );
482 }
483 END_CONSTRAINT
484 
485 
486 START_CONSTRAINT (91020, AssignmentRule, r)
487 {
488   pre (r.isSetMath() == true);
489 
490   List * names = r.getMath()
491                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
492 
493   unsigned int size = names->getSize();
494   delete names;
495   inv( size == 0 );
496 }
497 END_CONSTRAINT
498 
499 
500 START_CONSTRAINT (91020, RateRule, r)
501 {
502   pre (r.isSetMath() == true);
503 
504   List * names = r.getMath()
505                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
506 
507   unsigned int size = names->getSize();
508   delete names;
509   inv( size == 0 );
510 }
511 END_CONSTRAINT
512 
513 
514 START_CONSTRAINT (91020, AlgebraicRule, r)
515 {
516   pre (r.isSetMath() == true);
517 
518   List * names = r.getMath()
519                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
520 
521   unsigned int size = names->getSize();
522   delete names;
523   inv( size == 0 );
524 }
525 END_CONSTRAINT
526 
527 
528 START_CONSTRAINT (91020, EventAssignment, ea)
529 {
530   pre (ea.isSetMath() == true);
531 
532   List * names = ea.getMath()
533                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
534 
535   unsigned int size = names->getSize();
536   delete names;
537   inv( size == 0 );
538 }
539 END_CONSTRAINT
540 
541 
542 START_CONSTRAINT (91020, Trigger, t)
543 {
544   pre (t.isSetMath() == true);
545 
546   List * names = t.getMath()
547                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
548 
549   unsigned int size = names->getSize();
550   delete names;
551   inv( size == 0 );
552 }
553 END_CONSTRAINT
554 
555 
556 START_CONSTRAINT (91020, Delay, d)
557 {
558   pre (d.isSetMath() == true);
559 
560   List * names = d.getMath()
561                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
562 
563   unsigned int size = names->getSize();
564   delete names;
565   inv( size == 0 );
566 }
567 END_CONSTRAINT
568 
569 
570 START_CONSTRAINT (91020, InitialAssignment, ia)
571 {
572   pre (ia.isSetMath() == true);
573 
574   List * names = ia.getMath()
575                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
576 
577   unsigned int size = names->getSize();
578   delete names;
579   inv( size == 0 );
580 }
581 END_CONSTRAINT
582 
583 
584 START_CONSTRAINT (91020, Constraint, c)
585 {
586   pre (c.isSetMath() == true);
587 
588   List * names = c.getMath()
589                      ->getListOfNodes((ASTNodePredicate) ASTNode_isAvogadro);
590 
591   unsigned int size = names->getSize();
592   delete names;
593   inv( size == 0 );
594 }
595 END_CONSTRAINT
596 /** @endcond */
597 
598