{-# OPTIONS --safe --with-K #-} module Examples.WithMacros.List where open import Prelude open import Generics.Description open import Generics.Recursion open import Generics.Reflection open import Generics.RecursionScheme open import Generics.Ornament open import Generics.Ornament.Description open import Generics.Ornament.Algebraic open import Generics.Ornament.Algebraic.Isomorphism open import Generics.SimpleContainer open import Generics.SimpleContainer.All open import Generics.SimpleContainer.Any open import Examples.WithMacros.Nat -------- -- Connecting with the existing List datatype instance ListC : Named (quote List) _ unNamed ListC = genDataC ListD (genDataT ListD List) where ListD = genDataD List ListO : DataO (findDataD (quote List)) (findDataD (quote ℕ)) ListO = record { level = λ _ → tt ; applyL = λ (ℓ , _) → record { param = λ _ → tt ; index = λ _ _ → tt ; applyP = λ _ → ι ∷ ∺ (Δ[ _ ] ρ ι ι) ∷ ∺ [] } } ListFin : Finitary (findDataD (quote List)) ListFin = [] ∷ (tt ∷ refl ∷ []) ∷ [] ListS : SCᵈ (findDataD (quote List)) ListS = record { El = λ (A , _) → A ; pos = [] ∷ (true ∷ tt ∷ []) ∷ [] ; coe = λ _ → lift tt ,ωω (refl ,ωω λ _ → lift tt) ,ωω lift tt } -------- -- Connecting with the existing foldr function and deriving the fold fusion theorem private foldListP : FoldP foldListP = fold-operator (quote List) -- Generate foldList and its wrapper and connection, and then replace it with foldr unquoteDecl foldList = defineFold foldListP foldList instance foldrC = genFoldC' foldListP foldrT where foldrT : FoldT foldListP foldrT _ ((A , tt) , B , e , f , tt) = foldr e f private foldr-fusionP : IndP foldr-fusionP = fold-fusion (quote List) unquoteDecl foldr-fusion = defineInd foldr-fusionP foldr-fusion -- foldr-fusion : -- ∀ {ℓ' ℓ'' ℓ} {A : Set ℓ} {B : Set ℓ'} {C : Set ℓ''} (h : B → C) -- {e : B} {f : A → B → B} {e' : C} {f' : A → C → C} -- (he : h e ≡ e') (hf : (a : A) (b : B) (c : C) → h b ≡ c → h (f a b) ≡ f' a c) -- (as : List A) → h (foldr e f as) ≡ foldr e' f' as -- foldr-fusion h he hf [] = he -- foldr-fusion h he hf (a ∷ as) = hf a _ _ (foldr-fusion h he hf as) instance foldr-fusionC = genIndC foldr-fusionP foldr-fusion -------- -- Algebraic ornamentation private AlgListOD : DataOD (findDataD (quote List)) AlgListOD = AlgOD foldListP instance AlgListO = ⌈ AlgListOD ⌉ᵈ unquoteDecl data AlgList constructor [] _∷_ = defineByDataD ⌊ AlgListOD ⌋ᵈ AlgList (AlgList.[] List.∷ AlgList._∷_ List.∷ List.[]) --data AlgList {ℓ' ℓ} {A : Set ℓ} {B : Set ℓ'} -- (e : B) (f : A → B → B) : B → Set (ℓ ⊔ ℓ') where -- [] : AlgList e f e -- _∷_ : (a : A) {b : B} → AlgList e f b → AlgList e f (f a b) instance AlgListC = genDataC ⌊ AlgListOD ⌋ᵈ (genDataT ⌊ AlgListOD ⌋ᵈ AlgList) private lengthP : FoldP lengthP = forget (quote List) (quote ℕ) instance lengthC = genFoldC lengthP length private VecOD : DataOD (findDataD (quote List)) VecOD = AlgOD lengthP instance VecO = ⌈ VecOD ⌉ᵈ unquoteDecl data Vec constructor [] _∷_ = defineByDataD ⌊ VecOD ⌋ᵈ Vec (Vec.[] List.∷ Vec._∷_ List.∷ List.[]) --data Vec (A : Set ℓ) : (n : ℕ) → Set ℓ where -- [] : Vec A 0 -- _∷_ : (a : A) {n : ℕ} → Vec A n → Vec A (suc n) instance VecC : Named (quote Vec) _ unNamed VecC = genDataC ⌊ VecOD ⌋ᵈ (genDataT ⌊ VecOD ⌋ᵈ Vec) VecFin : Finitary ⌊ VecOD ⌋ᵈ VecFin = [] ∷ (tt ∷ tt ∷ refl ∷ []) ∷ [] private fromVecP : FoldP fromVecP = forget (quote Vec) (quote List) unquoteDecl fromVec = defineFold fromVecP fromVec -- fromVec : {A : Set ℓ} {n : ℕ} (v : Vec A n) → List A -- fromVec [] = [] -- fromVec (a ∷ as) = a ∷ fromVec as instance fromVecC = genFoldC fromVecP fromVec private toVecP : IndP toVecP = remember (quote Vec) unquoteDecl toVec = defineInd toVecP toVec -- toVec : {A : Set ℓ} (as : List A) → Vec A (length as) -- toVec [] = [] -- toVec (a ∷ as) = a ∷ toVec as instance toVecC = genIndC toVecP toVec --private -- from-toVecP : IndP -- from-toVecP = forget-remember-inv (quote Vec) (quote List) (inl it) -- --unquoteDecl from-toVec = defineInd from-toVecP from-toVec -- from-toVec : {A : Set ℓ} (as : List A) → fromVec (toVec as) ≡ as -- from-toVec [] = refl -- from-toVec (a ∷ as) = cong (_∷_ a) (from-toVec as) --instance from-toVecC = genIndC from-toVecP from-toVec --private -- to-fromVecP : IndP -- to-fromVecP = remember-forget-inv (quote Vec) (quote List) (inl it) --unquoteDecl to-fromVec = defineInd to-fromVecP to-fromVec -- to-fromVec : {A : Set ℓ} {n : ℕ} (as : Vec A n) → -- (length (fromVec as) , toVec (fromVec as)) ≡ ((n , as) ⦂ Σ ℕ (Vec A)) -- to-fromVec [] = refl -- to-fromVec (a ∷ as) = -- trans -- (cong -- (bimap (λ x₁ → x₁) (DataC.toN (findDataC (quote Vec)))) -- (cong (bimap (λ x₁ → x₁) inr) -- (cong (bimap (λ x₁ → x₁) inl) -- (cong (bimap (λ x₁ → x₁) (λ section → a , section)) -- (trans -- (cong (λ p₁ → suc (fst p₁) , fst p₁ , snd p₁ , refl) -- (to-fromVec as)) -- refl))))) -- refl --instance to-fromVecC = genIndC to-fromVecP to-fromVec private LenOD : DataOD (findDataD (quote Vec)) LenOD = AlgOD fromVecP instance LenO = ⌈ LenOD ⌉ᵈ unquoteDecl data Len constructor zero suc = defineByDataD ⌊ LenOD ⌋ᵈ Len (Len.zero ∷ Len.suc ∷ []) --data Len {A : Set ℓ} : ℕ → List A → Set ℓ where -- zero : Len 0 [] -- suc : {a : A} {n : ℕ} {as : List A} → Len n as → Len (suc n) (a ∷ as) instance LenC : Named (quote Len) _ unNamed LenC = genDataC ⌊ LenOD ⌋ᵈ (genDataT ⌊ LenOD ⌋ᵈ Len) private fromLenP : FoldP fromLenP = forget (quote Len) (quote Vec) unquoteDecl fromLen = defineFold fromLenP fromLen -- fromLen : {A : Set ℓ} {n : ℕ} {as : List A} → Len n as → Vec A n -- fromLen zero = [] -- fromLen (suc {a} l) = a ∷ fromLen l instance fromLenC = genFoldC fromLenP fromLen private toLenP : IndP toLenP = remember (quote Len) unquoteDecl toLen = defineInd toLenP toLen -- toLen : {A : Set ℓ} {n : ℕ} (as : Vec A n) → Len n (fromVec as) -- toLen [] = zero -- toLen (a ∷ as) = suc (toLen as) instance toLenC = genIndC toLenP toLen --private -- from-toLenP : IndP -- from-toLenP = forget-remember-inv (quote Len) (quote Vec) (inl it) --unquoteDecl from-toLen = defineInd from-toLenP from-toLen -- from-toLen : {A : Set ℓ} {n : ℕ} (as : Vec A n) → fromLen (toLen as) ≡ as -- from-toLen [] = refl -- from-toLen (a ∷ as) = cong (_∷_ a) (from-toLen as) --instance from-toLenC = genIndC from-toLenP from-toLen --private -- to-fromLenP : IndP -- to-fromLenP = remember-forget-inv (quote Len) (quote Vec) (inl it) -- --unquoteDecl to-fromLen = defineInd to-fromLenP to-fromLen -- to-fromLen : {A : Set ℓ} {n : ℕ} {as : List A} (l : Len n as) -- → (fromVec (fromLen l) , toLen (fromLen l)) -- ≡ ((as , l) ⦂ Σ[ as' ∈ List A ] Len n as') -- to-fromLen zero = refl -- to-fromLen {n = suc n} {a ∷ _} (suc l) = -- trans -- (cong -- (bimap (λ x → x) (DataC.toN (findDataC (quote Len)))) -- (cong (bimap (λ x → x) inr) -- (cong (bimap (λ x → x) inl) -- (cong (bimap (λ x → x) (λ section → a , section)) -- (cong (bimap (λ x → x) (λ section → n , section)) -- (trans -- (cong (λ p → a ∷ fst p , fst p , snd p , refl) (to-fromLen l)) -- refl)))))) -- refl --instance to-fromLenC = genIndC to-fromLenP to-fromLen -------- -- All predicate private ListPOD : DataOD (findDataD (quote List)) ListPOD = PredOD (quote List) instance ListPO = ⌈ ListPOD ⌉ᵈ unquoteDecl data ListP constructor [] ⟨_,_⟩∷_ = defineByDataD ⌊ ListPOD ⌋ᵈ ListP (ListP.[] ∷ ListP.⟨_,_⟩∷_ ∷ List.[]) --data ListP {ℓ' ℓ} {A : Set ℓ} (P : A → Set ℓ') : Set (ℓ ⊔ ℓ') where -- [] : ListP P -- ⟨_,_⟩∷_ : (a : A) → P a → ListP P → ListP P instance ListPC : Named (quote ListP) _ unNamed ListPC = genDataC ⌊ ListPOD ⌋ᵈ (genDataT ⌊ ListPOD ⌋ᵈ ListP) ListPFin : Finitary ⌊ ListPOD ⌋ᵈ ListPFin = [] ∷ (tt ∷ tt ∷ refl ∷ []) ∷ [] private fromListPP : FoldP fromListPP = forget (quote ListP) (quote List) unquoteDecl fromListP = defineFold fromListPP fromListP -- fromListP : ∀ {ℓ' ℓ} {A : Set ℓ} {P : A → Set ℓ'} → ListP P → List A -- fromListP [] = [] -- fromListP (⟨ a , p ⟩∷ aps) = a ∷ fromListP aps instance fromListPC = genFoldC fromListPP fromListP private ListAllOD : DataOD ⌊ ListPOD ⌋ᵈ ListAllOD = AllOD (quote List) instance ListAllO = ⌈ ListAllOD ⌉ᵈ unquoteDecl data ListAll constructor [] _∷_ = defineByDataD ⌊ ListAllOD ⌋ᵈ ListAll (ListAll.[] List.∷ ListAll._∷_ List.∷ List.[]) --data ListAll {ℓ' ℓ} {A : Set ℓ} (P : A → Set ℓ') : List A → Set (ℓ ⊔ ℓ') where -- [] : ListAll P [] -- _∷_ : {a : A} → P a → {as : List A} → ListAll P as → ListAll P (a ∷ as) instance ListAllC : Named (quote ListAll) _ unNamed ListAllC = genDataC ⌊ ListAllOD ⌋ᵈ ListAllT where ListAllT = genDataT ⌊ ListAllOD ⌋ᵈ ListAll private fromAllP : FoldP fromAllP = forget (quote ListAll) (quote ListP) unquoteDecl fromAll = defineFold fromAllP fromAll -- fromAll : ∀ {ℓ' ℓ} {A : Set ℓ} {P : A → Set ℓ'} {as : List A} → ListAll P as → ListP P -- fromAll [] = [] -- fromAll (p ∷ ps) = ⟨ _ , p ⟩∷ fromAll ps instance fromAllC = genFoldC fromAllP fromAll private toAllP : IndP toAllP = remember (quote ListAll) unquoteDecl toAll = defineInd toAllP toAll -- toAll : ∀ {ℓ' ℓ} {A : Set ℓ} {P : A → Set ℓ'} (aps : ListP P) → ListAll P (fromListP aps) -- toAll [] = [] -- toAll (⟨ a , p ⟩∷ aps) = p ∷ toAll aps instance toAllC = genIndC toAllP toAll --private -- from-toAllP : IndP -- from-toAllP = forget-remember-inv (quote ListAll) (quote ListP) (inl it) -- --unquoteDecl from-toAll = defineInd from-toAllP from-toAll -- from-toAll : {ℓ' ℓ : Level} {A : Set ℓ} {P : A → Set ℓ'} -- (aps : ListP P) → fromAll (toAll aps) ≡ aps -- from-toAll [] = refl -- from-toAll (⟨ a , p ⟩∷ aps) = cong (⟨_,_⟩∷_ a p) (from-toAll aps) --instance from-toAllC = genIndC from-toAllP from-toAll --private -- to-fromAllP : IndP -- to-fromAllP = remember-forget-inv (quote ListAll) (quote ListP) (inl it) -- --unquoteDecl to-fromAll = defineInd to-fromAllP to-fromAll -- to-fromAll : {ℓ' ℓ : Level} {A : Set ℓ} {P : A → Set ℓ'} -- {as : List A} (all : ListAll P as) -- → (fromListP (fromAll all) , toAll (fromAll all)) -- ≡ ((as , all) ⦂ Σ (List A) (ListAll P)) -- to-fromAll [] = refl -- to-fromAll (p ∷ all) = -- trans -- (cong -- (bimap (λ x₂ → x₂) (DataC.toN (findDataD (quote ListAll)))) -- (cong (bimap (λ x₂ → x₂) inr) -- (cong (bimap (λ x₂ → x₂) inl) -- (cong (bimap (λ x₂ → x₂) (λ section → a , section)) -- (cong (bimap (λ x₂ → x₂) (λ section → p , section)) -- (trans -- (cong (λ p₁ → a ∷ fst p₁ , fst p₁ , snd p₁ , refl) (to-fromAll all)) -- refl)))))) -- refl --instance to-fromAllC = genIndC to-fromAllP to-fromAll -------- -- Any predicate private ListAnyOD : DataOD (findDataD (quote ℕ)) ListAnyOD = AnyOD (quote List) instance ListAnyO = ⌈ ListAnyOD ⌉ᵈ unquoteDecl data ListAny constructor here there = defineByDataD ⌊ ListAnyOD ⌋ᵈ ListAny (ListAny.here ∷ ListAny.there ∷ []) --data ListAny {ℓ' ℓ} {A : Set ℓ} (P : A → Set ℓ') : List A → Set (ℓ ⊔ ℓ') where -- here : ∀ {a as} → P a → ListAny P (a ∷ as) -- there : ∀ {a as} → ListAny P as → ListAny P (a ∷ as) instance ListAnyC : Named (quote ListAny) _ unNamed ListAnyC = genDataC ⌊ ListAnyOD ⌋ᵈ ListAnyT where ListAnyT = genDataT ⌊ ListAnyOD ⌋ᵈ ListAny _∋_ : {A : Set ℓ} → List A → A → Set _ _∋_ {A = A} xs x = ListAny A (x ≡_) xs private toℕP : FoldP toℕP = forget (quote ListAny) (quote ℕ) unquoteDecl toℕ = defineFold toℕP toℕ -- toℕ : ∀ {ℓ' ℓ} {A : Set ℓ} {P : A → Set ℓ'} {as : List A} → ListAny P as → ℕ -- toℕ (here p) = 0 -- toℕ (there i) = suc (toℕ i) instance toℕC = genFoldC toℕP toℕ