{-# OPTIONS --safe #-}

open import Prelude
open import Data.Vec
open import Signatures
open import Cubical.Relation.Binary
open import FinitenessConditions
open import FreeMonad.PackagedTheory

module FreeMonad.Modalities {β„“} (theory : FullTheory β„“) where

open FullTheory theory
open import FreeMonad.Quotiented theory
open Signature 𝔽
open import FreeMonad.Syntax 𝔽 renaming (var to varβ‚›)
open import FreeMonad.Theory

private variable xs ys zs : Syntax A

β–‘β‚› : (A β†’ Type p) β†’ Syntax A β†’ Type p
β–‘β‚› P = interp (Ξ» { (O , xs) β†’ βˆ€ i β†’ xs i }) P

β—‡β‚› : (A β†’ Type p) β†’ Syntax A β†’ Type p
β—‡β‚› P = interp (Ξ» { (O , xs) β†’ βˆƒ i Γ— xs i }) P

mutual
  β–‘β‚›β‚š : (Syntax A β†’ Type p) β†’ Syntax A β†’ Type p
  β–‘β‚›β‚š P xs = P xs Γ— β–‘β‚›β‚šβ€² P xs

  β–‘β‚›β‚šβ€² : (Syntax A β†’ Type p) β†’ Syntax A β†’ Type p
  β–‘β‚›β‚šβ€² P (varβ‚› x) = Poly-⊀
  β–‘β‚›β‚šβ€² P (op (o , k)) = βˆ€ i β†’ β–‘β‚›β‚š P (k i)

β–‘β‚œ : (A β†’ Type p) β†’ Term A β†’ Type _
β–‘β‚œ P xs = βˆƒ ys Γ— [ ys ] ≑ xs Γ— β–‘β‚› P ys

β–‘β‚š : (Syntax A β†’ Type p) β†’ Term A β†’ Type _
β–‘β‚š P t = βˆƒ s Γ— [ s ] ≑ t Γ— β–‘β‚›β‚š P s

β—‡β‚œ : (A β†’ Type p) β†’ Term A β†’ Type _
β—‡β‚œ P xs = βˆƒ ys Γ— [ ys ] ≑ xs Γ— β—‡β‚› P ys