leanprover / lean4

Lean 4 programming language and theorem prover
https://lean-lang.org
Apache License 2.0
4.7k stars 423 forks source link

`tactic 'contradiction' failed, metavariable has already been assigned` during `simp` #6066

Open TwoFX opened 20 hours ago

TwoFX commented 20 hours ago

Prerequisites

Please put an X between the brackets as you perform the following steps:

Description

inductive Impl  where
  | inner (size : Nat) (l r : Impl)
  | leaf

inductive Balanced : Impl → Prop where
  | leaf : Balanced leaf

@[inline]
def balanceLErase (r : Impl) (hrb : Balanced r)
     : Impl :=
  match r with
  | .leaf => .leaf
  | l@(.inner _ _ _) =>
    match l with
    | .leaf => .leaf
    | r@(.inner _ ll lr) =>
        match ll, lr with
          | .inner _ _ _, .inner _ _ _ => .leaf
          | _, _ => .leaf

/--
error: tactic 'contradiction' failed, metavariable has already been assigned
size✝² size✝¹ : Nat
l✝¹ r✝¹ : Impl
size✝ : Nat
l✝ r✝ : Impl
size_eq✝⁵ size_eq✝⁴ : size✝² = size✝²
hrb✝ : Balanced (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
motive :
  (ll lr : Impl) →
    (h : Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝) = Impl.inner size✝² ll lr) →
      (h_3 :
          namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
              (Impl.inner size✝² ll lr) h =
            Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) →
        Balanced
            (namedPattern
              (namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
                (Impl.inner size✝² ll lr) h)
              (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) h_3) →
          Sort u_1
h✝ :
  namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
      (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) ⋯ =
    Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)
hrb :
  Balanced
    (namedPattern
      (namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
        (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) ⋯)
      (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) h✝)
h_1 :
  (size : Nat) →
    (l r : Impl) →
      (size_1 : Nat) →
        (l_1 r_1 : Impl) →
          (h :
              Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝) =
                Impl.inner size✝² (Impl.inner size l r) (Impl.inner size_1 l_1 r_1)) →
            (h_3 :
                namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
                    (Impl.inner size✝² (Impl.inner size l r) (Impl.inner size_1 l_1 r_1)) h =
                  Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) →
              (hrb :
                  Balanced
                    (namedPattern
                      (namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
                        (Impl.inner size✝² (Impl.inner size l r) (Impl.inner size_1 l_1 r_1)) h)
                      (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) h_3)) →
                motive (Impl.inner size l r) (Impl.inner size_1 l_1 r_1) h h_3 hrb
h_2 :
  (x x_1 : Impl) →
    (h : Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝) = Impl.inner size✝² x x_1) →
      (h_3 :
          namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
              (Impl.inner size✝² x x_1) h =
            Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) →
        (hrb :
            Balanced
              (namedPattern
                (namedPattern (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝))
                  (Impl.inner size✝² x x_1) h)
                (Impl.inner size✝² (Impl.inner size✝¹ l✝¹ r✝¹) (Impl.inner size✝ l✝ r✝)) h_3)) →
          motive x x_1 h h_3 hrb
size_eq✝³ : size✝¹ = size✝¹
l_eq✝² : l✝¹ = l✝¹
r_eq✝³ : r✝¹ = r✝¹
size_eq✝² : size✝ = size✝
l_eq✝¹ : l✝ = l✝
r_eq✝² : r✝ = r✝
size_eq✝¹ : size✝² = size✝²
r_eq✝¹ : Impl.inner size✝ l✝ r✝ = Impl.inner size✝ l✝ r✝
size_eq✝ : size✝¹ = size✝¹
l_eq✝ : l✝¹ = l✝¹
r_eq✝ : r✝¹ = r✝¹
⊢ False
-/
#guard_msgs in
theorem size_balanceLErase {r : Impl} {hrb} :
    (balanceLErase r hrb) =  .leaf := by
  rw [balanceLErase.eq_def]
  simp only []

Expected behavior: No error

Actual behavior: See above

Versions

4.15.0-nightly-2024-11-13 on live.lean-lang.org

Impact

Add :+1: to issues you consider important. If others are impacted by this issue, please ask them to add :+1: to it.

nomeata commented 20 hours ago

(I took the liberty to slightly adjust the #mwe to show that the issue appears with simp only [], and thus isn’t related to generating or applying the equational theorem.)