feat(library/unifier): additional memory checks
This commit is contained in:
parent
28dad944c5
commit
eb23a30626
1 changed files with 12 additions and 2 deletions
|
@ -485,7 +485,11 @@ struct unifier_fn {
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_system() {
|
void check_system() {
|
||||||
check_interrupted();
|
::lean::check_system("unifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_full() {
|
||||||
|
check_system();
|
||||||
if (m_num_steps > m_config.m_max_steps)
|
if (m_num_steps > m_config.m_max_steps)
|
||||||
throw exception(sstream() << "unifier maximum number of steps (" << m_config.m_max_steps << ") exceeded, " <<
|
throw exception(sstream() << "unifier maximum number of steps (" << m_config.m_max_steps << ") exceeded, " <<
|
||||||
"the maximum number of steps can be increased by setting the option unifier.max_steps " <<
|
"the maximum number of steps can be increased by setting the option unifier.max_steps " <<
|
||||||
|
@ -867,6 +871,11 @@ struct unifier_fn {
|
||||||
expr instantiate_meta(expr e, justification & j) {
|
expr instantiate_meta(expr e, justification & j) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (auto p = m_subst.expand_metavar_app(e)) {
|
if (auto p = m_subst.expand_metavar_app(e)) {
|
||||||
|
// The following check_system is defensive programming.
|
||||||
|
// If the unifier is correct, and no loops are introduced in the substituion,
|
||||||
|
// then this loop should always terminate.
|
||||||
|
// Anyway, we may have bugs, and we should interrupt the loop if all resources are being consumed.
|
||||||
|
check_system();
|
||||||
e = p->first;
|
e = p->first;
|
||||||
j = mk_composite1(j, p->second);
|
j = mk_composite1(j, p->second);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1112,7 +1121,7 @@ struct unifier_fn {
|
||||||
bool process_constraint(constraint const & c) {
|
bool process_constraint(constraint const & c) {
|
||||||
if (in_conflict())
|
if (in_conflict())
|
||||||
return false;
|
return false;
|
||||||
check_system();
|
check_full();
|
||||||
// std::cout << "process: " << c << "\n";
|
// std::cout << "process: " << c << "\n";
|
||||||
switch (c.kind()) {
|
switch (c.kind()) {
|
||||||
case constraint_kind::Choice:
|
case constraint_kind::Choice:
|
||||||
|
@ -1163,6 +1172,7 @@ struct unifier_fn {
|
||||||
bool resolve_conflict() {
|
bool resolve_conflict() {
|
||||||
lean_assert(in_conflict());
|
lean_assert(in_conflict());
|
||||||
while (!m_case_splits.empty()) {
|
while (!m_case_splits.empty()) {
|
||||||
|
check_system();
|
||||||
justification conflict = *m_conflict;
|
justification conflict = *m_conflict;
|
||||||
std::unique_ptr<case_split> & d = m_case_splits.back();
|
std::unique_ptr<case_split> & d = m_case_splits.back();
|
||||||
if (!m_config.m_nonchronological || depends_on(conflict, d->m_assumption_idx)) {
|
if (!m_config.m_nonchronological || depends_on(conflict, d->m_assumption_idx)) {
|
||||||
|
|
Loading…
Reference in a new issue