1 /**
2 * @cond doxygenLibsbmlInternal
3 *
4 * @file LocalParameterMathCheck.cpp
5 * @brief checks <ci> element of local parameter not used elsewhere
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 #include <sbml/Model.h>
45 #include <sbml/Compartment.h>
46 #include <sbml/Species.h>
47 #include <sbml/Parameter.h>
48 #include <sbml/UnitDefinition.h>
49 #include <sbml/Event.h>
50 #include <sbml/Reaction.h>
51 #include <sbml/EventAssignment.h>
52 #include <sbml/SpeciesReference.h>
53 #include <sbml/Rule.h>
54 #include <sbml/math/FormulaFormatter.h>
55 #include <sbml/SBMLTypeCodes.h>
56
57 #include <sbml/units/UnitFormulaFormatter.h>
58
59 #include "LocalParameterMathCheck.h"
60
61 /** @cond doxygenIgnored */
62 using namespace std;
63 /** @endcond */
64
65 LIBSBML_CPP_NAMESPACE_BEGIN
66 #ifdef __cplusplus
67
68 static const char* PREAMBLE =
69 "The 'id' value of a <parameter> defined within a <kineticLaw> can only "
70 "be used in 'ci' elements within the MathML content of that same "
71 "<kineticLaw>; the identifier is not visible to other parts of the "
72 "model. (References: L2V2 Section 3.5.3.)";
73
74
75 /*
76 * Creates a new Constraint with the given @p id.
77 */
LocalParameterMathCheck(unsigned int id,Validator & v)78 LocalParameterMathCheck::LocalParameterMathCheck (unsigned int id, Validator& v) : MathMLBase(id, v)
79 {
80 }
81
82
83 /*
84 * Destroys this Constraint.
85 */
~LocalParameterMathCheck()86 LocalParameterMathCheck::~LocalParameterMathCheck ()
87 {
88 }
89
90
91 /*
92 * @return the preamble to use when logging constraint violations.
93 */
94 const char*
getPreamble()95 LocalParameterMathCheck::getPreamble ()
96 {
97 return PREAMBLE;
98 }
99
100
101 /*
102 * Checks the MathML of the ASTnode
103 * is appropriate for the function being performed
104 *
105 * If an inconsistency is found, an error message is logged.
106 */
107 void
checkMath(const Model & m,const ASTNode & node,const SBase & sb)108 LocalParameterMathCheck::checkMath (const Model& m, const ASTNode& node, const SBase & sb)
109 {
110
111 ASTNodeType_t type = node.getType();
112
113 /* if the node is a <ci> element it will have type AST_NAME
114 * check that this name is an appropriate component of the model */
115
116 switch (type)
117 {
118 case AST_NAME:
119
120 checkCiElement(m, node, sb);
121 break;
122
123 default:
124
125 checkChildren(m, node, sb);
126 break;
127
128 }
129 }
130
131
132 /*
133 * Checks any <ci> elements in the MathML of the ASTnode
134 * contain the id of an appropriate component of the model
135 *
136 * If an inconsistency is found, an error message is logged.
137 */
138 void
checkCiElement(const Model & m,const ASTNode & node,const SBase & sb)139 LocalParameterMathCheck::checkCiElement (const Model& m,
140 const ASTNode& node,
141 const SBase & sb)
142 {
143 std::string name = node.getName();
144 const KineticLaw * kl;
145
146 if (m.getCompartment(name) == NULL &&
147 m.getSpecies(name) == NULL &&
148 m.getParameter(name) == NULL &&
149 m.getReaction(name) == NULL)
150 {
151 if (m.getLevel() >= 3 || (m.getLevel() == 2 && m.getVersion() == 5))
152 {
153 for (unsigned int rxn = 0; rxn < m.getNumReactions(); rxn++)
154 {
155 const Reaction* reaction = m.getReaction(rxn);
156 for (unsigned int reactant = 0; reactant < reaction->getNumReactants(); reactant++)
157 {
158 if (reaction->getReactant(reactant)->getIdAttribute() == name)
159 {
160 return;
161 }
162 }
163 for (unsigned int product = 0; product < reaction->getNumProducts(); product++)
164 {
165 if (reaction->getProduct(product)->getIdAttribute() == name)
166 {
167 return;
168 }
169 }
170 }
171 }
172
173 /* check whether we are in a kinetic law since there
174 * may be local parameters to this law that are allowed
175 */
176
177 if (sb.getTypeCode() == SBML_KINETIC_LAW)
178 {
179 kl = m.getReaction(mKLCount)->getKineticLaw();
180
181 if (kl->getParameter(name) == NULL && mLocalParameters.contains(name))
182 {
183 logMathConflict(node, sb);
184 }
185 }
186 else if (mLocalParameters.contains(name))
187 {
188 logMathConflict(node, sb);
189 }
190 }
191
192 }
193
194
195 /*
196 * @return the error message to use when logging constraint violations.
197 * This method is called by logFailure.
198 *
199 * Returns a message that the given @p id and its corresponding object are
200 * in conflict with an object previously defined.
201 */
202 const string
getMessage(const ASTNode & node,const SBase & object)203 LocalParameterMathCheck::getMessage (const ASTNode& node, const SBase& object)
204 {
205
206 ostringstream oss_msg;
207
208 //oss_msg << getPreamble();
209
210 oss_msg << "The <" << getFieldname() << "> element of the <" << object.getElementName();
211 oss_msg << "> ";
212 switch(object.getTypeCode()) {
213 case SBML_INITIAL_ASSIGNMENT:
214 case SBML_EVENT_ASSIGNMENT:
215 case SBML_ASSIGNMENT_RULE:
216 case SBML_RATE_RULE:
217 //LS DEBUG: could use other attribute values, or 'isSetActualId'.
218 break;
219 default:
220 if (object.isSetId()) {
221 oss_msg << "with id '" << object.getId() << "' ";
222 }
223 break;
224 }
225 oss_msg << "uses '" << node.getName() << "' that is the id of a local parameter.";
226
227 return oss_msg.str();
228 }
229
230 #endif /* __cplusplus */
231
232 LIBSBML_CPP_NAMESPACE_END
233 /** @endcond */
234
235