def _add_assertion(self, formula, named=None): self._assert_is_boolean(formula) term = self.get_term(formula) if (named is not None) and (self.options.unsat_cores_mode is not None): # TODO: IF unsat_cores_mode is all, then we add this fresh variable. # Otherwise, we should track this only if it is named. key = self.mgr.FreshSymbol(template="_assertion_%d") tkey = self.get_term(key) key2term = yicespy.yices_implies(tkey, term) self.yices_assumptions.append(tkey) code = yicespy.yices_assert_formula(self.yices, key2term) if code != 0: msg = yicespy.yices_error_string() if code == -1 and "non-linear arithmetic" in msg: raise NonLinearError(formula) raise InternalSolverError("Yices returned non-zero code upon assert"\ ": %s (code: %s)" % \ (msg, code)) return (key, named, formula) else: code = yicespy.yices_assert_formula(self.yices, term) if code != 0: msg = yicespy.yices_error_string() if code == -1 and "non-linear arithmetic" in msg: raise NonLinearError(formula) raise InternalSolverError("Yices returned non-zero code upon assert"\ ": %s (code: %s)" % \ (msg, code)) return formula
def _assert_vars_boolean(self, var_set): for v in var_set: if not v.symbol_type().is_bool_type(): raise InternalSolverError( "Shannon Quantifier Elimination only supports "\ "quantification over Boolean variables: "\ "(%s is %s)" % (v, v.symbol_type()))
def pop(self, levels=1): for _ in xrange(levels): if self.failed_pushes > 0: self.failed_pushes -= 1 else: c = yicespy.yices_pop(self.yices) if c != 0: raise InternalSolverError("Error in pop: %s" % \ yicespy.yices_error_string())
def add_assertion(self, formula, named=None): self._assert_is_boolean(formula) term = self.converter.convert(formula) res = mathsat.msat_assert_formula(self.msat_env, term) if res != 0: msat_msg = mathsat.msat_last_error_message(self.msat_env) raise InternalSolverError(msat_msg) return
def add_assertion(self, formula, named=None): self._assert_is_boolean(formula) term = self.converter.convert(formula) code = yicespy.yices_assert_formula(self.yices, term) if code != 0: msg = yicespy.yices_error_string() if code == -1 and "non-linear arithmetic" in msg: raise NonLinearError(formula) raise InternalSolverError("Yices returned non-zero code upon assert"\ ": %s (code: %s)" % \ (msg, code))
def convert(self, formula): """Convert a PySMT formula into a MathSat Term. This function might throw a InternalSolverError exception if an error during conversion occurs. """ res = self.walk(formula) if mathsat.MSAT_ERROR_TERM(res): msat_msg = mathsat.msat_last_error_message(self.msat_env) raise InternalSolverError(msat_msg) return res
def get_unsat_core(self): """After a call to solve() yielding UNSAT, returns the unsat core as a set of formulae""" if self.options.unsat_cores_mode == "all": self._check_unsat_core_config() terms = mathsat.msat_get_unsat_core(self.msat_env) if terms is None: raise InternalSolverError( mathsat.msat_last_error_message(self.msat_env)) return set(self.converter.back(t) for t in terms) else: return self.get_named_unsat_core().values()
def push(self, levels=1): for _ in xrange(levels): c = yicespy.yices_push(self.yices) if c != 0: # 4 is STATUS_UNSAT if yicespy.yices_context_status(self.yices) == 4: # Yices fails to push if the context is in UNSAT state # (It makes no sense to conjoin formulae to False) # PySMT allows this and we support it by counting the # spurious push calls self.failed_pushes += 1 else: raise InternalSolverError("Error in push: %s" % \ yicespy.yices_error_string())
def solve(self, assumptions=None): if assumptions is not None: conj_assumptions = self.environment.formula_manager.And(assumptions) cvc4_assumption = self.converter.convert(conj_assumptions) res = self.cvc4.checkSat(cvc4_assumption) else: try: res = self.cvc4.checkSat() except CVC4.LogicException as ex: raise InternalSolverError(ex.toString()) # Convert returned type res_type = res.isSat() if res_type == CVC4.Result.SAT_UNKNOWN: raise SolverReturnedUnknownResultError() else: return res_type == CVC4.Result.SAT return
def _add_assertion(self, formula, named=None): self._assert_is_boolean(formula) result = formula if self.options.unsat_cores_mode == "named": # If we want named unsat cores, we need to rewrite the # formulae as implications key = self.mgr.FreshSymbol(template="_assertion_%d") result = (key, named, formula) formula = self.mgr.Implies(key, formula) term = self.converter.convert(formula) res = mathsat.msat_assert_formula(self.msat_env, term) if res != 0: msat_msg = mathsat.msat_last_error_message(self.msat_env) raise InternalSolverError(msat_msg) return result
def solve(self, assumptions=None): if assumptions is not None: conj_assumptions = self.environment.formula_manager.And( assumptions) cvc4_assumption = self.get_term(conj_assumptions) res = self.cvc4.checkSat(cvc4_assumption) else: try: res = self.cvc4.checkSat() except: raise InternalSolverError() # Convert returned type res_type = res.isSat() if res_type == CVC4.Result.SAT_UNKNOWN: print(self.cvc4.whyUnknown()) raise SolverReturnedUnknownResultError() else: return res_type == CVC4.Result.SAT return
def get_named_unsat_core(self): """After a call to solve() yielding UNSAT, returns the unsat core as a dict of names to formulae""" if self.options.unsat_cores_mode is None: raise SolverNotConfiguredForUnsatCoresError if self.last_result is not False: raise SolverStatusError("The last call to solve() was not" \ " unsatisfiable") if self.last_command != "solve": raise SolverStatusError("The solver status has been modified by a" \ " '%s' command after the last call to" \ " solve()" % self.last_command) assumptions = yicespy.term_vector_t() yicespy.yices_init_term_vector(assumptions) code = yicespy.yices_get_unsat_core(self.yices, assumptions) if code != 0: msg = yicespy.yices_error_string() raise InternalSolverError("Yices returned non-zero code upon unsat core extraction"\ ": %s (code: %s)" % \ (msg, code)) # for i in range(assumptions.size): # d = assumptions.data[i] # print(yicespy.yices_term_to_string(d, 200, 10, 0)) pysmt_assumptions = set(self.converter.back(assumptions.data[i]) for i in range(assumptions.size)) yicespy.yices_delete_term_vector(assumptions) res = {} n_ass_map = self._named_assertions_map() cnt = 0 for key in pysmt_assumptions: if key in n_ass_map: (name, formula) = n_ass_map[key] if name is None: name = "_a_%d" % cnt cnt += 1 res[name] = formula return res
def _check_term_result(self, res): if res == -1: err = yicespy.yices_error_string() raise InternalSolverError("Yices returned an error: " + err)
def _check_error(self, res): if res != 0: err = yicespy.yices_error_string() raise InternalSolverError("Yices returned an error: " + err)
def _assert_var_scalar(self, v): if not v.symbol_type().is_enum_type(): raise InternalSolverError( "Scalar Shannon Quantifier Elimination only supports "\ "quantification over Enum variables: "\ "(%s is %s)" % (v, v.symbol_type()))