refactor(library/blast): use simpler encoding for lref and mref

This commit is contained in:
Leonardo de Moura 2015-09-28 13:02:15 -07:00
parent aac13a2ee7
commit d3937aa02d
3 changed files with 67 additions and 83 deletions

View file

@ -23,66 +23,6 @@ Author: Leonardo de Moura
namespace lean { namespace lean {
namespace blast { namespace blast {
/** \brief Auxiliary macro used to encode mref and lref expressions used by the blast tactic
\remark This macro should never occur in fully elaborated terms. */
class ref_definition_cell : public macro_definition_cell {
bool m_local;
unsigned m_idx;
public:
ref_definition_cell(bool local, unsigned idx):m_local(local), m_idx(idx) {}
bool is_local() const { return m_local; }
unsigned get_index() const { return m_idx; }
virtual name get_name() const { return name("ref"); }
virtual pair<expr, constraint_seq> check_type(expr const &, extension_context &, bool) const {
lean_unreachable();
}
virtual optional<expr> expand(expr const &, extension_context &) const {
lean_unreachable();
}
virtual void write(serializer &) const {
lean_unreachable();
}
virtual bool operator==(macro_definition_cell const & other) const {
return
dynamic_cast<ref_definition_cell const *>(&other) != nullptr &&
m_idx == static_cast<ref_definition_cell const&>(other).m_idx &&
m_local == static_cast<ref_definition_cell const&>(other).m_local;
}
virtual unsigned hash() const { return lean::hash(m_local, m_idx); }
};
static expr mk_lref_core(unsigned idx) {
return lean::mk_macro(macro_definition(new ref_definition_cell(true, idx)), 0, nullptr);
}
static expr mk_mref_core(unsigned idx) {
return lean::mk_macro(macro_definition(new ref_definition_cell(false, idx)), 0, nullptr);
}
bool is_lmref(expr const & e) {
return is_macro(e) && dynamic_cast<ref_definition_cell const *>(macro_def(e).raw());
}
bool is_lref(expr const & e) {
return is_lmref(e) && static_cast<ref_definition_cell const *>(macro_def(e).raw())->is_local();
}
bool is_mref(expr const & e) {
return is_lmref(e) && !is_lref(e);
}
unsigned lmref_index(expr const & e) {
lean_assert(is_lmref(e));
return static_cast<ref_definition_cell const *>(macro_def(e).raw())->get_index();
}
typedef typename std::unordered_set<expr, expr_hash, is_bi_equal_proc> expr_table; typedef typename std::unordered_set<expr, expr_hash, is_bi_equal_proc> expr_table;
typedef typename std::unordered_set<level, level_hash> level_table; typedef typename std::unordered_set<level, level_hash> level_table;
typedef typename std::vector<expr> expr_array; typedef typename std::vector<expr> expr_array;
@ -209,17 +149,11 @@ level update_max(level const & l, level const & new_lhs, level const & new_rhs)
} }
} }
expr mk_var(unsigned idx) { static name * g_prefix = nullptr;
lean_assert(g_var_array); static expr * g_dummy_type = nullptr; // dummy type for lref/mref
lean_assert(g_expr_table);
while (g_var_array->size() <= idx) { static expr mk_lref_core(unsigned idx) {
unsigned j = g_var_array->size(); return mk_local(name(*g_prefix, idx), *g_dummy_type);
expr new_var = lean::mk_var(j);
g_var_array->push_back(new_var);
g_expr_table->insert(new_var);
}
lean_assert(idx < g_var_array->size());
return (*g_var_array)[idx];
} }
expr mk_lref(unsigned idx) { expr mk_lref(unsigned idx) {
@ -235,6 +169,14 @@ expr mk_lref(unsigned idx) {
return (*g_lref_array)[idx]; return (*g_lref_array)[idx];
} }
bool is_lref(expr const & e) {
return is_local(e) && mlocal_type(e) == *g_dummy_type;
}
static expr mk_mref_core(unsigned idx) {
return mk_metavar(name(*g_prefix, idx), *g_dummy_type);
}
expr mk_mref(unsigned idx) { expr mk_mref(unsigned idx) {
lean_assert(g_mref_array); lean_assert(g_mref_array);
lean_assert(g_expr_table); lean_assert(g_expr_table);
@ -248,6 +190,33 @@ expr mk_mref(unsigned idx) {
return (*g_mref_array)[idx]; return (*g_mref_array)[idx];
} }
bool is_mref(expr const & e) {
return is_metavar(e) && mlocal_type(e) == *g_dummy_type;
}
unsigned mref_index(expr const & e) {
lean_assert(is_mref(e));
return mlocal_name(e).get_numeral();
}
unsigned lref_index(expr const & e) {
lean_assert(is_lref(e));
return mlocal_name(e).get_numeral();
}
expr mk_var(unsigned idx) {
lean_assert(g_var_array);
lean_assert(g_expr_table);
while (g_var_array->size() <= idx) {
unsigned j = g_var_array->size();
expr new_var = lean::mk_var(j);
g_var_array->push_back(new_var);
g_expr_table->insert(new_var);
}
lean_assert(idx < g_var_array->size());
return (*g_var_array)[idx];
}
expr mk_app(expr const & f, expr const & a) { expr mk_app(expr const & f, expr const & a) {
lean_assert(is_cached(f)); lean_assert(is_cached(f));
lean_assert(is_cached(a)); lean_assert(is_cached(a));
@ -351,8 +320,12 @@ class replace_rec_fn {
switch (e.kind()) { switch (e.kind()) {
case expr_kind::Constant: case expr_kind::Sort: case expr_kind::Var: case expr_kind::Constant: case expr_kind::Sort: case expr_kind::Var:
return save_result(e, offset, e); return save_result(e, offset, e);
case expr_kind::Meta: case expr_kind::Local: case expr_kind::Meta:
lean_unreachable(); lean_assert(is_mref(e));
return save_result(e, offset, e);
case expr_kind::Local:
lean_assert(is_lref(e));
return save_result(e, offset, e);
case expr_kind::App: { case expr_kind::App: {
expr new_f = apply(app_fn(e), offset); expr new_f = apply(app_fn(e), offset);
expr new_a = apply(app_arg(e), offset); expr new_a = apply(app_arg(e), offset);
@ -592,5 +565,14 @@ expr abstract_lrefs(expr const & e, unsigned n, expr const * subst) {
return none_expr(); return none_expr();
}); });
} }
void initialize_expr() {
g_prefix = new name(name::mk_internal_unique_name());
g_dummy_type = new expr(mk_constant(*g_prefix));
} }
void finalize_expr() {
delete g_prefix;
delete g_dummy_type;
} }
}}

