83 lines
2.3 KiB
Text
83 lines
2.3 KiB
Text
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
|