def add_assertion(self, formula, named=None): self._assert_is_boolean(formula) term = self.converter.convert(formula) code = libyices.yices_assert_formula(self.yices, term) if code != 0: raise InternalSolverError("Yices returned non-zero code upon assert"\ ": %s (code: %s)" % \ (libyices.yices_error_string(), code))
def pop(self, levels=1): for _ in xrange(levels): if self.failed_pushes > 0: self.failed_pushes -= 1 else: c = libyices.yices_pop(self.yices) if c != 0: raise InternalSolverError("Error in pop: %s" % \ libyices.yices_error_string())
def _get_yices_value(self, term, term_type, getter_func): status = getter_func( self.model, term, ctypes.byref(term_type) ) if status != 0: raise InternalSolverError("Failed to read the variable from " \ "the model: %s" % \ libyices.yices_error_string()) return term_type.value
def get_value(self, item): self._assert_no_function_type(item) titem = self.converter.convert(item) ty = self.environment.stc.get_type(item) if ty.is_bool_type(): res = self._get_yices_value(titem, ctypes.c_bool(), libyices.yices_get_bool_value) return self.mgr.Bool(res) else: yval = libyices.yval_t() status = libyices.yices_get_value(self.model, titem, ctypes.byref(yval)) if status != 0: raise InternalSolverError("Failed to read the variable from " \ "the model: %s" % \ libyices.yices_error_string()) if ty.is_int_type(): if libyices.yices_val_is_int64(self.model, ctypes.byref(yval)) == 0: raise NotImplementedError("Yices wrapper currently uses "\ "finite-precision integers! "\ "Your query required a non-"\ "representable integer.") else: res = self._get_yices_value(titem, ctypes.c_int64(), libyices.yices_get_int64_value) return self.mgr.Int(res) elif ty.is_real_type(): if libyices.yices_val_is_rational64(self.model, ctypes.byref(yval)) == 0: raise NotImplementedError("Yices wrapper currently uses "\ "finite-precision rationals! "\ "Your query required a non-"\ "representable rational.") else: res = self._get_yices_rational_value(titem) return self.mgr.Real(res) elif ty.is_bv_type(): width = ty.width res = (ctypes.c_int32 * width)() libyices.yices_get_bv_value(self.model, titem, res) str_val = "".join(str(x) for x in reversed(res)) return self.mgr.BV("#b" + str_val) else: raise NotImplementedError()
def _get_yices_rational_value(self, term): n = ctypes.c_int64() d = ctypes.c_uint64() status = libyices.yices_get_rational64_value( self.model, term, ctypes.byref(n), ctypes.byref(d)) if status != 0: raise InternalSolverError("Failed to read the variable from " \ "the model: %s" % \ libyices.yices_error_string()) return Fraction(n.value, d.value)
def push(self, levels=1): for _ in xrange(levels): c = libyices.yices_push(self.yices) if c != 0: # 4 is STATUS_UNSAT if libyices.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" % \ libyices.yices_error_string())
def _check_term_result(self, res): if res == -1: err = str(libyices.yices_error_string()) raise InternalSolverError("Yices returned an error: " + err)