2 agda w type stuff
rhi edited this page 2023-08-01 10:45:57 -04:00
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.

module _ where

open import Function
open import Data.Container hiding (refl)
open import Data.Container.Relation.Unary.All
open import Data.W
open import Data.Empty
open import Data.Unit
open import Data.Product
open import Relation.Binary.PropositionalEquality

variable A B : Set

postulate ⊥-funext : (f :   B)  f  λ ()

module Nat where
  data Tag : Set where #zero #suc : Tag

  Child : Tag  Set
  Child #zero = 
  Child #suc  = 

  Nat : Set
  Nat = W (Tag  Child)

  zero : Nat
  zero = sup (#zero , λ ())

  suc : Nat  Nat
  suc n = sup (#suc , const n)

  elim : (P : Nat  Set) 
         P zero  ( {n}  P n  P (suc n)) 
          n  P n
  elim P pz ps = induction P $ p _ where
    p :  t   (Tag  Child) P t  P (sup t)
    p (#zero , f) _        rewrite ⊥-funext f = pz
    p (#suc  , _) (all ih) = ps $ ih _

list

non recursive arguments can be put in A.

module List where
  data Tag : Set where #nil #cons : Tag

  Field : Set  Tag  Set
  Field _ #nil  = 
  Field A #cons = A

  Child : Tag  Set
  Child #nil  = 
  Child #cons = 

  Body : Set  Set
  Body A = Σ[ t  Tag ] (Field A t)

  List : Set  Set
  List A = W (Body A  Child  proj₁)

  nil : List A
  nil = sup ((#nil , tt) , λ ())

  infixr 5 _∷_
  _∷_ : A  List A  List A
  x  xs = sup ((#cons , x) , const xs)

  elim : (P : List A  Set) 
         P nil  ( x {xs}  P xs  P (x  xs)) 
          xs  P xs
  elim {A} P pn pc = induction P $ p _ where
    p :  t   (Body A  Child  proj₁) P t  P (sup t)
    p ((#nil  , _) , f) (all ih) rewrite ⊥-funext f = pn
    p ((#cons , x) , f) (all ih) = pc x (ih _)

indexed w-types

see e.g. https://github.com/jashug/IWTypes

record Desc : Set where
  field
    Index : Set
    Tag   : Set
    Child : Tag  Set
    this  : Tag  Index
    child :  {T}  Child T  Index

module IndexedW (𝒟 : Desc) where
  open Desc 𝒟 public

  T : Set
  T = W (Tag  Child)

  wf : T  Index  Set
  wf = induction _ λ where
    {t , _} (all ih) 𝑖  (this t  𝑖) × ( c  ih c (child c))

  T : Index  Set
  T 𝑖 = Σ[ x  T ] (wf x 𝑖)

  isup : (t : Tag) (f : (c : Child t)  T (child c))  T (this t)
  isup t f = sup (t , proj₁  f) , refl , proj₂  f

  iinduction : (P :  {𝑖}  T 𝑖  Set)
               (s :  t f  ( c  P (f c))  P (isup t f)) 
                {𝑖} (t : T 𝑖)  P t
  iinduction P s (t , φ) = induction P (p _) t φ where
    P : T  Set
    P t =  {𝑖} (φ : wf t 𝑖)  P (t , φ)

    p :  t   (Tag  Child) P t   {𝑖} φ  P (sup t , φ)
    p (t , f) (all ih) (refl , φ′) =
      s t (λ c  f c , φ′ c) (λ c  ih c (φ′ c))

fin

the elim doesn't actually compute properly because ⊥-funext gets stuck. oh well. not a problem for quox >:3

module Fin where
  open Nat public using (Nat; #zero; #suc)
    renaming (zero to nzero; suc to nsuc)

  module FinW =
    IndexedW (let open Desc in λ where
      .Index            Nat
      .Tag              Nat.Tag × Nat
      .Child (t , _)    Nat.Child t
      .this  (_ , n)    Nat.suc n
      .child {_ , n} c  n)

  Fin = FinW.T

  private variable n : Nat

  zero : Fin (nsuc n)
  zero = FinW.isup (#zero , _) (λ ())

  suc : Fin n  Fin (nsuc n)
  suc i = FinW.isup (#suc , _) (const i)

  elim : (P :  {n}  Fin n  Set) 
         ( {n}  P (zero {n})) 
         ( {n} (i : Fin n)  P i  P (suc i)) 
         (i : Fin n)  P i
  elim P pz ps = FinW.iinduction P p where
    p :  t f  ( c  P (f c))  P (FinW.isup t f)
    p (#zero , n) f ih rewrite ⊥-funext f = pz
    p (#suc  , n) f ih = ps (f _) (ih _)