static void tst17() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m), d2(m), d3(m); d1 = m.mk_empty(3); add_triple(m, d1, 5, 15, 10, 10, 50, 500); std::cout << mk_ll_pp(d1, m) << "\n"; m.mk_filter_disequal(d1, d2, 1, 10); std::cout << "filter_disequal(var1,10):\n"; std::cout << mk_ll_pp(d2, m) << "\n"; }
static void tst15() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m), d2(m), d3(m); d1 = m.mk_empty(3); add_triple(m, d1, 5, 5, 1, 10, 5, 5); std::cout << mk_ll_pp(d1, m) << "\n"; m.mk_filter_distinct(d1, d2, 0, 2); std::cout << "filter_distinct(0,2):\n"; std::cout << mk_ll_pp(d2, m) << "\n"; }
static void tst10() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m), d2(m), d3(m); d1 = m.mk_empty(3); add_triple(m, d1, 5, 100, 10, 20, 3, 10); add_triple(m, d1, 5, 100, 34, 50, 98, 110); m.add_bounded_var(d1, d2, 0, 66, 72); std::cout << mk_ll_pp(d1, m) << "\n"; std::cout << mk_ll_pp(d2, m) << "\n"; m.add_bounded_var(d1, d3, 1, 64, 73); std::cout << mk_ll_pp(d3, m) << "\n"; }
static void tst11() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m), d2(m), d3(m); d1 = m.mk_empty(3); add_triple(m, d1, 5, 100, 10, 20, 3, 10); add_triple(m, d1, 5, 100, 34, 50, 98, 110); add_triple(m, d1, 20, 30, 5, 25, 11, 13); m.mk_filter_distinct(d1, d2, 1, 2); std::cout << mk_ll_pp(d1, m) << "\n"; std::cout << "filter_distinct(1,2):\n"; std::cout << mk_ll_pp(d2, m) << "\n"; }
static void tst14() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m), d2(m), d3(m); d1 = m.mk_empty(3); add_triple(m, d1, 5, 25, 1, 10, 10, 13); add_triple(m, d1, 5, 25, 20, 30, 15, 18); std::cout << "destructive version\n"; std::cout << mk_ll_pp(d1, m) << "\n"; m.mk_filter_distinct_dupdt(d1, 0, 2); std::cout << "filter_distinct(0,2):\n"; std::cout << mk_ll_pp(d1, m) << "\n"; }
static void tst7() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d2(m), d3(m); d2 = m.mk_empty(3); add_triple(m, d2, 15, 22, 15, 23, 7, 18); add_triple(m, d2, 28, 42, 29, 39, 34, 46); add_triple(m, d2, 28, 42, 29, 39, 100, 200); add_triple(m, d2, 28, 42, 50, 60, 100, 200); std::cout << "mk_project\n"; std::cout << mk_ll_pp(d2, m) << "\n"; unsigned vars[1] = {1}; m.mk_project(d2, d3, 1, vars); std::cout << mk_ll_pp(d3, m) << "\n"; }
static void tst9() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d2(m), d3(m); d2 = m.mk_empty(5); add_5tuple(m, d2, 2,2, 3,3, 1, 1, 5, 10, 100, 200); std::cout << mk_ll_pp(d2, m) << "\n"; add_5tuple(m, d2, 2,2, 3,3, 1, 1, 15, 20, 100, 200); std::cout << mk_ll_pp(d2, m) << "\n"; add_5tuple(m, d2, 4,4, 5,5, 1, 1, 5, 10, 100, 200); std::cout << mk_ll_pp(d2, m) << "\n"; add_5tuple(m, d2, 4,4, 5,5, 1, 1, 15, 20, 100, 200); std::cout << mk_ll_pp(d2, m) << "\n"; m.mk_swap(d2, d3, 2); std::cout << "after swap 2<->3\n"; std::cout << mk_ll_pp(d3, m) << "\n"; }
void distribute_forall::operator()(expr * f, expr_ref & result) { m_todo.reset(); flush_cache(); m_todo.push_back(f); while (!m_todo.empty()) { expr * e = m_todo.back(); if (visit_children(e)) { m_todo.pop_back(); reduce1(e); } } result = get_cached(f); SASSERT(result!=0); TRACE("distribute_forall", tout << mk_ll_pp(f, m_manager) << "======>\n" << mk_ll_pp(result, m_manager););
static void tst8() { std::cout << "--------------------------------\n"; // enable_trace("mk_swap_bug"); imdd_manager m; imdd_ref d2(m), d3(m); d2 = m.mk_empty(3); add_triple(m, d2, 15, 22, 15, 23, 7, 18); add_triple(m, d2, 28, 42, 29, 39, 34, 46); add_triple(m, d2, 28, 42, 29, 39, 100, 200); add_triple(m, d2, 28, 42, 50, 60, 100, 200); std::cout << mk_ll_pp(d2, m) << "\n"; m.mk_swap(d2, d3, 0); std::cout << "after swap 0<->1\n"; std::cout << mk_ll_pp(d3, m) << "\n"; m.mk_swap(d2, d3, 1); std::cout << "after swap 1<->2\n"; std::cout << mk_ll_pp(d3, m) << "\n"; }
static void tst0() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m), d2(m), d3(m), d4(m); d1 = m.mk_empty(1); d2 = m.mk_empty(1); m.insert_dupdt(d1, 10, 20); m.insert_dupdt(d1, 31, 50); m.insert_dupdt(d2, 1, 5); m.insert_dupdt(d2, 11, 13); m.mk_product(d1, d2, d4); m.mk_product(d4, d2, d4); m.mk_product_dupdt(d1, d2); std::cout << "d1:\n" << mk_ll_pp(d1, m) << "\n-------\n"; m.mk_product_dupdt(d1, d2); std::cout << "d4:\n" << mk_ll_pp(d4, m) << "\nd1:\n" << mk_ll_pp(d1, m) << "\nd2:\n" << mk_ll_pp(d2, m) << "\n"; std::cout << d1 << "\n" << d2 << "\n"; m.mk_product_dupdt(d1, d1); std::cout << "d1 X d1:\n" << mk_ll_pp(d1, m) << "\n"; }
/** \brief Little HACK for simplifying injectivity axioms \remark It is not covering all possible cases. */ bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) { expr * n = q->get_expr(); if (q->is_forall() && m.is_or(n) && to_app(n)->get_num_args() == 2) { expr * arg1 = to_app(n)->get_arg(0); expr * arg2 = to_app(n)->get_arg(1); if (m.is_not(arg2)) std::swap(arg1, arg2); if (m.is_not(arg1) && m.is_eq(to_app(arg1)->get_arg(0)) && m.is_eq(arg2)) { expr * app1 = to_app(to_app(arg1)->get_arg(0))->get_arg(0); expr * app2 = to_app(to_app(arg1)->get_arg(0))->get_arg(1); expr * var1 = to_app(arg2)->get_arg(0); expr * var2 = to_app(arg2)->get_arg(1); if (is_app(app1) && is_app(app2) && to_app(app1)->get_decl() == to_app(app2)->get_decl() && to_app(app1)->get_num_args() == to_app(app2)->get_num_args() && to_app(app1)->get_family_id() == null_family_id && to_app(app1)->get_num_args() > 0 && is_var(var1) && is_var(var2) && var1 != var2) { app * f1 = to_app(app1); app * f2 = to_app(app2); bool found_vars = false; unsigned num = f1->get_num_args(); unsigned idx = UINT_MAX; unsigned num_vars = 1; for (unsigned i = 0; i < num; i++) { expr * c1 = f1->get_arg(i); expr * c2 = f2->get_arg(i); if (!is_var(c1) && !is_uninterp_const(c1)) return false; if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) { if (found_vars) return false; found_vars = true; idx = i; } else if (c1 == c2 && c1 != var1 && c1 != var2) { if (is_var(c1)) { ++num_vars; } } else { return false; } } if (found_vars && !has_free_vars(q)) { TRACE("inj_axiom", tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" << mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";);
static void tst5() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m), d2(m), d3(m); std::cout.flush(); d1 = m.mk_empty(3); add_triple(m, d1, 5, 100, 10, 20, 3, 10); std::cout << mk_ll_pp(d1,m) << std::endl; add_triple(m, d1, 5, 100, 34, 50, 98, 110); std::cout << mk_ll_pp(d1,m) << std::endl; unsigned vals[3] = {6, 8, 3}; SASSERT(!m.contains(d1, 3, vals)); add_triple(m, d1, 6, 25, 8, 30, 14, 50); std::cout << mk_ll_pp(d1,m) << std::endl; SASSERT(!m.contains(d1, 3, vals)); unsigned vars[2] = {0, 2}; d2 = d1; d3 = d1; m.mk_filter_identical(d1, d1, 2, vars); vars[1] = 1; std::cout << "d1:\n" << mk_ll_pp(d1,m) << "\n"; m.mk_filter_identical(d2, d2, 2, vars); std::cout << "d2:\n" << mk_ll_pp(d2,m) << "\n"; vars[0] = 1; vars[1] = 2; m.mk_filter_identical(d3, d3, 2, vars); std::cout << "d3:\n" << mk_ll_pp(d3,m) << "\n"; }
static void add_some_facts(imdd_manager & m, imdd_ref & d, bool destructive = false, bool memoize = true) { std::cout << "destructive: " << destructive << ", memoize: " << memoize << std::endl; add_triple(m, d, 1, 10, 3, 3, 0, 100, destructive, memoize); std::cout << mk_ll_pp(d, m) << std::endl; SASSERT(m.contains(d, 2, 3, 20)); SASSERT(!m.contains(d, 2, 4, 20)); SASSERT(!m.contains(d, 2, 3, 200)); SASSERT(!m.contains(d, 0, 3, 200)); SASSERT(m.contains(d,1,3,0)); add_triple(m, d, 3, 6, 3, 4, 7, 101, destructive, memoize); std::cout << mk_ll_pp(d, m) << std::endl; add_triple(m, d, 3, 6, 2, 2, 7, 101, destructive, memoize); std::cout << mk_ll_pp(d, m) << std::endl; add_triple(m, d, 3, 6, 5, 6, 7, 101, destructive, memoize); SASSERT(m.contains(d, 2, 3, 20)); std::cout << mk_ll_pp(d, m) << std::endl; SASSERT(!m.contains(d, 2, 4, 20)); SASSERT(m.contains(d, 3, 4, 20)); SASSERT(!m.contains(d, 2, 3, 200)); SASSERT(!m.contains(d, 0, 3, 200)); SASSERT(m.contains(d,1,3,0)); }
static void tst3() { std::cout << "--------------------------------\n"; imdd_manager m; imdd_ref d1(m); d1 = m.mk_empty(3); unsigned mins[3] = {0,0,0}; unsigned maxs[3] = {127, 511, 255}; m.mk_complement(d1, d1, 3, mins, maxs); std::cout << d1 << "\n"; m.mk_complement(d1, d1, 3, mins, maxs); std::cout << d1 << "\n"; SASSERT(d1->empty()); d1 = m.mk_empty(3); add_triple(m, d1, 10, 20, 11, 21, 12, 22); add_triple(m, d1, 30, 40, 31, 41, 32, 42); std::cout << d1 << "\n"; m.mk_complement(d1, d1, 3, mins, maxs); std::cout << mk_ll_pp(d1,m) << "\n"; m.mk_filter_equal(d1, d1, 1, 15); std::cout << "after selecting second column = 15\n" << mk_ll_pp(d1,m) << "\n"; }
static void tst1() { std::cout << "--------------------------------\n"; imdd_manager m; { imdd_ref d(m); d = m.mk_empty(3); add_some_facts(m, d); } { imdd_ref d(m); d = m.mk_empty(3); add_some_facts(m, d, true, false); m.defrag(d); std::cout << mk_ll_pp(d, m) << "\n"; } }
/** \brief External interface for the simplifier. A client will invoke operator()(s, r, p) to simplify s. The result is stored in r. When proof generation is enabled, a proof for the equivalence (or equisatisfiability) of s and r is stored in p. When proof generation is disabled, this method stores the "undefined proof" object in p. */ void simplifier::operator()(expr * s, expr_ref & r, proof_ref & p) { m_need_reset = true; reinitialize(); expr * s_orig = s; expr * old_s; expr * result; proof * result_proof; switch (m.proof_mode()) { case PGM_DISABLED: // proof generation is disabled. reduce_core(s); // after executing reduce_core, the result of the simplification is in the cache get_cached(s, result, result_proof); r = result; p = m.mk_undef_proof(); break; case PGM_COARSE: // coarse proofs... in this case, we do not produce a step by step (fine grain) proof to show the equivalence (or equisatisfiability) of s an r. m_subst_proofs.reset(); // m_subst_proofs is an auxiliary vector that is used to justify substitutions. See comment on method get_subst. reduce_core(s); get_cached(s, result, result_proof); r = result; if (result == s) p = m.mk_reflexivity(s); else { remove_duplicates(m_subst_proofs); p = m.mk_rewrite_star(s, result, m_subst_proofs.size(), m_subst_proofs.c_ptr()); } break; case PGM_FINE: // fine grain proofs... in this mode, every proof step (or most of them) is described. m_proofs.reset(); old_s = 0; // keep simplyfing until no further simplifications are possible. while (s != old_s) { TRACE("simplifier", tout << "simplification pass... " << s->get_id() << "\n";); TRACE("simplifier_loop", tout << mk_ll_pp(s, m) << "\n";); reduce_core(s); get_cached(s, result, result_proof); SASSERT(is_rewrite_proof(s, result, result_proof)); if (result_proof != 0) { m_proofs.push_back(result_proof); } old_s = s; s = result; }
literal theory::mk_eq(expr * a, expr * b, bool gate_ctx) { context & ctx = get_context(); app * eq = ctx.mk_eq_atom(a, b); TRACE("mk_var_bug", tout << "mk_eq: " << eq->get_id() << " " << a->get_id() << " " << b->get_id() << "\n"; tout << mk_ll_pp(a, get_manager()) << "\n" << mk_ll_pp(b, get_manager()););
void goal::display_ll(std::ostream & out) const { unsigned sz = size(); for (unsigned i = 0; i < sz; i++) { out << mk_ll_pp(form(i), m()) << "\n"; } }
static void tst21() { std::cout << "--------------------------------\n"; std::cout << "remove_facts\n"; imdd_manager m; imdd_ref d2(m), d3(m); d2 = m.mk_empty(3); add_triple(m, d2, 15, 22, 15, 23, 7, 18); add_triple(m, d2, 28, 42, 29, 39, 34, 46); add_triple(m, d2, 28, 42, 29, 39, 100, 200); add_triple(m, d2, 28, 42, 50, 60, 100, 200); std::cout << mk_ll_pp(d2, m) << "\n"; // // [15, 22] -> #1:{ // [15, 23] -> {[7, 18]}*$80}*$80 // [28, 42] -> #2:{ // [29, 39] -> {[34, 46], [100, 200]}*$160 // [50, 60] -> {[100, 200]}*$80}*$80}$80 // unsigned lowers[3] = {23,1,1}; unsigned uppers[3] = {24,1,1}; d3 = d2; m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (no change)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; d2 = d3; lowers[0] = 22; m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (no change)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; init(lowers, 22, 15, 0); init(uppers, 24, 23, 0); m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (no change)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; init(lowers, 22, 15, 7); init(uppers, 24, 23, 18); m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (narrow first interval)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; init(lowers, 22, 15, 8); init(uppers, 24, 23, 18); m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (split first interval)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; init(lowers, 22, 15, 8); init(uppers, 24, 23, 17); m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (split first interval)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; init(lowers, 22, 15, 8); init(uppers, 24, 23, 19); m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (split first interval)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; init(lowers, 30, 20, 120); init(uppers, 40, 60, 140); m.remove_facts_dupdt(d2, 3, lowers, uppers); std::cout << "new table (split second interval)\n"; std::cout << mk_ll_pp(d2, m) << "\n"; }
/** \brief Little HACK for simplifying injectivity axioms \remark It is not covering all possible cases. */ bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) { expr * n = q->get_expr(); expr* arg1 = nullptr, * arg2 = nullptr, *narg = nullptr; expr* app1 = nullptr, * app2 = nullptr; expr* var1 = nullptr, * var2 = nullptr; if (is_forall(q) && m.is_or(n, arg1, arg2)) { if (m.is_not(arg2)) std::swap(arg1, arg2); if (m.is_not(arg1, narg) && m.is_eq(narg, app1, app2) && m.is_eq(arg2, var1, var2)) { if (is_app(app1) && is_app(app2) && to_app(app1)->get_decl() == to_app(app2)->get_decl() && to_app(app1)->get_num_args() == to_app(app2)->get_num_args() && to_app(app1)->get_family_id() == null_family_id && to_app(app1)->get_num_args() > 0 && is_var(var1) && is_var(var2) && var1 != var2) { app * f1 = to_app(app1); app * f2 = to_app(app2); bool found_vars = false; unsigned num = f1->get_num_args(); unsigned idx = UINT_MAX; unsigned num_vars = 1; for (unsigned i = 0; i < num; i++) { expr * c1 = f1->get_arg(i); expr * c2 = f2->get_arg(i); if (!is_var(c1) && !is_uninterp_const(c1)) return false; if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) { if (found_vars) return false; found_vars = true; idx = i; } else if (c1 == c2 && c1 != var1 && c1 != var2) { if (is_var(c1)) { ++num_vars; } } else { return false; } } if (found_vars && !has_free_vars(q)) { TRACE("inj_axiom", tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" << mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";); // Building new (optimized) axiom func_decl * decl = f1->get_decl(); unsigned var_idx = 0; ptr_buffer<expr> f_args, inv_vars; ptr_buffer<sort> decls; buffer<symbol> names; expr * var = nullptr; for (unsigned i = 0; i < num; i++) { expr * c = f1->get_arg(i); if (is_var(c)) { names.push_back(symbol(i)); sort * s = decl->get_domain(i); decls.push_back(s); expr * new_c = m.mk_var(var_idx, s); var_idx++; f_args.push_back(new_c); if (i == idx) { var = new_c; } else { inv_vars.push_back(new_c); } } else { SASSERT(is_uninterp_const(c)); f_args.push_back(c); } } SASSERT(var != 0); app * f = m.mk_app(decl, f_args.size(), f_args.c_ptr()); ptr_vector<sort> domain; inv_vars.push_back(f); for (unsigned i = 0; i < inv_vars.size(); ++i) { domain.push_back(m.get_sort(inv_vars[i])); } sort * d = decl->get_domain(idx); func_decl * inv_decl = m.mk_fresh_func_decl("inj", domain.size(), domain.c_ptr(), d); expr * proj = m.mk_app(inv_decl, inv_vars.size(), inv_vars.c_ptr()); expr * eq = m.mk_eq(proj, var); expr * p = m.mk_pattern(f); // decls are in the wrong order... // Remark: the sort of the var 0 must be in the last position. std::reverse(decls.begin(), decls.end()); result = m.mk_forall(decls.size(), decls.c_ptr(), names.c_ptr(), eq, 0, symbol(), symbol(), 1, &p); TRACE("inj_axiom", tout << "new axiom:\n" << mk_pp(result, m) << "\n";); SASSERT(is_well_sorted(m, result)); return true; }