void expr_context_simplifier::reduce_rec(expr * m, expr_ref & result) { // // reduce expr in context evaluation. // bool polarity; if (m_context.find(m, polarity)) { result = polarity ? m_manager.mk_true() : m_manager.mk_false(); } else if (m_mark.is_marked(m) && !m_manager.is_not(m)) { result = m; } else if (is_quantifier(m)) { reduce_rec(to_quantifier(m), result); m_mark.mark(m, true); } else if (is_app(m)) { reduce_rec(to_app(m), result); m_mark.mark(m, true); } else if (is_var(m)) { result = m; m_mark.mark(m, true); } else { UNREACHABLE(); result = m; } }
bool expr_delta::delta_dfs(unsigned& n, expr* e, expr_ref& result) { ast_manager& m = m_manager; if (m.is_true(e) || m.is_false(e)) { return false; } if (n == 0 && m.is_bool(e)) { result = m.mk_true(); return true; } else if (n == 1 && m.is_bool(e)) { result = m.mk_false(); return true; } else if (is_app(e)) { if (m.is_bool(e)) { SASSERT(n >= 2); n -= 2; } return delta_dfs(n, to_app(e), result); } else if (is_quantifier(e)) { SASSERT(n >= 2); n -= 2; quantifier* q = to_quantifier(e); if (delta_dfs(n, q->get_expr(), result)) { result = m.update_quantifier(q, result.get()); return true; } else { return false; } } return false; }
void check_predicate(ast_mark& mark, expr* a) { ptr_vector<expr> todo; todo.push_back(a); while (!todo.empty()) { a = todo.back(); todo.pop_back(); if (mark.is_marked(a)) { continue; } mark.mark(a, true); if (is_quantifier(a)) { a = to_quantifier(a)->get_expr(); todo.push_back(a); } else if (m.is_not(a) || m.is_and(a) || m.is_or(a) || m.is_implies(a)) { todo.append(to_app(a)->get_num_args(), to_app(a)->get_args()); } else if (m.is_ite(a)) { todo.push_back(to_app(a)->get_arg(1)); todo.push_back(to_app(a)->get_arg(2)); } else if (is_predicate(a)) { register_predicate(a); } } }
// // Hoist quantifier from rule (universal) or query (existential) // unsigned rule_manager::hoist_quantifier(bool is_forall, expr_ref& fml, svector<symbol>* names) { unsigned index = var_counter().get_next_var(fml); while (is_quantifier(fml) && (is_forall == to_quantifier(fml)->is_forall())) { quantifier* q = to_quantifier(fml); index += q->get_num_decls(); if (names) { names->append(q->get_num_decls(), q->get_decl_names()); } fml = q->get_expr(); } if (!has_quantifiers(fml)) { return index; } app_ref_vector vars(m); quantifier_hoister qh(m); qh.pull_quantifier(is_forall, fml, vars); if (vars.empty()) { return index; } // replace vars by de-bruijn indices expr_substitution sub(m); for (unsigned i = 0; i < vars.size(); ++i) { app* v = vars[i].get(); if (names) { names->push_back(v->get_decl()->get_name()); } sub.insert(v, m.mk_var(index++,m.get_sort(v))); } scoped_ptr<expr_replacer> rep = mk_default_expr_replacer(m); rep->set_substitution(&sub); (*rep)(fml); return index; }
bool is_horn(expr* n) { expr* n1, *n2; while (is_forall(n)) n = to_quantifier(n)->get_expr(); if (m.is_implies(n, n1, n2) && is_predicate(n2)) { if (is_var(n1)) { return true; } if (is_quantifier(n1)) { return false; } app* a1 = to_app(n1); if (m.is_and(a1)) { for (unsigned i = 0; i < a1->get_num_args(); ++i) { if (!is_predicate(a1->get_arg(i)) && contains_predicate(a1->get_arg(i))) { return false; } } } else if (!is_predicate(a1) && contains_predicate(a1)) { return false; } return true; } return false; }
void collect(expr * t, expr_fast_mark1 & visited) { rational k; visit(t, visited); while (!m_todo.empty()) { checkpoint(); expr * t = m_todo.back(); m_todo.pop_back(); if (is_var(t)) continue; if (is_quantifier(t)) { unsigned num_children = to_quantifier(t)->get_num_children(); for (unsigned i = 0; i < num_children; i ++) visit(to_quantifier(t)->get_child(i), visited); } else { SASSERT(is_app(t)); if (m_autil.is_power(t) && m_autil.is_numeral(to_app(t)->get_arg(1), k) && k.is_int() && k.is_pos()) { expr * arg = to_app(t)->get_arg(0); save_degree(arg, k); visit_args(arg, visited); } else { visit_args(t, visited); } } } }
bool is_atom(ast_manager & m, expr * n) { if (is_quantifier(n) || !m.is_bool(n)) return false; if (is_var(n)) return true; SASSERT(is_app(n)); if (to_app(n)->get_family_id() != m.get_basic_family_id()) { return true; } // the other operators of the basic family are not considered atomic: distinct, ite, and, or, iff, xor, not, implies. return (m.is_eq(n) && !m.is_bool(to_app(n)->get_arg(0))) || m.is_true(n) || m.is_false(n); }
void quick_checker::collector::collect(expr * n, func_decl * f, unsigned idx) { if (is_quantifier(n)) return; if (is_var(n)) return; if (is_ground(n)) return; entry e(n, f, idx); if (m_cache.contains(e)) return; m_cache.insert(e); collect_core(to_app(n), f, idx); }
void print_answer(cmd_context& ctx) { if (m_params.get_bool(":print-answer", false)) { datalog::context& dlctx = m_dl_ctx->get_dl_context(); ast_manager& m = ctx.m(); expr_ref query_result(dlctx.get_answer_as_formula(), m); sbuffer<symbol> var_names; unsigned num_decls = 0; if (is_quantifier(m_target)) { num_decls = to_quantifier(m_target)->get_num_decls(); } ctx.display(ctx.regular_stream(), query_result, 0, num_decls, "X", var_names); ctx.regular_stream() << std::endl; } }
void tst_instantiate(ast_manager & m, expr * f) { if (is_quantifier(f)) { tst_instantiate(m, to_quantifier(f)->get_expr()); return; } quantifier * q = find_quantifier(f); if (q) { expr_ref_vector cnsts(m); for (unsigned i = 0; i < q->get_num_decls(); i++) cnsts.push_back(m.mk_fresh_const("a", q->get_decl_sort(i))); expr_ref r(m); instantiate(m, q, cnsts.c_ptr(), r); TRACE("var_subst", tout << "quantifier:\n" << mk_pp(q, m) << "\nresult:\n" << mk_pp(r, m) << "\n";); }
void fixedpoint_context::simplify_rules( unsigned num_rules, expr* const* rules, unsigned num_outputs, func_decl* const* outputs, expr_ref_vector& result) { ast_manager& m = m_context.get_manager(); datalog::context ctx(m, m_context.get_fparams()); datalog::rule_manager& rm = ctx.get_rule_manager(); for (unsigned i = 0; i < num_rules; ++i) { expr* rule = rules[i], *body, *head; while (true) { if (is_quantifier(rule)) { rule = to_quantifier(rule)->get_expr(); } else if (m.is_implies(rule, body, head)) { rule = head; } else { break; } } if (is_app(rule)) { func_decl* r = to_app(rule)->get_decl(); if (!ctx.is_predicate(r)) { ctx.register_predicate(r); if (num_outputs == 0) { ctx.set_output_predicate(r); } } } } for (unsigned i = 0; i < num_outputs; ++i) { ctx.set_output_predicate(outputs[i]); } for (unsigned i = 0; i < num_rules; ++i) { expr* rule = rules[i]; ctx.add_rule(rule, symbol::null); } model_converter_ref mc; // not exposed. proof_converter_ref pc; // not exposed. ctx.apply_default_transformation(mc, pc); datalog::rule_set const& new_rules = ctx.get_rules(); datalog::rule_set::iterator it = new_rules.begin(), end = new_rules.end(); for (; it != end; ++it) { datalog::rule* r = *it; expr_ref fml(m); r->to_formula(fml); result.push_back(fml); } }
bool is_well_formed_vars(ptr_vector<sort>& bound, expr* e) { ptr_vector<expr> todo; ast_mark mark; todo.push_back(e); while (!todo.empty()) { expr* e = todo.back(); todo.pop_back(); if (mark.is_marked(e)) { continue; } mark.mark(e, true); if (is_quantifier(e)) { quantifier* q = to_quantifier(e); unsigned depth = q->get_num_decls(); bound.append(depth, q->get_decl_sorts()); if (!is_well_formed_vars(bound, q->get_expr())) { return false; } bound.resize(bound.size()-depth); } else if (is_app(e)) { app* a = to_app(e); for (unsigned i = 0; i < a->get_num_args(); ++i) { todo.push_back(a->get_arg(i)); } } else if (is_var(e)) { var* v = to_var(e); unsigned index = v->get_idx(); sort* s = v->get_sort(); SASSERT(index < bound.size()); index = bound.size()-1-index; if (!bound[index]) { bound[index] = s; } if (bound[index] != s) { return false; } } else { UNREACHABLE(); } } return true; }
subpaving::var process(expr * t, unsigned depth, mpz & n, mpz & d) { SASSERT(is_int_real(t)); checkpoint(); if (is_cached(t)) { unsigned idx = m_cache.find(t); qm().set(n, m_cached_numerators[idx]); qm().set(d, m_cached_denominators[idx]); return m_cached_vars[idx]; } SASSERT(!is_quantifier(t)); if (::is_var(t) || !m_autil.is_arith_expr(t)) { qm().set(n, 1); qm().set(d, 1); return mk_var_for(t); } return process_arith_app(to_app(t), depth, n, d); }
quantifier_stat * quantifier_stat_gen::operator()(quantifier * q, unsigned generation) { reset(); quantifier_stat * r = new (m_region) quantifier_stat(generation); m_todo.push_back(entry(q->get_expr())); while (!m_todo.empty()) { entry & e = m_todo.back(); expr * n = e.m_expr; unsigned depth = e.m_depth; bool depth_only = e.m_depth_only; m_todo.pop_back(); unsigned old_depth; if (m_already_found.find(n, old_depth)) { if (old_depth >= depth) continue; depth_only = true; } m_already_found.insert(n, depth); if (depth >= r->m_depth) r->m_depth = depth; if (!depth_only) { r->m_size++; if (is_quantifier(n)) r->m_num_nested_quantifiers ++; if (is_app(n) && to_app(n)->get_family_id() == m_manager.get_basic_family_id()) { unsigned num_args = to_app(n)->get_num_args(); // Remark: I'm approximating the case_split factor. // I'm also ignoring the case split factor due to theories. switch (to_app(n)->get_decl_kind()) { case OP_OR: if (depth == 0) m_case_split_factor *= num_args; else m_case_split_factor *= (num_args + 1); break; case OP_AND: if (depth > 0) m_case_split_factor *= (num_args + 1); break; case OP_IFF: if (depth == 0) m_case_split_factor *= 4; else m_case_split_factor *= 9; break; case OP_ITE: if (depth == 0) m_case_split_factor *= 4; else m_case_split_factor *= 9; break; default: break; } } } if (is_app(n)) { unsigned j = to_app(n)->get_num_args(); while (j > 0) { --j; m_todo.push_back(entry(to_app(n)->get_arg(j), depth + 1, depth_only)); } } } r->m_case_split_factor = m_case_split_factor.get_value(); return r; }
/** \brief Returns true if n if of the form (forall (X) (iff (= (f X) t) def[X])) where t is a ground term, (f X) is the head. */ bool macro_util::is_pseudo_predicate_macro(expr * n, app * & head, app * & t, expr * & def) { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) return false; TRACE("macro_util", tout << "processing: " << mk_pp(n, m_manager) << "\n";);
static int bar(const char *re, int re_len, const char *s, int s_len, struct regex_info *info, int bi) { /* i is offset in re, j is offset in s, bi is brackets index */ int i, j, n, step; for (i = j = 0; i < re_len && j <= s_len; i += step) { /* Handle quantifiers. Get the length of the chunk. */ step = re[i] == '(' ? info->brackets[bi + 1].len + 2 : get_op_len(re + i, re_len - i); DBG(("%s [%.*s] [%.*s] re_len=%d step=%d i=%d j=%d\n", __func__, re_len - i, re + i, s_len - j, s + j, re_len, step, i, j)); FAIL_IF(is_quantifier(&re[i]), SLRE_UNEXPECTED_QUANTIFIER); FAIL_IF(step <= 0, SLRE_INVALID_CHARACTER_SET); if (i + step < re_len && is_quantifier(re + i + step)) { DBG(("QUANTIFIER: [%.*s]%c [%.*s]\n", step, re + i, re[i + step], s_len - j, s + j)); if (re[i + step] == '?') { int result = bar(re + i, step, s + j, s_len - j, info, bi); j += result > 0 ? result : 0; i++; } else if (re[i + step] == '+' || re[i + step] == '*') { int j2 = j, nj = j, n1, n2 = -1, ni, non_greedy = 0; /* Points to the regexp code after the quantifier */ ni = i + step + 1; if (ni < re_len && re[ni] == '?') { non_greedy = 1; ni++; } do { if ((n1 = bar(re + i, step, s + j2, s_len - j2, info, bi)) > 0) { j2 += n1; } if (re[i + step] == '+' && n1 < 0) break; if (ni >= re_len) { /* After quantifier, there is nothing */ nj = j2; } else if ((n2 = bar(re + ni, re_len - ni, s + j2, s_len - j2, info, bi)) >= 0) { /* Regex after quantifier matched */ nj = j2 + n2; } if (nj > j && non_greedy) break; } while (n1 > 0); if (n1 < 0 && re[i + step] == '*' && (n2 = bar(re + ni, re_len - ni, s + j, s_len - j, info, bi)) > 0) { nj = j + n2; } DBG(("STAR/PLUS END: %d %d %d %d %d\n", j, nj, re_len - ni, n1, n2)); FAIL_IF(re[i + step] == '+' && nj == j, SLRE_NO_MATCH); /* If while loop body above was not executed for the * quantifier, */ /* make sure the rest of the regex matches */ FAIL_IF(nj == j && ni < re_len && n2 < 0, SLRE_NO_MATCH); /* Returning here cause we've matched the rest of RE already */ return nj; } continue; } if (re[i] == '[') { n = match_set(re + i + 1, re_len - (i + 2), s + j, info); DBG(("SET %.*s [%.*s] -> %d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n <= 0, SLRE_NO_MATCH); j += n; } else if (re[i] == '(') { n = SLRE_NO_MATCH; bi++; FAIL_IF(bi >= info->num_brackets, SLRE_INTERNAL_ERROR); DBG(("CAPTURING [%.*s] [%.*s] [%s]\n", step, re + i, s_len - j, s + j, re + i + step)); if (re_len - (i + step) <= 0) { /* Nothing follows brackets */ n = doh(s + j, s_len - j, info, bi); } else { int j2; for (j2 = 0; j2 <= s_len - j; j2++) { if ((n = doh(s + j, s_len - (j + j2), info, bi)) >= 0 && bar(re + i + step, re_len - (i + step), s + j + n, s_len - (j + n), info, bi) >= 0) break; } } DBG(("CAPTURED [%.*s] [%.*s]:%d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n < 0, n); if (info->caps != NULL) { info->caps[bi - 1].ptr = s + j; info->caps[bi - 1].len = n; } j += n; } else if (re[i] == '^') { FAIL_IF(j != 0, SLRE_NO_MATCH); } else if (re[i] == '$') { FAIL_IF(j != s_len, SLRE_NO_MATCH); } else { FAIL_IF(j >= s_len, SLRE_NO_MATCH); n = match_op((unsigned char *) (re + i), (unsigned char *) (s + j), info); FAIL_IF(n <= 0, n); j += n; } } return j; }
order::result kbo::compare(expr_offset const & t1, expr_offset const & t2, substitution * s) { reset(); m_subst = s; if (t1 == t2) return EQUAL; expr * n1 = t1.get_expr(); expr * n2 = t2.get_expr(); // f(s) >_{kbo} f(t) iff s >_{kbo} t while (is_unary_app(n1) && is_unary_app(n2) && to_app(n1)->get_decl() == to_app(n2)->get_decl()) { n1 = to_app(n1)->get_arg(0); n2 = to_app(n2)->get_arg(0); } svector<entry> & todo = m_compare_todo; SASSERT(todo.empty()); todo.push_back(entry(find(expr_offset(n1, t1.get_offset())), find(expr_offset(n2, t2.get_offset())), 0)); result res = UNKNOWN; while (!todo.empty()) { entry & e = todo.back(); expr_offset t1 = e.m_t1; expr_offset t2 = e.m_t2; expr * n1 = t1.get_expr(); expr * n2 = t2.get_expr(); TRACE("kbo", tout << "processing with idx: " << e.m_idx << "\n" << mk_pp(n1, m_manager) << "\n" << mk_pp(n2, m_manager) << "\n"; tout << "wb : " << m_weight_balance << "\n";); SASSERT(!is_quantifier(n1) && !is_quantifier(n2)); bool v1 = is_var(n1); bool v2 = is_var(n2); if (v1 && v2) { todo.pop_back(); inc(t1); dec(t2); res = t1 == t2 ? EQUAL : UNCOMPARABLE; } else if (v1) { todo.pop_back(); res = VWBc<false>(t2, t1) ? LESSER : UNCOMPARABLE; inc(t1); m_weight_balance += var_weight(); } else if (v2) { todo.pop_back(); res = VWBc<true>(t1, t2) ? GREATER : UNCOMPARABLE; dec(t2); m_weight_balance -= var_weight(); } else { func_decl * f = to_app(n1)->get_decl(); func_decl * g = to_app(n2)->get_decl(); result lex; if (f != g || to_app(n1)->get_num_args() != to_app(n2)->get_num_args()) { VWB<true>(t1, 0); VWB<false>(t2, 0); lex = UNCOMPARABLE; } else { unsigned & idx = e.m_idx; // when idx > 0, res contains the result for child (idx - 1) if (idx > 0 && res != EQUAL) { VWB<true>(t1, idx); VWB<false>(t2, idx); lex = res; } else if (idx == to_app(n1)->get_num_args()) { // all children were visited lex = EQUAL; } else if (idx < to_app(n1)->get_num_args()) { expr_offset c1 = find(expr_offset(to_app(n1)->get_arg(idx), t1.get_offset())); expr_offset c2 = find(expr_offset(to_app(n2)->get_arg(idx), t2.get_offset())); idx++; // move curr entry child idx entry new_entry(c1, c2, 0); todo.push_back(new_entry); continue; // process child before continuing } } todo.pop_back(); m_weight_balance += f_weight(f); m_weight_balance -= f_weight(g); if (m_weight_balance > 0) res = no_neg(); else if (m_weight_balance < 0) res = no_pos(); else if (f_greater(f, g)) res = no_neg(); else if (f_greater(g, f)) res = no_pos(); else if (f != g) res = UNCOMPARABLE; else if (lex == EQUAL) res = EQUAL; else if (lex == GREATER) res = no_neg(); else if (lex == LESSER) res = no_pos(); else res = UNCOMPARABLE; } TRACE("kbo", tout << "result: " << res << "\n";);
void pull_quant::pull_quant1(func_decl * d, unsigned num_children, expr * const * children, expr_ref & result) { ptr_buffer<sort> var_sorts; buffer<symbol> var_names; symbol qid; int w = INT_MAX; // The input formula is in Skolem normal form... // So all children are forall (positive context) or exists (negative context). // Remark: (AND a1 ...) may be represented (NOT (OR (NOT a1) ...))) // So, when pulling a quantifier over a NOT, it becomes an exists. if (m_manager.is_not(d)) { SASSERT(num_children == 1); expr * child = children[0]; if (is_quantifier(child)) { quantifier * q = to_quantifier(child); expr * body = q->get_expr(); result = m_manager.update_quantifier(q, !q->is_forall(), m_manager.mk_not(body)); } else { result = m_manager.mk_not(child); } return; } bool found_quantifier = false; bool forall_children; for (unsigned i = 0; i < num_children; i++) { expr * child = children[i]; if (is_quantifier(child)) { if (!found_quantifier) { found_quantifier = true; forall_children = is_forall(child); } else { // Since the initial formula was in SNF, all children must be EXISTS or FORALL. SASSERT(forall_children == is_forall(child)); } quantifier * nested_q = to_quantifier(child); if (var_sorts.empty()) { // use the qid of one of the nested quantifiers. qid = nested_q->get_qid(); } w = std::min(w, nested_q->get_weight()); unsigned j = nested_q->get_num_decls(); while (j > 0) { --j; var_sorts.push_back(nested_q->get_decl_sort(j)); symbol s = nested_q->get_decl_name(j); if (std::find(var_names.begin(), var_names.end(), s) != var_names.end()) var_names.push_back(m_manager.mk_fresh_var_name(s.is_numerical() ? 0 : s.bare_str())); else var_names.push_back(s); } } } if (!var_sorts.empty()) { SASSERT(found_quantifier); // adjust the variable ids in formulas in new_children expr_ref_buffer new_adjusted_children(m_manager); expr_ref adjusted_child(m_manager); unsigned num_decls = var_sorts.size(); unsigned shift_amount = 0; TRACE("pull_quant", tout << "Result num decls:" << num_decls << "\n";);
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); }
static int bar(const char *re, int re_len, const char *s, int s_len, struct slre_cap *caps, struct regex_info *info, int bi) { /* i is offset in re, j is offset in s, bi is brackets index */ int i, j, n, step; DBG(("%s [%.*s] [%.*s]\n", __func__, re_len, re, s_len, s)); for (i = j = 0; i < re_len && j < s_len; i += step) { /* Handle quantifiers. Get the length of the chunk. */ step = re[i] == '(' ? info->brackets[bi + 1].len + 2 : get_op_len(re + i, re_len - i); DBG(("%s [%.*s] [%.*s] re_len=%d step=%d i=%d j=%d\n", __func__, re_len - i, re + i, s_len - j, s + j, re_len, step, i, j)); FAIL_IF(is_quantifier(&re[i]), static_error_unexpected_quantifier); FAIL_IF(step <= 0, static_error_invalid_set); if (i + step < re_len && is_quantifier(re + i + step)) { DBG(("QUANTIFIER: [%.*s] %c\n", step, re + i, re[i + step])); if (re[i + step] == '?') { j += bar(re + i, step, s + j, s_len - j, caps, info, bi); i++; continue; } else if (re[i + step] == '+' || re[i + step] == '*') { int j2 = j, nj = 0, n1, n2, ni, non_greedy = 0; /* Points to the regexp code after the quantifier */ ni = i + step + 1; if (ni < re_len && re[ni] == '?') { non_greedy = 1; ni++; } while ((n1 = bar(re + i, step, s + j2, s_len - j2, caps, info, bi)) > 0) { if (ni >= re_len) { /* After quantifier, there is nothing */ nj = j2 + n1; } else if ((n2 = bar(re + ni, re_len - ni, s + j2 + n1, s_len - (j2 + n1), caps, info, bi)) > 0) { nj = j2 + n1 + n2; } if (nj > 0 && non_greedy) break; j2 += n1; } FAIL_IF(re[i + step] == '+' && nj == 0, static_error_no_match); return nj; } } if (re[i] == '[') { n = match_set(re + i + 1, re_len - (i + 2), s + j, info); DBG(("SET %.*s [%.*s] -> %d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n <= 0, static_error_no_match); j += n; } else if (re[i] == '(') { bi++; FAIL_IF(bi >= info->num_brackets, static_error_internal); DBG(("CAPTURING [%.*s] [%.*s]\n", step, re + i, s_len - j, s + j)); n = doh(s + j, s_len - j, caps, info, bi); DBG(("CAPTURED [%.*s] [%.*s]:%d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n <= 0, info->error_msg); if (caps != NULL) { caps[bi - 1].ptr = s + j; caps[bi - 1].len = n; } j += n; } else if (re[i] == '^') { FAIL_IF(j != 0, static_error_no_match); } else { n = match_op((unsigned char *) (re + i), (unsigned char *) (s + j), info); FAIL_IF(n <= 0, info->error_msg); j += n; } } /* * Process $ anchor here. If we've reached the end of the string, * but did not exhaust regexp yet, this is no match. */ FAIL_IF(i < re_len && !(re[i] == '$' && i + 1 == re_len), static_error_no_match); return j; }