feat(library/type_context): new tmp local_constant policy
This commit is contained in:
parent
333ba83087
commit
fb7efa9337
4 changed files with 27 additions and 29 deletions
|
@ -23,7 +23,8 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
namespace blast {
|
namespace blast {
|
||||||
static name * g_prefix = nullptr;
|
static name * g_prefix = nullptr;
|
||||||
|
static name * g_tmp_prefix = nullptr;
|
||||||
|
|
||||||
class blastenv {
|
class blastenv {
|
||||||
friend class scope_assignment;
|
friend class scope_assignment;
|
||||||
|
@ -42,29 +43,39 @@ class blastenv {
|
||||||
|
|
||||||
class tctx : public type_context {
|
class tctx : public type_context {
|
||||||
blastenv & m_benv;
|
blastenv & m_benv;
|
||||||
|
unsigned m_next_local_idx;
|
||||||
std::vector<state> m_stack;
|
std::vector<state> m_stack;
|
||||||
public:
|
public:
|
||||||
tctx(blastenv & benv):
|
tctx(blastenv & benv):
|
||||||
type_context(benv.m_env, benv.m_ios),
|
type_context(benv.m_env, benv.m_ios),
|
||||||
m_benv(benv) {}
|
m_benv(benv), m_next_local_idx(0) {}
|
||||||
|
|
||||||
virtual bool is_extra_opaque(name const & n) const {
|
virtual bool is_extra_opaque(name const & n) const {
|
||||||
// TODO(Leo): class and instances
|
// TODO(Leo): class and instances
|
||||||
return m_benv.m_not_reducible_pred(n) || m_benv.m_projection_info.contains(n);
|
return m_benv.m_not_reducible_pred(n) || m_benv.m_projection_info.contains(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name mk_tmp_name() {
|
||||||
|
unsigned idx = m_next_local_idx;
|
||||||
|
m_next_local_idx++;
|
||||||
|
return name(*g_tmp_prefix, idx);
|
||||||
|
}
|
||||||
|
|
||||||
virtual expr mk_tmp_local(expr const & type, binder_info const & bi) {
|
virtual expr mk_tmp_local(expr const & type, binder_info const & bi) {
|
||||||
name n = m_benv.m_ngen.next();
|
name n = mk_tmp_name();
|
||||||
return blast::mk_local(n, n, type, bi);
|
return blast::mk_local(n, n, type, bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual expr mk_tmp_local(name const & pp_n, expr const & type, binder_info const & bi) {
|
virtual expr mk_tmp_local(name const & pp_n, expr const & type, binder_info const & bi) {
|
||||||
name n = m_benv.m_ngen.next();
|
name n = mk_tmp_name();
|
||||||
return blast::mk_local(n, pp_n, type, bi);
|
return blast::mk_local(n, pp_n, type, bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool is_tmp_local(expr const & e) const {
|
virtual bool is_tmp_local(expr const & e) const {
|
||||||
return blast::is_local(e);
|
if (!is_local(e))
|
||||||
|
return false;
|
||||||
|
name const & n = mlocal_name(e);
|
||||||
|
return !n.is_atomic() && n.get_prefix() == *g_tmp_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool is_uvar(level const & l) const {
|
virtual bool is_uvar(level const & l) const {
|
||||||
|
@ -102,7 +113,7 @@ class blastenv {
|
||||||
// 1. All href in new_v are in the context of m.
|
// 1. All href in new_v are in the context of m.
|
||||||
// 2. The context of any (unassigned) mref in new_v must be a subset of the context of m.
|
// 2. The context of any (unassigned) mref in new_v must be a subset of the context of m.
|
||||||
// If it is not we force it to be.
|
// If it is not we force it to be.
|
||||||
// 3. Any local constant occurring in new_v occurs in locals
|
// 3. Any (non tmp) local constant occurring in new_v occurs in locals
|
||||||
// 4. m does not occur in new_v
|
// 4. m does not occur in new_v
|
||||||
state & s = m_benv.m_curr_state;
|
state & s = m_benv.m_curr_state;
|
||||||
metavar_decl const * d = s.get_metavar_decl(m);
|
metavar_decl const * d = s.get_metavar_decl(m);
|
||||||
|
@ -116,7 +127,7 @@ class blastenv {
|
||||||
ok = false; // failed 1
|
ok = false; // failed 1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (blast::is_local(e)) {
|
} else if (is_local(e) && !is_tmp_local(e)) {
|
||||||
if (std::all_of(locals.begin(), locals.end(), [&](expr const & a) {
|
if (std::all_of(locals.begin(), locals.end(), [&](expr const & a) {
|
||||||
return local_index(a) != local_index(e); })) {
|
return local_index(a) != local_index(e); })) {
|
||||||
ok = false; // failed 3
|
ok = false; // failed 3
|
||||||
|
@ -593,9 +604,11 @@ optional<expr> blast_goal(environment const & env, io_state const & ios, list<na
|
||||||
return b(g);
|
return b(g);
|
||||||
}
|
}
|
||||||
void initialize_blast() {
|
void initialize_blast() {
|
||||||
blast::g_prefix = new name(name::mk_internal_unique_name());
|
blast::g_prefix = new name(name::mk_internal_unique_name());
|
||||||
|
blast::g_tmp_prefix = new name(name::mk_internal_unique_name());
|
||||||
}
|
}
|
||||||
void finalize_blast() {
|
void finalize_blast() {
|
||||||
delete blast::g_prefix;
|
delete blast::g_prefix;
|
||||||
|
delete blast::g_tmp_prefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1254,21 +1254,13 @@ bool type_context::on_is_def_eq_failure(expr & e1, expr & e2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool type_context::validate_assignment(expr const & m, buffer<expr> const & locals, expr const & v) {
|
bool type_context::validate_assignment(expr const & m, buffer<expr> const & /* locals */, expr const & v) {
|
||||||
// We must check
|
// Basic check: m does not occur in v
|
||||||
// 1. Any (internal) local constant occurring in v occurs in locals
|
|
||||||
// 2. m does not occur in v
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
for_each(v, [&](expr const & e, unsigned) {
|
for_each(v, [&](expr const & e, unsigned) {
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false; // stop search
|
return false; // stop search
|
||||||
if (is_tmp_local(e)) {
|
if (is_mvar(e)) {
|
||||||
if (std::all_of(locals.begin(), locals.end(), [&](expr const & a) {
|
|
||||||
return mlocal_name(a) != mlocal_name(e); })) {
|
|
||||||
ok = false; // failed 1
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (is_mvar(e)) {
|
|
||||||
if (m == e) {
|
if (m == e) {
|
||||||
ok = false; // failed 2
|
ok = false; // failed 2
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -267,16 +267,12 @@ public:
|
||||||
/** \brief Update the assignment for \c m.
|
/** \brief Update the assignment for \c m.
|
||||||
\pre is_mvar(m) */
|
\pre is_mvar(m) */
|
||||||
virtual void update_assignment(expr const & m, expr const & v) = 0;
|
virtual void update_assignment(expr const & m, expr const & v) = 0;
|
||||||
|
|
||||||
/** \brief Given a metavariable m that takes locals as arguments, this method
|
/** \brief Given a metavariable m that takes locals as arguments, this method
|
||||||
should return true if m can be assigned to an abstraction of \c v.
|
should return true if m can be assigned to an abstraction of \c v.
|
||||||
|
|
||||||
\remark This method should check at least if m does not occur in v,
|
\remark This method should check at least if m does not occur in v.
|
||||||
and if all tmp locals in v are in locals.
|
The default implementation only checks that. */
|
||||||
|
|
||||||
The default implementation checks the following things:
|
|
||||||
1. Any (internal) local constant occurring in v occurs in locals
|
|
||||||
2. m does not occur in v
|
|
||||||
*/
|
|
||||||
virtual bool validate_assignment(expr const & m, buffer<expr> const & locals, expr const & v);
|
virtual bool validate_assignment(expr const & m, buffer<expr> const & locals, expr const & v);
|
||||||
|
|
||||||
/** \brief Return the type of a local constant (local or not).
|
/** \brief Return the type of a local constant (local or not).
|
||||||
|
|
|
@ -62,7 +62,4 @@ theorem subst_iff {T : Type} {R : T → T → Prop} {P : T → Prop} [C : congru
|
||||||
-- iff_mp_left (congruence.rec id C a b H) H1
|
-- iff_mp_left (congruence.rec id C a b H) H1
|
||||||
iff.elim_left (@congr_app _ _ R iff P C a b H) H1
|
iff.elim_left (@congr_app _ _ R iff P C a b H) H1
|
||||||
|
|
||||||
theorem test2 (a b c d e : Prop) (H1 : a ↔ b) (H2 : a ∨ c → ¬(d → a)) : b ∨ c → ¬(d → b) :=
|
|
||||||
subst_iff H1 H2
|
|
||||||
|
|
||||||
end congruence
|
end congruence
|
||||||
|
|
Loading…
Reference in a new issue