/**
       \brief Return \c true if a cycle is detected.
    */
    bool main_loop(func_decl * f) {
        if (get_color(f) == CLOSED)
            return false;
        m_todo.push_back(f);
        while (!m_todo.empty()) {
            func_decl * f = m_todo.back();

            switch (get_color(f)) {
            case CLOSED:
                m_todo.pop_back();
                break;
            case OPEN:
                set_color(f, IN_PROGRESS);
                if (visit_children(f)) {
                    SASSERT(m_todo.back() == f);
                    m_todo.pop_back();
                    set_color(f, CLOSED);
                }
                break;
            case IN_PROGRESS:
                if (all_children_closed(f)) {
                    SASSERT(m_todo.back() == f);
                    set_color(f, CLOSED);
                } else {
                    m_todo.reset();
                    return true;
                }
                break;
            default:
                UNREACHABLE();
            }
        }
        return false;
    }
Exemplo n.º 2
0
 void process(expr * f) {
     if (fvisited.is_marked(f))
         return;
     fvisited.mark(f);
     todo.push_back(f);
     while (!todo.empty()) {
         expr * t = todo.back();
         todo.pop_back();
         if (is_uninterp_const(t))
             continue;
         if (is_app(t) && to_app(t)->get_family_id() == m.get_basic_family_id() && to_app(t)->get_num_args() > 0) {
             decl_kind k = to_app(t)->get_decl_kind();
             if (k == OP_OR || k == OP_NOT || k == OP_IFF || ((k == OP_EQ || k == OP_ITE) && m.is_bool(to_app(t)->get_arg(1)))) {
                 unsigned num = to_app(t)->get_num_args();
                 for (unsigned i = 0; i < num; i++) {
                     expr * arg = to_app(t)->get_arg(i);
                     if (fvisited.is_marked(arg))
                         continue;
                     fvisited.mark(arg);
                     todo.push_back(arg);
                 }
             }
         }
         else {
             quick_for_each_expr(proc, tvisited, t);
         }
     }
 }
Exemplo n.º 3
0
    void reduce(proof* pf, proof_ref &out)
    {
        proof *res = nullptr;

        m_todo.reset();
        m_todo.push_back(pf);
        ptr_buffer<proof> args;
        bool dirty = false;

        while (!m_todo.empty()) {
            proof *p, *tmp, *pp;
            unsigned todo_sz;

            p = m_todo.back();
            if (m_cache.find(p, tmp)) {
                res = tmp;
                m_todo.pop_back();
                continue;
            }

            dirty = false;
            args.reset();
            todo_sz = m_todo.size();
            for (unsigned i = 0, sz = m.get_num_parents(p); i < sz; ++i) {
                pp = m.get_parent(p, i);
                if (m_cache.find(pp, tmp)) {
                    args.push_back(tmp);
                    dirty = dirty || pp != tmp;
                } else {
                    m_todo.push_back(pp);
                }
            }

            if (todo_sz < m_todo.size()) { continue; }
            else { m_todo.pop_back(); }

            if (m.is_hypothesis(p)) {
                // hyp: replace by a corresponding unit
                if (m_units.find(m.get_fact(p), tmp)) {
                    res = tmp;
                } else { res = p; }
            }

            else if (!dirty) { res = p; }

            else if (m.is_lemma(p)) {
                //lemma: reduce the premise; remove reduced consequences from conclusion
                SASSERT(args.size() == 1);
                res = mk_lemma_core(args.get(0), m.get_fact(p));
                compute_mark1(res);
            } else if (m.is_unit_resolution(p)) {
                // unit: reduce units; reduce the first premise; rebuild unit resolution
                res = mk_unit_resolution_core(args.size(), args.c_ptr());
                compute_mark1(res);
            } else  {
                // other: reduce all premises; reapply
                if (m.has_fact(p)) { args.push_back(to_app(m.get_fact(p))); }
                SASSERT(p->get_decl()->get_arity() == args.size());
                res = m.mk_app(p->get_decl(), args.size(), (expr * const*)args.c_ptr());
                m_pinned.push_back(res);
                compute_mark1(res);
            }

            SASSERT(res);
            m_cache.insert(p, res);

            if (m.has_fact(res) && m.is_false(m.get_fact(res))) { break; }
        }

        out = res;
    }