lean4-htt/tests/lean/run/structuralRec1.lean
2024-03-13 12:37:58 -07:00

224 lines
5.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

inductive PList (α : Type) : Prop
| nil
| cons : α → PList α → PList α
infixr:67 " ::: " => PList.cons
def map {α β} (f : α → β) : List α → List β
| [] => []
| a::as => f a :: map f as
def pmap {α β} (f : α → β) : PList α → PList β
| PList.nil => PList.nil
| a:::as => f a ::: pmap f as
theorem ex1 : map Nat.succ [1] = [2] :=
rfl
theorem ex2 : map Nat.succ [] = [] :=
rfl
theorem ex3 (a : Nat) : map Nat.succ [a] = [Nat.succ a] :=
rfl
theorem ex4 {α β} (f : α → β) (a : α) (as : List α) : map f (a::as) = (f a) :: map f as :=
rfl
theorem ex5 {α β} (f : α → β) : map f [] = [] :=
rfl
def map2 {α β} (f : α → β) (as : List α) : List β :=
let rec loop : List α → List β
| [] => []
| a::as => f a :: loop as;
loop as
def pmap2 {α β} (f : α → β) (as : PList α) : PList β :=
let rec loop : PList α → PList β
| PList.nil => PList.nil
| a:::as => f a ::: loop as;
loop as
theorem ex6 {α β} (f : α → β) (a : α) (as : List α) : map2 f (a::as) = (f a) :: map2 f as :=
rfl
def foo (xs : List Nat) : List Nat :=
match xs with
| [] => []
| x::xs =>
let y := 2 * x;
match xs with
| [] => []
| x::xs => (y + x) :: foo xs
def pfoo (xs : PList Nat) : PList Nat :=
match xs with
| PList.nil => PList.nil
| x:::xs =>
let y := 2 * x;
match xs with
| PList.nil => PList.nil
| x:::xs => (y + x) ::: pfoo xs
#eval foo [1, 2, 3, 4]
theorem fooEq (x y : Nat) (xs : List Nat) : foo (x::y::xs) = (2*x + y) :: foo xs :=
rfl
def bla (x : Nat) (ys : List Nat) : List Nat :=
if x % 2 == 0 then
match ys with
| [] => []
| y::ys => (y + x/2) :: bla (x/2) ys
else
match ys with
| [] => []
| y::ys => (y + x/2 + 1) :: bla (x/2) ys
def pbla (x : Nat) (ys : PList Nat) : PList Nat :=
if x % 2 == 0 then
match ys with
| PList.nil => PList.nil
| y:::ys => (y + x/2) ::: pbla (x/2) ys
else
match ys with
| PList.nil => PList.nil
| y:::ys => (y + x/2 + 1) ::: pbla (x/2) ys
theorem blaEq (y : Nat) (ys : List Nat) : bla 4 (y::ys) = (y+2) :: bla 2 ys :=
rfl
inductive PNat : Prop
| zero
| succ : PNat → PNat
def f : Nat → Nat → Nat
| 0, y => y
| x+1, y =>
match f x y with
| 0 => f x y
| v => f x v + 1
def pf : PNat → PNat → PNat
| PNat.zero, y => y
| PNat.succ x, y =>
match pf x y with
| PNat.zero => pf x y
| v => PNat.succ $ pf x v
def g (xs : List Nat) : Nat :=
match xs with
| [] => 0
| y::ys =>
match ys with
| [] => 1
| _ => g ys + 1
def pg (xs : PList Nat) : True :=
match xs with
| PList.nil => True.intro
| y:::ys =>
match ys with
| PList.nil => True.intro
| _ => pg ys
def aux : Nat → Nat → Nat
| 0, y => y
| x+1, y =>
match f x y with
| 0 => f x y
| v => f x v + 1
def paux : PNat → PNat → PNat
| PNat.zero, y => y
| PNat.succ x, y =>
match pf x y with
| PNat.zero => pf x y
| v => PNat.succ (pf x v)
theorem ex (x y : Nat) : f x y = aux x y := by
cases x
rfl
rfl
axiom F : Nat → Nat
inductive is_nat : Nat -> Prop
| Z : is_nat 0
| S {n} : is_nat n → is_nat (F n)
inductive is_nat_T : Nat -> Type
| Z : is_nat_T 0
| S {n} : is_nat_T n → is_nat_T (F n)
axiom P : Nat → Prop
axiom F0 : P 0
axiom F1 : P (F 0)
axiom FS {n : Nat} : P n → P (F (F n))
axiom T : Nat → Prop
axiom TF0 : T 0
axiom TF1 : T (F 0)
axiom TFS {n : Nat} : T n → T (F (F n))
-- set_option trace.Elab.definition.structural true in
theorem «nested recursion» : ∀ {n}, is_nat n → P n
| _, is_nat.Z => F0
| _, is_nat.S is_nat.Z => F1
| _, is_nat.S (is_nat.S h) => FS («nested recursion» h)
/-- forbidding this, because it shouldn't exist in the first place.
We don't expect this kind of inconsistent inaccessible patterns. -/
-- theorem «nested recursion, inaccessible» : ∀ {n}, is_nat n → P n
-- | _, .(is_nat.Z) => F0
-- | _, is_nat.S .(is_nat.Z) => F1
-- | _, is_nat.S (is_nat.S h) => FS («nested recursion, inaccessible» h)
theorem «reordered discriminants, type» : ∀ n, is_nat_T n → Nat → T n := fun n hn m =>
match n, m, hn with
| _, _, is_nat_T.Z => TF0
| _, _, is_nat_T.S is_nat_T.Z => TF1
| _, m, is_nat_T.S (is_nat_T.S h) => TFS («reordered discriminants, type» _ h m)
theorem «reordered discriminants» : ∀ n, is_nat n → Nat → P n := fun n hn m =>
match n, m, hn with
| _, _, is_nat.Z => F0
| _, _, is_nat.S is_nat.Z => F1
| _, m, is_nat.S (is_nat.S h) => FS («reordered discriminants» _ h m)
/-- known unsupported case for types, just here for reference. -/
-- def «unsupported nesting» (xs : List Nat) : True :=
-- match xs with
-- | List.nil => True.intro
-- | y::ys =>
-- match ys with
-- | List.nil => True.intro
-- | _::_::zs => «unsupported nesting» zs
-- | zs => «unsupported nesting» ys
def «unsupported nesting, predicate» (xs : PList Nat) : True :=
match xs with
| PList.nil => True.intro
| y:::ys =>
match ys with
| PList.nil => True.intro
| _:::_:::zs => «unsupported nesting, predicate» zs
| zs => «unsupported nesting, predicate» ys
def f1 (xs : List Nat) : Nat :=
match xs with
| [] => 0
| x::xs =>
match xs with
| [] => 0
| _ => f1 xs + 1
def pf1 (xs : PList Nat) : True :=
match xs with
| PList.nil => True.intro
| x:::xs =>
match xs with
| PList.nil => True.intro
| _ => pf1 xs