module IDesc.Examples.Fin where

open import Data.Unit
open import Data.Nat
open import Data.Fin hiding (lift) renaming (Fin to FinNative)
open import Data.Vec 
open import Data.Empty
open import Data.Product
open import Data.Fin renaming (Fin to FinA)

open import Relation.Binary.PropositionalEquality

open import IDesc.IDesc
open import IDesc.Fixpoint
open import IDesc.Tagged

-- Paper: Example 3.7
module Constraint where

  FinD : func  
  FinD = func.mk λ n 
           (FinA 2) λ
             { zero    λ n'  
                       (n  suc n') λ _  
                      `1
             ; (suc zero)    λ n' 
                             (n  suc n') λ _ 
                            `var n'
             ; (suc (suc ())) }

  Fin :   Set
  Fin = μ FinD

  ze : ∀{n}  Fin (suc n)
  ze =  zero , _ , refl , tt 

  su : ∀{n}  Fin n  Fin (suc n)
  su k =  suc zero , _ , refl , k  


-- Paper: Example 3.8
module Compute where

  FinD : func  
  FinD = func.mk λ 
         { zero    λ () 
         ; (suc n)   (FinA 2) λ 
                        { zero  `1 
                        ; (suc zero)  `var n 
                        ; (suc (suc ())) } }

  Fin :   Set
  Fin = μ FinD

  ze : ∀{n}  Fin (suc n)
  ze =  zero , tt 

  su : ∀{n}  Fin n  Fin (suc n)
  su k =  suc zero , k