mirror of
https://github.com/Z3Prover/z3
synced 2025-04-18 06:39:02 +00:00
the solve_eqs_tactic is to be replaced by a re-implementation that uses solve_eqs in the simplifiers directory. The re-implementation should address efficiency issues with the previous code. At this point it punts on low level proofs. The plan is to use coarser dependency tracking instead of low level proofs for pre-processing. Dependencies can be converted into a proof hint representation that can be checked using a stronger checker.
119 lines
2.6 KiB
C++
119 lines
2.6 KiB
C++
/*++
|
|
Copyright (c) 2006 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
occurs.cpp
|
|
|
|
Abstract:
|
|
|
|
<abstract>
|
|
|
|
Author:
|
|
|
|
Leonardo de Moura (leonardo) 2007-06-07.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "ast/occurs.h"
|
|
|
|
#include "ast/for_each_expr.h"
|
|
|
|
// -----------------------------------
|
|
//
|
|
// Occurs check
|
|
//
|
|
// -----------------------------------
|
|
|
|
namespace {
|
|
struct found {};
|
|
|
|
struct proc {
|
|
expr * m_n;
|
|
|
|
#define CHECK() { if (n == m_n) throw found(); }
|
|
|
|
proc(expr * n):m_n(n) {}
|
|
void operator()(var const * n) { CHECK(); }
|
|
void operator()(app const * n) { CHECK(); }
|
|
void operator()(quantifier const * n) { CHECK(); }
|
|
};
|
|
|
|
struct decl_proc {
|
|
func_decl * m_d;
|
|
|
|
decl_proc(func_decl * d):m_d(d) {}
|
|
void operator()(var const * n) { }
|
|
void operator()(app const * n) { if (n->get_decl() == m_d) throw found(); }
|
|
void operator()(quantifier const * n) { }
|
|
};
|
|
|
|
}
|
|
|
|
// Return true if n1 occurs in n2
|
|
bool occurs(expr * n1, expr * n2) {
|
|
proc p(n1);
|
|
try {
|
|
quick_for_each_expr(p, n2);
|
|
}
|
|
catch (const found &) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool occurs(func_decl * d, expr * n) {
|
|
decl_proc p(d);
|
|
try {
|
|
quick_for_each_expr(p, n);
|
|
}
|
|
catch (const found &) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void mark_occurs(ptr_vector<expr>& to_check, expr* v, expr_mark& occ) {
|
|
expr_fast_mark2 visited;
|
|
occ.mark(v, true);
|
|
visited.mark(v, true);
|
|
while (!to_check.empty()) {
|
|
expr* e = to_check.back();
|
|
if (visited.is_marked(e)) {
|
|
to_check.pop_back();
|
|
continue;
|
|
}
|
|
if (is_app(e)) {
|
|
bool does_occur = false;
|
|
bool all_visited = true;
|
|
for (expr* arg : *to_app(e)) {
|
|
if (!visited.is_marked(arg)) {
|
|
to_check.push_back(arg);
|
|
all_visited = false;
|
|
}
|
|
else
|
|
does_occur |= occ.is_marked(arg);
|
|
}
|
|
if (all_visited) {
|
|
occ.mark(e, does_occur);
|
|
visited.mark(e, true);
|
|
to_check.pop_back();
|
|
}
|
|
}
|
|
else if (is_quantifier(e)) {
|
|
expr* body = to_quantifier(e)->get_expr();
|
|
if (visited.is_marked(body)) {
|
|
visited.mark(e, true);
|
|
occ.mark(e, occ.is_marked(body));
|
|
to_check.pop_back();
|
|
}
|
|
else
|
|
to_check.push_back(body);
|
|
}
|
|
else {
|
|
visited.mark(e, true);
|
|
to_check.pop_back();
|
|
}
|
|
}
|
|
} |