SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Uninterpreted.cpp
Go to the documentation of this file.
1 #include "Uninterpreted.h"
2 #include "ParserState.h"
3 #include "../ParserSettings.h"
4 
5 #include <carl-formula/uninterpreted/UFInstanceManager.h>
6 
7 namespace smtrat {
8 namespace parser {
9 namespace uninterpreted {
10 
11  inline bool convertTerm(const types::TermType& term, types::UTerm& result) {
12  if (boost::get<carl::UTerm>(&term) != nullptr) {
13  result = boost::get<carl::UTerm>(term);
14  return true;
15  } else if (boost::get<carl::UVariable>(&term) != nullptr) {
16  result = carl::UTerm(boost::get<carl::UVariable>(term));
17  return true;
18  } else {
19  return false;
20  }
21  }
22 
23  inline bool convertArguments(const std::vector<types::TermType>& arguments, std::vector<types::UTerm>& result, TheoryError& errors) {
24  result.clear();
25  for (std::size_t i = 0; i < arguments.size(); i++) {
26  types::UTerm res;
27  if (!convertTerm(arguments[i], res)) {
28  errors.next() << "Arguments are expected to be uninterpreted, but argument " << (i+1) << " is not: \"" << arguments[i] << "\".";
29  return false;
30  }
31  result.push_back(res);
32  }
33  return true;
34  }
35 }
36 
38  AbstractTheory(state),
39  mBoolSort(carl::SortManager::getInstance().addSort("UF_Bool", carl::VariableType::VT_UNINTERPRETED)),
40  mTrue(carl::fresh_variable("UF_TRUE", carl::VariableType::VT_UNINTERPRETED), mBoolSort),
41  mFalse(carl::fresh_variable("UF_FALSE", carl::VariableType::VT_UNINTERPRETED), mBoolSort)
42  {
43  state->artificialVariables.emplace_back(mTrue);
44  state->artificialVariables.emplace_back(mFalse);
45  }
46 
47  bool UninterpretedTheory::declareVariable(const std::string& name, const carl::Sort& sort, types::VariableType& result, TheoryError& errors) {
48  carl::SortManager& sm = carl::SortManager::getInstance();
49  if (sm.isInterpreted(sort)) {
50  errors.next() << "The request sort is not uninterpreted but \"" << sort << "\".";
51  return false;
52  }
53  assert(state->isSymbolFree(name));
54  carl::Variable v = carl::fresh_variable(name, carl::VariableType::VT_UNINTERPRETED);
55  carl::UVariable uv(v, sort);
56  state->variables[name] = uv;
57  result = uv;
58  return true;
59  }
60 
61  bool UninterpretedTheory::handleITE(const FormulaT& ifterm, const types::TermType& thenterm, const types::TermType& elseterm, types::TermType& result, TheoryError& errors) {
62  types::UTerm thent;
63  types::UTerm elset;
64  if (!uninterpreted::convertTerm(thenterm, thent)) {
65  errors.next() << "Failed to construct ITE, the then-term \"" << thenterm << "\" is unsupported.";
66  return false;
67  }
68  if (!uninterpreted::convertTerm(elseterm, elset)) {
69  errors.next() << "Failed to construct ITE, the else-term \"" << elseterm << "\" is unsupported.";
70  return false;
71  }
72  if (thent.domain() != elset.domain()) {
73  errors.next() << "Failed to construct ITE, the domains of \"" << thent << "\" (" << thent.domain() << ") and \"" << elset << "\" (" << elset.domain() << ") are different.";
74  return false;
75  }
76 
77  carl::Variable var = carl::fresh_uninterpreted_variable();
78  state->artificialVariables.emplace_back(var);
79  carl::UVariable uvar(var, thent.domain());
80  state->auxiliary_variables.insert(uvar);
81 
82 
83  FormulaT consThen(carl::UEquality(carl::UTerm(uvar), thent, false));
84  FormulaT consElse(carl::UEquality(carl::UTerm(uvar), elset, false));
85 
86  state->global_formulas.emplace_back(FormulaT(carl::FormulaType::IMPLIES, {ifterm, consThen}));
87  state->global_formulas.emplace_back(FormulaT(carl::FormulaType::IMPLIES, {!ifterm, consElse}));
88 
89  result = uvar;
90  return true;
91  }
92 
93  bool UninterpretedTheory::handleFunctionInstantiation(const carl::UninterpretedFunction& f, const std::vector<types::TermType>& arguments, types::TermType& result, TheoryError&) {
94  std::vector<carl::UTerm> vars;
95  for (const auto& v: arguments) {
96  auto it = mInstantiatedArguments.find(v);
97  if (it != mInstantiatedArguments.end()) {
98  vars.push_back(it->second);
99  continue;
100  } else if (const carl::Variable* var = boost::get<carl::Variable>(&v)) {
101  carl::Variable tmp = carl::fresh_uninterpreted_variable();
102  vars.push_back(carl::UTerm(carl::UVariable(tmp, mBoolSort)));
103  state->global_formulas.emplace_back(coupleBooleanVariables(*var, carl::UVariable(tmp, mBoolSort)));
104  } else if (const FormulaT* formula = boost::get<FormulaT>(&v)) {
105  carl::Variable tmp = carl::fresh_boolean_variable();
106  vars.push_back(carl::UTerm(carl::UVariable(tmp)));
107  state->global_formulas.emplace_back(FormulaT(carl::FormulaType::IFF, {FormulaT(tmp), *formula}));
108  } else if (const Poly* p = boost::get<Poly>(&v)) {
109  carl::Variable tmp = carl::fresh_real_variable();
110  vars.push_back(carl::UTerm(carl::UVariable(tmp)));
111  state->global_formulas.emplace_back(FormulaT(*p - Poly(tmp), carl::Relation::EQ));
112  } else if (const carl::UTerm* ut = boost::get<carl::UTerm>(&v)) {
113  if (!settings_parser().disable_uf_flattening && ut->isUFInstance()) { // do flattening
114  carl::Variable tmp = carl::fresh_uninterpreted_variable();
115  vars.emplace_back(carl::UVariable(tmp, ut->asUFInstance().uninterpretedFunction().codomain()));
116  state->global_formulas.emplace_back(FormulaT(carl::UEquality(carl::UTerm(vars.back()), *ut, false)));
117  } else {
118  vars.push_back(*ut);
119  }
120  } else if (const carl::UVariable* uv = boost::get<carl::UVariable>(&v)) {
121  vars.push_back(carl::UTerm(*uv));
122  } else {
123  SMTRAT_LOG_ERROR("smtrat.parser", "The function argument type of " << v << " for function " << f << " was invalid.");
124  continue;
125  }
126  mInstantiatedArguments[v] = vars.back();
127  }
128  carl::UFInstance ufi = carl::newUFInstance(f, vars);
129  carl::SortManager& sm = carl::SortManager::getInstance();
130  if (sm.isInterpreted(f.codomain())) {
131  carl::VariableType type = sm.getType(f.codomain());
132  if (type == carl::VariableType::VT_BOOL) {
133  SMTRAT_LOG_ERROR("smtrat.parser", "Boolan functions should be abstracted to be of sort " << mBoolSort);
134  } else {
135  carl::Variable var = carl::fresh_variable(type);
136  state->global_formulas.emplace_back(FormulaT(carl::UEquality(carl::UVariable(var), ufi, false)));
137  result = var;
138  }
139  } else if (f.codomain() == mBoolSort) {
140  carl::UVariable uvar(carl::fresh_variable(carl::VariableType::VT_UNINTERPRETED), mBoolSort);
141  state->global_formulas.emplace_back(carl::UEquality(carl::UTerm(uvar), carl::UTerm(ufi), false));
143  FormulaT(carl::UEquality(carl::UTerm(uvar), carl::UTerm(mTrue), false)),
144  FormulaT(carl::UEquality(carl::UTerm(uvar), carl::UTerm(mFalse), false))
145  }));
146  result = FormulaT(carl::UEquality(carl::UTerm(uvar), carl::UTerm(mTrue), false));
147  } else {
148  result = carl::UTerm(ufi);
149  }
150  return true;
151  }
152  bool UninterpretedTheory::handleDistinct(const std::vector<types::TermType>& arguments, types::TermType& result, TheoryError& errors) {
153  std::vector<types::UTerm> args;
154  if (!uninterpreted::convertArguments(arguments, args, errors)) return false;
155  result = expandDistinct(args, [](const types::UTerm& a, const types::UTerm& b){
156  return carl::UEquality(a, b, true);
157  });
158  return true;
159  }
160 
161  bool UninterpretedTheory::functionCall(const Identifier& identifier, const std::vector<types::TermType>& arguments, types::TermType& result, TheoryError& errors) {
162  auto fit = state->declared_functions.find(identifier.symbol);
163  if (fit != state->declared_functions.end()) {
164  return handleFunctionInstantiation(fit->second, arguments, result, errors);
165  }
166  if (identifier.symbol == "=") {
167  std::vector<types::UTerm> args;
168  if (!uninterpreted::convertArguments(arguments, args, errors)) return false;
169  FormulasT subformulas;
170  for (std::size_t i = 0; i < args.size() - 1; i++) {
171  subformulas.emplace_back(carl::UEquality(args[i], args[i+1], false));
172  }
173  result = FormulaT(carl::FormulaType::AND, subformulas);
174  return true;
175  }
176  errors.next() << "Invalid operator \"" << identifier << "\".";
177  return false;
178  }
179 
180 }
181 }
void sort(T *array, int size, LessThan lt)
Definition: Sort.h:67
int var(Lit p)
Definition: SolverTypes.h:64
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
bool convertTerm(const types::TermType &term, types::UTerm &result)
bool convertArguments(const std::vector< types::TermType > &arguments, std::vector< types::UTerm > &result, TheoryError &errors)
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::Formulas< Poly > FormulasT
Definition: types.h:39
const auto & settings_parser()
#define SMTRAT_LOG_ERROR(channel, msg)
Definition: logging.h:32
Base class for all theories.
FormulaT expandDistinct(const std::vector< T > &values, const Builder &neqBuilder)
std::string symbol
Definition: Common.h:37
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::set< types::VariableType > auxiliary_variables
Definition: ParserState.h:63
std::vector< smtrat::ModelVariable > artificialVariables
Definition: ParserState.h:72
std::map< std::string, carl::UninterpretedFunction > declared_functions
Definition: ParserState.h:67
TheoryError & next()
Definition: Common.h:25
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.
bool handleDistinct(const std::vector< types::TermType > &, types::TermType &, TheoryError &errors)
Resolve a distinct operator.
bool handleFunctionInstantiation(const carl::UninterpretedFunction &f, const std::vector< types::TermType > &arguments, types::TermType &result, TheoryError &errors)
UninterpretedTheory(ParserState *state)
bool functionCall(const Identifier &identifier, const std::vector< types::TermType > &arguments, types::TermType &result, TheoryError &errors)
Resolve another unknown function call.
std::map< types::TermType, carl::UTerm > mInstantiatedArguments
Definition: Uninterpreted.h:14
bool handleITE(const FormulaT &ifterm, const types::TermType &thenterm, const types::TermType &elseterm, types::TermType &result, TheoryError &errors)
Resolve an if-then-else operator.
FormulaT coupleBooleanVariables(carl::Variable v, carl::UVariable uv)
Definition: Uninterpreted.h:21