feat(library/type_context): new tmp local_constant policy

This commit is contained in:
Leonardo de Moura 2015-11-04 11:24:22 -08:00
parent 333ba83087
commit fb7efa9337
4 changed files with 27 additions and 29 deletions

View file

@ -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;
} }
} }

View file

@ -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;

View file

@ -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).

View file

@ -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