這裡參考的是 Code Generation for Higher Inductive Types 中的紀錄
首先我們規範 inductive data types 的 form 如下
data D(a1:A1)…(an:An):I1→⋯→Im→Type wherec1:Δ1→D a1…an e11…e1m…cr:Δr→D a1…an er1…erm
我們會生成以下形式的 induction principle
Dind:(a1:A1)→⋯→(an:An)→(i1:I1)→⋯→(im:Im)→(target:D a1…an i1…im)→(C:(i1:I1)→⋯→(im:Im)→D a1…an i1…im→Type)→(f1:Δ1′→C e11…e1m(c1 Δ1)…→(fr:Δr′→C er1…erm(cr Δr)→C i1...im target
ai 跟 ij 的差別就是,ij 涉及到使用者可以實例化的部分,比如
data Vec (A : Type) : Nat -> Type where
nil : Vec A 0
cons : {n : Nat} -> A -> Vec A n -> Vec A (suc n)
這個案例中的 a1:A1 就是 A : Type,而 i1:I1 是 _ : Nat。這裡 nil 的 Δ 是空的,而 cons 的 Δ 是 {n : Nat}, (_ : A), (_ : Vec A n)。
而 eij 分別是 0 跟 suc n,這就是使用者可以選擇不同 witness 填入的部分。
在 Δ 的生成部分可以看到特定標記成了 Δ′,這個意思是說
- 如果 (y:B)∈Δ 而且 B=D a…e…,那 Δ′ 中應該生成
(y : B), (y' : C e ... y)
- 如果 (y:B)∈Δ 而且 B=ψ→D a…e…,那 Δ′ 中應該生成
(y : B), (y' : Ψ -> C e ... (y Ψ))
- 除此之外 Δ′ 只需要把 Δ 中的 binding (y:B) 複製一遍就好了
所以 Vec 得到的 induction principle 就應該是
Vec.ind : (A : Type) -> (i : Nat) -> (target : Vec A i)
-> (C : (i : Nat) -> D A i -> Type)
-> (case_nil : C 0 nil)
-> (case_cons : {n : Nat}
-> (a : A)
-> (as : Vec A n)
-> (as' : C n as)
-> C (suc n) (cons {n} a as))
-> C i target