« Home

induction principle 的生成 [VGOA]

這裡參考的是 Code Generation for Higher Inductive Types 中的紀錄

首先我們規範 inductive data types 的 form 如下

data D(a1:A1)(an:An):I1ImType wherec1:Δ1D a1an e11e1mcr:ΔrD a1an er1erm\begin{aligned} \text{data } &D (a_1 : A_1) \dots (a_n : A_n) : I_1 \to \cdots \to I_m \to \text{Type where} \\ &c_1 : \Delta_1 \to D\ a_1 \dots a_n\ e_{11} \dots e_{1m} \\ &\dots \\ &c_r : \Delta_r \to D\ a_1 \dots a_n\ e_{r1} \dots e_{rm} \end{aligned}

我們會生成以下形式的 induction principle

Dind:(a1:A1)(an:An)(i1:I1)(im:Im)(target:D a1an i1im)(C:(i1:I1)(im:Im)D a1an i1imType)(f1:Δ1C e11e1m(c1 Δ1)(fr:ΔrC er1erm(cr Δr)C i1...im target\begin{aligned} D_{ind} &: (a_1 : A_1) \to \dots \to (a_n : A_n) \\ &\to (i_1 : I_1) \to \dots \to (i_m : I_m) \\ &\to (\text{target} : D\ a_1 \dots a_n\ i_1 \dots i_m) \\ &\to (C : (i_1 : I_1) \to \dots \to (i_m : I_m) \to D\ a_1 \dots a_n\ i_1 \dots i_m \to \text{Type}) \\ &\to (f_1 : \Delta_1' \to C\ e_{11} \dots e_{1m} (c_1\ \Delta_1) \\ & \dots \\ &\to (f_r : \Delta_r' \to C\ e_{r1} \dots e_{rm} (c_r\ \Delta_r) \\ &\to C\ i_1 ... i_m\ \text{target} \end{aligned}

aia_iiji_j 的差別就是,iji_j 涉及到使用者可以實例化的部分,比如

data Vec (A : Type) : Nat -> Type where
  nil : Vec A 0
  cons : {n : Nat} -> A -> Vec A n -> Vec A (suc n)

這個案例中的 a1:A1a_1 : A_1 就是 A : Type,而 i1:I1i_1 : I_1_ : Nat。這裡 nilΔ\Delta 是空的,而 consΔ\Delta{n : Nat}, (_ : A), (_ : Vec A n)

eije_{ij} 分別是 0suc n,這就是使用者可以選擇不同 witness 填入的部分。

Δ\Delta 的生成部分可以看到特定標記成了 Δ\Delta',這個意思是說

  1. 如果 (y:B)Δ(y : B) \in \Delta 而且 B=D aeB = D\ a \dots e \dots,那 Δ\Delta' 中應該生成 (y : B), (y' : C e ... y)
  2. 如果 (y:B)Δ(y : B) \in \Delta 而且 B=ψD aeB = \psi \to D\ a \dots e \dots,那 Δ\Delta' 中應該生成 (y : B), (y' : Ψ -> C e ... (y Ψ))
  3. 除此之外 Δ\Delta' 只需要把 Δ\Delta 中的 binding (y:B)(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