2 * SMT-RAT - Satisfiability-Modulo-Theories Real Algebra Toolbox
3 * Copyright (C) 2012 Florian Corzilius, Ulrich Loup, Erika Abraham, Sebastian Junges
5 * This file is part of SMT-RAT.
7 * SMT-RAT is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * SMT-RAT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with SMT-RAT. If not, see <http://www.gnu.org/licenses/>.
23 * @author Andreas Krueger <andreas.krueger@rwth-aachen.de>
24 * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
27 * Created on 2015-02-05.
33 #include <carl-formula/model/Assignment.h>
34 #include <carl-formula/formula/functions/Complexity.h>
36 //#define DEBUG_BVMODULE
44 template<class Settings>
45 BVModule<Settings>::BVModule( const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager ):
46 Module( _formula, _conditionals, _manager ),
47 mModelComputed( true ),
50 mPositionInFormulasToBlast(),
58 template<class Settings>
59 BVModule<Settings>::~BVModule()
63 template<class Settings>
64 bool BVModule<Settings>::informCore( const FormulaT& /* _constraint */ )
69 template<class Settings>
70 void BVModule<Settings>::init()
73 template<class Settings>
74 bool BVModule<Settings>::addCore( ModuleInput::const_iterator _subformula )
76 if( _subformula->formula().is_true() )
78 mModelComputed = false;
79 if( _subformula->formula().is_false() )
81 receivedFormulasAsInfeasibleSubset( _subformula );
84 if( Settings::incremental_flattening )
86 auto sortKey = std::make_pair( evaluateBVFormula(_subformula->formula()), _subformula->formula().id() );
88 std::cout << std::endl << std::endl << "add formula" << std::endl;
89 std::cout << _subformula->formula() << std::endl;
90 std::cout << "Evaluation: " << sortKey << std::endl;
92 auto ret = mFormulasToBlast.insert( std::make_pair(sortKey, _subformula->formula() ) );
94 assert( mPositionInFormulasToBlast.find( _subformula->formula() ) == mPositionInFormulasToBlast.end() );
95 mPositionInFormulasToBlast[_subformula->formula()] = ret.first;
100 template<class Settings>
101 void BVModule<Settings>::removeCore( ModuleInput::const_iterator _subformula )
103 if( Settings::incremental_flattening )
105 auto iterA = mBlastedFormulas.find( _subformula->formula() );
106 if( iterA != mBlastedFormulas.end() )
108 #ifdef DEBUG_BVMODULE
109 std::cout << std::endl << std::endl << "remove formula" << std::endl;
110 std::cout << _subformula->formula() << std::endl;
112 mBlastedFormulas.erase( iterA );
116 #ifdef DEBUG_BVMODULE
117 std::cout << std::endl << std::endl << "remove formula" << std::endl;
118 std::cout << _subformula->formula() << std::endl;
120 auto iterB = mPositionInFormulasToBlast.find( _subformula->formula() );
121 assert( iterB != mPositionInFormulasToBlast.end() );
122 mFormulasToBlast.erase( iterB->second );
123 mPositionInFormulasToBlast.erase( iterB );
128 template<class Settings>
129 void BVModule<Settings>::updateModel() const
131 if( solverState() != SAT )
133 if( !Settings::incremental_flattening || !mModelComputed )
135 transferBackendModel();
137 if( Settings::incremental_flattening && !mModelComputed )
138 mModelComputed = true;
142 template<class Settings>
143 void BVModule<Settings>::transferBackendModel() const
146 const Model& bModel = backendsModel();
147 // Build bitvector values from the values of the single bits
148 auto& blastings = mEncoder.bitvectorBlastings();
150 for(auto const & bitvectorToBits : blastings)
152 carl::BVValue composedValue(bitvectorToBits.first.width());
154 for(std::size_t i=0;i<bitvectorToBits.second.size();++i)
156 auto iter = bModel.find( bitvectorToBits.second[i] );
157 assert( iter != bModel.end() );
158 composedValue[i] = iter->second.asBool();
160 mModel.emplace(bitvectorToBits.first, composedValue);
162 if( rReceivedFormula().containsBooleanVariables() )
164 carl::carlVariables bvars;
165 rReceivedFormula().gatherVariables(bvars);
166 auto modelIter = mModel.begin();
167 for( carl::Variable var : bvars )
169 if (var.type() != carl::VariableType::VT_BOOL) continue;
170 auto bmodelIter = bModel.find( var );
171 assert( bmodelIter != bModel.end() );
172 modelIter = mModel.emplace_hint( modelIter, var, bmodelIter->second.asBool() );
175 getDefaultModel( mModel, (FormulaT) rReceivedFormula() );
178 template<class Settings>
179 Answer BVModule<Settings>::checkCore()
181 if( Settings::incremental_flattening )
183 #ifdef DEBUG_BVMODULE
184 std::cout << "Check in BVModule" << std::endl;
186 getDefaultModel( mModel, (FormulaT) rReceivedFormula() );
187 #ifdef DEBUG_BVMODULE
188 std::cout << "initial model:" << std::endl;
189 std::cout << mModel << std::endl << std::endl;
191 if( !mFormulasToBlast.empty() )
193 FormulaT origin = mFormulasToBlast.begin()->second;
194 #ifdef DEBUG_BVMODULE
195 std::cout << std::endl << std::endl << "Take into account: " << std::endl;
196 std::cout << origin << std::endl;
198 const FormulaSetT& formulasToPass = mEncoder.encode( origin );
199 mFormulasToBlast.erase( mFormulasToBlast.begin() );
200 for( const FormulaT& formulaToPass : formulasToPass )
201 addSubformulaToPassedFormula( formulaToPass, origin );
205 #ifdef DEBUG_BVMODULE
206 std::cout << std::endl << "Run backends" << std::endl;
208 Answer backendAnswer = runBackends();
209 #ifdef DEBUG_BVMODULE
210 std::cout << " --> " << backendAnswer << std::endl << std::endl;
212 switch( backendAnswer )
216 getInfeasibleSubsets();
221 transferBackendModel();
222 const Model& currentModel = model();
223 #ifdef DEBUG_BVMODULE
224 std::cout << "current model: " << std::endl;
225 std::cout << currentModel << std::endl;
227 auto iter = mFormulasToBlast.begin();
228 for( ; iter != mFormulasToBlast.end(); ++iter )
230 unsigned tmp = satisfies( currentModel, iter->second );
231 #ifdef DEBUG_BVMODULE
232 std::cout << "currentModel satisfies" << std::endl << iter->second << std::endl << " -> " << tmp << std::endl;
237 #ifdef DEBUG_BVMODULE
238 std::cout << std::endl << std::endl << "Not yet satisfied: " << std::endl;
239 std::cout << iter->second << std::endl;
244 if( iter == mFormulasToBlast.end() )
246 #ifdef DEBUG_BVMODULE
247 std::cout << "All formulas satisfied!" << std::endl;
249 mModelComputed = true;
254 #ifdef DEBUG_BVMODULE
255 std::cout << std::endl << std::endl << "Take into account: " << std::endl;
256 std::cout << iter->second << std::endl;
258 const FormulaSetT& formulasToPass = mEncoder.encode( iter->second );
259 for( const FormulaT& formulaToPass : formulasToPass )
260 addSubformulaToPassedFormula( formulaToPass, iter->second );
261 mPositionInFormulasToBlast.erase( iter->second );
262 mFormulasToBlast.erase( iter );
267 assert( backendAnswer == UNKNOWN );
276 auto receivedSubformula = firstUncheckedReceivedSubformula();
277 while(receivedSubformula != rReceivedFormula().end())
279 const FormulaWithOrigins& fwo = *receivedSubformula;
280 const FormulaT& formula = fwo.formula();
282 const FormulaSetT& formulasToPass = mEncoder.encode(formula);
284 for(const FormulaT& formulaToPass : formulasToPass)
285 addSubformulaToPassedFormula(formulaToPass, formula);
286 ++receivedSubformula;
289 Answer backendAnswer = runBackends();
290 if(backendAnswer == UNSAT)
292 getInfeasibleSubsets();
295 return backendAnswer;
299 template<class Settings>
300 size_t BVModule<Settings>::evaluateBVFormula( const FormulaT& _formula )
302 if( _formula.type() == carl::FormulaType::CONSTRAINT && _formula.constraint().relation() == carl::Relation::EQ )
303 return carl::complexity(_formula);
304 return Settings::equation_preference_weight * carl::complexity(_formula);