`zero : β―βΊ πΈ
`zero = val β¨ x β© x
`suc : β―βΊ πΈ
`suc = val β¨ x β© `pair `Β· `false `Β· x
`num : Nat β β―βΊ πΈ
`num zero = `zero
`num (suc x) = record
{ fst = `pair β `false β `num x
; snd = `pairββ (absβ _ _) (`num x .snd)
}
`pred : β―βΊ πΈ
`pred = val β¨ x β© `fst `Β· x `Β· `zero `Β· (`snd `Β· x)
`iszero : β―βΊ πΈ
`iszero = `fst
private
variable f g x y z : β― β πΈ β
`worker : β―βΊ πΈ
`worker = val β¨ rec β© β¨ zc β© β¨ sc β© β¨ num β©
`iszero `Β· num
`Β· (`true `Β· zc)
`Β· (β¨ y β© sc `Β· (`pred `Β· num) `Β· (rec `Β· zc `Β· sc `Β· (`pred `Β· num) `Β· `zero))
`primrec : β―βΊ πΈ
`primrec = val β¨ z β© β¨ s β© β¨ n β© `Z `Β· `worker `Β· z `Β· s `Β· n `Β· `zero
abstract
`num-suc : β x β `num (suc x) .fst β‘ `suc β `num x
`num-suc x = sym (abs-Ξ² _ _ (`num x))
`sucββ : β {a} β β a β β β `suc .fst % a β
`sucββ ah = subst β_β (sym (abs-Ξ²β [] ((_ , ah) β· []))) (`pairββ (`false .snd) ah)
`iszero-zero : `iszero β `zero β‘ `true .fst
`iszero-zero = abs-Ξ² _ _ `zero β abs-Ξ² _ _ (_ , absβ _ _)
`iszero-suc : β x β β `iszero β (`suc β x) β‘ `false .fst
`iszero-suc {x} xh =
`iszero β (`suc β x) β‘β¨ ap (`iszero β_) (abs-Ξ² _ _ (_ , xh)) β©
`iszero β (`pair β `false β x) β‘β¨ `fst-Ξ² (`false .snd) xh β©
`false .fst β
`pred-zero : `pred β `zero β‘ `zero .fst
`pred-zero =
`pred β `zero β‘β¨ abs-Ξ² _ _ `zero β©
β `fst β `zero β β `zero β (`snd β `zero) β‘β¨ ap! (`iszero-zero) β©
`true β `zero β (`snd β `zero) β‘β¨ abs-Ξ²β [] ((_ , subst β_β (sym remβ) (absβ _ _)) β· `zero β· []) β©
`zero .fst β
where
remβ : `snd β `zero β‘ `false .fst
remβ = abs-Ξ² _ _ `zero β abs-Ξ² _ _ `false
`pred-suc : β x β β `pred β (`suc β x) β‘ x
`pred-suc {x} xh =
`pred β (`suc β x) β‘β¨ abs-Ξ² _ _ (_ , `sucββ xh) β©
β `fst β (`suc β x) β β `zero β (`snd β (`suc β x)) β‘β¨ ap! (ap (`fst β_) (abs-Ξ² _ _ (_ , xh)) β `fst-Ξ² (`false .snd) xh) β©
`false β `zero β β `snd β (`suc β x) β β‘β¨ ap! (ap (`snd β_) (abs-Ξ² _ _ (_ , xh)) β `snd-Ξ² (`false .snd) xh) β©
`false β `zero β x β‘β¨ abs-Ξ²β [] ((_ , xh) β· `zero β· []) β©
x β
`primrec-zero : β z β β β f β β `primrec β z β f β `zero β‘ z
`primrec-zero {z} {f} zh fh =
`primrec β z β f β `zero β‘β¨ abs-Ξ²β [] (`zero β· (_ , fh) β· (_ , zh) β· []) β©
β `Z β `worker β z β β f β `zero β `zero β‘β¨ ap! (`Z-Ξ² (`worker .snd) zh) β©
β `worker β (`Z β `worker) β z β f β `zero β β `zero β‘β¨ ap (Ξ» e β e % `zero .fst) (abs-Ξ²β [] (`zero β· (_ , fh) β· (_ , zh) β· (_ , `Zββ (`worker .snd)) β· [])) β©
β `iszero β `zero β (`true β z) β % _ % `zero .fst β‘β¨ apβ _%_ (apβ _%_ (apβ _%_ `iszero-zero refl) refl β `true-Ξ² (`trueββ zh) (absβ _ _)) refl β©
`true β z β `zero .fst β‘β¨ `true-Ξ² zh (`zero .snd) β©
z β
`primrec-suc : β z β β β f β β β x β β `primrec β z β f β (`suc β x) β‘ f β x β (`primrec β z β f β x)
`primrec-suc {z} {f} {x} zh fh xh =
`primrec β z β f β (`suc β x) β‘β¨ abs-Ξ²β [] ((_ , `sucββ xh) β· (_ , fh) β· (_ , zh) β· []) β©
β `Z β `worker β z β β f β (`suc β x) β `zero β‘β¨ ap! (`Z-Ξ² (`worker .snd) zh) β©
`worker β (`Z β `worker) β z β f β (`suc β x) β `zero β‘β¨ ap (Ξ» e β e % `zero .fst) (abs-Ξ²β [] ((_ , `sucββ xh) β· (_ , fh) β· (_ , zh) β· (_ , `Zββ (`worker .snd)) β· [])) β©
`iszero β (`suc β x) β (`true β z) % _ % `zero .fst β‘β¨ apβ _%_ (apβ _%_ (apβ _%_ (`iszero-suc xh) refl) refl β `false-Ξ² (`trueββ zh) (absβ _ _)) refl β abs-Ξ²β ((`suc β x , `sucββ xh) β· (f , fh) β· (z , zh) β· (`Z β `worker , `Zββ (`worker .snd)) β· []) (`zero β· []) β©
f % `pred β (`suc β x) % `Z β `worker β z β f β (`pred β (`suc β x)) β `zero β‘β¨ ap (Ξ» e β f % e % `Z β `worker β z β f β e β `zero) (`pred-suc xh) β©
f β x β (`Z β `worker β z β f β x β `zero) β‘β¨ apβ _%_ refl (sym (abs-Ξ²β [] ((_ , xh) β· (_ , fh) β· (_ , zh) β· []))) β©
f β x β (`primrec β z β f β x) β