1 /**
2 * @cond doxygenLibsbmlInternal
3 *
4 * @file UniqueIdsInModel.cpp
5 * @brief Ensures the appropriate ids within a Model are unique
6 * @author Ben Bornstein
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/ModifierSpeciesReference.h>
46 #include "UniqueIdsInModel.h"
47
48 /** @cond doxygenIgnored */
49 using namespace std;
50 /** @endcond */
51
52 LIBSBML_CPP_NAMESPACE_BEGIN
53
54 static const char* PREAMBLE =
55 "The value of the 'id' field on every instance of the following type of "
56 "object in a model must be unique: <model>, <functionDefinition>, "
57 "<compartmentType>, <compartment>, <speciesType>, <species>, <reaction>, "
58 "<speciesReference>, <modifierSpeciesReference>, <event>, and model-wide "
59 "<parameter>s. Note that <unitDefinition> and parameters defined inside "
60 "a reaction are treated separately. (References: L2V1 Section 3.5; L2V2 "
61 "Section 3.4; L2V3 Section 3.3.)";
62
63
64 /*
65 * Creates a new Constraint with the given constraint id.
66 */
UniqueIdsInModel(unsigned int id,Validator & v)67 UniqueIdsInModel::UniqueIdsInModel (unsigned int id, Validator& v) :
68 UniqueIdBase(id, v)
69 {
70 }
71
72
73 /*
74 * Destroys this Constraint.
75 */
~UniqueIdsInModel()76 UniqueIdsInModel::~UniqueIdsInModel ()
77 {
78 }
79
80
81 /*
82 * @return the preamble to use when logging constraint violations.
83 */
84 const char*
getPreamble()85 UniqueIdsInModel::getPreamble ()
86 {
87 return PREAMBLE;
88 }
89
90
91 /*
92 * Checks that all ids on the following Model objects are unique:
93 * FunctionDefinitions, Species, Compartments, global Parameters,
94 * Reactions, and Events.
95 */
96 void
doCheck(const Model & m)97 UniqueIdsInModel::doCheck (const Model& m)
98 {
99 // from l3v2 all sbase objects may have an id
100 if (m.getLevel() == 3 && m.getVersion() > 1)
101 {
102 doAllIdCheck(m);
103 }
104 else
105 {
106 unsigned int n, size, sr, sr_size;
107
108 checkId( m );
109
110 size = m.getNumFunctionDefinitions();
111 for (n = 0; n < size; ++n) checkId( *m.getFunctionDefinition(n) );
112
113 size = m.getNumCompartments();
114 for (n = 0; n < size; ++n) checkId( *m.getCompartment(n) );
115
116 size = m.getNumSpecies();
117 for (n = 0; n < size; ++n) checkId( *m.getSpecies(n) );
118
119 size = m.getNumParameters();
120 for (n = 0; n < size; ++n) checkId( *m.getParameter(n) );
121
122 size = m.getNumReactions();
123 for (n = 0; n < size; ++n)
124 {
125 checkId( *m.getReaction(n) );
126
127 sr_size = m.getReaction(n)->getNumReactants();
128 for (sr = 0; sr < sr_size; sr++)
129 {
130 checkId(*m.getReaction(n)->getReactant(sr));
131 }
132
133 sr_size = m.getReaction(n)->getNumProducts();
134 for (sr = 0; sr < sr_size; sr++)
135 {
136 checkId(*m.getReaction(n)->getProduct(sr));
137 }
138
139 sr_size = m.getReaction(n)->getNumModifiers();
140 for (sr = 0; sr < sr_size; sr++)
141 {
142 checkId(*m.getReaction(n)->getModifier(sr));
143 }
144
145 }
146
147 size = m.getNumEvents();
148 for (n = 0; n < size; ++n) checkId( *m.getEvent(n) );
149
150 size = m.getNumCompartmentTypes();
151 for (n = 0; n < size; ++n) checkId( *m.getCompartmentType(n) );
152
153 size = m.getNumSpeciesTypes();
154 for (n = 0; n < size; ++n) checkId( *m.getSpeciesType(n) );
155
156 }
157 reset();
158 }
159
160 void
doAllIdCheck(const Model & m)161 UniqueIdsInModel::doAllIdCheck (const Model& m)
162 {
163 unsigned int n, size, j, num;
164
165 /* check any id on the sbml container */
166 doCheckId((SBase&)(*m.getSBMLDocument()));
167
168 doCheckId( m );
169
170 size = m.getNumFunctionDefinitions();
171 doCheckId(*m.getListOfFunctionDefinitions());
172 for (n = 0; n < size; ++n) doCheckId( *m.getFunctionDefinition(n) );
173
174 size = m.getNumUnitDefinitions();
175 doCheckId(*m.getListOfUnitDefinitions());
176 for (n = 0; n < size; ++n)
177 {
178 // unitDefinitions have their own rule
179 const UnitDefinition *ud = m.getUnitDefinition(n);
180 //doCheckId( *ud );
181 num = ud->getNumUnits();
182 doCheckId(*ud->getListOfUnits());
183 for (j = 0; j < num; j++)
184 {
185 doCheckId(*ud->getUnit(j));
186 }
187 }
188
189 size = m.getNumCompartments();
190 doCheckId(*m.getListOfCompartments());
191 for (n = 0; n < size; ++n) doCheckId( *m.getCompartment(n) );
192
193 size = m.getNumSpecies();
194 doCheckId(*m.getListOfSpecies());
195 for (n = 0; n < size; ++n) doCheckId( *m.getSpecies(n) );
196
197 size = m.getNumParameters();
198 doCheckId(*m.getListOfParameters());
199 for (n = 0; n < size; ++n) doCheckId( *m.getParameter(n) );
200
201 size = m.getNumInitialAssignments();
202 doCheckId(*m.getListOfInitialAssignments());
203 for (n = 0; n < size; ++n) doCheckId( *m.getInitialAssignment(n) );
204
205 size = m.getNumRules();
206 doCheckId(*m.getListOfRules());
207 for (n = 0; n < size; ++n) doCheckId( *m.getRule(n) );
208
209 size = m.getNumConstraints();
210 doCheckId(*m.getListOfConstraints());
211 for (n = 0; n < size; ++n) doCheckId( *m.getConstraint(n) );
212
213 size = m.getNumReactions();
214 doCheckId(*m.getListOfReactions());
215 for (n = 0; n < size; ++n)
216 {
217 const Reaction *r = m.getReaction(n);
218 doCheckId( *r );
219
220 if (r->isSetKineticLaw())
221 {
222 doCheckId(*r->getKineticLaw());
223 // local parameters do not apply
224 num = r->getKineticLaw()->getNumParameters();
225 doCheckId(*r->getKineticLaw()->getListOfParameters());
226 //for (j = 0; j < num; j++)
227 //{
228 // doCheckId(*r->getKineticLaw()->getParameter(j));
229 //}
230 }
231
232 num = r->getNumReactants();
233 doCheckId(*r->getListOfReactants());
234 for (j = 0; j < num; j++)
235 {
236 doCheckId(*r->getReactant(j));
237 }
238
239 num = r->getNumProducts();
240 doCheckId(*r->getListOfProducts());
241 for (j = 0; j < num; j++)
242 {
243 doCheckId(*r->getProduct(j));
244 }
245
246 num = r->getNumModifiers();
247 doCheckId(*r->getListOfModifiers());
248 for (j = 0; j < num; j++)
249 {
250 doCheckId(*r->getModifier(j));
251 }
252 }
253 size = m.getNumEvents();
254 doCheckId(*m.getListOfEvents());
255 for (n = 0; n < size; ++n)
256 {
257 const Event *e = m.getEvent(n);
258 doCheckId( *e );
259
260 if (e->isSetTrigger())
261 {
262 doCheckId( *e->getTrigger());
263 }
264
265 if (e->isSetDelay())
266 {
267 doCheckId( *e->getDelay());
268 }
269
270 if (e->isSetPriority())
271 {
272 doCheckId( *e->getPriority());
273 }
274
275 num = e->getNumEventAssignments();
276 doCheckId(*e->getListOfEventAssignments());
277 for (j = 0; j < num; j++)
278 {
279 doCheckId(*e->getEventAssignment(j));
280 }
281 }
282
283 }
284
285 LIBSBML_CPP_NAMESPACE_END
286 /** @endcond */
287