mirror of
https://github.com/Z3Prover/z3
synced 2026-06-22 00:20:27 +00:00
Merge branch 'master' into c3
This commit is contained in:
commit
043c6c0ad1
259 changed files with 18907 additions and 3725 deletions
|
|
@ -89,6 +89,7 @@ add_executable(test-z3
|
|||
memory.cpp
|
||||
model2expr.cpp
|
||||
model_based_opt.cpp
|
||||
mod_factor.cpp
|
||||
model_evaluator.cpp
|
||||
model_retrieval.cpp
|
||||
monomial_bounds.cpp
|
||||
|
|
@ -116,6 +117,7 @@ add_executable(test-z3
|
|||
prime_generator.cpp
|
||||
proof_checker.cpp
|
||||
qe_arith.cpp
|
||||
mbp_qel.cpp
|
||||
quant_elim.cpp
|
||||
quant_solve.cpp
|
||||
random.cpp
|
||||
|
|
@ -151,6 +153,7 @@ add_executable(test-z3
|
|||
theory_dl.cpp
|
||||
theory_pb.cpp
|
||||
timeout.cpp
|
||||
tptp.cpp
|
||||
total_order.cpp
|
||||
totalizer.cpp
|
||||
trigo.cpp
|
||||
|
|
@ -169,12 +172,11 @@ add_executable(test-z3
|
|||
z3_add_install_tactic_rule(${z3_test_deps})
|
||||
z3_add_memory_initializer_rule(${z3_test_deps})
|
||||
z3_add_gparams_register_modules_rule(${z3_test_deps})
|
||||
target_compile_definitions(test-z3 PRIVATE ${Z3_COMPONENT_CXX_DEFINES})
|
||||
target_compile_definitions(test-z3 PRIVATE
|
||||
${Z3_COMPONENT_CXX_DEFINES}
|
||||
)
|
||||
target_compile_options(test-z3 PRIVATE ${Z3_COMPONENT_CXX_FLAGS})
|
||||
target_link_libraries(test-z3 PRIVATE ${Z3_DEPENDENT_LIBS})
|
||||
target_include_directories(test-z3 PRIVATE ${Z3_COMPONENT_EXTRA_INCLUDE_DIRS})
|
||||
z3_append_linker_flag_list_to_target(test-z3 ${Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS})
|
||||
z3_add_component_dependencies_to_target(test-z3 ${z3_test_expanded_deps})
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,48 @@ void test_algebraic_comparison() {
|
|||
VERIFY(!am.eq(a, b)); // 2 != 3
|
||||
}
|
||||
|
||||
void test_algebraic_comparison_edge_case() {
|
||||
std::cout << "test_algebraic_comparison edge case\n";
|
||||
|
||||
// Let p1 = 1073741837 x^2 - 576460758745874510 x - 16106127555
|
||||
// Let p2 = p1 * (1073741837 x^2 - 576460759819616347 x -16106127555)
|
||||
// = 1152921532524134569 x^4 - 1237940069261339757601884309 x^3
|
||||
// + 332307006992839334837849081482577900 x^2 + 18569101038920096364028264635 x
|
||||
// + 259407344817930278025
|
||||
// Compare a = root(p1, 1) in (-8, 0) and b = root(p2, 2) in (-15/2^29, -7/2^28)
|
||||
// The two numbers are different (a < b), but very close, and both are roots of p2
|
||||
|
||||
reslimit rl;
|
||||
unsynch_mpq_manager qm;
|
||||
anum_manager am(rl, qm);
|
||||
manager m(rl, qm);
|
||||
polynomial_ref x(m);
|
||||
x = m.mk_polynomial(m.mk_var());
|
||||
|
||||
rational a0, a1, a2;
|
||||
a0 = 161061;
|
||||
a0 = (a0 * 100000) + 27555;
|
||||
a1 = 576460758;
|
||||
a1 = (a1 * 1000000000) + 745874510;
|
||||
a2 = 10737;
|
||||
a2 = (a2 * 100000) + 41837;
|
||||
|
||||
rational b1;
|
||||
b1 = 576460759;
|
||||
b1 = (b1 * 1000000000) + 819616347;
|
||||
|
||||
polynomial_ref p1(m);
|
||||
polynomial_ref p2(m);
|
||||
p1 = ((a2*x*x) - (a1*x)) - a0;
|
||||
p2 = p1 * (((a2*x*x) - (b1*x)) - a0);
|
||||
|
||||
scoped_anum a(am), b(am);
|
||||
am.mk_root(p1, 1, a);
|
||||
am.mk_root(p2, 2, b);
|
||||
|
||||
VERIFY(!am.eq(a, b));
|
||||
}
|
||||
|
||||
void test_algebraic_degree() {
|
||||
std::cout << "test_algebraic_degree\n";
|
||||
|
||||
|
|
@ -158,6 +200,7 @@ void test_algebraic_numbers() {
|
|||
test_algebraic_basic_operations();
|
||||
test_algebraic_arithmetic();
|
||||
test_algebraic_comparison();
|
||||
test_algebraic_comparison_edge_case();
|
||||
test_algebraic_degree();
|
||||
test_algebraic_signs();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ void test_max_reg() {
|
|||
Z3_optimize_dec_ref(ctx, opt);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Approach 3: Weighted sum method (Python loop over weights)
|
||||
int weights[][2] = {{1, 4}, {2, 3}, {1, 1}, {3, 2}, {4, 1}};
|
||||
for (auto& w : weights) {
|
||||
|
|
@ -271,9 +272,10 @@ void test_max_reg() {
|
|||
}
|
||||
Z3_optimize_dec_ref(ctx, opt);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::cout << "BNH: " << num_sat << "/7 optimizations returned sat" << std::endl;
|
||||
ENSURE(num_sat == 7);
|
||||
std::cout << "BNH: " << num_sat << "/2 optimizations returned sat" << std::endl;
|
||||
ENSURE(num_sat == 2);
|
||||
Z3_del_context(ctx);
|
||||
std::cout << "BNH optimization test done" << std::endl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,5 +64,31 @@ void tst_api_datalog() {
|
|||
Z3_fixedpoint_dec_ref(ctx, fp);
|
||||
}
|
||||
|
||||
// Regression test for Spacer model construction on ADT CHCs
|
||||
{
|
||||
char const* chc =
|
||||
"(set-logic HORN)\n"
|
||||
"(set-option :fp.engine spacer)\n"
|
||||
"(set-option :fp.spacer.random_seed 51)\n"
|
||||
"(set-option :timeout 2000)\n"
|
||||
"(declare-datatypes ((L 0)) (((cons (hd Int) (tl L)) (nil))))\n"
|
||||
"(declare-fun reva (L L L) Bool)\n"
|
||||
"(assert (forall ((a L)) (reva nil a a)))\n"
|
||||
"(assert (forall ((x L) (acc L) (r L) (h Int))\n"
|
||||
" (=> (reva x (cons h acc) r)\n"
|
||||
" (reva (cons h x) acc r))))\n"
|
||||
"(assert (forall ((B L) (C L) (D L) (E L) (F L))\n"
|
||||
" (=> (and (reva B C D)\n"
|
||||
" (reva D nil E)\n"
|
||||
" (reva C B F)\n"
|
||||
" (not (= E F)))\n"
|
||||
" false)))\n"
|
||||
"(check-sat)\n";
|
||||
|
||||
Z3_string response = Z3_eval_smtlib2_string(ctx, chc);
|
||||
ENSURE(response != nullptr);
|
||||
ENSURE(Z3_get_error_code(ctx) == Z3_OK);
|
||||
}
|
||||
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,10 +23,13 @@ static void test_table(mk_table_fn mk_table) {
|
|||
sig.push_back(8);
|
||||
sig.push_back(4);
|
||||
smt_params params;
|
||||
params_ref fp_params;
|
||||
gparams::set("fp.engine", "datalog");
|
||||
// fp_params.set_sym("fp.engine", symbol("datalog"));
|
||||
ast_manager ast_m;
|
||||
reg_decl_plugins(ast_m);
|
||||
datalog::register_engine re;
|
||||
datalog::context ctx(ast_m, re, params);
|
||||
datalog::context ctx(ast_m, re, params, fp_params);
|
||||
datalog::relation_manager & m = ctx.get_rel_context()->get_rmanager();
|
||||
|
||||
m.register_plugin(alloc(datalog::bitvector_table_plugin, m));
|
||||
|
|
@ -48,13 +51,10 @@ static void test_table(mk_table_fn mk_table) {
|
|||
table.add_fact(row2);
|
||||
table.display(std::cout);
|
||||
|
||||
datalog::table_base::iterator it = table.begin();
|
||||
datalog::table_base::iterator end = table.end();
|
||||
for (; it != end; ++it) {
|
||||
it->get_fact(row);
|
||||
for (unsigned j = 0; j < row.size(); ++j) {
|
||||
std::cout << row[j] << " ";
|
||||
}
|
||||
for (auto &r : table) {
|
||||
r.get_fact(row);
|
||||
for (auto v : row)
|
||||
std::cout << v << " ";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
|
||||
--*/
|
||||
|
||||
#include "util/gparams.h"
|
||||
#include "muz/base/dl_util.h"
|
||||
|
||||
using namespace datalog;
|
||||
|
|
@ -49,6 +50,7 @@ void dl_util_cycle_from_permutation() {
|
|||
}
|
||||
|
||||
void tst_dl_util() {
|
||||
gparams::set("fp.engine", "datalog");
|
||||
dl_util_two_array_sort();
|
||||
dl_util_cycle_from_permutation();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ public:
|
|||
//sub:{xxx \ {1x0, 0x1}}
|
||||
//result:{100}
|
||||
|
||||
for (unsigned i = 0; i < 1000; ++i) {
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
udoc d1, d2;
|
||||
mk_rand_udoc(3, 3, d1);
|
||||
mk_rand_udoc(3, 3, d2);
|
||||
|
|
@ -453,7 +453,7 @@ public:
|
|||
|
||||
void test_intersect() {
|
||||
expr_ref fml1(m), fml2(m), fml3(m);
|
||||
for (unsigned i = 0; i < 10000; ++i) {
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
udoc d1, d2;
|
||||
mk_rand_udoc(3, 3, d1);
|
||||
mk_rand_udoc(3, 3, d2);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,43 @@ static void test_fp_to_real_denormal() {
|
|||
true);
|
||||
}
|
||||
|
||||
// Regression test for soundness bug in to_fp (from real) with symbolic real interval.
|
||||
// When the rounding mode is RTZ and the real variable is constrained to an interval
|
||||
// that includes the exact rational value of a float, Z3 should return SAT.
|
||||
// This was broken because mk_to_real computed 2^(1/|exp|) instead of 1/(2^|exp|)
|
||||
// for floats with negative exponents, causing a conflict in the NRA solver.
|
||||
static void test_to_fp_from_real_interval() {
|
||||
// The interval (-4127125/16777216, -16508499/67108864] contains -16508499/67108864
|
||||
// which is the exact rational value of fp #b1 #b01111100 #b11110111110011001010011.
|
||||
// to_fp(RTZ, r) for r in this closed interval must equal that float.
|
||||
run_fp_test(
|
||||
"(set-logic QF_FPLRA)\n"
|
||||
"(declare-const x Float32)\n"
|
||||
"(assert (= x (fp #b1 #b01111100 #b11110111110011001010011)))\n"
|
||||
"(declare-const r Real)\n"
|
||||
"(assert (and (> r (- (/ 4127125.0 16777216.0))) (<= r (- (/ 16508499.0 67108864.0)))))\n"
|
||||
"(declare-const w Float32)\n"
|
||||
"(assert (= w ((_ to_fp 8 24) RTZ r)))\n"
|
||||
"(assert (= x w))\n"
|
||||
"(check-sat)\n",
|
||||
true);
|
||||
}
|
||||
|
||||
static void test_recfun_defined_function_soundness() {
|
||||
run_fp_test(
|
||||
"(set-option :model_validate true)\n"
|
||||
"(declare-fun fixedAdd () Int)\n"
|
||||
"(declare-fun variableAdd () Int)\n"
|
||||
"(define-fun-rec $$add$$ ((a Int) (b Int)) Int\n"
|
||||
" (ite (= 0 b) 2 (- a (+ 0 (- fixedAdd b)))))\n"
|
||||
"(assert (= fixedAdd (* 9 fixedAdd)))\n"
|
||||
"(assert (= 1 ($$add$$ 1 3)))\n"
|
||||
"(check-sat)\n",
|
||||
false);
|
||||
}
|
||||
|
||||
void tst_fpa() {
|
||||
test_fp_to_real_denormal();
|
||||
test_to_fp_from_real_interval();
|
||||
test_recfun_defined_function_soundness();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1971,28 +1971,28 @@ void test_lp_local(int argn, char **argv) {
|
|||
|
||||
if (args_parser.option_is_used("-nla_blfmz_mf")) {
|
||||
#ifdef Z3DEBUG
|
||||
nla::test_basic_lemma_for_mon_zero_from_monomial_to_factors();
|
||||
// nla::test_basic_lemma_for_mon_zero_from_monomial_to_factors();
|
||||
#endif
|
||||
return finalize(0);
|
||||
}
|
||||
|
||||
if (args_parser.option_is_used("-nla_blfmz_fm")) {
|
||||
#ifdef Z3DEBUG
|
||||
nla::test_basic_lemma_for_mon_zero_from_factors_to_monomial();
|
||||
//nla::test_basic_lemma_for_mon_zero_from_factors_to_monomial();
|
||||
#endif
|
||||
return finalize(0);
|
||||
}
|
||||
|
||||
if (args_parser.option_is_used("-nla_blnt_mf")) {
|
||||
#ifdef Z3DEBUG
|
||||
nla::test_basic_lemma_for_mon_neutral_from_monomial_to_factors();
|
||||
// nla::test_basic_lemma_for_mon_neutral_from_monomial_to_factors();
|
||||
#endif
|
||||
return finalize(0);
|
||||
}
|
||||
|
||||
if (args_parser.option_is_used("-nla_blnt_fm")) {
|
||||
#ifdef Z3DEBUG
|
||||
nla::test_basic_lemma_for_mon_neutral_from_factors_to_monomial();
|
||||
// nla::test_basic_lemma_for_mon_neutral_from_factors_to_monomial();
|
||||
#endif
|
||||
return finalize(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ void create_abcde(solver & nla,
|
|||
nla.add_monic(lp_be, vec.size(), vec.begin());
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0() {
|
||||
std::cout << "test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0\n";
|
||||
enable_trace("nla_solver");
|
||||
|
|
@ -222,6 +222,7 @@ void test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0() {
|
|||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void s_set_column_value_test(lp::lar_solver&s, lpvar j, const rational & v) {
|
||||
s.set_column_value_test(j, lp::impq(v));
|
||||
|
|
@ -231,6 +232,7 @@ void s_set_column_value_test(lp::lar_solver&s, lpvar j, const lp::impq & v) {
|
|||
s.set_column_value_test(j, v);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1() {
|
||||
std::cout << "test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1\n";
|
||||
TRACE(nla_solver,);
|
||||
|
|
@ -367,6 +369,7 @@ void test_basic_lemma_for_mon_zero_from_factors_to_monomial() {
|
|||
VERIFY(found0 && found1);
|
||||
}
|
||||
|
||||
|
||||
void test_basic_lemma_for_mon_zero_from_monomial_to_factors() {
|
||||
std::cout << "test_basic_lemma_for_mon_zero_from_monomial_to_factors\n";
|
||||
enable_trace("nla_solver");
|
||||
|
|
@ -420,6 +423,7 @@ void test_basic_lemma_for_mon_zero_from_monomial_to_factors() {
|
|||
|
||||
}
|
||||
|
||||
|
||||
void test_basic_lemma_for_mon_neutral_from_monomial_to_factors() {
|
||||
std::cout << "test_basic_lemma_for_mon_neutral_from_monomial_to_factors\n";
|
||||
enable_trace("nla_solver");
|
||||
|
|
@ -489,6 +493,7 @@ void test_basic_lemma_for_mon_neutral_from_monomial_to_factors() {
|
|||
|
||||
VERIFY(found0 && found1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_horner() {
|
||||
enable_trace("nla_solver");
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@
|
|||
X(hilbert_basis) \
|
||||
X(heap_trie) \
|
||||
X(karr) \
|
||||
X(mod_factor) \
|
||||
X(no_overflow) \
|
||||
X(datalog_parser) \
|
||||
X_ARGV(datalog_parser_file) \
|
||||
|
|
@ -162,6 +163,7 @@
|
|||
X(rcf) \
|
||||
X(polynorm) \
|
||||
X(qe_arith) \
|
||||
X(mbp_qel) \
|
||||
X(expr_substitution) \
|
||||
X(sorting_network) \
|
||||
X(theory_pb) \
|
||||
|
|
@ -539,7 +541,7 @@ int main(int argc, char ** argv) {
|
|||
}
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
if (num_jobs > 0)
|
||||
if (num_jobs > 0 && (test_all || requested_tests.size() > 1))
|
||||
return run_parallel(argv[0], test_all, num_jobs, extra_args, requested_tests);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
250
src/test/mbp_qel.cpp
Normal file
250
src/test/mbp_qel.cpp
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2025 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
mbp_qel.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Unit tests for model-based projection with QEL (term-graph based)
|
||||
|
||||
Author:
|
||||
|
||||
Hari Govind V K (hgvk94) 2025-05-25
|
||||
|
||||
--*/
|
||||
|
||||
#include "qe/qe_mbp.h"
|
||||
#include "ast/reg_decl_plugins.h"
|
||||
#include "ast/datatype_decl_plugin.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "smt/smt_context.h"
|
||||
#include "params/smt_params.h"
|
||||
#include <iostream>
|
||||
|
||||
// Test that MBP with QEL does not return false for a satisfiable formula
|
||||
// involving datatype accessors applied past the end of a list.
|
||||
//
|
||||
// Formula: (and ((_ is cons) x) ((_ is nil) (tl x)) (= nil (tl (tl x))) (< 8 n))
|
||||
// Project: x
|
||||
// Expected: result should imply n >= 9 (and model should satisfy it)
|
||||
// Bug: QEL was returning false because rm_accessor unconditionally
|
||||
// assumed (tl x) has constructor cons when eliminating (tl (tl x)),
|
||||
// contradicting the ((_ is nil) (tl x)) literal.
|
||||
static void test_dt_accessor_past_end() {
|
||||
std::cout << "test_dt_accessor_past_end\n";
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
datatype_util dt(m);
|
||||
arith_util a(m);
|
||||
|
||||
// Create list datatype: (declare-datatypes ((L 0)) (((cons (hd Int) (tl L)) (nil))))
|
||||
sort_ref int_sort(a.mk_int(), m);
|
||||
func_decl_ref cons(m), is_cons(m), head(m), tail(m), nil(m), is_nil(m);
|
||||
sort_ref L = dt.mk_list_datatype(int_sort, symbol("L"),
|
||||
cons, is_cons, head, tail, nil, is_nil);
|
||||
|
||||
// Declare variables
|
||||
app_ref x(m.mk_const("x", L), m);
|
||||
app_ref n(m.mk_const("n", int_sort), m);
|
||||
|
||||
// Build formula: (and ((_ is cons) x) ((_ is nil) (tl x)) (= nil (tl (tl x))) (< 8 n))
|
||||
expr_ref tl_x(m.mk_app(tail, x.get()), m);
|
||||
expr_ref tl_tl_x(m.mk_app(tail, tl_x.get()), m);
|
||||
expr_ref nil_val(m.mk_const(nil), m);
|
||||
|
||||
expr_ref is_cons_x(m.mk_app(is_cons, x.get()), m);
|
||||
expr_ref is_nil_tl_x(m.mk_app(is_nil, tl_x.get()), m);
|
||||
expr_ref eq_nil_tl_tl_x(m.mk_eq(nil_val, tl_tl_x), m);
|
||||
expr_ref lt_8_n(a.mk_lt(a.mk_int(8), n), m);
|
||||
|
||||
expr_ref_vector conjs(m);
|
||||
conjs.push_back(is_cons_x).push_back(is_nil_tl_x).push_back(eq_nil_tl_tl_x).push_back(lt_8_n);
|
||||
expr_ref fml(m.mk_and(conjs), m);
|
||||
|
||||
std::cout << " formula:\n " << mk_pp(fml, m, 5) << "\n";
|
||||
|
||||
// Get a model
|
||||
smt_params params;
|
||||
params.m_model = true;
|
||||
model_ref mdl;
|
||||
{
|
||||
smt::context ctx(m, params);
|
||||
ctx.assert_expr(fml);
|
||||
lbool result = ctx.check();
|
||||
VERIFY(result == l_true);
|
||||
ctx.get_model(mdl);
|
||||
}
|
||||
|
||||
std::cout << " model: x = " << mk_pp((*mdl)(x), m)
|
||||
<< ", n = " << mk_pp((*mdl)(n), m) << "\n";
|
||||
|
||||
// Call MBP with QEL enabled
|
||||
app_ref_vector vars(m);
|
||||
vars.push_back(x);
|
||||
|
||||
params_ref p;
|
||||
p.set_bool("qsat_use_qel", true);
|
||||
qe::mbproj mbp(m, p);
|
||||
expr_ref projected(fml, m);
|
||||
mbp.spacer(vars, *mdl.get(), projected);
|
||||
|
||||
std::cout << " projected (qel=true):\n " << mk_pp(projected, m, 5) << "\n";
|
||||
|
||||
// The result must not be false
|
||||
VERIFY(!m.is_false(projected));
|
||||
|
||||
// The model should satisfy the projected formula
|
||||
VERIFY(mdl->is_true(projected));
|
||||
|
||||
// x should have been eliminated
|
||||
VERIFY(vars.empty());
|
||||
|
||||
std::cout << " PASS\n\n";
|
||||
}
|
||||
|
||||
// Same test but with a deeper list structure:
|
||||
// x is a 2-element list with a past-end accessor constraint
|
||||
// Formula: (and ((_ is cons) x) ((_ is cons) (tl x)) ((_ is nil) (tl (tl x)))
|
||||
// (= nil (tl (tl (tl x)))) (< 8 n))
|
||||
static void test_dt_accessor_past_end_depth2() {
|
||||
std::cout << "test_dt_accessor_past_end_depth2\n";
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
datatype_util dt(m);
|
||||
arith_util a(m);
|
||||
|
||||
sort_ref int_sort(a.mk_int(), m);
|
||||
func_decl_ref cons(m), is_cons(m), head(m), tail(m), nil(m), is_nil(m);
|
||||
sort_ref L = dt.mk_list_datatype(int_sort, symbol("L"),
|
||||
cons, is_cons, head, tail, nil, is_nil);
|
||||
|
||||
app_ref x(m.mk_const("x", L), m);
|
||||
app_ref n(m.mk_const("n", int_sort), m);
|
||||
|
||||
// Build: (and (is-cons x) (is-cons (tl x)) (is-nil (tl (tl x)))
|
||||
// (= nil (tl (tl (tl x)))) (< 8 n))
|
||||
expr_ref tl_x(m.mk_app(tail, x.get()), m);
|
||||
expr_ref tl_tl_x(m.mk_app(tail, tl_x.get()), m);
|
||||
expr_ref tl_tl_tl_x(m.mk_app(tail, tl_tl_x.get()), m);
|
||||
expr_ref nil_val(m.mk_const(nil), m);
|
||||
|
||||
expr_ref is_cons_x(m.mk_app(is_cons, x.get()), m);
|
||||
expr_ref is_cons_tl_x(m.mk_app(is_cons, tl_x.get()), m);
|
||||
expr_ref is_nil_tl_tl_x(m.mk_app(is_nil, tl_tl_x.get()), m);
|
||||
expr_ref eq_nil_tl3(m.mk_eq(nil_val, tl_tl_tl_x), m);
|
||||
expr_ref lt_8_n(a.mk_lt(a.mk_int(8), n), m);
|
||||
|
||||
expr_ref_vector conjs(m);
|
||||
conjs.push_back(is_cons_x).push_back(is_cons_tl_x).push_back(is_nil_tl_tl_x).push_back(eq_nil_tl3).push_back(lt_8_n);
|
||||
expr_ref fml(m.mk_and(conjs), m);
|
||||
|
||||
std::cout << " formula:\n " << mk_pp(fml, m, 5) << "\n";
|
||||
|
||||
smt_params sparams;
|
||||
sparams.m_model = true;
|
||||
model_ref mdl;
|
||||
{
|
||||
smt::context ctx(m, sparams);
|
||||
ctx.assert_expr(fml);
|
||||
lbool result = ctx.check();
|
||||
VERIFY(result == l_true);
|
||||
ctx.get_model(mdl);
|
||||
}
|
||||
|
||||
std::cout << " model: x = " << mk_pp((*mdl)(x), m)
|
||||
<< ", n = " << mk_pp((*mdl)(n), m) << "\n";
|
||||
|
||||
app_ref_vector vars(m);
|
||||
vars.push_back(x);
|
||||
|
||||
params_ref p;
|
||||
p.set_bool("qsat_use_qel", true);
|
||||
qe::mbproj mbp(m, p);
|
||||
expr_ref projected(fml, m);
|
||||
mbp.spacer(vars, *mdl.get(), projected);
|
||||
|
||||
std::cout << " projected (qel=true):\n " << mk_pp(projected, m, 5) << "\n";
|
||||
|
||||
VERIFY(!m.is_false(projected));
|
||||
VERIFY(mdl->is_true(projected));
|
||||
VERIFY(vars.empty());
|
||||
|
||||
std::cout << " PASS\n\n";
|
||||
}
|
||||
|
||||
// Test with multiple DT variables projected simultaneously
|
||||
// Formula: (and (= nil (tl (tl (tl x)))) ((_ is nil) (tl (tl x)))
|
||||
// ((_ is cons) y) ((_ is nil) (tl y)) (< 8 n))
|
||||
// Project: x, y
|
||||
static void test_dt_multiple_vars() {
|
||||
std::cout << "test_dt_multiple_vars\n";
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
datatype_util dt(m);
|
||||
arith_util a(m);
|
||||
|
||||
sort_ref int_sort(a.mk_int(), m);
|
||||
func_decl_ref cons(m), is_cons(m), head(m), tail(m), nil(m), is_nil(m);
|
||||
sort_ref L = dt.mk_list_datatype(int_sort, symbol("L"),
|
||||
cons, is_cons, head, tail, nil, is_nil);
|
||||
|
||||
app_ref x(m.mk_const("x", L), m);
|
||||
app_ref y(m.mk_const("y", L), m);
|
||||
app_ref n(m.mk_const("n", int_sort), m);
|
||||
|
||||
expr_ref tl_x(m.mk_app(tail, x.get()), m);
|
||||
expr_ref tl_tl_x(m.mk_app(tail, tl_x.get()), m);
|
||||
expr_ref tl_tl_tl_x(m.mk_app(tail, tl_tl_x.get()), m);
|
||||
expr_ref tl_y(m.mk_app(tail, y.get()), m);
|
||||
expr_ref nil_val(m.mk_const(nil), m);
|
||||
|
||||
expr_ref eq_nil_tl3x(m.mk_eq(nil_val, tl_tl_tl_x), m);
|
||||
expr_ref is_nil_tl2x(m.mk_app(is_nil, tl_tl_x.get()), m);
|
||||
expr_ref is_cons_y(m.mk_app(is_cons, y.get()), m);
|
||||
expr_ref is_nil_tl_y(m.mk_app(is_nil, tl_y.get()), m);
|
||||
expr_ref lt_8_n(a.mk_lt(a.mk_int(8), n), m);
|
||||
|
||||
expr_ref_vector conjs(m);
|
||||
conjs.push_back(eq_nil_tl3x).push_back(is_nil_tl2x).push_back(is_cons_y).push_back(is_nil_tl_y).push_back(lt_8_n);
|
||||
expr_ref fml(m.mk_and(conjs), m);
|
||||
|
||||
std::cout << " formula:\n " << mk_pp(fml, m, 5) << "\n";
|
||||
|
||||
smt_params sparams;
|
||||
sparams.m_model = true;
|
||||
model_ref mdl;
|
||||
{
|
||||
smt::context ctx(m, sparams);
|
||||
ctx.assert_expr(fml);
|
||||
lbool result = ctx.check();
|
||||
VERIFY(result == l_true);
|
||||
ctx.get_model(mdl);
|
||||
}
|
||||
|
||||
app_ref_vector vars(m);
|
||||
vars.push_back(x);
|
||||
vars.push_back(y);
|
||||
|
||||
params_ref p;
|
||||
p.set_bool("qsat_use_qel", true);
|
||||
qe::mbproj mbp(m, p);
|
||||
expr_ref projected(fml, m);
|
||||
mbp.spacer(vars, *mdl.get(), projected);
|
||||
|
||||
std::cout << " projected (qel=true):\n " << mk_pp(projected, m, 5) << "\n";
|
||||
|
||||
VERIFY(!m.is_false(projected));
|
||||
VERIFY(mdl->is_true(projected));
|
||||
|
||||
std::cout << " PASS\n\n";
|
||||
}
|
||||
|
||||
void tst_mbp_qel() {
|
||||
test_dt_accessor_past_end();
|
||||
test_dt_accessor_past_end_depth2();
|
||||
test_dt_multiple_vars();
|
||||
}
|
||||
91
src/test/mod_factor.cpp
Normal file
91
src/test/mod_factor.cpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*++
|
||||
Copyright (c) 2025 Microsoft Corporation
|
||||
--*/
|
||||
|
||||
#include "api/z3.h"
|
||||
#include "util/util.h"
|
||||
#include <string>
|
||||
|
||||
// x mod 7 = 0 & (x*y) mod 7 != 0 should be unsat
|
||||
// Exercises: mod internalization path (is_mod with numeric divisor)
|
||||
static void test_mod_factor_mod_path() {
|
||||
Z3_config cfg = Z3_mk_config();
|
||||
Z3_context ctx = Z3_mk_context(cfg);
|
||||
Z3_solver s = Z3_mk_solver_for_logic(ctx, Z3_mk_string_symbol(ctx, "QF_NIA"));
|
||||
Z3_solver_inc_ref(ctx, s);
|
||||
Z3_sort int_sort = Z3_mk_int_sort(ctx);
|
||||
Z3_ast x = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "x"), int_sort);
|
||||
Z3_ast y = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "y"), int_sort);
|
||||
Z3_ast seven = Z3_mk_int(ctx, 7, int_sort);
|
||||
Z3_ast zero = Z3_mk_int(ctx, 0, int_sort);
|
||||
Z3_ast xy_args[] = {x, y};
|
||||
Z3_ast xy = Z3_mk_mul(ctx, 2, xy_args);
|
||||
// assert mul term first so ensure_nla() fires before mod internalization
|
||||
Z3_solver_assert(ctx, s, Z3_mk_not(ctx, Z3_mk_eq(ctx, Z3_mk_mod(ctx, xy, seven), zero)));
|
||||
Z3_solver_assert(ctx, s, Z3_mk_eq(ctx, Z3_mk_mod(ctx, x, seven), zero));
|
||||
ENSURE(Z3_solver_check(ctx, s) == Z3_L_FALSE);
|
||||
Z3_solver_dec_ref(ctx, s);
|
||||
Z3_del_config(cfg);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
// (x mod 100) mod 7 = 0 => ((x mod 100) * y) mod 7 = 0
|
||||
// Exercises: idiv internalization path (is_idiv + numeric divisor + bounded dividend)
|
||||
// because (x mod 100) is recognized as bounded by is_bounded()
|
||||
static void test_mod_factor_idiv_path() {
|
||||
Z3_config cfg = Z3_mk_config();
|
||||
Z3_context ctx = Z3_mk_context(cfg);
|
||||
Z3_solver s = Z3_mk_solver_for_logic(ctx, Z3_mk_string_symbol(ctx, "QF_NIA"));
|
||||
Z3_solver_inc_ref(ctx, s);
|
||||
Z3_sort int_sort = Z3_mk_int_sort(ctx);
|
||||
Z3_ast x = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "x"), int_sort);
|
||||
Z3_ast y = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "y"), int_sort);
|
||||
Z3_ast seven = Z3_mk_int(ctx, 7, int_sort);
|
||||
Z3_ast zero = Z3_mk_int(ctx, 0, int_sort);
|
||||
Z3_ast hundred = Z3_mk_int(ctx, 100, int_sort);
|
||||
// xm = x mod 100 (bounded by is_bounded)
|
||||
Z3_ast xm = Z3_mk_mod(ctx, x, hundred);
|
||||
// (xm * y) — assert mul term first so ensure_nla() fires before mod internalization
|
||||
Z3_ast xm_y_args[] = {xm, y};
|
||||
Z3_ast xm_y = Z3_mk_mul(ctx, 2, xm_y_args);
|
||||
Z3_ast xm_y_div = Z3_mk_div(ctx, xm_y, seven);
|
||||
// assert (xm * y) mod 7 != 0
|
||||
Z3_solver_assert(ctx, s, Z3_mk_not(ctx, Z3_mk_eq(ctx, Z3_mk_mod(ctx, xm_y, seven), zero)));
|
||||
// use div to keep it alive
|
||||
Z3_solver_assert(ctx, s, Z3_mk_ge(ctx, xm_y_div, zero));
|
||||
// xm mod 7 = 0
|
||||
Z3_solver_assert(ctx, s, Z3_mk_eq(ctx, Z3_mk_mod(ctx, xm, seven), zero));
|
||||
ENSURE(Z3_solver_check(ctx, s) == Z3_L_FALSE);
|
||||
Z3_solver_dec_ref(ctx, s);
|
||||
Z3_del_config(cfg);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
static void test_const_array_store_chain_unsat() {
|
||||
Z3_config cfg = Z3_mk_config();
|
||||
Z3_context ctx = Z3_mk_context(cfg);
|
||||
const char* script = R"(
|
||||
(set-logic QF_ABV)
|
||||
(declare-const x (_ BitVec 8))
|
||||
(declare-const y (_ BitVec 8))
|
||||
(define-fun A0 () (Array (_ BitVec 2) (_ BitVec 8)) ((as const (Array (_ BitVec 2) (_ BitVec 8))) x))
|
||||
(define-fun A1 () (Array (_ BitVec 2) (_ BitVec 8)) ((as const (Array (_ BitVec 2) (_ BitVec 8))) y))
|
||||
(declare-const i0 (_ BitVec 2))
|
||||
(declare-const e0 (_ BitVec 8))
|
||||
(declare-const i1 (_ BitVec 2))
|
||||
(declare-const e1 (_ BitVec 8))
|
||||
(assert (distinct x y))
|
||||
(assert (= (store A0 i0 e0) (store A1 i1 e1)))
|
||||
(check-sat)
|
||||
)";
|
||||
std::string resp = Z3_eval_smtlib2_string(ctx, script);
|
||||
ENSURE(resp.find("unsat") != std::string::npos);
|
||||
Z3_del_config(cfg);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
void tst_mod_factor() {
|
||||
test_mod_factor_mod_path();
|
||||
test_mod_factor_idiv_path();
|
||||
test_const_array_store_chain_unsat();
|
||||
}
|
||||
|
|
@ -207,13 +207,82 @@ void test_nla_intervals_fractional() {
|
|||
VERIFY(true); // Placeholder
|
||||
}
|
||||
|
||||
void test_fetch_normalized_term_column() {
|
||||
std::cout << "test_fetch_normalized_term_column\n";
|
||||
|
||||
lp::lar_solver s;
|
||||
|
||||
// Create some variables
|
||||
lpvar x = s.add_var(0, true); // j0
|
||||
lpvar y = s.add_var(1, true); // j1
|
||||
lpvar z = s.add_var(2, true); // j2
|
||||
|
||||
// Add a term t = 2*x + 3*y and register it
|
||||
lp::lar_term t;
|
||||
t.add_monomial(rational(2), x);
|
||||
t.add_monomial(rational(3), y);
|
||||
s.add_term(t.coeffs_as_vector(), UINT_MAX);
|
||||
s.register_existing_terms();
|
||||
|
||||
// Now build the same term independently and look it up
|
||||
lp::lar_term query;
|
||||
query.add_monomial(rational(2), x);
|
||||
query.add_monomial(rational(3), y);
|
||||
lp::mpq a;
|
||||
lp::lar_term norm_query = query.get_normalized_by_min_var(a);
|
||||
|
||||
std::pair<lp::mpq, lpvar> result;
|
||||
bool found = s.fetch_normalized_term_column(norm_query, result);
|
||||
VERIFY(found);
|
||||
std::cout << " round-trip lookup: " << (found ? "PASS" : "FAIL") << "\n";
|
||||
|
||||
// Build query with variables added in reverse order
|
||||
lp::lar_term query_rev;
|
||||
query_rev.add_monomial(rational(3), y);
|
||||
query_rev.add_monomial(rational(2), x);
|
||||
lp::lar_term norm_rev = query_rev.get_normalized_by_min_var(a);
|
||||
|
||||
bool found_rev = s.fetch_normalized_term_column(norm_rev, result);
|
||||
VERIFY(found_rev);
|
||||
std::cout << " reverse-order lookup: " << (found_rev ? "PASS" : "FAIL") << "\n";
|
||||
|
||||
// Test a 3-variable term: x - y + 5*z
|
||||
lp::lar_term t2;
|
||||
t2.add_monomial(rational(1), x);
|
||||
t2.add_monomial(rational(-1), y);
|
||||
t2.add_monomial(rational(5), z);
|
||||
s.add_term(t2.coeffs_as_vector(), UINT_MAX);
|
||||
s.register_existing_terms();
|
||||
|
||||
lp::lar_term query2;
|
||||
query2.add_monomial(rational(1), x);
|
||||
query2.add_monomial(rational(-1), y);
|
||||
query2.add_monomial(rational(5), z);
|
||||
lp::lar_term norm2 = query2.get_normalized_by_min_var(a);
|
||||
|
||||
found = s.fetch_normalized_term_column(norm2, result);
|
||||
VERIFY(found);
|
||||
std::cout << " 3-variable term lookup: " << (found ? "PASS" : "FAIL") << "\n";
|
||||
|
||||
// Test that a non-registered term is NOT found
|
||||
lp::lar_term query3;
|
||||
query3.add_monomial(rational(7), x);
|
||||
query3.add_monomial(rational(11), y);
|
||||
lp::lar_term norm3 = query3.get_normalized_by_min_var(a);
|
||||
|
||||
bool found_missing = s.fetch_normalized_term_column(norm3, result);
|
||||
VERIFY(!found_missing);
|
||||
std::cout << " non-existent term not found: " << (!found_missing ? "PASS" : "FAIL") << "\n";
|
||||
}
|
||||
|
||||
void test_nla_intervals() {
|
||||
test_nla_intervals_basic();
|
||||
test_nla_intervals_negative();
|
||||
test_nla_intervals_negative();
|
||||
test_nla_intervals_zero_crossing();
|
||||
test_nla_intervals_power();
|
||||
test_nla_intervals_mixed_signs();
|
||||
test_nla_intervals_fractional();
|
||||
test_fetch_normalized_term_column();
|
||||
}
|
||||
|
||||
} // namespace nla
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
|
||||
#include "api/z3.h"
|
||||
#include "api/z3_private.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include "util/util.h"
|
||||
#include "util/trace.h"
|
||||
|
|
@ -211,6 +212,26 @@ static void test_array() {
|
|||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
static void test_sat_smt_ufbv_predicate_model_validation() {
|
||||
Z3_context ctx = Z3_mk_context(nullptr);
|
||||
const char* result =
|
||||
Z3_eval_smtlib2_string(ctx,
|
||||
"(set-logic QF_UFBV)\n"
|
||||
"(set-option :sat.smt true)\n"
|
||||
"(set-option :model_validate true)\n"
|
||||
"(declare-fun p ((_ BitVec 4)) Bool)\n"
|
||||
"(declare-const x (_ BitVec 4))\n"
|
||||
"(declare-const y (_ BitVec 4))\n"
|
||||
"(assert (xor (p x) (p y)))\n"
|
||||
"(assert (bvuge x (_ bv1 4)))\n"
|
||||
"(assert (bvult y (_ bv1 4)))\n"
|
||||
"(check-sat)\n"
|
||||
"(get-model)\n");
|
||||
ENSURE(std::strstr(result, "sat") != nullptr);
|
||||
ENSURE(std::strstr(result, "invalid model") == nullptr);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
void tst_simplifier() {
|
||||
|
||||
test_array();
|
||||
|
|
@ -218,4 +239,5 @@ void tst_simplifier() {
|
|||
test_datatypes();
|
||||
test_bool();
|
||||
test_skolemize_bug();
|
||||
test_sat_smt_ufbv_predicate_model_validation();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,6 +160,39 @@ void test_repeated_eval() {
|
|||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
void test_ho_curried_application() {
|
||||
char const* spec =
|
||||
"(set-logic HO_ALL)\n"
|
||||
"(declare-fun transfer () (-> (-> Int Bool) (-> Int Bool)))\n"
|
||||
"(assert (forall ((P (-> Int Bool))) (=> (P 0) ((transfer P) 0))))\n"
|
||||
"(declare-fun top () (-> Int Bool))\n"
|
||||
"(assert (forall ((x Int)) (top x)))\n"
|
||||
"(assert (not ((transfer top) 0)))\n"
|
||||
"(check-sat)\n";
|
||||
|
||||
Z3_context ctx = Z3_mk_context(nullptr);
|
||||
Z3_set_error_handler(ctx, setError);
|
||||
test_eval(ctx, spec, false);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
void test_ho_choice_expression() {
|
||||
char const* spec =
|
||||
"(set-logic HO_ALL)\n"
|
||||
"(declare-sort U 0)\n"
|
||||
"(declare-fun P () (-> U Bool))\n"
|
||||
"(assert (exists ((x U)) (P x)))\n"
|
||||
"(declare-fun witness () U)\n"
|
||||
"(assert (= witness (choice ((x U)) (P x))))\n"
|
||||
"(assert (not (P witness)))\n"
|
||||
"(check-sat)\n";
|
||||
|
||||
Z3_context ctx = Z3_mk_context(nullptr);
|
||||
Z3_set_error_handler(ctx, setError);
|
||||
test_eval(ctx, spec, false);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
void test_name(Z3_string spec, Z3_string expected_name) {
|
||||
Z3_context ctx = Z3_mk_context(nullptr);
|
||||
Z3_set_error_handler(ctx, setError);
|
||||
|
|
@ -289,6 +322,8 @@ void tst_smt2print_parse() {
|
|||
// Test ?
|
||||
|
||||
test_repeated_eval();
|
||||
test_ho_curried_application();
|
||||
test_ho_choice_expression();
|
||||
|
||||
test_symbol_escape();
|
||||
|
||||
|
|
|
|||
126
src/test/tptp.cpp
Normal file
126
src/test/tptp.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "util/debug.h"
|
||||
#include "util/error_codes.h"
|
||||
#include "cmd_context/tptp_frontend.h"
|
||||
|
||||
struct tptp_case {
|
||||
char const* name;
|
||||
char const* input;
|
||||
char const* expected_status;
|
||||
};
|
||||
|
||||
static unsigned run_tptp(char const* input, std::string& out, std::string& err) {
|
||||
std::streambuf* old_out = std::cout.rdbuf();
|
||||
std::streambuf* old_err = std::cerr.rdbuf();
|
||||
std::ostringstream out_buf;
|
||||
std::ostringstream err_buf;
|
||||
std::cout.rdbuf(out_buf.rdbuf());
|
||||
std::cerr.rdbuf(err_buf.rdbuf());
|
||||
unsigned code = read_tptp_string(input);
|
||||
std::cout.rdbuf(old_out);
|
||||
std::cerr.rdbuf(old_err);
|
||||
out = out_buf.str();
|
||||
err = err_buf.str();
|
||||
return code;
|
||||
}
|
||||
|
||||
static std::string run_tptp(char const* input) {
|
||||
std::string out, err;
|
||||
unsigned code = run_tptp(input, out, err);
|
||||
ENSURE(code == 0);
|
||||
return out;
|
||||
}
|
||||
|
||||
extern bool g_display_statistics;
|
||||
extern bool g_display_model;
|
||||
|
||||
void tst_tptp() {
|
||||
g_display_statistics = false;
|
||||
g_display_model = false;
|
||||
std::vector<tptp_case> cases = {
|
||||
{"agatha-butler",
|
||||
R"(fof(ax1,axiom, lives(agatha)).
|
||||
fof(ax2,axiom, lives(butler)).
|
||||
fof(ax3,axiom, lives(charles)).
|
||||
fof(ax4,axiom, ! [X] : (lives(X) => (X = agatha | X = butler | X = charles))).
|
||||
fof(ax5,axiom, ! [X,Y] : (killed(X,Y) => hates(X,Y))).
|
||||
fof(ax6,axiom, ! [X,Y] : (killed(X,Y) => ~ richer(X,Y))).
|
||||
fof(ax7,axiom, ! [X] : (hates(agatha,X) => ~ hates(charles,X))).
|
||||
fof(ax8,axiom, ! [X] : (X != butler => hates(agatha,X))).
|
||||
fof(ax9,axiom, ! [X] : (~ richer(X,agatha) => hates(butler,X))).
|
||||
fof(ax10,axiom, ! [X] : (hates(agatha,X) => hates(butler,X))).
|
||||
fof(ax11,axiom, ! [X] : (? [Y] : ~ hates(X,Y))).
|
||||
fof(ax12,axiom, agatha != butler).
|
||||
fof(ax13,axiom, ? [X] : killed(X,agatha)).
|
||||
fof(conj,conjecture, ~ killed(butler,agatha)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"socrates-theorem",
|
||||
R"(fof(a1,axiom, ! [X] : (human(X) => mortal(X))).
|
||||
fof(a2,axiom, human(socrates)).
|
||||
fof(c1,conjecture, mortal(socrates)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"simple-sat",
|
||||
R"(fof(a1,axiom, p(a)).)",
|
||||
"% SZS status Satisfiable"},
|
||||
{"fof-implicit-forall",
|
||||
R"(fof(a1,axiom, p(X)).
|
||||
fof(c1,conjecture, p(a)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"cnf-implicit-forall",
|
||||
R"(cnf(c1,axiom, p(X)).
|
||||
cnf(c2,axiom, ~ p(a)).)",
|
||||
"% SZS status Unsatisfiable"},
|
||||
// {"fof-bare-constant-equality",
|
||||
// R"(fof(a1,axiom, ! [X] : (X = a)).
|
||||
//fof(c1,conjecture, b = a).)",
|
||||
// "% SZS status Theorem"},
|
||||
{"tff-negative-literal",
|
||||
R"(tff(c1,conjecture, $less(-2,2)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-rational-literal",
|
||||
R"(tff(c1,conjecture, $less(1/2,2/3)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-type-decl-arrow",
|
||||
R"(tff(p_type,type, p: $int > $o ).
|
||||
tff(a1,axiom, p(1)).
|
||||
tff(c1,conjecture, p(1)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-typed-int-quantifier",
|
||||
R"(tff(c1,conjecture, ? [X: $int] : $less(12,X)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-lesseq-built-in",
|
||||
R"(tff(c1,conjecture, $lesseq(2,2)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-bare-integer-equality",
|
||||
R"(tff(c1,conjecture, 31 != 12).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-decimal-literal",
|
||||
R"(tff(c1,conjecture, ~ $less(-3.25,-8.69)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-uminus-built-in",
|
||||
R"(tff(c1,conjecture, $less($uminus(2),0)).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-let-single-binding",
|
||||
R"(tff(c1,conjecture, $let(a: $int, a := 3, $less(a,4))).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-let-multiple-bindings",
|
||||
R"(tff(c1,conjecture, $let([a: $int, b: $int], [a := 1, b := 2], $less($sum(a,b),4))).)",
|
||||
"% SZS status Theorem"},
|
||||
{"tff-let-nested",
|
||||
R"(tff(c1,conjecture, $let(a: $int, a := 5, $let(b: $int, b := 3, $less(b,a)))).)",
|
||||
"% SZS status Theorem"}
|
||||
};
|
||||
for (auto const& c : cases) {
|
||||
std::string out = run_tptp(c.input);
|
||||
std::cout << c.name << " status: " << c.expected_status << " out: " << out << "\n";
|
||||
ENSURE(out.find(c.expected_status) != std::string::npos);
|
||||
}
|
||||
|
||||
std::string out, err;
|
||||
unsigned code = run_tptp("tff(c1,conjecture, $less(1/0,1)).", out, err);
|
||||
ENSURE(code == ERR_PARSER);
|
||||
ENSURE(err.find("denominator of rational literal cannot be zero") != std::string::npos);
|
||||
}
|
||||
|
|
@ -6,7 +6,9 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
|
||||
#include "muz/rel/udoc_relation.h"
|
||||
#include "util/trace.h"
|
||||
#include "util/gparams.h"
|
||||
#include "util/vector.h"
|
||||
#include "util/gparams.h"
|
||||
#include "ast/ast.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "ast/reg_decl_plugins.h"
|
||||
|
|
@ -35,6 +37,7 @@ class udoc_tester {
|
|||
|
||||
struct init {
|
||||
init(ast_manager& m) {
|
||||
gparams::set("fp.engine", "datalog");
|
||||
reg_decl_plugins(m);
|
||||
}
|
||||
};
|
||||
|
|
@ -44,6 +47,7 @@ class udoc_tester {
|
|||
bv_util bv;
|
||||
expr_ref_vector m_vars;
|
||||
smt_params m_smt_params;
|
||||
params_ref m_fp_params;
|
||||
datalog::register_engine m_reg;
|
||||
datalog::context m_ctx;
|
||||
datalog::rel_context rc;
|
||||
|
|
@ -113,7 +117,7 @@ class udoc_tester {
|
|||
|
||||
public:
|
||||
udoc_tester():
|
||||
m_init(m), bv(m), m_vars(m), m_ctx(m, m_reg, m_smt_params), rc(m_ctx),
|
||||
m_init(m), bv(m), m_vars(m), m_ctx(m, m_reg, m_smt_params, m_fp_params), rc(m_ctx),
|
||||
p(dynamic_cast<udoc_plugin&>(*rc.get_rmanager().get_relation_plugin(symbol("doc")))),
|
||||
cr(dynamic_cast<datalog::check_relation_plugin&>(*rc.get_rmanager().get_relation_plugin(symbol("check_relation"))))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue