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