module Chapter5.Ornament.Examples.Vec where

open import Function

open import Data.Empty
open import Data.Unit
open import Data.Nat
open import Data.Fin
open import Data.Product

open import Relation.Binary.PropositionalEquality

open import Chapter1.Logic

import Chapter2.Desc.Examples.List as Desc

open import Chapter2.IDesc
open import Chapter2.IDesc.Fixpoint
open import Chapter2.IDesc.Examples.ToIDesc


open import Chapter5.Ornament

u :   
u _ = tt

ListD : Set  func  
ListD A = func.mk λ _  toIDesc (Desc.ListD A)

module Constraint {A : Set} where

  VecO : orn (ListD A) u u
  VecO = orn.mk λ n  
          {S = Fin 2}
             λ { zero  insert (0  n) λ _  
                        `1
               ; (suc zero)  insert  λ m  
                              insert (suc m  n) λ _  
                               λ _ 
                              `var (inv m)  `1
               ; (suc (suc ())) }

  Vec :   Set
  Vec = μ  VecO ⟧orn 
  
  nil : Vec 0
  nil =  zero , refl , tt 
  
  cons : ∀{n}  A  Vec n  Vec (suc n)
  cons {n} a xs =  suc zero , n , refl , a , xs , tt 

module Compute {A : Set} where

  VecO : orn (ListD A) u u
  VecO = orn.mk λ { zero  deleteΣ zero `1
                  ; (suc n)  deleteΣ (suc zero) ( λ _  `var (inv n)  `1) }

  Vec :   Set
  Vec = μ  VecO ⟧orn 
  
  nil : Vec 0
  nil =  tt 

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