feat(kernel/expr): cache is_arrow result
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
1faf42e2e1
commit
90dbdaec40
2 changed files with 37 additions and 1 deletions
|
@ -64,6 +64,25 @@ void expr_cell::dec_ref(optional<expr> & c, buffer<expr_cell*> & todelete) {
|
||||||
dec_ref(*c, todelete);
|
dec_ref(*c, todelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional<bool> expr_cell::is_arrow() const {
|
||||||
|
// it is stored in bits 3-4
|
||||||
|
unsigned r = (m_flags & (8+16)) >> 3;
|
||||||
|
if (r == 0) {
|
||||||
|
return optional<bool>();
|
||||||
|
} else if (r == 1) {
|
||||||
|
return optional<bool>(true);
|
||||||
|
} else {
|
||||||
|
lean_assert(r == 2);
|
||||||
|
return optional<bool>(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_cell::set_is_arrow(bool flag) {
|
||||||
|
unsigned mask = flag ? 8 : 16;
|
||||||
|
m_flags |= mask;
|
||||||
|
lean_assert(is_arrow() && *is_arrow() == flag);
|
||||||
|
}
|
||||||
|
|
||||||
expr_var::expr_var(unsigned idx):
|
expr_var::expr_var(unsigned idx):
|
||||||
expr_cell(expr_kind::Var, idx, false),
|
expr_cell(expr_kind::Var, idx, false),
|
||||||
m_vidx(idx) {}
|
m_vidx(idx) {}
|
||||||
|
@ -227,7 +246,14 @@ bool operator==(expr const & a, expr const & b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_arrow(expr const & t) {
|
bool is_arrow(expr const & t) {
|
||||||
return is_pi(t) && !has_free_var(abst_body(t), 0);
|
optional<bool> r = t.raw()->is_arrow();
|
||||||
|
if (r) {
|
||||||
|
return *r;
|
||||||
|
} else {
|
||||||
|
bool res = is_pi(t) && !has_free_var(abst_body(t), 0);
|
||||||
|
t.raw()->set_is_arrow(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_eq(expr const & e, expr & lhs, expr & rhs) {
|
bool is_eq(expr const & e, expr & lhs, expr & rhs) {
|
||||||
|
|
|
@ -68,6 +68,11 @@ typedef list<local_entry> local_context;
|
||||||
class expr_cell {
|
class expr_cell {
|
||||||
protected:
|
protected:
|
||||||
unsigned short m_kind;
|
unsigned short m_kind;
|
||||||
|
// The bits of the following field mean:
|
||||||
|
// 0 - term is maximally shared
|
||||||
|
// 1 - term is closed
|
||||||
|
// 2 - term contains metavariables
|
||||||
|
// 3-4 - term is an arrow (0 - not initialized, 1 - is arrow, 2 - is not arrow)
|
||||||
atomic_ushort m_flags;
|
atomic_ushort m_flags;
|
||||||
unsigned m_hash; // hash based on the structure of the expression (this is a good hash for structural equality)
|
unsigned m_hash; // hash based on the structure of the expression (this is a good hash for structural equality)
|
||||||
unsigned m_hash_alloc; // hash based on 'time' of allocation (this is a good hash for pointer-based equality)
|
unsigned m_hash_alloc; // hash based on 'time' of allocation (this is a good hash for pointer-based equality)
|
||||||
|
@ -80,6 +85,11 @@ protected:
|
||||||
|
|
||||||
bool is_closed() const { return (m_flags & 2) != 0; }
|
bool is_closed() const { return (m_flags & 2) != 0; }
|
||||||
void set_closed() { m_flags |= 2; }
|
void set_closed() { m_flags |= 2; }
|
||||||
|
|
||||||
|
optional<bool> is_arrow() const;
|
||||||
|
void set_is_arrow(bool flag);
|
||||||
|
friend bool is_arrow(expr const & e);
|
||||||
|
|
||||||
friend class has_free_var_fn;
|
friend class has_free_var_fn;
|
||||||
static void dec_ref(expr & c, buffer<expr_cell*> & todelete);
|
static void dec_ref(expr & c, buffer<expr_cell*> & todelete);
|
||||||
static void dec_ref(optional<expr> & c, buffer<expr_cell*> & todelete);
|
static void dec_ref(optional<expr> & c, buffer<expr_cell*> & todelete);
|
||||||
|
|
Loading…
Reference in a new issue