fix(library/unifier): missing occurs check
This commit is contained in:
parent
2edf91ce42
commit
769da9c95a
6 changed files with 16 additions and 12 deletions
|
@ -305,16 +305,6 @@ level mk_result_level(environment const & env, buffer<level> const & r_lvls) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool occurs(level const & u, level const & l) {
|
|
||||||
bool found = false;
|
|
||||||
for_each(l, [&](level const & l) {
|
|
||||||
if (found) return false;
|
|
||||||
if (l == u) { found = true; return false; }
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Functional object for converting the universe metavariables in an expression in new universe parameters.
|
/** \brief Functional object for converting the universe metavariables in an expression in new universe parameters.
|
||||||
The substitution is updated with the mapping metavar -> new param.
|
The substitution is updated with the mapping metavar -> new param.
|
||||||
The set of parameter names m_params and the buffer m_new_params are also updated.
|
The set of parameter names m_params and the buffer m_new_params are also updated.
|
||||||
|
|
|
@ -78,8 +78,6 @@ expr Fun_as_is(buffer<expr> const & locals, expr const & e, parser & p);
|
||||||
expr Pi_as_is(buffer<expr> const & locals, expr const & e, parser & p);
|
expr Pi_as_is(buffer<expr> const & locals, expr const & e, parser & p);
|
||||||
/** \brief Create the resultant universe level using the levels computed during introduction rule elaboration */
|
/** \brief Create the resultant universe level using the levels computed during introduction rule elaboration */
|
||||||
level mk_result_level(environment const & env, buffer<level> const & r_lvls);
|
level mk_result_level(environment const & env, buffer<level> const & r_lvls);
|
||||||
/** \brief Return true if \c u occurs in \c l */
|
|
||||||
bool occurs(level const & u, level const & l);
|
|
||||||
|
|
||||||
/** \brief Convert the universe metavariables in \c e in new universe parameters.
|
/** \brief Convert the universe metavariables in \c e in new universe parameters.
|
||||||
The substitution \c s is updated with the mapping metavar -> new param.
|
The substitution \c s is updated with the mapping metavar -> new param.
|
||||||
|
|
|
@ -418,6 +418,16 @@ level replace_level_fn::apply(level const & l) {
|
||||||
lean_unreachable(); // LCOV_EXCL_LINE
|
lean_unreachable(); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool occurs(level const & u, level const & l) {
|
||||||
|
bool found = false;
|
||||||
|
for_each(l, [&](level const & l) {
|
||||||
|
if (found) return false;
|
||||||
|
if (l == u) { found = true; return false; }
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
optional<name> get_undef_param(level const & l, level_param_names const & ps) {
|
optional<name> get_undef_param(level const & l, level_param_names const & ps) {
|
||||||
optional<name> r;
|
optional<name> r;
|
||||||
for_each(l, [&](level const & l) {
|
for_each(l, [&](level const & l) {
|
||||||
|
|
|
@ -200,6 +200,9 @@ public:
|
||||||
};
|
};
|
||||||
template<typename F> level replace(level const & l, F const & f) { return replace_level_fn(f)(l); }
|
template<typename F> level replace(level const & l, F const & f) { return replace_level_fn(f)(l); }
|
||||||
|
|
||||||
|
/** \brief Return true if \c u occurs in \c l */
|
||||||
|
bool occurs(level const & u, level const & l);
|
||||||
|
|
||||||
typedef list<name> level_param_names;
|
typedef list<name> level_param_names;
|
||||||
|
|
||||||
/** \brief If \c l contains a global that is not in \c env, then return it. Otherwise, return none. */
|
/** \brief If \c l contains a global that is not in \c env, then return it. Otherwise, return none. */
|
||||||
|
|
|
@ -74,6 +74,7 @@ void substitution::assign(name const & m, expr const & t, justification const &
|
||||||
}
|
}
|
||||||
|
|
||||||
void substitution::assign(name const & m, level const & l, justification const & j) {
|
void substitution::assign(name const & m, level const & l, justification const & j) {
|
||||||
|
lean_assert(!::lean::occurs(mk_meta_univ(m), l), m, l);
|
||||||
m_level_subst.insert(m, l);
|
m_level_subst.insert(m, l);
|
||||||
if (!j.is_none())
|
if (!j.is_none())
|
||||||
m_level_jsts.insert(m, j);
|
m_level_jsts.insert(m, j);
|
||||||
|
|
|
@ -2504,6 +2504,8 @@ struct unifier_fn {
|
||||||
}
|
}
|
||||||
if (!is_meta(m))
|
if (!is_meta(m))
|
||||||
return Continue;
|
return Continue;
|
||||||
|
if (occurs(m, lhs))
|
||||||
|
return Continue;
|
||||||
if (assign(m, lhs, jst)) {
|
if (assign(m, lhs, jst)) {
|
||||||
return Solved;
|
return Solved;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue