Esempio n. 1
0
	bool BitvectorTheory::handleITE(const FormulaT& ifterm, const types::TermType& thenterm, const types::TermType& elseterm, types::TermType& result, TheoryError& errors) {
		types::BVTerm thent;
		types::BVTerm elset;
		if (!termConverter(thenterm, thent)) {
			errors.next() << "Failed to construct ITE, the then-term \"" << thenterm << "\" is unsupported.";
			return false;
		}
		if (!termConverter(elseterm, elset)) {
			errors.next() << "Failed to construct ITE, the else-term \"" << elseterm << "\" is unsupported.";
			return false;
		}
		if (thent.width() != elset.width()) {
			errors.next() << "Failed to construct ITE, the then-term \"" << thent << "\" and the else-term \"" << elset << "\" have different widths.";
			return false;
		}
		if (ifterm.isTrue()) { result = thent; return true; }
		if (ifterm.isFalse()) { result = elset; return true; }
		carl::SortManager& sm = carl::SortManager::getInstance();
		carl::Variable var = carl::freshVariable(carl::VariableType::VT_BITVECTOR);
		state->artificialVariables.emplace_back(var);
		carl::BVVariable bvvar(var, sm.index(this->bvSort, {thent.width()}));
		state->auxiliary_variables.insert(bvvar);
		types::BVTerm vart = types::BVTerm(carl::BVTermType::VARIABLE, bvvar);

		FormulaT consThen = FormulaT(types::BVConstraint::create(carl::BVCompareRelation::EQ, vart, thent));
		FormulaT consElse = FormulaT(types::BVConstraint::create(carl::BVCompareRelation::EQ, vart, elset));

		state->global_formulas.emplace_back(FormulaT(carl::FormulaType::IMPLIES, {ifterm, consThen}));
		state->global_formulas.emplace_back(FormulaT(carl::FormulaType::IMPLIES, {FormulaT(carl::FormulaType::NOT,ifterm), consElse}));
		result = vart;
		return true;
	}
Esempio n. 2
0
	FormulaT MCBModule<Settings>::applyReplacements(const FormulaT& f) {
		if (mChoices.empty()) return f;
		std::set<AVar> variables;
		std::map<FormulaT, FormulaT> repl;
		for (const auto& r: mChoices) {
			variables.insert(r.first);
			for (const auto& f: r.second) {
				BVar v = f.second.first;
				const FormulaT& form = f.second.second;
				repl.emplace(form, FormulaT(v));
			}
		}
		carl::FormulaSubstitutor<FormulaT> subs;
		SMTRAT_LOG_DEBUG("smtrat.mcb", "Applying " << repl << " on \n\t" << f);
		FormulaT res = subs.substitute(f, repl);
		SMTRAT_LOG_DEBUG("smtrat.mcb", "Resulting in\n\t" << res);
		
		mRemaining.clear();
		res.allVars(mRemaining);
		FormulasT equiv;
		for (const auto& v: variables) {
			if (mRemaining.count(v) > 0) {
				// Variable is still in the formula
				for (const auto& r: mChoices.at(v)) {
					equiv.push_back(FormulaT(carl::FormulaType::IFF, {FormulaT(r.second.first), r.second.second}));
				}
			} else {
				// Variable has been eliminated
				ModelVariable var(v);
				std::map<BVar,Rational> assignment;
				for (const auto& c: mChoices.at(v)) {
					assignment.emplace(c.second.first, c.first);
				}
				SMTRAT_LOG_DEBUG("smtrat.mcb", "Adding " << var << " = " << assignment);
				mAssignments.emplace(var, carl::createSubstitution<Rational,Poly,MCBModelSubstitution>(assignment));
			}
			for (const auto& c1: mChoices.at(v)) {
				for (const auto& c2: mChoices.at(v)) {
					if (c1.second.first >= c2.second.first) continue;
					equiv.push_back(FormulaT(carl::FormulaType::OR, {FormulaT(c1.second.first).negated(), FormulaT(c2.second.first).negated()}));
					SMTRAT_LOG_DEBUG("smtrat.mcb", "Adding exclusion " << equiv.back());
				}
			}
		}
		if (equiv.empty()) return res;
		SMTRAT_LOG_DEBUG("smtrat.mcb", "Adding equivalences " << equiv);
		equiv.push_back(res);
		return FormulaT(carl::FormulaType::AND, std::move(equiv));
	}
Esempio n. 3
0
	void MCBModule<Settings>::collectChoices(const FormulaT& formula) {
		if (formula.getType() != carl::FormulaType::OR) return;
		
		FormulaT::ConstraintBounds cb;
		collectBounds(cb, formula, false);
		if (cb.empty()) return;
			
		for (const auto& poly: cb) {
			if (!poly.first.isVariable()) continue;
			AVar var = poly.first.getSingleVariable();
			std::vector<std::pair<Rational,FormulaT>> choices;
			for (const auto& entry: poly.second) {
				if (entry.second.first != carl::Relation::EQ) break;
				choices.emplace_back(entry.first, entry.second.second);
			}
			if (choices.size() != poly.second.size()) continue;
			auto& m = mChoices[var];
			for (const auto& c: choices) {
				auto it = m.find(c.first);
				if (it == m.end()) {
					m.emplace(c.first, std::make_pair(carl::freshBooleanVariable(), c.second));
				}
			}
		}
	}
