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;
}
Beispiel #3
0
 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);
         }
     }
 }
Beispiel #4
0
    // 
    // 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;
    }
Beispiel #5
0
 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);
}
Beispiel #8
0
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);
}
Beispiel #9
0
 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;
     }
 }
Beispiel #10
0
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";);
    }
Beispiel #11
0
 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;
}
Beispiel #13
0
    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;
 }
Beispiel #15
0
/**
   \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";);
Beispiel #16
0
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;
}
Beispiel #17
0
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";);
Beispiel #19
0
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);
}
Beispiel #20
0
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;
}