fix(library/blast/congruence_closure): is_relation_app ==> is_equivalence_relation_app

This commit is contained in:
Leonardo de Moura 2015-12-02 23:28:57 -08:00
parent 42dcbebd1c
commit 87995b96e3
4 changed files with 40 additions and 10 deletions

View file

@ -67,6 +67,7 @@ class blastenv {
relation_info_getter m_rel_getter;
refl_info_getter m_refl_getter;
symm_info_getter m_symm_getter;
trans_info_getter m_trans_getter;
unfold_macro_pred m_unfold_macro_pred;
class tctx : public type_context {
@ -448,6 +449,7 @@ public:
m_rel_getter(mk_relation_info_getter(env)),
m_refl_getter(mk_refl_info_getter(env)),
m_symm_getter(mk_symm_info_getter(env)),
m_trans_getter(mk_trans_info_getter(env)),
m_unfold_macro_pred([](expr const &) { return true; }),
m_tctx(*this),
m_normalizer(m_tctx) {
@ -595,6 +597,14 @@ public:
return static_cast<bool>(m_symm_getter(rop));
}
bool is_transitive(name const & rop) const {
return static_cast<bool>(m_trans_getter(rop, rop));
}
bool is_equivalence_relation_app(expr const & e, name & rop, expr & lhs, expr & rhs) {
return is_relation_app(e, rop, lhs, rhs) && is_reflexive(rop) && is_symmetric(rop) && is_transitive(rop);
}
optional<relation_info> get_relation_info(name const & rop) const {
return m_rel_getter(rop);
}
@ -663,6 +673,16 @@ bool is_symmetric(name const & rop) {
return g_blastenv->is_symmetric(rop);
}
bool is_transitive(name const & rop) {
lean_assert(g_blastenv);
return g_blastenv->is_transitive(rop);
}
bool is_equivalence_relation_app(expr const & e, name & rop, expr & lhs, expr & rhs) {
lean_assert(g_blastenv);
return g_blastenv->is_equivalence_relation_app(e, rop, lhs, rhs);
}
optional<relation_info> get_relation_info(name const & rop) {
lean_assert(g_blastenv);
return g_blastenv->get_relation_info(rop);

View file

@ -46,6 +46,8 @@ inline optional<relation_info> is_relation(expr const & R) {
}
bool is_reflexive(name const & rop);
bool is_symmetric(name const & rop);
bool is_transitive(name const & rop);
bool is_equivalence_relation_app(expr const & e, name & rop, expr & lhs, expr & rhs);
/** \brief Put the given expression in weak-head-normal-form with respect to the
current state being processed by the blast tactic. */

View file

@ -202,7 +202,7 @@ static optional<ext_congr_lemma> to_ext_congr_lemma(name const & R, expr const &
}
expr h_type = ctx->infer(h);
name h_R; expr h_lhs, h_rhs;
if (!is_relation_app(h_type, h_R, h_lhs, h_rhs)) {
if (!is_equivalence_relation_app(h_type, h_R, h_lhs, h_rhs)) {
return optional<ext_congr_lemma>();
}
bool found_lhs_rhs = false;
@ -393,8 +393,8 @@ int congruence_closure::congr_key_cmp::operator()(congr_key const & k1, congr_ke
} else if (k1.m_symm_rel) {
name R1, R2;
expr lhs1, rhs1, lhs2, rhs2;
lean_verify(is_relation_app(k1.m_expr, R1, lhs1, rhs1));
lean_verify(is_relation_app(k2.m_expr, R2, lhs2, rhs2));
lean_verify(is_equivalence_relation_app(k1.m_expr, R1, lhs1, rhs1));
lean_verify(is_equivalence_relation_app(k2.m_expr, R2, lhs2, rhs2));
if (R1 != R2)
return quick_cmp(R1, R2);
return g_cc->compare_symm(R1, lhs1, rhs1, lhs2, rhs2);
@ -466,7 +466,7 @@ auto congruence_closure::mk_congr_key(ext_congr_lemma const & lemma, expr const
} else if (std && is_iff(e, lhs, rhs)) {
k.m_iff = true;
k.m_hash = symm_hash(get_iff_name(), lhs, rhs);
} else if (std && is_relation_app(e, R, lhs, rhs) && is_symmetric(R)) {
} else if (std && is_equivalence_relation_app(e, R, lhs, rhs) && is_symmetric(R)) {
k.m_symm_rel = true;
k.m_hash = symm_hash(R, lhs, rhs);
} else {
@ -513,7 +513,7 @@ void congruence_closure::check_iff_true(congr_key const & k) {
lhs = app_arg(app_fn(e));
rhs = app_arg(e);
} else if (k.m_symm_rel) {
lean_verify(is_relation_app(e, R, lhs, rhs));
lean_verify(is_equivalence_relation_app(e, R, lhs, rhs));
} else {
return;
}
@ -908,7 +908,7 @@ void congruence_closure::add(expr const & type, expr const & proof) {
if (is_neg && !is_standard(env()))
return;
name R; expr lhs, rhs;
if (is_relation_app(p, R, lhs, rhs)) {
if (is_equivalence_relation_app(p, R, lhs, rhs)) {
if (is_neg) {
bool toplevel = true; bool to_propagate = false;
internalize_core(get_iff_name(), p, toplevel, to_propagate);
@ -1011,9 +1011,9 @@ expr congruence_closure::mk_congr_proof_core(name const & R, expr const & lhs, e
expr congruence_closure::mk_congr_proof(name const & R, expr const & e1, expr const & e2) const {
name R1; expr lhs1, rhs1;
if (is_relation_app(e1, R1, lhs1, rhs1)) {
if (is_equivalence_relation_app(e1, R1, lhs1, rhs1)) {
name R2; expr lhs2, rhs2;
if (is_relation_app(e2, R2, lhs2, rhs2) && R1 == R2) {
if (is_equivalence_relation_app(e2, R2, lhs2, rhs2) && R1 == R2) {
if (!is_eqv(R1, lhs1, lhs2)) {
lean_assert(is_eqv(R1, lhs1, rhs2));
// We must apply symmetry.
@ -1044,10 +1044,10 @@ expr congruence_closure::mk_proof(name const & R, expr const & lhs, expr const &
bool flip;
name R1; expr a, b;
if (lhs == mk_true()) {
lean_verify(is_relation_app(rhs, R1, a, b));
lean_verify(is_equivalence_relation_app(rhs, R1, a, b));
flip = true;
} else {
lean_verify(is_relation_app(lhs, R1, a, b));
lean_verify(is_equivalence_relation_app(lhs, R1, a, b));
flip = false;
}
expr H1 = get_app_builder().mk_iff_true_intro(*get_eqv_proof(R1, a, b));

View file

@ -0,0 +1,8 @@
constant R : nat → nat → Prop
axiom R_trans : ∀ a b c, R a b → R b c → R a c
attribute R_trans [trans]
set_option blast.subst false
example (a b c : nat) : a = b → R a b → R a a :=
by blast