Esempio n. 4
0
	void MCBModule<Settings>::collectBounds(FormulaT::ConstraintBounds& cb, const FormulaT& formula, bool conjunction) const {
		for (const auto& f: formula.subformulas()) {
			if (f.getType() == carl::FormulaType::CONSTRAINT || (f.getType() == carl::FormulaType::NOT && f.subformula().getType() == carl::FormulaType::CONSTRAINT)) {
				FormulaT::addConstraintBound(cb, f, conjunction);
			}
		}
	}
Esempio n. 5
0
    FormulaT EMModule<Settings>::eliminateEquation(const FormulaT& formula) {
		if (formula.getType() != carl::FormulaType::CONSTRAINT) return formula;
		carl::Relation rel = formula.constraint().relation();
		switch (rel) {
			case carl::Relation::EQ:
			case carl::Relation::NEQ: {
				auto factors = formula.constraint().factorization();
				FormulasT res;
				for (const auto& factor: factors) {
					res.emplace_back(factor.first, rel);
				}
				carl::FormulaType ft = (rel == carl::Relation::EQ) ? carl::FormulaType::OR : carl::FormulaType::AND;
				FormulaT result(ft, std::move(res));
				if (result != formula) {
					SMTRAT_LOG_INFO("smtrat.em", "Translated\n\t" << formula << "\nto\n\t" << result);
				}
				return result;
			}
			default:
				return formula;
		}
	}
Esempio n. 6
0
 Answer EMModule<Settings>::checkCore()
 {
     auto receivedFormula = firstUncheckedReceivedSubformula();
     while (receivedFormula != rReceivedFormula().end()) {
         FormulaT formula = receivedFormula->formula();
         if (receivedFormula->formula().propertyHolds(carl::PROP_CONTAINS_NONLINEAR_POLYNOMIAL)) {
             formula = mVisitor.visitResult(receivedFormula->formula(), eliminateEquationFunction);
         }
         if (formula.isFalse()) {
             receivedFormulasAsInfeasibleSubset(receivedFormula);
             return UNSAT;
         }
         if (!formula.isTrue()) {
             addSubformulaToPassedFormula(formula, receivedFormula->formula());
         }
         ++receivedFormula;
     }
     Answer ans = runBackends();
     if (ans == UNSAT)
         getInfeasibleSubsets();
     return ans;
 }
Esempio n. 7
0
    Answer CNFerModule::checkCore()
    {
        auto receivedSubformula = firstUncheckedReceivedSubformula();
        while( receivedSubformula != rReceivedFormula().end() )
        {
            /*
             * Add the currently considered formula of the received constraint as clauses
             * to the passed formula.
             */
            FormulaT formulaToAssertInCnf = receivedSubformula->formula().toCNF( true, true, true );
            if( formulaToAssertInCnf.getType() == TRUE )
            {
                // No need to add it.
            }
            else if( formulaToAssertInCnf.getType() == FALSE )
            {
                receivedFormulasAsInfeasibleSubset( receivedSubformula );
                return UNSAT;
            }
            else
            {
                if( formulaToAssertInCnf.getType() == AND )
                {
                    for( const FormulaT& subFormula : formulaToAssertInCnf.subformulas()  )
                    {
                        #ifdef SMTRAT_DEVOPTION_Statistics
                        mpStatistics->addClauseOfSize( subFormula.size() );
                        #endif
                        addSubformulaToPassedFormula( subFormula, receivedSubformula->formula() );
                    }
                }
                else
                {
                    #ifdef SMTRAT_DEVOPTION_Statistics
                    mpStatistics->addClauseOfSize( receivedSubformula->formula().size() );
                    #endif
                    addSubformulaToPassedFormula( formulaToAssertInCnf, receivedSubformula->formula() );
                }
            }
            ++receivedSubformula;
        }
        //No given formulas is SAT but only if no other run was before
        if( rPassedFormula().empty() && solverState() == UNKNOWN )
        {
            return SAT;
        }
        else
        {
            #ifdef SMTRAT_DEVOPTION_Statistics
            carl::Variables avars;
            rPassedFormula().arithmeticVars( avars );
            mpStatistics->nrOfArithVariables() = avars.size();
            carl::Variables bvars;
            rPassedFormula().booleanVars( bvars );
            mpStatistics->nrOfBoolVariables() = bvars.size();
            #endif
            Answer a = runBackends();

            if( a == UNSAT )
            {
                getInfeasibleSubsets();
            }
            return a;
        }
    }