1 /**
2  * @cond doxygenLibsbmlInternal
3  *
4  * @file    LambdaMathCheck.cpp
5  * @brief   Ensures a lambda function is not used outside a functionDefinition.
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 "LambdaMathCheck.h"
60 
61 /** @cond doxygenIgnored */
62 using namespace std;
63 /** @endcond */
64 
65 LIBSBML_CPP_NAMESPACE_BEGIN
66 
67 static const char* PREAMBLE =
68     "MathML 'lambda' elements are only permitted as the first element inside "
69     "the 'math' element of a <functionDefinition> or as the first element "
70     "of a semantics element immediately inside inside the math element "
71     "of a <functionDefinition>; they may not be used "
72     "elsewhere in an SBML model. (References: L2V2 Section 4.3.2.)";
73 
74 
75 /*
76  * Creates a new Constraint with the given @p id.
77  */
LambdaMathCheck(unsigned int id,Validator & v)78 LambdaMathCheck::LambdaMathCheck (unsigned int id, Validator& v) : MathMLBase(id, v)
79 {
80 }
81 
82 
83 /*
84  * Destroys this Constraint.
85  */
~LambdaMathCheck()86 LambdaMathCheck::~LambdaMathCheck ()
87 {
88 }
89 
90 
91 /*
92  * @return the preamble to use when logging constraint violations.
93  */
94 const char*
getPreamble()95 LambdaMathCheck::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 LambdaMathCheck::checkMath (const Model& m, const ASTNode& node, const SBase & sb)
109 {
110 
111   ASTNodeType_t type = node.getType();
112 
113   /* a lambda function outside a functionDefinition is a conflict */
114   switch (type)
115   {
116     case AST_LAMBDA:
117 
118       logMathConflict(node, sb);
119       break;
120 
121     default:
122 
123       checkChildren(m, node, sb);
124       break;
125 
126   }
127 }
128 
129 
130 /*
131  * @return the error message to use when logging constraint violations.
132  * This method is called by logFailure.
133  *
134  * Returns a message that the given @p id and its corresponding object are
135  * in  conflict with an object previously defined.
136  */
137 const string
getMessage(const ASTNode & node,const SBase & object)138 LambdaMathCheck::getMessage (const ASTNode& node, const SBase& object)
139 {
140 
141   ostringstream oss_msg;
142 
143   //oss_msg << getPreamble();
144   char * formula = SBML_formulaToString(&node);
145   oss_msg << "The formula '" << formula;
146   oss_msg << "' in the " << getFieldname() << " element of the <" << object.getElementName();
147   oss_msg << "> ";
148   switch(object.getTypeCode()) {
149   case SBML_INITIAL_ASSIGNMENT:
150   case SBML_EVENT_ASSIGNMENT:
151   case SBML_ASSIGNMENT_RULE:
152   case SBML_RATE_RULE:
153     //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
154     break;
155   default:
156     if (object.isSetId()) {
157       oss_msg << "with id '" << object.getId() << "' ";
158     }
159     break;
160   }
161   oss_msg << "uses a lambda function.";
162   safe_free(formula);
163 
164   return oss_msg.str();
165 }
166 
167 LIBSBML_CPP_NAMESPACE_END
168 /** @endcond */
169 
170