open import DynamicallyChecked.Universe
open import Data.Nat
module DynamicallyChecked.BiGUL where
open import DynamicallyChecked.Utilities
open import DynamicallyChecked.Partiality
open import DynamicallyChecked.Lens
open import DynamicallyChecked.Rearrangement
open import DynamicallyChecked.Case as Case
open import Level
open import Data.Product
open import Data.Bool
open import Data.Maybe
open import Data.List
open import Relation.Nullary
open import Relation.Binary.PropositionalEquality
mutual
data BiGUL {n : ℕ} (F : Functor n) : U n → U n → Set₁ where
fail : {S V : U n} → BiGUL F S V
skip : {S V : U n} (f : ⟦ S ⟧ (μ F) → ⟦ V ⟧ (μ F)) → BiGUL F S V
replace : {S : U n} → BiGUL F S S
prod : {S V S' V' : U n} (b : BiGUL F S V) (b' : BiGUL F S' V') → BiGUL F (S ⊗ S') (V ⊗ V')
rearrS : {S S' V : U n}
(spat : Pattern F S) (spat' : Pattern F S') (expr : Expr spat spat') (c : CompleteExpr spat spat' expr)
(b : BiGUL F S' V) → BiGUL F S V
rearrV : {S V V' : U n}
(vpat : Pattern F V) (vpat' : Pattern F V') (expr : Expr vpat vpat') (c : CompleteExpr vpat vpat' expr)
(b : BiGUL F S V') → BiGUL F S V
case : {S V : U n} (branches : List (CaseBranch F S V)) → BiGUL F S V
data CaseBranchType {n : ℕ} (F : Functor n) (S V : U n) : Set₁ where
normal : (b : BiGUL F S V) (q : ⟦ S ⟧ (μ F) → Bool) → CaseBranchType F S V
adaptive : (f : ⟦ S ⟧ (μ F) → ⟦ V ⟧ (μ F) → ⟦ S ⟧ (μ F)) → CaseBranchType F S V
CaseBranch : {n : ℕ} (F : Functor n) (S V : U n) → Set₁
CaseBranch F S V = (⟦ S ⟧ (μ F) → ⟦ V ⟧ (μ F) → Bool) × CaseBranchType F S V
elimCaseBranchType : {n : ℕ} {F : Functor n} {S V : U n} {l : Level} {A : Set l} →
(BiGUL F S V → (⟦ S ⟧ (μ F) → Bool) → A) → ((⟦ S ⟧ (μ F) → ⟦ V ⟧ (μ F) → ⟦ S ⟧ (μ F)) → A) →
CaseBranchType F S V → A
elimCaseBranchType n a (normal b q) = n b q
elimCaseBranchType n a (adaptive f) = a f
mutual
interp : {n : ℕ} {F : Functor n} {S V : U n} (b : BiGUL F S V) → ⟦ S ⟧ (μ F) ⇆ ⟦ V ⟧ (μ F)
interp fail = iso-lens empty-iso
interp (skip {V = V} f) = skip-lens (U-dec V) f
interp replace = iso-lens id-iso
interp (prod b b') = interp b ↕ interp b'
interp (rearrS spat spat' expr c b) = rearrangement-iso spat spat' expr c ▸ interp b
interp (rearrV vpat vpat' expr c b) = interp b ◂ sym-iso (rearrangement-iso vpat vpat' expr c)
interp {F = F} (case {S} {V} branches) = case-lens (⟦ S ⟧ (μ F)) (⟦ V ⟧ (μ F)) (interp-CaseBranch branches)
interp-CaseBranch : {n : ℕ} {F : Functor n} {S V : U n} →
List (CaseBranch F S V) → List (Case.Branch (⟦ S ⟧ (μ F)) (⟦ V ⟧ (μ F)))
interp-CaseBranch [] = []
interp-CaseBranch ((p , normal b q) ∷ branches) = (p , normal (interp b) q) ∷ interp-CaseBranch branches
interp-CaseBranch ((p , adaptive u) ∷ branches) = (p , adaptive u) ∷ interp-CaseBranch branches