View file

@ -40,8 +40,8 @@ level mk_global_univ(name const & n);
level mk_meta_univ(name const & n); level mk_meta_univ(name const & n);
expr mk_var(unsigned idx); expr mk_var(unsigned idx);
// Remark: lref and mref expressions are implemented using kernel macros. // mk_lref and mk_mref are helper functions for creating local constants and meta-variables used in the blast tactic.
// We use them to encode local constants and meta-variables in the blast tactic. // Remark: the local constants and metavariables manipulated by the blast tactic do **not** store their types.
expr mk_lref(unsigned idx); expr mk_lref(unsigned idx);
expr mk_mref(unsigned idx); expr mk_mref(unsigned idx);
expr mk_sort(level const & l); expr mk_sort(level const & l);
@ -67,15 +67,10 @@ inline expr mk_lambda(name const & n, expr const & t, expr const & e) {
} }
expr mk_macro(macro_definition const & m, unsigned num, expr const * args); expr mk_macro(macro_definition const & m, unsigned num, expr const * args);
// Return true iff \c e is a lref of mref.
bool is_lmref(expr const & e);
bool is_mref(expr const & e);
bool is_lref(expr const & e); bool is_lref(expr const & e);
/** \brief Return the index of the give lref/mref. unsigned lref_index(expr const & e);
\pre is_mref(e) || is_lref(e) */ bool is_mref(expr const & e);
unsigned lmref_index(expr const & e); unsigned mref_index(expr const & e);
inline unsigned mref_index(expr const & e) { return lmref_index(e); }
inline unsigned lref_index(expr const & e) { return lmref_index(e); }
level update_succ(level const & l, level const & new_arg); level update_succ(level const & l, level const & new_arg);
level update_max(level const & l, level const & new_lhs, level const & new_rhs); level update_max(level const & l, level const & new_lhs, level const & new_rhs);
@ -83,6 +78,7 @@ level update_max(level const & l, level const & new_lhs, level const & new_rhs);
level replace(level const & l, std::function<optional<level>(level const & l)> const & f); level replace(level const & l, std::function<optional<level>(level const & l)> const & f);
expr update_app(expr const & e, expr const & new_fn, expr const & new_arg); expr update_app(expr const & e, expr const & new_fn, expr const & new_arg);
expr update_metavar(expr const & e, expr const & new_type);
expr update_binding(expr const & e, expr const & new_domain, expr const & new_body); expr update_binding(expr const & e, expr const & new_domain, expr const & new_body);
expr update_sort(expr const & e, level const & new_level); expr update_sort(expr const & e, level const & new_level);
expr update_constant(expr const & e, levels const & new_levels); expr update_constant(expr const & e, levels const & new_levels);
@ -105,5 +101,8 @@ expr instantiate_type_univ_params(declaration const & d, levels const & ls);
expr instantiate_value_univ_params(declaration const & d, levels const & ls); expr instantiate_value_univ_params(declaration const & d, levels const & ls);
expr abstract_lrefs(expr const & e, unsigned n, expr const * s); expr abstract_lrefs(expr const & e, unsigned n, expr const * s);
void initialize_expr();
void finalize_expr();
} }
} }

View file

@ -4,15 +4,18 @@ Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura Author: Leonardo de Moura
*/ */
#include "library/blast/expr.h"
#include "library/blast/blast.h" #include "library/blast/blast.h"
#include "library/blast/blast_tactic.h" #include "library/blast/blast_tactic.h"
namespace lean { namespace lean {
void initialize_blast_module() { void initialize_blast_module() {
blast::initialize_expr();
initialize_blast(); initialize_blast();
initialize_blast_tactic(); initialize_blast_tactic();
} }
void finalize_blast_module() { void finalize_blast_module() {
blast::finalize_expr();
finalize_blast(); finalize_blast();
finalize_blast_tactic(); finalize_blast_tactic();
} }