void process_arith_atom(expr * lhs, expr * rhs, bool nested) { if (is_uninterp(lhs) && is_uninterp(rhs)) { visit(lhs, nested); visit(rhs, nested); return; } if (m_util.is_numeral(lhs)) std::swap(lhs, rhs); if (!m_util.is_numeral(rhs)) throw_failed(lhs, rhs); expr * t, * ms, * s; // check if lhs is of the form: (+ t (* (- 1) s)) if (m_util.is_add(lhs, t, ms) && m_util.is_times_minus_one(ms, s) && is_uninterp(t) && is_uninterp(s)) { visit(t, nested); visit(s, nested); } else { CTRACE("fix_dl_var", m_util.is_add(lhs, t, ms), s = 0; tout << "is_times_minus_one: " << m_util.is_times_minus_one(ms, s) << "\n"; tout << "is_uninterp(t): " << is_uninterp(t) << "\n"; tout << "t.family_id(): " << (is_app(t) ? to_app(t)->get_family_id() : -1) << "\n"; tout << "util.family_id: " << m_util.get_family_id() << "\n"; if (s) { tout << "is_uninterp(s): " << is_uninterp(s) << "\n"; tout << "s.family_id(): " << (is_app(s) ? to_app(s)->get_family_id() : -1) << "\n"; }); throw_failed(lhs, rhs); }
void operator()(app * n) { if (!compatible_sort(n)) throw found(); family_id fid = n->get_family_id(); if (fid == m.get_basic_family_id()) return; if (fid == m_arith_util.get_family_id()) { switch (n->get_decl_kind()) { case OP_LE: case OP_GE: case OP_LT: case OP_GT: case OP_ADD: case OP_NUM: return; case OP_MUL: if (n->get_num_args() != 2) throw found(); if (!m_arith_util.is_numeral(n->get_arg(0))) throw found(); return; case OP_TO_REAL: if (!m_real) throw found(); break; default: throw found(); } return; } if (is_uninterp(n)) return; throw found(); }
void variable_intersection::populate_self(const app * a) { SASSERT(is_uninterp(a)); //TODO: optimize quadratic complexity //TODO: optimize number of checks when variable occurs multiple times unsigned arity = a->get_num_args(); for(unsigned i1=0; i1<arity; i1++) { expr * e1=a->get_arg(i1); if(is_var(e1)) { var* v1=to_var(e1); for(unsigned i2=i1+1; i2<arity; i2++) { expr * e2=a->get_arg(i2); if(!is_var(e2)) { continue; } var* v2=to_var(e2); if(v1->get_idx()==v2->get_idx()) { add_pair(i1, i2); } } } else { SASSERT(is_app(e1)); app * c1 = to_app(e1); SASSERT(c1->get_num_args()==0); //c1 must be a constant m_const_indexes.push_back(i1); m_consts.push_back(c1); SASSERT(m_const_indexes.size()==m_consts.size()); } } }
void mk_safe(expr_ref_vector& conjs) { datalog::flatten_and(conjs); for (unsigned i = 0; i < conjs.size(); ++i) { expr * atom = conjs[i].get(); bool negated = m.is_not(atom, atom); //remove negation SASSERT(!m.is_true(atom)); if (!is_uninterp(atom) || to_app(atom)->get_num_args() != 0) { app * name = mk_fresh(atom); conjs[i] = negated?m.mk_not(name):name; } } }
unsigned count_variable_arguments(app * pred) { SASSERT(is_uninterp(pred)); unsigned res = 0; unsigned n = pred->get_num_args(); for (unsigned i = 0; i < n; i++) { expr * arg = pred->get_arg(i); if (is_var(arg)) { res++; } } return res; }
void mk_safe(expr_ref_vector& conjs) { qe::flatten_and(conjs); expand_literals(conjs); for (unsigned i = 0; i < conjs.size(); ++i) { expr * lit = conjs[i].get(); expr * lit_core = lit; m.is_not(lit, lit_core); SASSERT(!m.is_true(lit)); if (!is_uninterp(lit_core) || to_app(lit_core)->get_num_args() != 0) { conjs[i] = mk_proxy(lit); } } m_assumptions.append(conjs); }
bool quasi_macros::is_non_ground_uninterp(expr const * e) const { return is_non_ground(e) && is_uninterp(e); }
void tst_dl_rule_set() { enable_trace("mk_filter_rules"); front_end_params params; ast_manager m; smtlib::parser * parser = smtlib::parser::create(m); parser->initialize_smtlib(); datalog::context ctx(m, params); datalog::rule_set rs(ctx); datalog::rule_manager& rm = ctx.get_rule_manager(); datalog::rule_ref_vector rv(rm); if (!parser->parse_string( "(benchmark test\n" ":extrapreds ((T Int Int) (Q Int Int) (R Int Int Int) (S Int Int Int) (DynActual Int Int Int) (GlobalSym Int Int) (HeapPointsTo Int Int Int) (Calls Int Int)) \n" ":extrapreds ((Actual Int Int Int) (PointsTo Int Int) (PointsTo0 Int Int) (FuncDecl0 Int Int) (Assign Int Int) (Load Int Int Int))\n" ":formula (forall (x Int) (=> (Q x 1) (T x x)))\n" ":formula (forall (v Int) (h Int) (=> (PointsTo0 v h) (PointsTo v h)))\n" ":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n" ":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n" ":formula (forall (v1 Int) (v2 Int) (h Int) (=> (and (PointsTo v2 h) (Assign v1 v2)) (PointsTo v1 h)))\n" ":formula (forall (x Int) (y Int) (z Int) (=> (and (Q x y) (T y z)) (T x y)))\n" ":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 0 h1) (PointsTo v h1)) (DynActual i1 2 v)))\n" ":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 1 h1) (PointsTo v h1)) (DynActual i1 3 v)))\n" ":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 2 h1) (PointsTo v h1)) (DynActual i1 4 v)))\n" ":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 f) (PointsTo v1 h1) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n" ":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 0) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n" ":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (not (Load v2 v1 0)) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n" ")")) { SASSERT(false); dealloc(parser); return; } smtlib::benchmark * b = parser->get_benchmark(); for (unsigned j = 0; j < b->get_num_formulas(); ++j) { expr * e = b->begin_formulas()[j]; ptr_vector<expr> todo; todo.push_back(e); while (!todo.empty()) { e = todo.back(); todo.pop_back(); if (is_quantifier(e)) { e = to_quantifier(e)->get_expr(); todo.push_back(e); } else if (is_app(e)) { app* a = to_app(e); if (is_uninterp(e) && !ctx.is_predicate(a->get_decl())) { std::cout << "registering " << a->get_decl()->get_name() << "\n"; ctx.register_predicate(a->get_decl()); } else { todo.append(a->get_num_args(), a->get_args()); } } } } for (unsigned j = 0; j < b->get_num_formulas(); ++j) { expr * e = b->begin_formulas()[j]; if (is_quantifier(e)) { try { rm.mk_rule(e, rv); } catch(...) { std::cerr << "ERROR: it is not a valid Datalog rule:\n" << mk_pp(e, m) << "\n"; } } } rs.add_rules(rv.size(), rv.c_ptr()); rs.display(std::cout); datalog::mk_filter_rules p(ctx); model_converter_ref mc; proof_converter_ref pc; datalog::rule_set * new_rs = p(rs, mc, pc); std::cout << "\nAfter mk_filter:\n"; new_rs->display(std::cout); datalog::mk_simple_joins p2(ctx); datalog::rule_set * new_rs2 = p2(*new_rs, mc, pc); std::cout << "\nAfter mk_simple_joins:\n"; new_rs2->display(std::cout); dealloc(new_rs); dealloc(new_rs2); dealloc(parser); }