fix(library/blast/congruence_closure): is_relation_app ==> is_equivalence_relation_app
This commit is contained in:
parent
42dcbebd1c
commit
87995b96e3
4 changed files with 40 additions and 10 deletions
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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));
|
||||
|
|
8
tests/lean/run/blast_cc14.lean
Normal file
8
tests/lean/run/blast_cc14.lean
Normal 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
|
Loading…
Reference in a new issue