MicroModelicaCCompiler  4.5.3
equation.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  This file is part of QSS Solver.
4 
5  QSS Solver is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  QSS Solver is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QSS Solver. If not, see <http://www.gnu.org/licenses/>.
17 
18  ******************************************************************************/
19 
20 #include "equation.hpp"
21 
22 #include <boost/optional/optional_io.hpp>
23 #include <sstream>
24 
25 #include <ast/ast_builder.hpp>
26 #include <ast/equation.hpp>
27 #include <ast/expression.hpp>
28 #include <ast/parser/parse.hpp>
29 #include <ir/alg_usage.hpp>
30 #include <ir/derivative.hpp>
31 #include <ir/equation_printer.hpp>
32 #include <ir/helpers.hpp>
33 #include <util/error.hpp>
34 #include <util/model_config.hpp>
35 #include <util/util.hpp>
36 #include <util/visitors/algebraics.hpp>
37 #include <util/visitors/called_functions.hpp>
38 #include <util/visitors/get_index_variables.hpp>
39 #include <util/visitors/is_recursive_def.hpp>
40 #include <util/visitors/replace_der.hpp>
41 #include <util/visitors/revert_index.hpp>
42 
43 namespace MicroModelica {
44 using namespace Util;
45 using namespace Deps;
46 namespace IR {
47 
49  : _eq(nullptr),
50  _lhs(),
51  _rhs(),
52  _range(),
53  _autonomous(true),
54  _type(EQUATION::QSSDerivative),
55  _id(0),
56  _offset(0),
57  _lhs_exp(),
58  _usage(),
59  _alg_code()
60 {
61 }
62 
63 Equation::Equation(AST_Expression lhs, AST_Expression rhs, Option<Range> range, EQUATION::Type type, int id)
64  : _eq(), _lhs(), _rhs(), _range(range), _autonomous(true), _type(type), _id(id), _offset(0), _lhs_exp(), _usage(), _alg_code()
65 {
66  initialize(lhs, rhs);
67 }
68 
69 Equation::Equation(AST_Expression eq, Option<Range> range, EQUATION::Type type, int id, int offset)
70  : _eq(), _lhs(), _rhs(), _range(range), _autonomous(true), _type(type), _id(id), _offset(offset), _lhs_exp(), _usage(), _alg_code()
71 {
72  initialize(eq);
73 }
74 
75 Equation::Equation(AST_Equation eq, EQUATION::Type type, int id)
76  : _eq(eq), _lhs(), _rhs(), _range(), _autonomous(true), _type(type), _id(id), _offset(0), _lhs_exp(), _usage(), _alg_code()
77 {
78  initialize(eq);
79 }
80 
81 Equation::Equation(AST_Equation eq, Range r, EQUATION::Type type, int id)
82  : _eq(eq), _lhs(), _rhs(), _range(r), _autonomous(true), _type(type), _id(id), _offset(0), _lhs_exp(), _usage(), _alg_code()
83 {
84  initialize(eq);
85 }
86 
87 Equation::Equation(AST_Equation eq, Option<Range> r, EQUATION::Type type, int id)
88  : _eq(eq), _lhs(), _rhs(), _range(r), _autonomous(true), _type(type), _id(id), _offset(0), _lhs_exp(), _usage(), _alg_code()
89 {
90  initialize(eq);
91 }
92 
93 void Equation::initialize(AST_Expression lhs, AST_Expression rhs)
94 {
95  _lhs = Expression(lhs);
96  _rhs = Expression(rhs);
97  setup();
98 }
99 
100 void Equation::initialize(AST_Expression exp)
101 {
102  string model_variable = EquationVariable::modelVariables(_id, _type);
103  if (_range) {
105  } else {
106  AST_Expression lhs = newAST_Expression_ComponentReferenceExp(newAST_String(model_variable));
107  _lhs = Expression(lhs);
108  }
109  _rhs = Expression(exp);
110  setup();
111 }
112 
113 void Equation::initialize(AST_Equation eq)
114 {
115  AST_Equation_Equality eqe = eq->getAsEquality();
116  if (eqe->left()->expressionType() == EXPDERIVATIVE) {
117  _lhs = Expression(AST_ListFirst(eqe->left()->getAsDerivative()->arguments()));
118  _rhs = Expression(eqe->right());
119  } else if (eqe->left()->expressionType() == EXPCOMPREF) {
120  _lhs = Expression(eqe->left());
121  _rhs = Expression(eqe->right());
122  } else if (eqe->left()->expressionType() == EXPOUTPUT) {
123  AST_Expression_Output eout = eqe->left()->getAsOutput();
124  _lhs = Expression(eout);
125  _rhs = Expression(eqe->right());
126  }
127  setup();
128 }
129 
131 {
132  stringstream buffer;
134  CalledFunctions cf;
135  _calledFunctions = cf.apply(_rhs.expression());
136  if (_range) {
137  buffer << LHSVariable();
138  } else {
139  buffer << _lhs;
140  }
141  _lhs_exp = buffer.str();
142 }
143 
144 string Equation::identifier() const { return getPrinter(*this)->identifier(); }
145 
146 string Equation::applyId() const { return getPrinter(*this)->equationId(); }
147 
149 {
150  if (isDerivative() || isAlgebraic() || isZeroCrossing() || isOutput()) {
151  return _lhs.reference();
152  }
153  return Option<Variable>();
154 }
155 
156 bool Equation::isRecursive() const
157 {
158  if (_lhs.isScalar()) {
159  return false;
160  }
161  Variable var = _lhs.reference().get();
162  IsRecursiveDef is_recursive(var.name());
163  return is_recursive.apply(_rhs.expression());
164 }
165 
166 bool Equation::isValid() const { return _lhs.isValid() && _rhs.isValid(); }
167 
168 std::ostream &operator<<(std::ostream &out, const Equation &e)
169 {
170  out << e.print();
171  return out;
172 }
173 
174 Index Equation::index() const
175 {
176  assert(isValid());
177  Index idx = Index(_lhs);
178  return idx;
179 }
180 
181 bool Equation::isEmpty() const { return _lhs.isEmpty() || _rhs.isEmpty(); }
182 
183 bool Equation::isRHSReference() const { return _rhs.isReference(); }
184 
186 {
187  assert(isValid());
188  Algebraics has_algebraics;
189  return has_algebraics.apply(_rhs.expression());
190 }
191 
192 string Equation::macro() const { return getPrinter(*this)->macro(); }
193 
194 string Equation::print() const { return getPrinter(*this)->print(); }
195 
196 void Equation::setType(EQUATION::Type type) { _type = type; }
197 
199 {
200  VariableUsage alg_usage(_lhs, _rhs, usage);
201  _rhs = alg_usage.rhs();
202  _lhs = alg_usage.lhs();
203  if (usage.isConstant()) {
204  _range = Option<Range>();
205  }
206  setup();
207 }
208 
209 Equation Equation::genAlgEquation(Equation der_eq, Index rhs_usage, Index lhs_usage)
210 {
211  Equation a = *this;
212  a.applyUsage(rhs_usage);
213  if (lhs_usage.isConstant()) {
214  if (!rhs_usage.isConstant()) {
215  Expression new_usage = VariableUsage(der_eq.lhs(), rhs_usage.expression(), lhs_usage).rhs();
216  a.applyUsage(new_usage);
217  }
218  } else {
219  // Compute new LHS.
220  Expression map_usage = rhs_usage.revert().expression();
221  Expression new_usage = VariableUsage(map_usage, lhs_usage.revert()).usage();
222  a.applyUsage(Index(new_usage));
223  }
224  return a;
225 }
226 
227 int Equation::arrayId() const { return _id - 1; }
228 
229 void Equation::setAlgCode(std::string alg_code) { _alg_code = alg_code; }
230 
231 std::string Equation::algCode() const { return _alg_code; }
232 
233 std::multimap<std::string, int> Equation::usedVariables() const
234 {
235  std::multimap<std::string, int> ret = _lhs.usedVariables();
236  std::multimap<std::string, int> ret_rhs = _rhs.usedVariables();
237  ret.insert(ret_rhs.begin(), ret_rhs.end());
238  return ret;
239 }
240 
241 } // namespace IR
242 } // namespace MicroModelica
equation.hpp
MicroModelica::IR::Range
Definition: index.hpp:164
EXPOUTPUT
@ EXPOUTPUT
Definition: ast_types.hpp:182
ast_builder.hpp
MicroModelica::IR::operator<<
std::ostream & operator<<(std::ostream &out, const Equation &e)
Definition: equation.cpp:185
EXPCOMPREF
@ EXPCOMPREF
Definition: ast_types.hpp:165
usage
void usage()
Definition: main.cpp:48
MicroModelica::IR::Equation::isRHSReference
bool isRHSReference() const
Definition: equation.cpp:200
MicroModelica::Util::Variable
Definition: symbol_table.hpp:75
MicroModelica::IR::Expression::reference
Option< Util::Variable > reference() const
Definition: expression.cpp:94
MicroModelica::IR::Equation::macro
std::string macro() const
Definition: equation.cpp:209
MicroModelica::IR::Equation::_lhs
Expression _lhs
Definition: equation.hpp:124
MicroModelica::IR::Equation::LHSVariable
Option< Util::Variable > LHSVariable() const
Definition: equation.cpp:165
MicroModelica::IR::Expression::expression
AST_Expression expression() const
Definition: expression.hpp:87
MicroModelica::IR::VariableUsage
Definition: alg_usage.hpp:63
MicroModelica::IR::getPrinter
EquationPrinter * getPrinter(Equation eq)
Definition: equation_printer.cpp:64
MicroModelica::IR::Equation::genAlgEquation
Equation genAlgEquation(Equation der_eq, Index rhs_usage, Index lhs_usage)
Definition: equation.cpp:226
MicroModelica::IR::Equation::Equation
Equation()
Definition: equation.cpp:65
helpers.hpp
MicroModelica::IR::Expression::autonomous
bool autonomous() const
Definition: expression.cpp:198
Option
Definition: util_types.hpp:32
MicroModelica::IR::Equation::_autonomous
bool _autonomous
Definition: equation.hpp:127
MicroModelica::Util::Variable::name
string name() const
Definition: symbol_table.hpp:127
MicroModelica::IR::EQUATION::Type
Type
Definition: equation.hpp:50
MicroModelica::IR::Equation::_lhs_exp
std::string _lhs_exp
Definition: equation.hpp:132
MicroModelica::IR::VariableUsage::rhs
Expression rhs() const
Definition: alg_usage.cpp:67
MicroModelica::IR::Equation::print
std::string print() const
Definition: equation.cpp:211
MicroModelica::IR::Index::revert
Index revert() const
Definition: index.cpp:169
model_config.hpp
newAST_Expression_ComponentReferenceExp
AST_Expression newAST_Expression_ComponentReferenceExp(AST_String s)
Definition: ast_builder.cpp:198
EXPDERIVATIVE
@ EXPDERIVATIVE
Definition: ast_types.hpp:167
MicroModelica::IR::Expression
Definition: expression.hpp:64
MicroModelica::IR::EquationPrinter::print
virtual std::string print() const
Definition: equation_printer.hpp:57
MicroModelica::IR::Equation::lhs
Expression lhs() const
Definition: equation.hpp:78
MicroModelica::IR::Expression::isValid
bool isValid() const
Definition: expression.hpp:92
MicroModelica::IR::Expression::usedVariables
std::multimap< std::string, int > usedVariables() const
Definition: expression.cpp:192
MicroModelica::IR::Equation::isValid
bool isValid() const
Definition: equation.cpp:183
MicroModelica::IR::Equation::setup
void setup()
Definition: equation.cpp:147
MicroModelica::IR::Equation::isZeroCrossing
bool isZeroCrossing() const
Definition: equation.hpp:94
MicroModelica::IR::Equation
Definition: equation.hpp:67
MicroModelica::IR::VariableUsage::usage
Expression usage() const
Definition: alg_usage.cpp:69
alg_usage.hpp
MicroModelica::IR::Index::isConstant
bool isConstant() const
Definition: index.cpp:134
MicroModelica::IR::Equation::algCode
std::string algCode() const
Definition: equation.cpp:248
MicroModelica::IR::EquationPrinter::equationId
virtual std::string equationId() const
Definition: equation_printer.cpp:109
MicroModelica::IR::Equation::arrayId
int arrayId() const
Definition: equation.cpp:244
MicroModelica::IR::Equation::isRecursive
bool isRecursive() const
Definition: equation.cpp:173
MicroModelica::IR::Equation::_alg_code
std::string _alg_code
Definition: equation.hpp:134
MicroModelica::IR::Equation::usage
Index usage() const
Definition: equation.hpp:104
MicroModelica::IR::Equation::setType
void setType(EQUATION::Type type)
Definition: equation.cpp:213
MicroModelica::IR::Expression::isEmpty
bool isEmpty() const
Definition: expression.hpp:91
AST_ListFirst
T1 AST_ListFirst(list< T1 > *l)
Definition: ast_types.hpp:271
MicroModelica::IR::Equation::_id
int _id
Definition: equation.hpp:130
MicroModelica::IR::EquationPrinter::identifier
std::string identifier() const
Definition: equation_printer.hpp:59
MicroModelica::IR::Equation::isOutput
bool isOutput() const
Definition: equation.hpp:95
MicroModelica::IR::Equation::_calledFunctions
Util::SymbolTable _calledFunctions
Definition: equation.hpp:128
MicroModelica::Util::Utils::variableExpression
IR::Expression variableExpression(string name, Option< IR::Range > range)
Definition: util.cpp:384
MicroModelica::IR::EQUATION::QSSDerivative
@ QSSDerivative
Definition: equation.hpp:50
MicroModelica::IR::Equation::_type
EQUATION::Type _type
Definition: equation.hpp:129
MicroModelica::IR::Index
Definition: index.hpp:92
derivative.hpp
MicroModelica::Generator::MODEL_INSTANCE::Component::Deps
@ Deps
MicroModelica::IR::Equation::identifier
std::string identifier() const
Definition: equation.cpp:161
MicroModelica::IR::Equation::applyUsage
void applyUsage(Index usage)
Definition: equation.cpp:215
MicroModelica::IR::Expression::isScalar
bool isScalar() const
Definition: expression.cpp:73
MicroModelica
Definition: files.cpp:45
MicroModelica::IR::Equation::applyId
std::string applyId() const
Definition: equation.cpp:163
MicroModelica::IR::Equation::_range
Option< Range > _range
Definition: equation.hpp:126
MicroModelica::IR::Equation::index
Index index() const
Definition: equation.cpp:191
MicroModelica::IR::EquationVariable::modelVariables
static std::string modelVariables(int id, EQUATION::Type type)
Definition: equation.hpp:54
equation_printer.hpp
MicroModelica::Util::Utils::instance
static Utils & instance()
Definition: util.hpp:83
MicroModelica::IR::Equation::usedVariables
std::multimap< std::string, int > usedVariables() const
Definition: equation.cpp:250
MicroModelica::IR::EquationPrinter::macro
virtual std::string macro() const
Definition: equation_printer.hpp:58
MicroModelica::IR::Expression::isReference
bool isReference() const
Definition: expression.cpp:86
MicroModelica::IR::Equation::setAlgCode
void setAlgCode(std::string alg_code)
Definition: equation.cpp:246
MicroModelica::IR::Equation::rhs
Expression rhs() const
Definition: equation.hpp:80
MicroModelica::IR::Equation::initialize
void initialize(AST_Equation eq)
Definition: equation.cpp:130
MicroModelica::IR::Equation::isDerivative
bool isDerivative() const
Definition: equation.hpp:90
MicroModelica::IR::Index::expression
Expression expression() const
Definition: index.cpp:126
MicroModelica::IR::Equation::hasAlgebraics
bool hasAlgebraics()
Definition: equation.cpp:202
MicroModelica::IR::Equation::_rhs
Expression _rhs
Definition: equation.hpp:125
MicroModelica::IR::Equation::type
EQUATION::Type type() const
Definition: equation.hpp:89
util.hpp
error.hpp
expression.hpp
MicroModelica::IR::Equation::isAlgebraic
bool isAlgebraic() const
Definition: equation.hpp:96
newAST_String
AST_String newAST_String(string s)
Definition: ast_builder.cpp:57
MicroModelica::IR::Equation::isEmpty
bool isEmpty() const
Definition: equation.cpp:198