fix(library/tactic/smt/congruence_closure): must check whether constructors have the same type or not

This commit is contained in:
Leonardo de Moura 2017-01-08 00:36:57 -08:00
parent 8a12c834ca
commit 9d273d924f
2 changed files with 53 additions and 1 deletions

View file

@ -1253,6 +1253,13 @@ void congruence_closure::propagate_constructor_eq(expr const & e1, expr const &
optional<name> c1 = is_constructor_app(env(), e1);
optional<name> c2 = is_constructor_app(env(), e2);
lean_assert(c1 && c2);
if (!m_ctx.is_def_eq(m_ctx.infer(e1), m_ctx.infer(e2))) {
/* The implications above only hold if the types are equal.
TODO(Leo): if the types are different, we may still propagate by searching the equivalence
classes of e1 and e2 for other constructors that may have compatible types. */
return;
}
expr type = mk_eq(m_ctx, e1, e2);
expr h = *get_eq_proof(e1, e2);
if (*c1 == *c2) {
@ -1885,7 +1892,7 @@ void congruence_closure::add_eqv_step(expr e1, expr e2, expr const & H, bool heq
auto fmt = out.get_formatter();
out << "merged: " << e1_root << " = " << e2_root << "\n";
out << m_state.pp_eqcs(fmt) << "\n";
out << m_state.pp_parent_occs(fmt) << "\n";
// out << m_state.pp_parent_occs(fmt) << "\n";
out << "--------\n";);
}

View file

@ -0,0 +1,45 @@
open nat
notation `⟦`:max a `⟧`:0 := cast (by simp) a
inductive vector (α : Type) : nat → Type
| nil {} : vector 0
| cons : Π {n}, α → vector n → vector (succ n)
namespace vector
local attribute [simp] add_succ succ_add add_comm
variable {α : Type}
def app : Π {n m : nat}, vector α n → vector α m → vector α (n + m)
| 0 m nil w := ⟦ w ⟧
| (succ n) m (cons a v) w := ⟦ cons a (app v w) ⟧
lemma app_nil_right {n : nat} (v : vector α n) : app v nil == v :=
begin induction v, reflexivity, {[smt] ematch_using [app, add_comm, zero_add, add_zero] }, end
def smt_cfg : smt_config :=
{ default_smt_config with cc_cfg := {default_cc_config with ac := ff}}
lemma app_assoc {n₁ n₂ n₃ : nat} (v₁ : vector α n₁) (v₂ : vector α n₂) (v₃ : vector α n₃) :
app v₁ (app v₂ v₃) == app (app v₁ v₂) v₃ :=
begin
intros,
induction v₁,
{[smt] ematch_using [app, zero_add] },
{[smt] with smt_cfg, repeat { ematch_using [app, add_succ, succ_add, add_comm, add_assoc] }}
end
def rev : Π {n : nat}, vector α n → vector α n
| 0 nil := nil
| (n+1) (cons x xs) := app (rev xs) (cons x nil)
lemma rev_app : ∀ {n₁ n₂ : nat} (v₁ : vector α n₁) (v₂ : vector α n₂),
rev (app v₁ v₂) == app (rev v₂) (rev v₁) :=
begin
intros,
induction v₁,
{[smt] repeat {ematch_using [app, rev, zero_add, add_zero, add_comm, app_nil_right]}},
{[smt] repeat {ematch_using [app, rev, zero_add, add_zero, add_comm, app_assoc, add_one_eq_succ]} }
end
end vector