def test_error(self): yapi.yices_reset() # First with no error errcode = yapi.yices_error_code() self.assertEqual(errcode, 0) errep = yapi.yices_error_report() self.assertEqual(errep.code, 0) yapi.yices_clear_error() errstr = yapi.yices_error_string() self.assertEqual(errstr, 'no error') yapi.yices_print_error_fd(1) # Illegal - only scalar or uninterpreted types allowed bool_t = yapi.yices_bool_type() self.assertTrue(yapi.yices_type_is_bool(bool_t)) #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'invalid type in constant creation'): #iam: 9/19/2018 const1 = yices_constant(bool_t, 0) const1 = yapi.yices_constant(bool_t, 0) error_string = yapi.yices_error_string() self.assertEqual(const1, -1) self.assertEqual(error_string, 'invalid type in constant creation') yapi.yices_clear_error() errpt = yapi.yices_error_report() self.assertEqual(yapi.yices_error_code(), 0) self.assertEqual(yapi.yices_error_code(), errpt.code) errstr = yapi.yices_error_string() self.assertEqual(errstr, 'no error') yapi.yices_print_error_fd(1) yapi.yices_clear_error() self.assertEqual(yapi.yices_error_code(), 0)
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 test_mpz_models(self): i1 = define_const('i1', self.int_t) i2 = define_const('i2', self.int_t) assert_formula('(> i1 987654321987654321987654321)', self.ctx) assert_formula('(< i2 i1)', self.ctx) self.assertEqual(yapi.yices_check_context(self.ctx, self.param), yapi.STATUS_SAT) mdl = yapi.yices_get_model(self.ctx, 1) mdlstr = yapi.yices_model_to_string(mdl, 80, 100, 0) self.assertEqual( mdlstr, '(= i1 987654321987654321987654322)\n(= i2 987654321987654321987654321)' ) i32v1 = c_int32() #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, #iam: 9/19/2018 'eval error: the term value does not fit the expected type'): #iam: 9/19/2018 yapi.yices_get_int32_value(mdl, i1, i32v1) errcode = yapi.yices_get_int32_value(mdl, i1, i32v1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual( error_string, 'eval error: the term value does not fit the expected type') i64v1 = c_int64() #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, #iam: 9/19/2018 'eval error: the term value does not fit the expected type'): #iam: 9/19/2018 yapi.yices_get_int64_value(mdl, i1, i64v1) errcode = yapi.yices_get_int64_value(mdl, i1, i64v1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual( error_string, 'eval error: the term value does not fit the expected type') gmpz1 = yapi.yices_new_mpz() gmpz2 = yapi.yices_new_mpz() yapi.yices_get_mpz_value(mdl, i1, gmpz1) yapi.yices_get_mpz_value(mdl, i2, gmpz2) mpz1 = yapi.yices_mpz(gmpz1) mpz2 = yapi.yices_mpz(gmpz2) self.assertEqual(yapi.yices_term_to_string(mpz1, 200, 10, 0), '987654321987654321987654322') self.assertEqual(yapi.yices_term_to_string(mpz2, 200, 10, 0), '987654321987654321987654321') if not yapi.yices_has_mcsat(): return yapi.yices_pp_term_fd(1, mpz1, 100, 10, 0) alg1 = yapi.lp_algebraic_number_t() #yapi.yices_get_algebraic_number_value(mdl, i1, alg1) #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, #iam: 9/19/2018 'could not convert value \(in model\) to a term'): #iam: 9/19/2018 yapi.yices_get_algebraic_number_value(mdl, i1, alg1) errcode = yapi.yices_get_algebraic_number_value(mdl, i1, alg1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'could not convert value (in model) to a term')
def test_context(self): cfg = yapi.yices_new_config() ctx = yapi.yices_new_context(cfg) stat = yapi.yices_context_status(ctx) yapi.yices_push(ctx) yapi.yices_pop(ctx) yapi.yices_reset_context(ctx) yapi.yices_context_enable_option(ctx, "arith-elim") yapi.yices_context_disable_option(ctx, "arith-elim") stat = yapi.yices_context_status(ctx) self.assertEqual(stat, 0) yapi.yices_reset_context(ctx) bool_t = yapi.yices_bool_type() bvar1 = yapi.yices_new_variable(bool_t) #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'assertion contains a free variable'): #iam: 9/19/2018 yapi.yices_assert_formula(ctx, bvar1) errcode = yapi.yices_assert_formula(ctx, bvar1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'assertion contains a free variable') bv_t = yapi.yices_bv_type(3) bvvar1 = yapi.yices_new_uninterpreted_term(bv_t) yapi.yices_set_term_name(bvvar1, 'x') bvvar2 = yapi.yices_new_uninterpreted_term(bv_t) yapi.yices_set_term_name(bvvar2, 'y') bvvar3 = yapi.yices_new_uninterpreted_term(bv_t) yapi.yices_set_term_name(bvvar3, 'z') fmla1 = yapi.yices_parse_term('(= x (bv-add y z))') fmla2 = yapi.yices_parse_term('(bv-gt y 0b000)') fmla3 = yapi.yices_parse_term('(bv-gt z 0b000)') yapi.yices_assert_formula(ctx, fmla1) yapi.yices_assert_formulas(ctx, 3, yapi.make_term_array([fmla1, fmla2, fmla3])) smt_stat = yapi.yices_check_context(ctx, None) self.assertEqual(smt_stat, yapi.STATUS_SAT) yapi.yices_assert_blocking_clause(ctx) yapi.yices_stop_search(ctx) param = yapi.yices_new_param_record() yapi.yices_default_params_for_context(ctx, param) yapi.yices_set_param(param, "dyn-ack", "true") #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'invalid parameter'): #iam: 9/19/2018 yapi.yices_set_param(param, "foo", "bar") errcode = yapi.yices_set_param(param, "foo", "bar") error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'invalid parameter') #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'value not valid for parameter'): #iam: 9/19/2018 yapi.yices_set_param(param, "dyn-ack", "bar") errcode = yapi.yices_set_param(param, "dyn-ack", "bar") error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'value not valid for parameter') yapi.yices_free_param_record(param) yapi.yices_free_context(ctx)
def test_mpq_models(self): r1 = define_const('r1', self.real_t) r2 = define_const('r2', self.real_t) assert_formula( '(> (* r1 3456666334217777794) 987654321987654321987654321)', self.ctx) assert_formula('(< r2 r1)', self.ctx) self.assertEqual(yapi.yices_check_context(self.ctx, self.param), yapi.STATUS_SAT) mdl = yapi.yices_get_model(self.ctx, 1) mdlstr = yapi.yices_model_to_string(mdl, 80, 100, 0) self.assertEqual( mdlstr, '(= r1 987654325444320656205432115/3456666334217777794)\n(= r2 987654321987654321987654321/3456666334217777794)' ) r32num1 = c_int32() r32den1 = c_uint32() #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, #iam: 9/19/2018 'eval error: the term value does not fit the expected type'): #iam: 9/19/2018 yapi.yices_get_rational32_value(mdl, r1, r32num1, r32den1) errcode = yapi.yices_get_rational32_value(mdl, r1, r32num1, r32den1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual( error_string, 'eval error: the term value does not fit the expected type') r64num1 = c_int64() r64den1 = c_uint64() #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, #iam: 9/19/2018 'eval error: the term value does not fit the expected type'): #iam: 9/19/2018 yapi.yices_get_rational64_value(mdl, r1, r64num1, r64den1) errcode = yapi.yices_get_rational64_value(mdl, r1, r64num1, r64den1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual( error_string, 'eval error: the term value does not fit the expected type') gmpq1 = yapi.yices_new_mpq() gmpq2 = yapi.yices_new_mpq() yapi.yices_get_mpq_value(mdl, r1, gmpq1) yapi.yices_get_mpq_value(mdl, r2, gmpq2) mpq1 = yapi.yices_mpq(gmpq1) mpq2 = yapi.yices_mpq(gmpq2) self.assertEqual(yapi.yices_term_to_string(mpq1, 200, 10, 0), '987654325444320656205432115/3456666334217777794') self.assertEqual(yapi.yices_term_to_string(mpq2, 200, 10, 0), '987654321987654321987654321/3456666334217777794')
def __init__(self, function=None, msg=None): if function is None: super().__init__('' if msg is None else msg) else: super().__init__( YicesException.LONG_MSG.format(function, yapi.yices_error_string()))
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 test_config(self): cfg = yapi.yices_new_config() # Valid call yapi.yices_set_config(cfg, "mode", "push-pop") # Invalid name #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'invalid parameter'): #iam: 9/19/2018 yapi.yices_set_config(cfg, "baz", "bar") errcode = yapi.yices_set_config(cfg, "baz", "bar") error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'invalid parameter') # Invalid value #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'value not valid for parameter'): #iam: 9/19/2018 yapi.yices_set_config(cfg, "mode", "bar") errcode = yapi.yices_set_config(cfg, "mode", "bar") error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'value not valid for parameter') yapi.yices_default_config_for_logic(cfg, "QF_UFNIRA") yapi.yices_free_config(cfg)
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 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 test_yval_numeric_models(self): i1 = define_const('i1', self.int_t) define_const('i2', self.int_t) assert_formula('(> i1 3)', self.ctx) assert_formula('(< i2 i1)', self.ctx) self.assertEqual(yapi.yices_check_context(self.ctx, self.param), yapi.STATUS_SAT) mdl = yapi.yices_get_model(self.ctx, 1) yv1 = yapi.yval_t() yapi.yices_get_value(mdl, i1, yv1) self.assertEqual(yapi.yices_val_is_int32(mdl, yv1), 1) self.assertEqual(yapi.yices_val_is_int64(mdl, yv1), 1) self.assertEqual(yapi.yices_val_is_rational32(mdl, yv1), 1) self.assertEqual(yapi.yices_val_is_rational64(mdl, yv1), 1) self.assertEqual(yapi.yices_val_is_integer(mdl, yv1), 1) # The next four just return 0 since yval is not a bv, tuple, mapping, or function self.assertEqual(yapi.yices_val_bitsize(mdl, yv1), 0) # Note that the next three aren't real tests, since 0 is returned if the tag is wrong self.assertEqual(yapi.yices_val_tuple_arity(mdl, yv1), 0) self.assertEqual(yapi.yices_val_mapping_arity(mdl, yv1), 0) self.assertEqual(yapi.yices_val_function_arity(mdl, yv1), 0) bval1 = c_int32() #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'invalid operation on yval'): #iam: 9/19/2018 yapi.yices_val_get_bool(mdl, yv1, bval1) errcode = yapi.yices_val_get_bool(mdl, yv1, bval1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'invalid operation on yval') i32val1 = c_int32() yapi.yices_val_get_int32(mdl, yv1, i32val1) self.assertEqual(i32val1.value, 4) i64val1 = c_int64() yapi.yices_val_get_int64(mdl, yv1, i64val1) self.assertEqual(i64val1.value, 4) r32num1 = c_int32() r32den1 = c_uint32() yapi.yices_val_get_rational32(mdl, yv1, r32num1, r32den1) self.assertEqual(r32num1.value, 4) self.assertEqual(r32den1.value, 1) r64num1 = c_int64() r64den1 = c_uint64() yapi.yices_val_get_rational64(mdl, yv1, r64num1, r64den1) self.assertEqual(r64num1.value, 4) self.assertEqual(r64den1.value, 1) rdoub1 = c_double() yapi.yices_val_get_double(mdl, yv1, rdoub1) self.assertEqual(rdoub1.value, 4.0) gmpz1 = yapi.yices_new_mpz() yapi.yices_val_get_mpz(mdl, yv1, gmpz1) mpz1 = yapi.yices_mpz(gmpz1) self.assertEqual(yapi.yices_term_to_string(mpz1, 200, 10, 0), '4') gmpq1 = yapi.yices_new_mpq() yapi.yices_val_get_mpq(mdl, yv1, gmpq1) mpq1 = yapi.yices_mpq(gmpq1) self.assertEqual(yapi.yices_term_to_string(mpq1, 200, 10, 0), '4') #iam: 9/19/2018 with self.assertRaisesRegexp(YicesAPIException, 'invalid operation on yval'): #iam: 9/19/2018 yapi.yices_val_get_bv(mdl, yv1, bval1) errcode = yapi.yices_val_get_bv(mdl, yv1, bval1) error_string = yapi.yices_error_string() self.assertEqual(errcode, -1) self.assertEqual(error_string, 'invalid operation on yval')
def error_string(): """Returns a string explaining the last error.""" return yapi.yices_error_string()