3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-18 06:39:02 +00:00
z3/src/ast/occurs.cpp
Nikolaj Bjorner 4d8860c0bc wip - adding context equation solver
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.
2022-11-05 10:34:57 -07:00

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();
}
}
}