chore: eliminator examples

This commit is contained in:
Leonardo de Moura 2020-07-30 10:45:54 -07:00
parent 0f598cca58
commit 5a08e042df

140
tmp/eqns/elim1.lean Normal file
View file

@ -0,0 +1,140 @@
universes u v
inductive Foo (α : Type u)
| leaf (a : α) : Foo
| node (left : Foo) (right : Foo) : Foo
| cons (head : α) (tail : Foo) : Foo
def Foo.elim {α : Type u} (C : Foo α → Foo α → Sort v) (x y : Foo α)
(h₁ : forall (a₁ a₂ : α), C (Foo.leaf a₁) (Foo.leaf a₂))
(h₂ : forall (l₁ r₁ l₂ r₂ : Foo α), C (Foo.node l₁ r₁) (Foo.node l₂ r₂))
(h₃ : forall (h₁ t₁ h₂ t₂), C (Foo.cons h₁ t₁) (Foo.cons h₂ t₂))
(h₄ : forall (x y), C x y)
: C x y :=
Foo.casesOn x
(fun a₁ => Foo.casesOn y
(fun a₂ => h₁ a₁ a₂)
(fun l₂ r₂ => h₄ (Foo.leaf a₁) (Foo.node l₂ r₂))
(fun h₂ t₂ => h₄ (Foo.leaf a₁) (Foo.cons h₂ t₂)))
(fun l₁ r₁ => Foo.casesOn y
(fun a₂ => h₄ (Foo.node l₁ r₁) (Foo.leaf a₂))
(fun l₂ r₂ => h₂ l₁ r₁ l₂ r₂)
(fun h₂ t₂ => h₄ (Foo.node l₁ r₁) (Foo.cons h₂ t₂)))
(fun h₁ t₁ => Foo.casesOn y
(fun a₂ => h₄ (Foo.cons h₁ t₁) (Foo.leaf a₂))
(fun l₂ r₂ => h₄ (Foo.cons h₁ t₁) (Foo.node l₂ r₂))
(fun h₂ t₂ => h₃ h₁ t₁ h₂ t₂))
def f : List Nat → List Nat → List Nat
| x::xs, _ => []
| _, [] => []
| xs, ys => xs ++ ys
def List.elim (C : List Nat → List Nat → Sort v) (xs ys : List Nat)
(h₁ : forall x xs ys, C (x::xs) ys)
(h₂ : forall xs, C xs [])
(h₃ : forall xs ys, C xs ys)
: C xs ys :=
List.casesOn xs
(List.casesOn ys
(h₂ [])
(fun y ys => h₃ [] (y::ys)))
(fun x xs => h₁ x xs ys)
theorem List.elim.eq1 (C : List Nat → List Nat → Sort v)
(h₁ : forall x xs ys, C (x::xs) ys)
(h₂ : forall xs, C xs [])
(h₃ : forall xs ys, C xs ys)
(x : Nat) (xs ys : List Nat)
: List.elim C (x::xs) ys h₁ h₂ h₃ = h₁ x xs ys :=
rfl
theorem List.elim.eq2 (C : List Nat → List Nat → Sort v)
(h₁ : forall x xs ys, C (x::xs) ys)
(h₂ : forall xs, C xs [])
(h₃ : forall xs ys, C xs ys)
(xs : List Nat)
: (forall x' xs', xs = x'::xs' → False) → List.elim C xs [] h₁ h₂ h₃ = h₂ xs :=
List.casesOn xs
(fun _ => rfl)
(fun x xs h => False.elim (h x xs rfl))
theorem List.elim.eq3 (C : List Nat → List Nat → Sort v)
(h₁ : forall x xs ys, C (x::xs) ys)
(h₂ : forall xs, C xs [])
(h₃ : forall xs ys, C xs ys)
(xs : List Nat) (ys : List Nat)
: (forall x' xs', xs = x'::xs' → False) → (ys = [] → False) → List.elim C xs ys h₁ h₂ h₃ = h₃ xs ys :=
List.casesOn xs
(List.casesOn ys
(fun _ h => False.elim (h rfl))
(fun y ys _ _ => rfl))
(fun x xs h _ => False.elim (h x xs rfl))
theorem List.elim.eq3.a (C : List Nat → List Nat → Sort v)
(h₁ : forall x xs ys, C (x::xs) ys)
(h₂ : forall xs, C xs [])
(h₃ : forall xs ys, C xs ys)
(y : Nat) (ys : List Nat)
: List.elim C [] (y::ys) h₁ h₂ h₃ = h₃ [] (y::ys) :=
rfl
def List.elim2 (C : List Nat → List Nat → Sort v) (xs ys : List Nat)
(h₁ : forall x xs ys, C (x::xs) ys)
(h₂ : forall xs, (forall (x' : Nat) (xs' : List Nat), xs = x' :: xs' → False) → C xs [])
(h₃ : forall xs ys, (forall (x' : Nat) (xs' : List Nat), xs = x' :: xs' → False) → (ys = [] → False) → C xs ys)
: C xs ys :=
List.casesOn xs
(List.casesOn ys
(h₂ [] (fun _ _ h => List.noConfusion h))
(fun y ys => h₃ [] (y::ys) (fun _ _ h => List.noConfusion h) (fun h => List.noConfusion h)))
(fun x xs => h₁ x xs ys)
def List.elim3 (C : List Nat → List Nat → List Nat → Sort v) (xs ys zs : List Nat)
(h₁ : forall zs, C [] [] zs)
(h₂ : forall xs ys, C xs ys [])
(h₃ : forall xs ys zs, C xs ys zs)
: C xs ys zs :=
List.casesOn xs
(List.casesOn ys
(h₁ zs)
(fun y ys => List.casesOn zs
(h₃ [] (y::ys) [])
(fun z zs => h₃ [] (y::ys) (z::zs))))
(fun x xs =>
(List.casesOn zs
(h₂ (x::xs) ys)
(fun z zs => h₃ (x::xs) ys (z::zs))))
theorem List.elim3.eq (C : List Nat → List Nat → List Nat → Sort v)
(h₁ : forall zs, C [] [] zs)
(h₂ : forall xs ys, C xs ys [])
(h₃ : forall xs ys zs, C xs ys zs)
(xs ys zs : List Nat)
: (xs = [] → ys = [] → False) → (zs = [] → False) → List.elim3 C xs ys zs h₁ h₂ h₃ = h₃ xs ys zs :=
List.casesOn xs
(List.casesOn ys
(fun h _ => False.elim (h rfl rfl))
(fun y ys => List.casesOn zs
(fun _ h => False.elim (h rfl))
(fun z zs _ _ => rfl)))
(fun x xs =>
List.casesOn zs
(fun _ h => False.elim (h rfl))
(fun z zs _ _ => rfl))
theorem List.elim3.eq.a (C : List Nat → List Nat → List Nat → Sort v)
(h₁ : forall zs, C [] [] zs)
(h₂ : forall xs ys, C xs ys [])
(h₃ : forall xs ys zs, C xs ys zs)
(y : Nat) (ys : List Nat) (z : Nat) (zs : List Nat)
: List.elim3 C [] (y::ys) (z::zs) h₁ h₂ h₃ = h₃ [] (y::ys) (z::zs) :=
rfl
theorem List.elim3.eq.b (C : List Nat → List Nat → List Nat → Sort v)
(h₁ : forall zs, C [] [] zs)
(h₂ : forall xs ys, C xs ys [])
(h₃ : forall xs ys zs, C xs ys zs)
(x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat) (z : Nat) (zs : List Nat)
: List.elim3 C (x::xs) (y::ys) (z::zs) h₁ h₂ h₃ = h₃ (x::xs) (y::ys) (z::zs) :=
rfl