SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
CurryModule.tpp
Go to the documentation of this file.
1 /**
2  * @file CurryModule.cpp
3  * @author Henrich Lauko <xlauko@mail.muni.cz>
4  * @author Dominika Krejci <dominika.krejci@rwth-aachen.de>
5  *
6  * @version 2018-11-18
7  * Created on 2018-11-18.
8  */
9 
10 #include "CurryModule.h"
11 
12 #include <carl-formula/uninterpreted/UFInstanceManager.h>
13 
14 namespace smtrat
15 {
16  using carl::overloaded;
17  using carl::fresh_uninterpreted_variable;
18  using carl::newUninterpretedFunction;
19  using carl::newUFInstance;
20  using carl::SortManager;
21 
22  template<class Settings>
23  CurryModule<Settings>::CurryModule(const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager):
24  Module( _formula, _conditionals, _manager )
25  {
26  const std::string sort_name = "__curry_sort";
27  curry_sort = SortManager::getInstance().addSort( sort_name );
28  curry_function = newUninterpretedFunction( "__curry", {curry_sort, curry_sort}, curry_sort );
29  }
30 
31  template<class Settings>
32  CurryModule<Settings>::~CurryModule()
33  {}
34 
35  template<class Settings>
36  bool CurryModule<Settings>::informCore( const FormulaT& /*_constraint*/ )
37  {
38  // Your code.
39  return true; // This should be adapted according to your implementation.
40  }
41 
42  template<class Settings>
43  void CurryModule<Settings>::init()
44  {
45  }
46 
47  template<class Settings>
48  auto CurryModule<Settings>::curry(const FormulaT& formula) noexcept -> FormulaT
49  {
50  assert(formula.type() == carl::UEQ);
51 
52  if (auto res = formula_store.find(formula); res != formula_store.end()) {
53  return res->second;
54  }
55 
56  const auto& ueq = formula.u_equality();
57 
58  auto eq = FormulaT(curry(ueq.lhs()), curry(ueq.rhs()), ueq.negated());
59  formula_store.emplace(formula, eq);
60  return eq;
61  }
62 
63  template<class Settings>
64  auto CurryModule<Settings>::curry(const UTerm& term) noexcept -> UTerm
65  {
66  if (auto res = term_store.find(term); res != term_store.end()) {
67  return res->second;
68  }
69 
70  auto uvar = [&] (const std::string& name) -> UVariable {
71  return UVariable( fresh_uninterpreted_variable(name), curry_sort );
72  };
73 
74  auto res = std::visit(overloaded {
75  [&](const UVariable& var) {
76  return UTerm{uvar(var.variable().name())};
77  },
78  [&](const UFInstance& ufi) {
79  UTerm sub;
80  const auto& fn = ufi.uninterpretedFunction();
81  if ( auto c = constants_store.find(fn); c != constants_store.end()) {
82  sub = c->second;
83  } else {
84  sub = UTerm{uvar(fn.name())};
85  constants_store.emplace(fn, sub);
86  }
87 
88  for (const auto& arg : ufi.args()) {
89  sub = newUFInstance(curry_function, {sub, curry(arg)});
90  }
91  return sub;
92  }
93  }, term.asVariant());
94 
95  term_store.emplace(term, res);
96  return res;
97  }
98 
99  template<class Settings>
100  auto CurryModule<Settings>::flatten(const UTerm& term, std::vector<FormulaT>& flat) noexcept -> UVariable
101  {
102  if ( term.isUVariable() ) {
103  return term.asUVariable();
104  } else {
105  if (auto res = flattened_terms.find(term); res != flattened_terms.end()) {
106  auto& vec = flat_substitution[res->second];
107  std::copy(vec.begin(), vec.end(), std::back_inserter(flat));
108  return res->second;
109  }
110 
111  auto ufi = term.asUFInstance();
112 
113  assert( ufi.args().size() == 2 );
114  std::vector<FormulaT> substitution;
115  auto lhs = flatten(ufi.args()[0], substitution);
116  auto rhs = flatten(ufi.args()[1], substitution);
117 
118  auto fn = newUFInstance(curry_function, {lhs, rhs});
119  auto new_var = UVariable( fresh_uninterpreted_variable(), curry_sort );
120  substitution.emplace_back(fn, new_var, false);
121 
122  std::copy(substitution.begin(), substitution.end(), std::back_inserter(flat));
123 
124  flattened_terms.emplace(term, new_var);
125  flat_substitution[new_var] = std::move(substitution);
126  return new_var;
127  }
128  }
129 
130  template<class Settings>
131  auto CurryModule<Settings>::flatten(const FormulaT& formula) noexcept -> const std::vector<FormulaT>&
132  {
133  assert(formula.type() == carl::UEQ);
134  if (auto res = flattened_store.find(formula); res != flattened_store.end()) {
135  return res->second;
136  }
137 
138  const auto& ueq = formula.u_equality();
139 
140  std::vector<FormulaT> substitution;
141  auto lhs = flatten(ueq.lhs(), substitution);
142  auto rhs = flatten(ueq.rhs(), substitution);
143  substitution.emplace_back(lhs, rhs, ueq.negated());
144 
145  flattened_store[formula] = std::move(substitution);
146  return flattened_store[formula];
147  }
148 
149  template<class Settings>
150  bool CurryModule<Settings>::addCore( ModuleInput::const_iterator _subformula )
151  {
152  auto curryfied = carl::visit_result( _subformula->formula(), [&] (const auto& formula) {
153  if (formula.type() == carl::UEQ)
154  return curry(formula);
155  else
156  return formula;
157  } );
158 
159  auto flattened = carl::visit_result( curryfied, [&] (const auto& formula) {
160  if (formula.type() == carl::UEQ)
161  return FormulaT(carl::FormulaType::AND, flatten(formula));
162  else
163  return formula;
164  } );
165 
166  addSubformulaToPassedFormula(flattened, _subformula->formula());
167  return true;
168  }
169 
170  template<class Settings>
171  void CurryModule<Settings>::removeCore( ModuleInput::const_iterator /*_subformula*/ )
172  {
173  }
174 
175  template<class Settings>
176  void CurryModule<Settings>::updateModel() const
177  {
178  mModel.clear();
179  if( solverState() == Answer::SAT )
180  {
181  // Your code.
182  }
183  }
184 
185  template<class Settings>
186  Answer CurryModule<Settings>::checkCore()
187  {
188  auto result = runBackends();
189  if (result == Answer::SAT) {
190  getBackendsModel();
191  }
192 
193  if (result == Answer::UNSAT) {
194  getInfeasibleSubsets();
195  }
196 
197  return result;
198  }
199 }
200 
201