perf(kernel/metavar): performance problem with occurs method
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
61661478ad
commit
301c395e59
5 changed files with 13 additions and 12 deletions
|
@ -186,18 +186,16 @@ expr substitution::instantiate_metavars_wo_jst(expr const & e) {
|
||||||
return instantiate_metavars_fn(*this, false)(e);
|
return instantiate_metavars_fn(*this, false)(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool substitution::occurs_expr(name const & m, expr const & e) const {
|
bool substitution::occurs_expr(name const & m, expr const & e) {
|
||||||
if (!has_expr_metavar(e))
|
if (!has_expr_metavar(e))
|
||||||
return false;
|
return false;
|
||||||
|
expr new_e = instantiate(e);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for_each(e, [&](expr const & e, unsigned) {
|
for_each(new_e, [&](expr const & e, unsigned) {
|
||||||
if (found || !has_expr_metavar(e)) return false;
|
if (found || !has_expr_metavar(e)) return false;
|
||||||
if (is_metavar(e)) {
|
if (is_metavar(e)) {
|
||||||
if (mlocal_name(e) == m)
|
if (mlocal_name(e) == m)
|
||||||
found = true;
|
found = true;
|
||||||
auto s = get_expr(e);
|
|
||||||
if (s && occurs_expr(m, *s))
|
|
||||||
found = true;
|
|
||||||
return false; // do not visit type
|
return false; // do not visit type
|
||||||
}
|
}
|
||||||
if (is_local(e)) return false; // do not visit type
|
if (is_local(e)) return false; // do not visit type
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
expr instantiate(expr const & e) { return instantiate_metavars_wo_jst(e); }
|
expr instantiate(expr const & e) { return instantiate_metavars_wo_jst(e); }
|
||||||
|
|
||||||
/** \brief Return true iff the metavariable \c m occurrs (directly or indirectly) in \c e. */
|
/** \brief Return true iff the metavariable \c m occurrs (directly or indirectly) in \c e. */
|
||||||
bool occurs_expr(name const & m, expr const & e) const;
|
bool occurs_expr(name const & m, expr const & e);
|
||||||
bool occurs(expr const & m, expr const & e) const { lean_assert(is_metavar(m)); return occurs_expr(mlocal_name(m), e); }
|
bool occurs(expr const & m, expr const & e) { lean_assert(is_metavar(m)); return occurs_expr(mlocal_name(m), e); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ bool context_check(expr const & e, buffer<expr> const & locals) {
|
||||||
// constants are in \c e are in \c locals.
|
// constants are in \c e are in \c locals.
|
||||||
// - l_false if \c e contains \c m or it contains a local constant \c l
|
// - l_false if \c e contains \c m or it contains a local constant \c l
|
||||||
// not in locals that is not in a metavariable application.
|
// not in locals that is not in a metavariable application.
|
||||||
lbool occurs_context_check(substitution const & s, expr const & e, expr const & m, buffer<expr> const & locals) {
|
lbool occurs_context_check(substitution & s, expr const & e, expr const & m, buffer<expr> const & locals) {
|
||||||
expr root = e;
|
expr root = e;
|
||||||
lbool r = l_true;
|
lbool r = l_true;
|
||||||
for_each(e, [&](expr const & e, unsigned) {
|
for_each(e, [&](expr const & e, unsigned) {
|
||||||
|
|
|
@ -91,11 +91,14 @@ static void tst2() {
|
||||||
expr f = Const("f");
|
expr f = Const("f");
|
||||||
expr g = Const("g");
|
expr g = Const("g");
|
||||||
expr a = Const("a");
|
expr a = Const("a");
|
||||||
|
lean_assert(s.occurs(m1, f(m1)));
|
||||||
|
lean_assert(!s.occurs(m2, f(m1)));
|
||||||
s.assign(m1, f(m2), mk_assumption_justification(1));
|
s.assign(m1, f(m2), mk_assumption_justification(1));
|
||||||
|
lean_assert(s.occurs(m2, f(m1)));
|
||||||
s.assign(m2, g(a), mk_assumption_justification(2));
|
s.assign(m2, g(a), mk_assumption_justification(2));
|
||||||
lean_assert(check_assumptions(s.get_assignment(m1)->second, {1}));
|
lean_assert(check_assumptions(s.get_assignment(m1)->second, {1}));
|
||||||
lean_assert(s.occurs(m1, f(m1)));
|
lean_assert(!s.occurs(m1, f(m1)));
|
||||||
lean_assert(s.occurs(m2, f(m1)));
|
lean_assert(!s.occurs(m2, f(m1)));
|
||||||
lean_assert(!s.occurs(m1, f(m2)));
|
lean_assert(!s.occurs(m1, f(m2)));
|
||||||
lean_assert(!s.occurs(m1, f(a)));
|
lean_assert(!s.occurs(m1, f(a)));
|
||||||
lean_assert(!s.occurs(m3, f(m1)));
|
lean_assert(!s.occurs(m3, f(m1)));
|
||||||
|
|
|
@ -24,8 +24,8 @@ assert(s:get_expr("m") == a)
|
||||||
local m2 = mk_metavar("m2", Prop)
|
local m2 = mk_metavar("m2", Prop)
|
||||||
s:assign(m2, f(m))
|
s:assign(m2, f(m))
|
||||||
print(s:get_expr("m2"))
|
print(s:get_expr("m2"))
|
||||||
assert(s:occurs(m, f(m2)))
|
assert(not s:occurs(m, f(m2)))
|
||||||
assert(s:occurs_expr("m", f(m2)))
|
assert(not s:occurs_expr("m", f(m2)))
|
||||||
print(s:get_level("u"))
|
print(s:get_level("u"))
|
||||||
print(s:instantiate(mk_sort(u)))
|
print(s:instantiate(mk_sort(u)))
|
||||||
assert(s:instantiate(mk_sort(u)) == mk_sort(l))
|
assert(s:instantiate(mk_sort(u)) == mk_sort(l))
|
||||||
|
|
Loading…
Reference in a new issue