SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Arithmetic.cpp
Go to the documentation of this file.
1 #include "Arithmetic.h"
2 #include "ParserState.h"
3 #include <carl-arith/core/Variable.h>
4 #include <smtrat-common/types.h>
5 
6 namespace smtrat {
7 namespace parser {
8 inline bool ArithmeticTheory::convertTerm(const types::TermType& term, Poly& result, bool allow_bool) {
9  if (boost::get<Poly>(&term) != nullptr) {
10  result = boost::get<Poly>(term);
11  return true;
12  } else if (boost::get<Rational>(&term) != nullptr) {
13  result = Poly(boost::get<Rational>(term));
14  return true;
15  } else if (boost::get<carl::Variable>(&term) != nullptr) {
16  switch (boost::get<carl::Variable>(term).type()) {
17  case carl::VariableType::VT_REAL:
18  case carl::VariableType::VT_INT:
19  result = Poly(boost::get<carl::Variable>(term));
20  return true;
21  case carl::VariableType::VT_BOOL:
22  if (allow_bool) {
23  result = Poly(boost::get<carl::Variable>(term));
24  return true;
25  }
26  return false;
27  default:
28  return false;
29  }
30  } else if (allow_bool && boost::get<FormulaT>(&term) != nullptr) {
31  FormulaT formula = boost::get<FormulaT>(term);
32  const auto& mappedFormulaIt = mappedFormulas.find(formula);
33 
34  if (mappedFormulaIt != mappedFormulas.end()) {
35  carl::Variable var = mappedFormulaIt->second;
36  result = Poly(var);
37  } else {
38  carl::Variable var = carl::fresh_boolean_variable();
40 
41  state->global_formulas.emplace_back(subst);
42  mappedFormulas[formula] = var;
43 
44  result = Poly(var);
45  }
46 
47  return true;
48  } else {
49  return false;
50  }
51 }
52 
53 inline bool ArithmeticTheory::convertArguments(const arithmetic::OperatorType& op, const std::vector<types::TermType>& arguments, std::vector<Poly>& result, TheoryError& errors) {
54  SMTRAT_LOG_DEBUG("smtrat.parser", "Converting arguments: " << arguments << " for operator " << op);
55  result.clear();
56  for (std::size_t i = 0; i < arguments.size(); i++) {
57  Poly res;
58  if (!convertTerm(arguments[i], res, state->logic == carl::Logic::QF_PB)) {
59  errors.next() << "Operator \"" << op << "\" expects arguments to be polynomials, but argument " << (i + 1) << " is not: \"" << arguments[i] << "\".";
60  return false;
61  }
62  result.push_back(res);
63  }
64  return true;
65 }
66 
67 namespace arithmetic {
68 inline FormulaT makeConstraint(ArithmeticTheory& at, const Poly& lhs, const Poly& rhs, carl::Relation rel) {
69  Poly p = lhs - rhs;
70  carl::carlVariables pVars;
71  carl::variables(p, pVars);
72  std::vector<carl::Variable> vars;
73  while (!pVars.empty()) {
74  auto it = at.mITEs.find(*pVars.begin());
75  pVars.erase(*pVars.begin());
76  if (it != at.mITEs.end()) {
77  carl::variables(std::get<1>(it->second), pVars);
78  carl::variables(std::get<2>(it->second), pVars);
79  vars.push_back(it->first);
80  }
81  }
82  std::size_t n = vars.size();
83  if (n == 0) {
84  // There are no ITEs.
85  ConstraintT cons = ConstraintT(p, rel);
86  return FormulaT(cons);
87  } else if (n < 1) {
88  // There are only a few ITEs, hence we expand them here directly to 2^n cases.
89  // 2^n Polynomials with values substituted.
90  std::vector<Poly> polys({p});
91  // 2^n Formulas collecting the conditions.
92  std::vector<FormulasT> conds(1 << n);
93  unsigned repeat = 1 << (n - 1);
94  for (auto v : vars) {
95  auto t = at.mITEs[v];
96  std::vector<Poly> ptmp;
97  for (auto& p : polys) {
98  // Substitute both possibilities for this ITE.
99  ptmp.push_back(carl::substitute(p, v, std::get<1>(t)));
100  ptmp.push_back(carl::substitute(p, v, std::get<2>(t)));
101  }
102  std::swap(polys, ptmp);
103  // Add the conditions at the appropriate positions.
104  FormulaT f[2] = {std::get<0>(t), FormulaT(carl::FormulaType::NOT, std::get<0>(t))};
105  for (size_t i = 0; i < (size_t)(1 << n); i++) {
106  conds[i].push_back(f[0]);
107  if ((i + 1) % repeat == 0) std::swap(f[0], f[1]);
108  }
109  repeat /= 2;
110  }
111  // Now combine everything: (and (=> (and conditions) constraint) ...)
112  FormulasT subs;
113  for (unsigned i = 0; i < polys.size(); i++) {
114  subs.push_back(FormulaT(carl::FormulaType::IMPLIES, {FormulaT(carl::FormulaType::AND, conds[i]), FormulaT(polys[i], rel)}));
115  }
116  auto res = FormulaT(carl::FormulaType::AND, subs);
117 
118  return res;
119  } else {
120  // There are many ITEs, we keep the auxiliary variables.
121  for (const auto& v : vars) {
122  auto t = at.mITEs[v];
123  FormulaT consThen = FormulaT(std::move(Poly(v) - std::get<1>(t)), carl::Relation::EQ);
124  FormulaT consElse = FormulaT(std::move(Poly(v) - std::get<2>(t)), carl::Relation::EQ);
125 
126  at.state->global_formulas.emplace_back(FormulaT(carl::FormulaType::ITE, {std::get<0>(t), consThen, consElse}));
127  // state->global_formulas.emplace(FormulaT(carl::FormulaType::IMPLIES,std::get<0>(t), consThen));
128  // state->global_formulas.emplace(FormulaT(carl::FormulaType::IMPLIES,FormulaT(carl::FormulaType::NOT,std::get<0>(t)), consElse));
129  }
130  return FormulaT(p, rel);
131  }
132 }
133 
134 inline bool isBooleanIdentity(const OperatorType& op, const std::vector<types::TermType>& arguments, TheoryError& errors) {
135  if (boost::get<carl::Relation>(&op) == nullptr) return false;
136  if (boost::get<carl::Relation>(op) != carl::Relation::EQ) return false;
137  for (const auto& a : arguments) {
138  if (boost::get<carl::Variable>(&a) != nullptr) {
139  if (boost::get<carl::Variable>(a).type() != carl::VariableType::VT_BOOL) return false;
140  } else if (boost::get<FormulaT>(&a) == nullptr) {
141  return false;
142  }
143  }
144  errors.next() << "Operator \"" << op << "\" only has boolean variables which is handled by the core theory.";
145  return true;
146 }
147 } // namespace arithmetic
149  bool operator()(const std::vector<types::TermType>& arguments, types::TermType& result, TheoryError& errors) const {
150  if (arguments.size() != 1) {
151  errors.next() << "to_real should have a single argument";
152  return false;
153  }
154  result = arguments[0];
155  return true;
156  }
157 };
158 
159 void ArithmeticTheory::addSimpleSorts(qi::symbols<char, carl::Sort>& sorts) {
160  carl::SortManager& sm = carl::SortManager::getInstance();
161  sorts.add("Int", sm.getInterpreted(carl::VariableType::VT_INT));
162  sorts.add("Real", sm.getInterpreted(carl::VariableType::VT_REAL));
163 }
164 
166  : AbstractTheory(state) {
167  carl::SortManager& sm = carl::SortManager::getInstance();
168  sm.addInterpretedSort("Int", carl::VariableType::VT_INT);
169  sm.addInterpretedSort("Real", carl::VariableType::VT_REAL);
170 
171  state->registerFunction("to_real", new ToRealInstantiator());
172 
173  ops.emplace("+", arithmetic::OperatorType(Poly::ConstructorOperation::ADD));
174  ops.emplace("-", arithmetic::OperatorType(Poly::ConstructorOperation::SUB));
175  ops.emplace("*", arithmetic::OperatorType(Poly::ConstructorOperation::MUL));
176  ops.emplace("/", arithmetic::OperatorType(Poly::ConstructorOperation::DIV));
177  ops.emplace("<", arithmetic::OperatorType(carl::Relation::LESS));
178  ops.emplace("<=", arithmetic::OperatorType(carl::Relation::LEQ));
180  ops.emplace("!=", arithmetic::OperatorType(carl::Relation::NEQ));
181  ops.emplace("<>", arithmetic::OperatorType(carl::Relation::NEQ));
182  ops.emplace(">=", arithmetic::OperatorType(carl::Relation::GEQ));
183  ops.emplace(">", arithmetic::OperatorType(carl::Relation::GREATER));
184 }
185 
186 bool ArithmeticTheory::declareVariable(const std::string& name, const carl::Sort& sort, types::VariableType& result, TheoryError& errors) {
187  carl::SortManager& sm = carl::SortManager::getInstance();
188  switch (sm.getType(sort)) {
189  case carl::VariableType::VT_INT:
190  case carl::VariableType::VT_REAL: {
191  assert(state->isSymbolFree(name));
192  carl::Variable var = carl::fresh_variable(name, sm.getType(sort));
193  state->variables[name] = var;
194  result = var;
195  return true;
196  }
197  default:
198  errors.next() << "The requested sort was neither \"Int\" nor \"Real\" but \"" << sort << "\".";
199  return false;
200  }
201 }
202 
203 bool ArithmeticTheory::handleITE(const FormulaT& ifterm, const types::TermType& thenterm, const types::TermType& elseterm, types::TermType& result, TheoryError& errors) {
204  Poly thenpoly;
205  Poly elsepoly;
206  if (!convertTerm(thenterm, thenpoly)) {
207  errors.next() << "Failed to construct ITE, the then-term \"" << thenterm << "\" is unsupported.";
208  return false;
209  }
210  if (!convertTerm(elseterm, elsepoly)) {
211  errors.next() << "Failed to construct ITE, the else-term \"" << elseterm << "\" is unsupported.";
212  return false;
213  }
214  if (thenpoly == elsepoly) {
215  result = thenpoly;
216  return true;
217  }
218  if (ifterm.type() == carl::FormulaType::CONSTRAINT) {
219  if (ifterm.constraint().relation() == carl::Relation::EQ) {
220  if (ifterm.constraint() == ConstraintT(thenpoly - elsepoly, carl::Relation::EQ)) {
221  result = elsepoly;
222  return true;
223  }
224  } else if (ifterm.constraint().relation() == carl::Relation::NEQ) {
225  if (ifterm.constraint() == ConstraintT(thenpoly - elsepoly, carl::Relation::NEQ)) {
226  result = thenpoly;
227  return true;
228  }
229  }
230  } else if (ifterm.type() == carl::FormulaType::NOT && ifterm.subformula().type() == carl::FormulaType::CONSTRAINT) {
231  if (ifterm.subformula().constraint().relation() == carl::Relation::EQ) {
232  if (ifterm.subformula().constraint() == ConstraintT(thenpoly - elsepoly, carl::Relation::EQ)) {
233  result = thenpoly;
234  return true;
235  }
236  } else if (ifterm.subformula().constraint().relation() == carl::Relation::NEQ) {
237  if (ifterm.subformula().constraint() == ConstraintT(thenpoly - elsepoly, carl::Relation::NEQ)) {
238  result = elsepoly;
239  return true;
240  }
241  }
242  }
243  carl::Variable auxVar = /*thenpoly.integer_valued() && elsepoly.integer_valued() ? carl::fresh_integer_variable() :*/ carl::fresh_real_variable();
244  state->artificialVariables.emplace_back(auxVar);
245  mITEs[auxVar] = std::make_tuple(ifterm, thenpoly, elsepoly);
246  result = Poly(auxVar);
247  return true;
248 }
249 bool ArithmeticTheory::handleDistinct(const std::vector<types::TermType>& arguments, types::TermType& result, TheoryError& errors) {
250  std::vector<Poly> args;
252  if (!c(arguments, args, errors)) return false;
253  result = expandDistinct(args, [](const Poly& a, const Poly& b) {
254  return FormulaT(a - b, carl::Relation::NEQ);
255  });
256  return true;
257 }
258 
260  carl::Variable v;
262  if (!c(var, v)) {
263  errors.next() << "The variable is not an arithmetic variable.";
264  return false;
265  }
266  if ((v.type() != carl::VariableType::VT_INT) && (v.type() != carl::VariableType::VT_REAL)) {
267  errors.next() << "Sort is neither \"Int\" nor \"Real\" but \"" << v.type() << "\".";
268  return false;
269  }
270  Poly repl;
271  if (!convertTerm(replacement, repl)) {
272  errors.next() << "Could not convert argument \"" << replacement << "\" to an arithmetic expression.";
273  return false;
274  }
276  return instantiator.instantiate(v, repl, result);
277 }
278 
279 bool ArithmeticTheory::functionCall(const Identifier& identifier, const std::vector<types::TermType>& arguments, types::TermType& result, TheoryError& errors) {
280  SMTRAT_LOG_DEBUG("smtrat.parser", "Function call " << identifier.symbol << " with arguments " << arguments);
281  std::vector<Poly> args;
282  if (identifier.symbol == "to_int") {
283  if (arguments.size() != 1) {
284  errors.next() << "to_int should have a single argument";
285  return false;
286  }
288  carl::Variable arg;
289  if (!c(arguments[0], arg)) {
290  errors.next() << "to_int should be called with a variable";
291  return false;
292  }
293  carl::Variable v = carl::fresh_variable(carl::VariableType::VT_INT);
294  FormulaT lower(Poly(v) - arg, carl::Relation::LEQ);
295  FormulaT greater(Poly(v) - arg - Rational(1), carl::Relation::GREATER);
296  state->global_formulas.emplace_back(FormulaT(carl::FormulaType::AND, {lower, greater}));
297  result = v;
298  return true;
299  }
300  if (identifier.symbol == "mod") {
301  if (arguments.size() != 2) {
302  errors.next() << "mod should have exactly two arguments.";
303  return false;
304  }
306  Rational modulus;
307  if (!ci(arguments[1], modulus)) {
308  errors.next() << "mod should be called with an integer as second argument.";
309  return false;
310  }
312  carl::Variable arg;
313  Rational rarg;
314  if (cv(arguments[0], arg)) {
315  carl::Variable v = carl::fresh_variable(carl::VariableType::VT_INT);
316  carl::Variable u = carl::fresh_variable(carl::VariableType::VT_INT);
317  FormulaT relation(Poly(v) - arg + u * modulus, carl::Relation::EQ);
318  FormulaT geq(Poly(v), carl::Relation::GEQ);
319  FormulaT less(Poly(v) - modulus, carl::Relation::LESS);
320  state->global_formulas.emplace_back(FormulaT(carl::FormulaType::AND, {relation, geq, less}));
321  result = v;
322  return true;
323  } else if (ci(arguments[0], rarg)) {
324  Integer lhs = carl::to_int<Integer>(rarg);
325  Integer rhs = carl::to_int<Integer>(modulus);
326  result = carl::mod(lhs, rhs);
327  return true;
328  } else {
329  errors.next() << "mod should be called with a variable as first argument.";
330  return false;
331  }
332  }
333  if (identifier.symbol == "root") {
334  if (arguments.size() != 3) {
335  errors.next() << "root should have exactly three arguments.";
336  return false;
337  }
338  Poly p;
339  if (!convertTerm(arguments[0], p)) {
340  errors.next() << "root should be called with a polynomial as first argument.";
341  return false;
342  }
344  Rational k;
345  if (!ci(arguments[1], k)) {
346  errors.next() << "root should be called with an integer as second argument.";
347  return false;
348  }
350  carl::Variable var;
351  if (!cv(arguments[2], var)) {
352  errors.next() << "root should be called with a variable as third argument.";
353  return false;
354  }
355  result = carl::MultivariateRoot<Poly>(p, carl::to_int<std::size_t>(carl::get_num(k)), var);
356  return true;
357  }
358  auto it = ops.find(identifier.symbol);
359  if (it == ops.end()) {
360  errors.next() << "Invalid operator \"" << identifier << "\".";
361  return false;
362  }
363  arithmetic::OperatorType op = it->second;
364  if (boost::get<carl::Relation>(&op) != nullptr && arguments.size() == 3 && boost::get<FormulaT>(&arguments[0]) != nullptr && boost::get<carl::Variable>(&arguments[1]) != nullptr && boost::get<carl::MultivariateRoot<Poly>>(&arguments[2]) != nullptr) {
365  bool negated = boost::get<FormulaT>(arguments[0]).type() == carl::FormulaType::TRUE;
366  carl::Variable var = boost::get<carl::Variable>(arguments[1]);
367  carl::MultivariateRoot<Poly> root = boost::get<carl::MultivariateRoot<Poly>>(arguments[2]);
368  carl::Relation rel = boost::get<carl::Relation>(op);
369  result = FormulaT(carl::VariableComparison<Poly>(var, root, rel, negated));
370  return true;
371  }
372  if (arithmetic::isBooleanIdentity(op, arguments, errors)) return false;
373  if (!convertArguments(op, arguments, args, errors)) return false;
374 
375  if (boost::get<Poly::ConstructorOperation>(&op) != nullptr) {
376  auto o = boost::get<Poly::ConstructorOperation>(op);
377  if (o == Poly::ConstructorOperation::DIV) {
378  if (args.size() != 2) {
379  errors.next() << "Division needs to have two operands.";
380  return false;
381  }
382  if (carl::is_zero(args[1]) || !args[1].is_number()) {
383  /*
384  Ackermanize division:
385  For each p/q:
386  (q != 0 => div_pq*q = p) == (q = 0 || div_pq*q = p)
387  For each p/q, p'/q'
388  ((p = p' and q = q') => div_pq = div_pq') == (p != p' || q != q' || div_pq = div_pq')
389  */
390 
391  std::stringstream name;
392  name << "div_" << mNewDivisions.size() + mKnownDivisions.size();
393  auto div_var_new = carl::fresh_variable(name.str(), carl::VariableType::VT_REAL);
394  auto p_new = Poly(args[0]);
395  auto q_new = Poly(args[1]);
396 
397  //(q != 0 => div_pq*q = p) == (q = 0 || div_pq*q = p)
398  // const FormulaT lhs_s = FormulaT(ConstraintT(q_new, carl::Relation::NEQ));
399  // const FormulaT rhs_s = FormulaT(ConstraintT(Poly(div_var_new)*q_new - p_new, carl::Relation::EQ));
400  // const FormulaT div_formula(carl::FormulaType::IMPLIES, lhs_s, rhs_s);
401  const FormulaT den_is0 = FormulaT(ConstraintT(q_new, carl::Relation::EQ));
402  const FormulaT div_formula(carl::FormulaType::OR, den_is0, FormulaT(ConstraintT(Poly(div_var_new) * q_new - p_new, carl::Relation::EQ)));
403  SMTRAT_LOG_DEBUG("smtrat.parser", "Adding division formula: " << div_formula);
404  state->global_formulas.emplace_back(div_formula);
405 
406  for (const auto& [div_var_old, div_pair_old] : mKnownDivisions) {
407  // ((p = p' and q = q') => div_pq = div_pq') == (p != p' || q != q' || div_pq = div_pq')
408  const auto& [p_old, q_old] = div_pair_old;
409  // const FormulaT lhs = FormulaT(carl::FormulaType::AND, FormulaT(ConstraintT(p_new - p_old, carl::Relation::EQ)), FormulaT(ConstraintT(q_new - q_old, carl::Relation::EQ)));
410  // const FormulaT rhs = FormulaT(ConstraintT(Poly(div_var_new) - Poly(div_var_old), carl::Relation::EQ));
411  // const FormulaT div_formula_pairwise(carl::FormulaType::IMPLIES, lhs, rhs);
412 
413  const FormulaT p_new_neq_p_old = FormulaT(ConstraintT(p_new - p_old, carl::Relation::NEQ));
414  const FormulaT q_new_neq_q_old = FormulaT(ConstraintT(q_new - q_old, carl::Relation::NEQ));
415  const FormulaT div_eq = FormulaT(ConstraintT(Poly(div_var_new) - Poly(div_var_old), carl::Relation::EQ));
416  const FormulaT div_formula_pairwise(carl::FormulaType::OR, p_new_neq_p_old, q_new_neq_q_old, div_eq);
417 
418  SMTRAT_LOG_DEBUG("smtrat.parser", "Adding division pairwise formula: " << div_formula_pairwise);
419  state->global_formulas.emplace_back(div_formula_pairwise);
420  }
421  mKnownDivisions[div_var_new] = std::make_pair(p_new, q_new);
422 
423  result = Poly(div_var_new);
424  return true;
425  }
426  result = Poly(o, args);
427  return true;
428  } else {
429  result = Poly(o, args);
430  }
431  } else if (boost::get<carl::Relation>(&op) != nullptr) {
432  if (args.size() < 2) {
433  errors.next() << "Operator \"" << boost::get<carl::Relation>(op) << "\" expects at least two operands.";
434  return false;
435  } else if (args.size() == 2) {
436  result = arithmetic::makeConstraint(*this, args[0], args[1], boost::get<carl::Relation>(op));
437  } else {
438  FormulasT constr;
439  for (std::size_t i = 0; i < args.size()-1; i++) {
440  constr.emplace_back(arithmetic::makeConstraint(*this, args[i], args[i+1], boost::get<carl::Relation>(op)));
441  }
442  result = FormulaT(carl::FormulaType::AND, std::move(constr));
443  }
444  } else {
445  errors.next() << "Invalid operator \"" << op << "\".";
446  return false;
447  }
448  return true;
449 }
450 
451 bool ArithmeticTheory::declareQuantifiedTerm(const std::vector<std::pair<std::string, carl::Sort>>& vars, const carl::FormulaType& type, const types::TermType& term, types::TermType& result, smtrat::parser::TheoryError& errors) {
452  SMTRAT_LOG_DEBUG("smtrat.parser", "Declaring quantified term " << term << " with quantification " << type << " and variables " << vars);
453  std::vector<carl::Variable> variables;
454  for (const auto& v : vars) {
455  auto it = state->variables.find(v.first);
456  if (it == state->variables.end()) {
457  errors.next() << "Variable " << v.first << " not declared.";
458  return false;
459  }
460  variables.push_back(boost::get<carl::Variable>(it->second));
461  }
462  result = FormulaT(type, std::move(variables), boost::get<FormulaT>(term));
463  return true;
464 }
465 } // namespace parser
466 } // namespace smtrat
void sort(T *array, int size, LessThan lt)
Definition: Sort.h:67
int var(Lit p)
Definition: SolverTypes.h:64
auto get(const It &it, level)
Numeric mod(const Numeric &_valueA, const Numeric &_valueB)
Calculates the result of the first argument modulo the second argument.
Definition: Numeric.cpp:288
bool substitute(const FormulaT &constr, const carl::Variable var, const carl::vs::Term< Poly > &term, FormulaT &result)
Definition: VSHelper.h:138
bool isBooleanIdentity(const OperatorType &op, const std::vector< types::TermType > &arguments, TheoryError &errors)
Definition: Arithmetic.cpp:134
FormulaT makeConstraint(ArithmeticTheory &at, const Poly &lhs, const Poly &rhs, carl::Relation rel)
Definition: Arithmetic.cpp:68
boost::variant< Poly::ConstructorOperation, carl::Relation > OperatorType
Definition: Arithmetic.h:11
carl::mpl_variant_of< TermTypes >::type TermType
Variant type for all terms.
Definition: TheoryTypes.h:160
carl::mpl_variant_of< VariableTypes >::type VariableType
Variant type for all variables.
Definition: TheoryTypes.h:132
QuantifierType type(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:39
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:43
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::MultivariatePolynomial< Rational > Poly
Definition: types.h:25
carl::Constraint< Poly > ConstraintT
Definition: types.h:29
carl::Formulas< Poly > FormulasT
Definition: types.h:39
mpq_class Rational
Definition: types.h:19
carl::IntegralType< Rational >::type Integer
Definition: types.h:21
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35
Base class for all theories.
FormulaT expandDistinct(const std::vector< T > &values, const Builder &neqBuilder)
Implements the theory of arithmetic, including LRA, LIA, NRA and NIA.
Definition: Arithmetic.h:16
bool handleDistinct(const std::vector< types::TermType > &arguments, types::TermType &result, TheoryError &errors)
Resolve a distinct operator.
Definition: Arithmetic.cpp:249
std::map< carl::Variable, std::tuple< FormulaT, Poly, Poly > > mITEs
Definition: Arithmetic.h:20
bool instantiate(const types::VariableType &var, const types::TermType &replacement, types::TermType &result, TheoryError &errors)
Instantiate a variable within a term.
Definition: Arithmetic.cpp:259
std::map< carl::Variable, std::tuple< Poly, Poly > > mKnownDivisions
Definition: Arithmetic.h:21
bool functionCall(const Identifier &identifier, const std::vector< types::TermType > &arguments, types::TermType &result, TheoryError &errors)
Resolve another unknown function call.
Definition: Arithmetic.cpp:279
std::map< FormulaT, carl::Variable > mappedFormulas
Definition: Arithmetic.h:39
bool convertTerm(const types::TermType &term, Poly &result, bool allow_bool=false)
Definition: Arithmetic.cpp:8
ArithmeticTheory(ParserState *state)
Definition: Arithmetic.cpp:165
bool declareVariable(const std::string &name, const carl::Sort &sort, types::VariableType &result, TheoryError &errors)
Declare a new variable with the given name and the given sort.
Definition: Arithmetic.cpp:186
bool convertArguments(const arithmetic::OperatorType &op, const std::vector< types::TermType > &arguments, std::vector< Poly > &result, TheoryError &errors)
Definition: Arithmetic.cpp:53
std::map< std::string, arithmetic::OperatorType > ops
Definition: Arithmetic.h:19
bool declareQuantifiedTerm(const std::vector< std::pair< std::string, carl::Sort >> &vars, const carl::FormulaType &type, const types::TermType &term, types::TermType &result, TheoryError &errors)
Resolve a quantified term.
Definition: Arithmetic.cpp:451
bool handleITE(const FormulaT &ifterm, const types::TermType &thenterm, const types::TermType &elseterm, types::TermType &result, TheoryError &errors)
Resolve an if-then-else operator.
Definition: Arithmetic.cpp:203
std::map< carl::Variable, std::tuple< Poly, Poly > > mNewDivisions
Definition: Arithmetic.h:22
static void addSimpleSorts(qi::symbols< char, carl::Sort > &sorts)
Definition: Arithmetic.cpp:159
std::string symbol
Definition: Common.h:37
bool instantiate(V v, const T &repl, types::TermType &subject)
void registerFunction(const std::string &name, const FunctionInstantiator *fi)
Definition: ParserState.h:163
bool isSymbolFree(const std::string &name, bool output=true)
Definition: ParserState.h:129
std::map< std::string, types::VariableType > variables
Definition: ParserState.h:66
std::vector< smtrat::ModelVariable > artificialVariables
Definition: ParserState.h:72
TheoryError & next()
Definition: Common.h:25
bool operator()(const std::vector< types::TermType > &arguments, types::TermType &result, TheoryError &errors) const
Definition: Arithmetic.cpp:149
Converts variants to some type using the Converter class.
Definition: Conversions.h:99
Converts a vector of variants to a vector of some type using the Converter class.
Definition: Conversions.h:150