| def Vec (α : Type u) (n : Nat) : Type u := { a : List α // a.length = n } | |
| def Vec.nil : Vec α 0 := ⟨[], rfl⟩ | |
| def Vec.cons (a : α) (as : Vec α n) : Vec α (n+1) := ⟨a :: as.val, by simp [as.property]⟩ | |
| set_option pp.analyze false | |
| set_option linter.unusedVariables false | |
| set_option pp.mvars false | |
| def Vec.casesOn | |
| (motive : (n : Nat) → Vec α n → Sort v) | |
| (n : Nat) | |
| (as : Vec α n) | |
| (nil : motive 0 Vec.nil) | |
| (cons : (n : Nat) → (a : α) → (as : Vec α n) → (ih : motive n as) → motive (n+1) (Vec.cons a as)) | |
| : motive n as := | |
| let rec go (n : Nat) (as : List α) (h : as.length = n) : motive n ⟨as, h⟩ := | |
| match n, as, h with | |
| | 0, [], _ => nil | |
| | n+1, a::as, h => | |
| have : as.length = n := by injection h | |
| have ih : motive n ⟨as, this⟩ := go n as this | |
| cons n a ⟨as, this⟩ ih | |
| match as with | |
| | ⟨as, h⟩ => go n as h | |
| /-- | |
| trace: α : Type u_1 | |
| n✝ : Nat | |
| a✝ : α | |
| as✝ : Vec α n✝ | |
| x✝ n : Nat | |
| a : α | |
| as : Vec α n | |
| ih : as = as | |
| ⊢ Vec.cons a as = Vec.cons a as | |
| -/ | |
| #guard_msgs in | |
| example (n : Nat) (a : α) (as : Vec α n) : Vec.cons a (Vec.cons a as) = Vec.cons a (Vec.cons a as) := by | |
| induction n+2, Vec.cons a (Vec.cons a as) using Vec.casesOn | |
| case nil => constructor | |
| case cons n a as ih => | |
| trace_state | |
| constructor | |
| /-- | |
| trace: α : Type u_1 | |
| n✝ : Nat | |
| a✝ : α | |
| as✝ : Vec α n✝ | |
| n : Nat | |
| a : α | |
| as : Vec α n | |
| ih : n + 1 = n → Vec.cons a as ≍ as → Vec.cons a as = Vec.cons a as | |
| ⊢ Vec.cons a as = Vec.cons a as | |
| -/ | |
| #guard_msgs in | |
| example (n : Nat) (a : α) (as : Vec α n) : Vec.cons a (Vec.cons a as) = Vec.cons a (Vec.cons a as) := by | |
| cases n+2, Vec.cons a (Vec.cons a as) using Vec.casesOn | |
| case nil => constructor | |
| case cons n a as ih => | |
| trace_state | |
| constructor | |
| /-- | |
| trace: α : Type u_1 | |
| n : Nat | |
| a : α | |
| as : Vec α n | |
| n' : Nat | |
| a' : α | |
| as' : Vec α n' | |
| h₁ : n + 2 = n' + 1 | |
| h₂ : Vec.cons a (Vec.cons a as) ≍ Vec.cons a' as' | |
| ih : n' + 1 = n' → Vec.cons a' as' ≍ as' → Vec.cons a' as' = Vec.cons a' as' | |
| ⊢ Vec.cons a' as' = Vec.cons a' as' | |
| -/ | |
| #guard_msgs in | |
| example (n : Nat) (a : α) (as : Vec α n) : Vec.cons a (Vec.cons a as) = Vec.cons a (Vec.cons a as) := by | |
| cases h₁ : n+2, h₂ : Vec.cons a (Vec.cons a as) using Vec.casesOn | |
| case nil => constructor | |
| case cons n' a' as' ih => | |
| trace_state | |
| constructor |