2 * @file CurryModule.cpp
3 * @author Henrich Lauko <xlauko@mail.muni.cz>
4 * @author Dominika Krejci <dominika.krejci@rwth-aachen.de>
7 * Created on 2018-11-18.
10 #include "CurryModule.h"
12 #include <carl-formula/uninterpreted/UFInstanceManager.h>
16 using carl::overloaded;
17 using carl::fresh_uninterpreted_variable;
18 using carl::newUninterpretedFunction;
19 using carl::newUFInstance;
20 using carl::SortManager;
22 template<class Settings>
23 CurryModule<Settings>::CurryModule(const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager):
24 Module( _formula, _conditionals, _manager )
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 );
31 template<class Settings>
32 CurryModule<Settings>::~CurryModule()
35 template<class Settings>
36 bool CurryModule<Settings>::informCore( const FormulaT& /*_constraint*/ )
39 return true; // This should be adapted according to your implementation.
42 template<class Settings>
43 void CurryModule<Settings>::init()
47 template<class Settings>
48 auto CurryModule<Settings>::curry(const FormulaT& formula) noexcept -> FormulaT
50 assert(formula.type() == carl::UEQ);
52 if (auto res = formula_store.find(formula); res != formula_store.end()) {
56 const auto& ueq = formula.u_equality();
58 auto eq = FormulaT(curry(ueq.lhs()), curry(ueq.rhs()), ueq.negated());
59 formula_store.emplace(formula, eq);
63 template<class Settings>
64 auto CurryModule<Settings>::curry(const UTerm& term) noexcept -> UTerm
66 if (auto res = term_store.find(term); res != term_store.end()) {
70 auto uvar = [&] (const std::string& name) -> UVariable {
71 return UVariable( fresh_uninterpreted_variable(name), curry_sort );
74 auto res = std::visit(overloaded {
75 [&](const UVariable& var) {
76 return UTerm{uvar(var.variable().name())};
78 [&](const UFInstance& ufi) {
80 const auto& fn = ufi.uninterpretedFunction();
81 if ( auto c = constants_store.find(fn); c != constants_store.end()) {
84 sub = UTerm{uvar(fn.name())};
85 constants_store.emplace(fn, sub);
88 for (const auto& arg : ufi.args()) {
89 sub = newUFInstance(curry_function, {sub, curry(arg)});
95 term_store.emplace(term, res);
99 template<class Settings>
100 auto CurryModule<Settings>::flatten(const UTerm& term, std::vector<FormulaT>& flat) noexcept -> UVariable
102 if ( term.isUVariable() ) {
103 return term.asUVariable();
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));
111 auto ufi = term.asUFInstance();
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);
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);
122 std::copy(substitution.begin(), substitution.end(), std::back_inserter(flat));
124 flattened_terms.emplace(term, new_var);
125 flat_substitution[new_var] = std::move(substitution);
130 template<class Settings>
131 auto CurryModule<Settings>::flatten(const FormulaT& formula) noexcept -> const std::vector<FormulaT>&
133 assert(formula.type() == carl::UEQ);
134 if (auto res = flattened_store.find(formula); res != flattened_store.end()) {
138 const auto& ueq = formula.u_equality();
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());
145 flattened_store[formula] = std::move(substitution);
146 return flattened_store[formula];
149 template<class Settings>
150 bool CurryModule<Settings>::addCore( ModuleInput::const_iterator _subformula )
152 auto curryfied = carl::visit_result( _subformula->formula(), [&] (const auto& formula) {
153 if (formula.type() == carl::UEQ)
154 return curry(formula);
159 auto flattened = carl::visit_result( curryfied, [&] (const auto& formula) {
160 if (formula.type() == carl::UEQ)
161 return FormulaT(carl::FormulaType::AND, flatten(formula));
166 addSubformulaToPassedFormula(flattened, _subformula->formula());
170 template<class Settings>
171 void CurryModule<Settings>::removeCore( ModuleInput::const_iterator /*_subformula*/ )
175 template<class Settings>
176 void CurryModule<Settings>::updateModel() const
179 if( solverState() == Answer::SAT )
185 template<class Settings>
186 Answer CurryModule<Settings>::checkCore()
188 auto result = runBackends();
189 if (result == Answer::SAT) {
193 if (result == Answer::UNSAT) {
194 getInfeasibleSubsets();