module IDesc.Examples.Vec where

open import Data.Unit
open import Data.Nat
open import Data.Fin hiding (lift)
open import Data.Vec renaming (Vec to VecNative)
open import Data.Product

open import Relation.Binary.PropositionalEquality

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

-- Paper: Example 3.7

module Constraint where

  VecD : (A : Set)  func  
  VecD A = func.mk  n   (Fin 2) 
                          λ { zero   (n  0) λ _  `1  
                            ; (suc zero)    λ m  
                                            (n  suc m) λ _  
                                            A λ _  
                                           `var m 
                            ; (suc (suc ())) } )

  Vec : (A : Set)    Set
  Vec A = μ (VecD A)

  nil : ∀{A}  Vec A 0
  nil =  zero , refl , tt 

  cons : ∀{A n}  A  Vec A n  Vec A (suc n)
  cons a xs =  suc zero ,  _ , refl , a , xs  

-- Paper: Example 3.8

module Compute where
  
  VecD : (A : Set)  func  
  VecD A = func.mk  { zero   (Fin 1) λ { zero  `1 
                                            ; (suc ()) } 
                      ; (suc n)   (Fin 1) λ { zero   A λ _  `var n  `1 
                                               ; (suc ()) }})

  Vec : (A : Set)    Set
  Vec A = μ (VecD A)

  nil : ∀{A}  Vec A 0
  nil =  zero , tt 

  cons : ∀{A n}  A  Vec A n  Vec A (suc n)
  cons a xs =  zero , a , xs , tt