lean4-htt/tests/elab/funind_mutual_dep.lean
Garmelon 08eb78a5b2
chore: switch to new test/bench suite (#12590)
This PR sets up the new integrated test/bench suite. It then migrates
all benchmarks and some related tests to the new suite. There's also
some documentation and some linting.

For now, a lot of the old tests are left alone so this PR doesn't become
even larger than it already is. Eventually, all tests should be migrated
to the new suite though so there isn't a confusing mix of two systems.
2026-02-25 13:51:53 +00:00

66 lines
2.5 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.

-- Testing functional induction derivation with mutual recursion + dependent types
inductive Finite where
| unit : Finite
| bool : Finite
| pair : Finite → Finite → Finite
| arr : Finite → Finite → Finite
abbrev Finite.asType : Finite → Type
| .unit => Unit
| .bool => Bool
| .pair t1 t2 => asType t1 × asType t2
| .arr t1 t2 => asType t1 → asType t2
def List.product (xs : List α) (ys : List β) : List (α × β) := Id.run do
let mut out : List (α × β) := []
for x in xs do
for y in ys do
out := (x, y) :: out
pure out.reverse
mutual
def Finite.enumerate (t : Finite) : List t.asType :=
match t with
| .unit => [()]
| .bool => [true, false]
| .pair t1 t2 => t1.enumerate.product t2.enumerate
| .arr t1 t2 => t1.functions t2.enumerate
def Finite.functions (t : Finite) (results : List α) : List (t.asType → α) :=
match t with
| .unit => results.map fun r => fun () => r
| .bool =>
(results.product results).map fun (r1, r2) =>
fun
| true => r1
| false => r2
| .pair t1 t2 =>
let f1s := t1.functions <| t2.functions results
f1s.map fun f => fun (x, y) => f x y
| .arr t1 t2 =>
let args := t1.enumerate
let base := results.map fun r => fun _ => r
args.foldr (init := base) fun arg rest =>
(t2.functions rest).map fun (more : t2.asType → (t1.asType → t2.asType) → α) =>
fun (f : t1.asType → t2.asType) => more (f arg) f
end
/--
info: Finite.functions.induct (motive1 : Finite → Prop) (motive2 : (α : Type) → Finite → List α → Prop)
(case1 : motive1 Finite.unit) (case2 : motive1 Finite.bool)
(case3 : ∀ (t1 t2 : Finite), motive1 t1 → motive1 t2 → motive1 (t1.pair t2))
(case4 : ∀ (t1 t2 : Finite), motive1 t2 → motive2 t2.asType t1 t2.enumerate → motive1 (t1.arr t2))
(case5 : ∀ (α : Type) (results : List α), motive2 α Finite.unit results)
(case6 : ∀ (α : Type) (results : List α), motive2 α Finite.bool results)
(case7 :
∀ (α : Type) (results : List α) (t1 t2 : Finite),
motive2 α t2 results → motive2 (t2.asType → α) t1 (t2.functions results) → motive2 α (t1.pair t2) results)
(case8 :
∀ (α : Type) (results : List α) (t1 t2 : Finite),
motive1 t1 →
(∀ (rest : List ((t1.arr t2).asType → α)), motive2 ((t1.arr t2).asType → α) t2 rest) →
motive2 α (t1.arr t2) results)
(α : Type) (t : Finite) (results : List α) : motive2 α t results
-/
#guard_msgs in
#check Finite.functions.induct