{-# OPTIONS --without-K --safe #-} open import Function open import Relation.Binary import Relation.Binary.PropositionalEquality as ≔ module Cfe.Expression.Base {c ā„“} (over : Setoid c ā„“) where open Setoid over renaming (Carrier to C) open import Cfe.Language over as š•ƒ open import Cfe.Language.Construct.Concatenate over renaming (_āˆ™_ to _āˆ™ā‚—_) open import Cfe.Language.Construct.Single over open import Cfe.Language.Construct.Union over open import Cfe.Language.Indexed.Construct.Iterate over open import Data.Fin as F hiding (_≤_; cast) open import Data.Nat as ā„• hiding (_≤_; _āŠ”_) open import Data.Product open import Data.Vec open import Level renaming (suc to lsuc) hiding (Lift) open import Relation.Binary.PropositionalEquality open import Relation.Nullary infix 10 _[_/_] infix 7 _āˆ™_ infix 6 _∨_ infix 4 _≋_ data Expression : ā„• → Set c where ⊄ : āˆ€ {n} → Expression n ε : āˆ€ {n} → Expression n Char : āˆ€ {n} → C → Expression n _∨_ : āˆ€ {n} → Expression n → Expression n → Expression n _āˆ™_ : āˆ€ {n} → Expression n → Expression n → Expression n Var : āˆ€ {n} → Fin n → Expression n μ : āˆ€ {n} → Expression (suc n) → Expression n cast : āˆ€ {m n} → .(_ : m ≔ n) → Expression m → Expression n cast eq ⊄ = ⊄ cast eq ε = ε cast eq (Char x) = Char x cast eq (e₁ ∨ eā‚‚) = cast eq e₁ ∨ cast eq eā‚‚ cast eq (e₁ āˆ™ eā‚‚) = cast eq e₁ āˆ™ cast eq eā‚‚ cast eq (Var i) = Var (F.cast eq i) cast eq (μ e) = μ (cast (cong suc eq) e) wkn : āˆ€ {n} → Expression n → Fin (suc n) → Expression (suc n) wkn ⊄ i = ⊄ wkn ε i = ε wkn (Char x) i = Char x wkn (e₁ ∨ eā‚‚) i = wkn e₁ i ∨ wkn eā‚‚ i wkn (e₁ āˆ™ eā‚‚) i = wkn e₁ i āˆ™ wkn eā‚‚ i wkn (Var x) i = Var (punchIn i x) wkn (μ e) i = μ (wkn e (suc i)) _[_/_] : āˆ€ {n} → Expression (suc n) → Expression n → Fin (suc n) → Expression n ⊄ [ e′ / i ] = ⊄ ε [ e′ / i ] = ε Char x [ e′ / i ] = Char x (e₁ ∨ eā‚‚) [ e′ / i ] = e₁ [ e′ / i ] ∨ eā‚‚ [ e′ / i ] (e₁ āˆ™ eā‚‚) [ e′ / i ] = e₁ [ e′ / i ] āˆ™ eā‚‚ [ e′ / i ] Var j [ e′ / i ] with i F.ā‰Ÿ j ... | yes i≔j = e′ ... | no i≢j = Var (punchOut i≢j) μ e [ e′ / i ] = μ (e [ wkn e′ F.zero / suc i ]) shift : āˆ€ {n} → Expression n → (i j : Fin n) → .(_ : i F.≤ j) → Expression n shift ⊄ _ _ _ = ⊄ shift ε _ _ _ = ε shift (Char x) _ _ _ = Char x shift (e₁ ∨ eā‚‚) i j i≤j = shift e₁ i j i≤j ∨ shift eā‚‚ i j i≤j shift (e₁ āˆ™ eā‚‚) i j i≤j = shift e₁ i j i≤j āˆ™ shift eā‚‚ i j i≤j shift {suc n} (Var k) i j _ with i F.ā‰Ÿ k ... | yes i≔k = Var j ... | no i≢k = Var (punchIn j (punchOut i≢k)) shift (μ e) i j i≤j = μ (shift e (suc i) (suc j) (s≤s i≤j)) ⟦_⟧ : āˆ€ {n : ā„•} → Expression n → Vec (Language (c āŠ” ā„“)) n → Language (c āŠ” ā„“) ⟦ ⊄ ⟧ _ = Lift (c āŠ” ā„“) āˆ… ⟦ ε ⟧ _ = Lift ā„“ ļ½›Īµļ½ ⟦ Char x ⟧ _ = Lift ā„“ ļ½› x ļ½ ⟦ e₁ ∨ eā‚‚ ⟧ γ = ⟦ e₁ ⟧ γ ∪ ⟦ eā‚‚ ⟧ γ ⟦ e₁ āˆ™ eā‚‚ ⟧ γ = ⟦ e₁ ⟧ γ āˆ™ā‚— ⟦ eā‚‚ ⟧ γ ⟦ Var n ⟧ γ = lookup γ n ⟦ μ e ⟧ γ = ā‹ƒ (Ī» X → ⟦ e ⟧ (X ∷ γ)) _≋_ : {n : ā„•} → Expression n → Expression n → Set (lsuc (c āŠ” ā„“)) e₁ ≋ eā‚‚ = āˆ€ γ → ⟦ e₁ ⟧ γ š•ƒ.ā‰ˆ ⟦ eā‚‚ ⟧ γ