2 * Class to create a state object.
3 * @author Florian Corzilius
8 #include "Assignment.h"
9 #include <carl-formula/uninterpreted/SortValueManager.h>
10 #include <carl-formula/formula/functions/Substitution.h>
15 template<typename Rational, typename Poly>
16 bool getRationalAssignmentsFromModel( const Model<Rational,Poly>& _model, std::map<Variable,Rational>& _rationalAssigns )
19 for( auto ass = _model.begin(); ass != _model.end(); ++ass )
21 if (ass->second.isRational())
23 _rationalAssigns.insert( _rationalAssigns.end(), std::make_pair(ass->first.asVariable(), ass->second.asRational()));
25 else if (ass->second.isSqrtEx())
27 if( ass->second.asSqrtEx().is_constant() && !ass->second.asSqrtEx().has_sqrt() )
29 assert( ass->first.is_variable() );
30 Rational value = ass->second.asSqrtEx().constant_part().constant_part()/ass->second.asSqrtEx().denominator().constant_part();
31 assert( !(ass->first.asVariable().type() == carl::VariableType::VT_INT) || carl::is_integer( value ) );
32 _rationalAssigns.insert( _rationalAssigns.end(), std::make_pair(ass->first.asVariable(), value));
39 else if (ass->second.isRAN())
41 if (ass->second.asRAN().is_numeric())
43 assert( ass->first.is_variable() );
44 _rationalAssigns.insert( _rationalAssigns.end(), std::make_pair(ass->first.asVariable(), ass->second.asRAN().value()) );
51 template<typename Rational, typename Poly>
52 unsigned satisfies( const Model<Rational,Poly>& _assignment, const Formula<Poly>& _formula )
54 std::map<Variable,Rational> rationalAssigns;
55 getRationalAssignmentsFromModel( _assignment, rationalAssigns );
56 std::map<carl::BVVariable, carl::BVTerm> bvAssigns;
57 for( auto& varAndValue : _assignment )
59 if( varAndValue.first.isBVVariable() )
61 assert(varAndValue.second.isBVValue());
62 carl::BVTerm replacement(carl::BVTermType::CONSTANT, varAndValue.second.asBVValue());
63 bvAssigns[varAndValue.first.asBVVariable()] = replacement;
66 return satisfies( _assignment, rationalAssigns, bvAssigns, _formula );
69 template<typename Rational, typename Poly>
70 bool isPartOf( const std::map<Variable,Rational>& _assignment, const Model<Rational,Poly>& _model )
72 auto assIter = _assignment.begin();
73 auto modIter = _model.begin();
74 while( assIter != _assignment.end() && modIter != _model.end() )
76 if( modIter->first < assIter->first )
80 else if( assIter->first < modIter->first )
90 return assIter == _assignment.end();
93 template<typename Rational, typename Poly>
94 SortValue satisfiesUF( const Model<Rational,Poly>& _model, const UFInstance _ufi )
96 auto iter = _model.find( _ufi.uninterpretedFunction() );
97 if( iter == _model.end() )
98 return defaultSortValue(_ufi.uninterpretedFunction().codomain());
99 assert( iter->second.isUFModel() );
100 const UFModel& ufm = iter->second.asUFModel();
101 std::vector<SortValue> inst;
102 for( const carl::UTerm& arg : _ufi.args() )
104 if(arg.isUVariable()) {
105 auto iterB = _model.find( arg.asUVariable() );
106 if( iterB == _model.end() )
107 return defaultSortValue(_ufi.uninterpretedFunction().codomain());
108 assert( iterB->second.isSortValue() );
109 inst.push_back( iterB->second.asSortValue() );
110 } else if(arg.isUFInstance()) {
111 inst.push_back(satisfiesUF(_model, arg.asUFInstance()));
114 SortValue sv = ufm.get( inst );
118 template<typename Rational, typename Poly>
119 unsigned satisfies( const Model<Rational,Poly>& _model, const std::map<Variable,Rational>& _assignment, const std::map<carl::BVVariable, carl::BVTerm>& _bvAssigns, const Formula<Poly>& _formula )
121 assert( isPartOf( _assignment, _model ) );
122 switch( _formula.type() )
124 case carl::FormulaType::TRUE:
128 case carl::FormulaType::FALSE:
132 case carl::FormulaType::BOOL:
134 auto ass = _model.find( _formula.boolean() );
135 return ass == _model.end() ? 2 : (ass->second.asBool() ? 1 : 0);
137 case carl::FormulaType::CONSTRAINT:
139 return satisfied_by(_formula.constraint(), _assignment);
141 case carl::FormulaType::BITVECTOR:
143 Formula<Poly> substituted = carl::substitute(_formula, _bvAssigns);
144 if(substituted.is_true())
146 else if(substituted.is_false())
150 case carl::FormulaType::NOT:
152 switch( satisfies( _model, _assignment, _bvAssigns, _formula.subformula() ) )
162 case carl::FormulaType::OR:
165 for( const Formula<Poly>& subFormula : _formula.subformulas() )
167 switch( satisfies( _model, _assignment, _bvAssigns, subFormula ) )
174 if( result != 2 ) result = 2;
179 case carl::FormulaType::AND:
182 for( const Formula<Poly>& subFormula : _formula.subformulas() )
184 switch( satisfies( _model, _assignment, _bvAssigns, subFormula ) )
191 if( result != 2 ) result = 2;
196 case carl::FormulaType::IMPLIES:
198 unsigned result = satisfies( _model, _assignment, _bvAssigns, _formula.premise() );
199 if( result == 0 ) return 1;
200 switch( satisfies( _model, _assignment, _bvAssigns, _formula.conclusion() ) )
203 return result == 1 ? 0 : 2;
210 case carl::FormulaType::ITE:
212 unsigned result = satisfies( _model, _assignment, _bvAssigns, _formula.condition() );
216 return satisfies( _model, _assignment, _bvAssigns, _formula.second_case() );
218 return satisfies( _model, _assignment, _bvAssigns, _formula.first_case() );
223 case carl::FormulaType::IFF:
225 auto subFormula = _formula.subformulas().begin();
226 unsigned result = satisfies( _model, _assignment, _bvAssigns, *subFormula );
227 bool containsTrue = (result == 1 ? true : false);
228 bool containsFalse = (result == 0 ? true : false);
230 while( subFormula != _formula.subformulas().end() )
232 unsigned resultTmp = satisfies( _model, _assignment, _bvAssigns, *subFormula );
236 containsFalse = true;
244 if( containsFalse && containsTrue )
248 return (result == 2 ? 2 : 1);
250 case carl::FormulaType::XOR:
252 auto subFormula = _formula.subformulas().begin();
253 unsigned result = satisfies( _model, _assignment, _bvAssigns, *subFormula );
254 if( result == 2 ) return 2;
256 while( subFormula != _formula.subformulas().end() )
258 unsigned resultTmp = satisfies( _model, _assignment, _bvAssigns, *subFormula );
259 if( resultTmp == 2 ) return 2;
260 result = resultTmp != result;
265 case carl::FormulaType::EXISTS:
267 ///@todo do something here
270 case carl::FormulaType::FORALL:
272 ///@todo do something here
275 case carl::FormulaType::UEQ:
277 const carl::UEquality& eq = _formula.u_equality();
278 std::size_t lhsResult = 0;
279 std::size_t rhsResult = 0;
280 // get sortvalue for lhs and rhs
281 if( eq.lhs().isUVariable() )
283 auto iter = _model.find( eq.lhs().asUVariable() );
284 if( iter == _model.end() )
286 assert( iter->second.isSortValue() );
287 lhsResult = iter->second.asSortValue().id();
291 SortValue sv = satisfiesUF(_model, eq.lhs().asUFInstance());
292 if( sv == defaultSortValue( sv.sort() ) )
296 if( eq.rhs().isUVariable() )
298 auto iter = _model.find( eq.rhs().asUVariable() );
299 if( iter == _model.end() )
301 assert( iter->second.isSortValue() );
302 rhsResult = iter->second.asSortValue().id();
306 SortValue sv = satisfiesUF(_model, eq.rhs().asUFInstance());
307 if( sv == defaultSortValue( sv.sort() ) )
311 // check eq.negated() <=> sv(lhs) != sv(rhs)
312 return eq.negated() ? lhsResult != rhsResult : lhsResult == rhsResult;
317 std::cerr << "Undefined operator!" << std::endl;
323 template<typename Rational, typename Poly>
324 void getDefaultModel( Model<Rational,Poly>& /*_defaultModel*/, const carl::UEquality& /*_constraint*/, bool /*_overwrite*/, size_t /*_seed*/ )
329 template<typename Rational, typename Poly>
330 void getDefaultModel( Model<Rational,Poly>& _defaultModel, const carl::BVTerm& _bvTerm, bool _overwrite, size_t _seed )
332 if( _bvTerm.type() == carl::BVTermType::VARIABLE )
334 auto ass = _defaultModel.find( _bvTerm.variable() );
335 if( ass == _defaultModel.end() )
337 _defaultModel.emplace(_bvTerm.variable(), carl::BVValue(_bvTerm.variable().width()));
341 // TODO: something with the seed
344 else if( carl::typeIsUnary( _bvTerm.type() ) )
345 getDefaultModel( _defaultModel, _bvTerm.operand(), _overwrite, _seed );
346 else if( carl::typeIsBinary( _bvTerm.type() ) )
348 getDefaultModel( _defaultModel, _bvTerm.first(), _overwrite, _seed );
349 getDefaultModel( _defaultModel, _bvTerm.second(), _overwrite, _seed );
351 else if( _bvTerm.type() == carl::BVTermType::EXTRACT )
352 getDefaultModel( _defaultModel, _bvTerm.operand(), _overwrite, _seed );
355 template<typename Rational, typename Poly>
356 void getDefaultModel( Model<Rational,Poly>& _defaultModel, const Constraint<Poly>& _constraint, bool /*_overwrite*/, size_t /*_seed*/ )
358 for( carl::Variable var : variables(_constraint) )
360 auto ass = _defaultModel.find( var );
361 if( ass == _defaultModel.end() )
363 _defaultModel.emplace(var, 0);
367 // TODO: something with the seed
372 template<typename Rational, typename Poly>
373 void getDefaultModel( Model<Rational,Poly>& _defaultModel, const Formula<Poly>& _formula, bool _overwrite, size_t _seed )
375 switch( _formula.type() )
377 case carl::FormulaType::TRUE:
378 case carl::FormulaType::FALSE:
379 case carl::FormulaType::BOOL:
381 auto ass = _defaultModel.find( _formula.boolean() );
382 if( ass == _defaultModel.end() )
384 _defaultModel.emplace(_formula.boolean(), false);
388 // TODO: something with the seed
392 case carl::FormulaType::CONSTRAINT:
393 getDefaultModel( _defaultModel, _formula.constraint(), _overwrite, _seed );
395 case carl::FormulaType::BITVECTOR:
396 getDefaultModel( _defaultModel, _formula.bv_constraint().lhs(), _overwrite, _seed );
397 getDefaultModel( _defaultModel, _formula.bv_constraint().rhs(), _overwrite, _seed );
399 case carl::FormulaType::UEQ:
400 getDefaultModel( _defaultModel, _formula.u_equality(), _overwrite, _seed );
402 case carl::FormulaType::NOT:
403 getDefaultModel( _defaultModel, _formula.subformula(), _overwrite, _seed );
406 assert( _formula.is_nary() );
407 for (const auto& subFormula: _formula.subformulas() )
408 getDefaultModel(_defaultModel, subFormula, _overwrite, _seed);
412 template<typename Rational, typename Poly>
413 Formula<Poly> representingFormula(const ModelVariable& mv, const Model<Rational,Poly>& model) {
414 auto it = model.find(mv);
415 assert(it != model.end());
416 return representingFormula(mv, it->second);
418 template<typename Rational, typename Poly>
419 Formula<Poly> representingFormula(const ModelVariable& mv, const ModelValue<Rational,Poly>& val) {
421 assert(mv.is_variable());
422 if (val.asBool()) return Formula<Poly>(mv.asVariable());
423 else return Formula<Poly>(FormulaType::NOT, Formula<Poly>(mv.asVariable()));
424 } else if (val.isRational()) {
425 assert(mv.is_variable());
426 return Formula<Poly>(VariableAssignment<Poly>(mv.asVariable(), val.asRational()));
427 } else if (val.isSqrtEx()) {
429 } else if (val.isRAN()) {
430 return Formula<Poly>(VariableAssignment<Poly>(mv.asVariable(), val.asRAN()));
431 } else if (val.isBVValue()) {
433 } else if (val.isSortValue()) {
435 } else if (val.isUFModel()) {
437 } else if (val.isSubstitution()) {
438 return val.asSubstitution()->representingFormula(mv);
441 return Formula<Poly>(FormulaType::FALSE);