Zulip Chat Archive
Stream: lean4
Topic: Potential elaboration bug with `elabAsElim`
Scott Morrison (Sep 19 2022 at 04:59):
Calling refine'
as below with a lemma marked as elabAsElim
doesn't seem to be behaving correctly (on leanprover/lean4:nightly-2022-09-15):
/-- `Perm l₁ l₂` or `l₁ ~ l₂` asserts that `l₁` and `l₂` are Permutations
of each other. This is defined by induction using pairwise swaps. -/
inductive Perm {α} : List α → List α → Prop
| nil : Perm [] []
| cons : ∀ (x : α) {l₁ l₂ : List α}, Perm l₁ l₂ → Perm (x::l₁) (x::l₂)
| swap : ∀ (x y : α) (l : List α), Perm (y::x::l) (x::y::l)
| trans : ∀ {l₁ l₂ l₃ : List α}, Perm l₁ l₂ → Perm l₂ l₃ → Perm l₁ l₃
infixl:50 " ~ " => Perm
protected theorem Perm.refl : ∀ (l : List α), l ~ l
| [] => Perm.nil
| (x::xs) => (Perm.refl xs).cons x
@[elabAsElim]
theorem perm_induction_on {P : List α → List α → Prop} {l₁ l₂ : List α} (p : l₁ ~ l₂) (h₁ : P [] [])
(h₂ : ∀ x l₁ l₂, l₁ ~ l₂ → P l₁ l₂ → P (x :: l₁) (x :: l₂))
(h₃ : ∀ x y l₁ l₂, l₁ ~ l₂ → P l₁ l₂ → P (y :: x :: l₁) (x :: y :: l₂))
(h₄ : ∀ l₁ l₂ l₃, l₁ ~ l₂ → l₂ ~ l₃ → P l₁ l₂ → P l₂ l₃ → P l₁ l₃) : P l₁ l₂ :=
have P_refl : ∀ l, P l l := fun l => List.recOn l h₁ fun x xs ih => h₂ x xs xs (Perm.refl xs) ih
Perm.recOn p h₁ h₂ (fun x y l => h₃ x y l l (Perm.refl l) (P_refl l)) @h₄
theorem perm_inv_core {a : α} {l₁ l₂ r₁ r₂ : List α} : l₁ ++ a :: r₁ ~ l₂ ++ a :: r₂ → l₁ ++ r₁ ~ l₂ ++ r₂ := by
generalize e₁ : l₁ ++ a :: r₁ = s₁
generalize e₂ : l₂ ++ a :: r₂ = s₂
intro p
revert l₁ l₂ r₁ r₂ e₁ e₂
refine' @(perm_induction_on p _ (fun x t₁ t₂ p IH => _) (fun x y t₁ t₂ p IH => _) (fun t₁ t₂ t₃ p₁ p₂ IH₁ IH₂ => _))
intro l₁ l₂ r₁ r₂ e₁ e₂
-- Hypotheses include
-- `e₁: l₁ ++ a :: r₁ = s₁`
-- `e₂: l₂ ++ a :: r₂ = s₂`
-- but these should be
-- `e₁: l₁ ++ a :: r₁ = nil`
-- `e₂: l₂ ++ a :: r₂ = nil`
all_goals sorry
Scott Morrison (Sep 19 2022 at 10:23):
This can be readily minimized to
inductive Q {α} : List α → Prop
| nil : Q []
@[elabAsElim]
theorem Q_induction_on {P : List α → Prop} {l₁ : List α} (p : Q l₁) (h : P []) : P l₁ :=
Q.recOn p h
example {a : α} {l r : List α} : Q (l ++ a :: r) → Q (l ++ r) := by
generalize e : l ++ a :: r = s
intro p
revert l r e
refine' @(Q_induction_on p _)
intro l r e
-- Hypotheses include
-- `e: l ++ a :: r = s`
-- but this should should be
-- `e: l ++ a :: r = nil`
sorry
Leonardo de Moura (Sep 19 2022 at 13:42):
@Scott Morrison I cannot reproduce the errors above, could you please get the latest nightly build and try again?
Leonardo de Moura (Sep 19 2022 at 14:17):
elabAsElim
instructs Lean to use a different approach/heuristic to compute the implicit motive (P
in your example). However, the motive does not take the major premise p
as a parameter, and this information is necessary for the current implementation. The following variant works
inductive Q {α} : List α → Prop
| nil : Q []
@[elabAsElim]
theorem Q_induction_on {P : (s : List α) → Q s → Prop} {l₁ : List α} (p : Q l₁) (h : P [] .nil) : P l₁ p :=
Q.recOn p h
example {a : α} {l r : List α} : Q (l ++ a :: r) → Q (l ++ r) := by
generalize e : l ++ a :: r = s
intro p
revert l r e
refine' @(Q_induction_on p _)
Last updated: Dec 20 2023 at 11:08 UTC