130 lines
4.2 KiB
C++
130 lines
4.2 KiB
C++
/*
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
Author: Leonardo de Moura
|
|
*/
|
|
#include <algorithm>
|
|
#include "kernel/for_each_fn.h"
|
|
#include "library/blast/branch.h"
|
|
|
|
namespace lean {
|
|
namespace blast {
|
|
struct hypothesis_depth_lt {
|
|
branch const & m_branch;
|
|
hypothesis_depth_lt(branch const & b): m_branch(b) {}
|
|
bool operator()(unsigned hidx1, unsigned hidx2) const {
|
|
hypothesis const * h1 = m_branch.get(hidx1);
|
|
hypothesis const * h2 = m_branch.get(hidx2);
|
|
return h1 && h2 && h1->get_depth() < h2->get_depth() && (h1->get_depth() == h2->get_depth() && hidx1 < hidx2);
|
|
}
|
|
};
|
|
|
|
void branch::get_sorted_hypotheses(hypothesis_idx_buffer & r) const {
|
|
m_context.for_each([&](unsigned hidx, hypothesis const &) {
|
|
r.push_back(hidx);
|
|
});
|
|
std::sort(r.begin(), r.end(), hypothesis_depth_lt(*this));
|
|
}
|
|
|
|
void branch::add_forward_dep(unsigned hidx_user, unsigned hidx_provider) {
|
|
if (auto s = m_forward_deps.find(hidx_provider)) {
|
|
if (!s->contains(hidx_user)) {
|
|
hypothesis_idx_set new_s(*s);
|
|
new_s.insert(hidx_user);
|
|
m_forward_deps.insert(hidx_provider, new_s);
|
|
}
|
|
} else {
|
|
hypothesis_idx_set new_s;
|
|
new_s.insert(hidx_user);
|
|
m_forward_deps.insert(hidx_provider, new_s);
|
|
}
|
|
}
|
|
|
|
void branch::add_deps(expr const & e, hypothesis & h_user, unsigned hidx_user) {
|
|
if (!has_href(e) && !has_mref(e))
|
|
return; // nothing to be done
|
|
for_each(e, [&](expr const & l, unsigned) {
|
|
if (!has_href(l) && !has_mref(l)) {
|
|
return false;
|
|
} else if (is_href(l)) {
|
|
unsigned hidx_provider = href_index(l);
|
|
hypothesis const * h_provider = get(hidx_provider);
|
|
lean_assert(h_provider);
|
|
if (h_user.m_depth <= h_provider->m_depth)
|
|
h_user.m_depth = h_provider->m_depth + 1;
|
|
if (!h_user.m_deps.contains(hidx_provider)) {
|
|
h_user.m_deps.insert(hidx_provider);
|
|
add_forward_dep(hidx_user, hidx_provider);
|
|
}
|
|
return false;
|
|
} else if (is_mref(l)) {
|
|
m_mvar_idxs.insert(mref_index(l));
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
void branch::add_deps(hypothesis & h_user, unsigned hidx_user) {
|
|
add_deps(h_user.m_type, h_user, hidx_user);
|
|
if (h_user.m_value)
|
|
add_deps(*h_user.m_value, h_user, hidx_user);
|
|
}
|
|
|
|
expr branch::add_hypothesis(name const & n, expr const & type, optional<expr> const & value, optional<expr> const & jst) {
|
|
hypothesis new_h;
|
|
new_h.m_name = n;
|
|
new_h.m_type = type;
|
|
new_h.m_value = value;
|
|
new_h.m_justification = jst;
|
|
unsigned new_hidx = m_next;
|
|
m_next++;
|
|
add_deps(new_h, new_hidx);
|
|
m_context.insert(new_hidx, new_h);
|
|
return blast::mk_href(new_hidx);
|
|
}
|
|
|
|
static name * g_prefix = nullptr;
|
|
|
|
expr branch::add_hypothesis(expr const & type, optional<expr> const & value, optional<expr> const & jst) {
|
|
return add_hypothesis(name(*g_prefix, m_next), type, value, jst);
|
|
}
|
|
|
|
bool branch::hidx_depends_on(unsigned hidx_user, unsigned hidx_provider) const {
|
|
if (auto s = m_forward_deps.find(hidx_provider)) {
|
|
return s->contains(hidx_user);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void branch::set_target(expr const & t) {
|
|
m_target = t;
|
|
m_target_deps.clear();
|
|
if (has_href(t) || has_mref(t)) {
|
|
for_each(t, [&](expr const & e, unsigned) {
|
|
if (!has_href(e) && !has_mref(e)) {
|
|
return false;
|
|
} else if (is_href(e)) {
|
|
m_target_deps.insert(href_index(e));
|
|
return false;
|
|
} else if (is_mref(e)) {
|
|
m_mvar_idxs.insert(mref_index(e));
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
void initialize_branch() {
|
|
g_prefix = new name(name::mk_internal_unique_name());
|
|
}
|
|
|
|
void finalize_branch() {
|
|
delete g_prefix;
|
|
}
|
|
}}
|