{-# OPTIONS --without-K --safe #-} open import Relation.Binary module Cfe.Expression.Properties {c ℓ} (over : Setoid c ℓ) where open Setoid over using () renaming (Carrier to C; _≈_ to _∼_) open import Algebra open import Cfe.Expression.Base over open import Cfe.Language over hiding ( ≈-isPartialEquivalence; partialSetoid ; ∙-isMagma; ∙-isSemigroup; ∙-isMonoid; ∙-magma; ∙-semigroup; ∙-monoid ) renaming ( _≈_ to _≈ˡ_ ; ≈-refl to ≈ˡ-refl ; ≈-sym to ≈ˡ-sym ; ≈-trans to ≈ˡ-trans ; ≈-isEquivalence to ≈ˡ-isEquivalence ; setoid to setoidˡ ; _∙_ to _∙ˡ_ ; ∙-cong to ∙ˡ-cong ; ∙-assoc to ∙ˡ-assoc ; ∙-identityˡ to ∙ˡ-identityˡ ; ∙-identityʳ to ∙ˡ-identityʳ ; ∙-identity to ∙ˡ-identity ; ∙-zeroˡ to ∙ˡ-zeroˡ ; ∙-zeroʳ to ∙ˡ-zeroʳ ; ∙-zero to ∙ˡ-zero ) open import Cfe.Vec.Relation.Binary.Pointwise.Inductive using (Pointwise-insert) open import Data.Empty using (⊥-elim) open import Data.Fin hiding (_+_; _≤_; _<_) open import Data.Fin.Properties using (punchIn-punchOut) open import Data.List using (List; length; _++_) open import Data.List.Properties using (length-++) open import Data.List.Relation.Binary.Equality.Setoid over using (_≋_) open import Data.List.Relation.Binary.Pointwise using (Pointwise-length) open import Data.Nat hiding (_≟_; _⊔_; _^_) open import Data.Nat.Induction using (<-wellFounded) open import Data.Nat.Properties hiding (_≟_) open import Data.Product open import Data.Product.Relation.Binary.Lex.Strict using (×-wellFounded) open import Data.Sum using (_⊎_; inj₁; inj₂; [_,_]′) open import Data.Vec hiding (length; map; _++_) open import Data.Vec.Properties open import Data.Vec.Relation.Binary.Pointwise.Inductive as Pw hiding (refl; sym; trans; setoid; lookup; map) open import Function using (_∘_; _|>_; id) open import Induction.WellFounded using (WellFounded) open import Level using (_⊔_) open import Relation.Binary.Construct.On using () renaming (wellFounded to on-wellFounded) open import Relation.Binary.PropositionalEquality hiding (setoid) open import Relation.Nullary open import Relation.Nullary.Decidable using (fromWitness) private variable k m n : ℕ ≈ˡ-reflexive = IsEquivalence.reflexive (≈ˡ-isEquivalence {c ⊔ ℓ}) ------------------------------------------------------------------------ -- Properties of ⟦_⟧ ------------------------------------------------------------------------ -- Algebraic properties of ⟦_⟧ ⟦⟧-mono-env : ∀ (e : Expression n) {γ γ′} → Pointwise _⊆_ γ γ′ → ⟦ e ⟧ γ ⊆ ⟦ e ⟧ γ′ ⟦⟧-mono-env ⊥ mono = ⊆-refl ⟦⟧-mono-env ε mono = ⊆-refl ⟦⟧-mono-env (Char _) mono = ⊆-refl ⟦⟧-mono-env (e₁ ∨ e₂) mono = ∪-mono (⟦⟧-mono-env e₁ mono) (⟦⟧-mono-env e₂ mono) ⟦⟧-mono-env (e₁ ∙ e₂) mono = ∙-mono (⟦⟧-mono-env e₁ mono) (⟦⟧-mono-env e₂ mono) ⟦⟧-mono-env (Var j) mono = Pw.lookup mono j ⟦⟧-mono-env (μ e) mono = ⋃-mono λ A⊆B → ⟦⟧-mono-env e (A⊆B ∷ mono) ⟦⟧-cong-env : ∀ (e : Expression n) {γ γ′} → Pointwise _≈ˡ_ γ γ′ → ⟦ e ⟧ γ ≈ˡ ⟦ e ⟧ γ′ ⟦⟧-cong-env ⊥ cong = ≈ˡ-refl ⟦⟧-cong-env ε cong = ≈ˡ-refl ⟦⟧-cong-env (Char _) cong = ≈ˡ-refl ⟦⟧-cong-env (e₁ ∨ e₂) cong = ∪-cong (⟦⟧-cong-env e₁ cong) (⟦⟧-cong-env e₂ cong) ⟦⟧-cong-env (e₁ ∙ e₂) cong = ∙ˡ-cong (⟦⟧-cong-env e₁ cong) (⟦⟧-cong-env e₂ cong) ⟦⟧-cong-env (Var j) cong = Pw.lookup cong j ⟦⟧-cong-env (μ e) cong = ⋃-cong λ A≈B → ⟦⟧-cong-env e (A≈B ∷ cong) ------------------------------------------------------------------------ -- Properties of _≈_ ------------------------------------------------------------------------ -- Relational properties ≈-refl : Reflexive (_≈_ {n}) ≈-refl _ = ≈ˡ-refl ≈-sym : Symmetric (_≈_ {n}) ≈-sym e≈e′ γ = ≈ˡ-sym (e≈e′ γ) ≈-trans : Transitive (_≈_ {n}) ≈-trans e≈e′ e′≈e′′ γ = ≈ˡ-trans (e≈e′ γ) (e′≈e′′ γ) ------------------------------------------------------------------------ -- Structures ≈-isPartialEquivalence : IsPartialEquivalence (_≈_ {n}) ≈-isPartialEquivalence {n} = record { sym = λ {e} {e′} → ≈-sym {n} {e} {e′} ; trans = λ {e} {e′} {e′′} → ≈-trans {n} {e} {e′} {e′′} } ≈-isEquivalence : IsEquivalence (_≈_ {n}) ≈-isEquivalence {n} = record { refl = λ {e} → ≈-refl {n} {e} ; sym = λ {e} {e′} → ≈-sym {n} {e} {e′} ; trans = λ {e} {e′} {e′′} → ≈-trans {n} {e} {e′} {e′′} } ------------------------------------------------------------------------ -- Bundles partialSetoid : ∀ {n} → PartialSetoid _ _ partialSetoid {n} = record { isPartialEquivalence = ≈-isPartialEquivalence {n} } setoid : ∀ {n} → Setoid _ _ setoid {n} = record { isEquivalence = ≈-isEquivalence {n} } ------------------------------------------------------------------------ -- Properties of _<ᵣₐₙₖ_ ------------------------------------------------------------------------ -- Definitions infix 4 _<ₗₑₓ_ infix 4 _<ₕₑₜ_ _<ₗₑₓ_ : REL (List C × Expression m) (List C × Expression n) _ (w , e) <ₗₑₓ (w′ , e′) = length w < length w′ ⊎ length w ≡ length w′ × e <ᵣₐₙₖ e′ _<ₕₑₜ_ : Rel (List C × ∃[ m ] Expression m) _ (w , _ , e) <ₕₑₜ (w′ , _ , e′) = (w , e) <ₗₑₓ (w′ , e′) ------------------------------------------------------------------------ -- Relational properties <ᵣₐₙₖ-trans : Trans (_<ᵣₐₙₖ_ {k}) (_<ᵣₐₙₖ_ {m} {n}) _<ᵣₐₙₖ_ <ᵣₐₙₖ-trans = <-trans <ᵣₐₙₖ-asym : Asymmetric (_<ᵣₐₙₖ_ {n}) <ᵣₐₙₖ-asym = <-asym <ₗₑₓ-trans : Trans (_<ₗₑₓ_ {k}) (_<ₗₑₓ_ {m} {n}) _<ₗₑₓ_ <ₗₑₓ-trans (inj₁ ∣w₁∣<∣w₂∣) (inj₁ ∣w₂∣<∣w₃∣) = inj₁ (<-trans ∣w₁∣<∣w₂∣ ∣w₂∣<∣w₃∣) <ₗₑₓ-trans (inj₁ ∣w₁∣<∣w₂∣) (inj₂ (∣w₂∣≡∣w₃∣ , _)) = inj₁ (<-transˡ ∣w₁∣<∣w₂∣ (≤-reflexive ∣w₂∣≡∣w₃∣)) <ₗₑₓ-trans (inj₂ (∣w₁∣≡∣w₂∣ , _)) (inj₁ ∣w₂∣<∣w₃∣) = inj₁ (<-transʳ (≤-reflexive ∣w₁∣≡∣w₂∣) ∣w₂∣<∣w₃∣) <ₗₑₓ-trans (inj₂ (∣w₁∣≡∣w₂∣ , r₁ insert-lookup γ j |> ≈ˡ-reflexive |> ≈ˡ-sym |> ∈-resp-≈) (tag (∈-resp-≈ (≈ˡ-reflexive (insert-lookup γ j A)) w∈⟦e⟧)) ... | no i≢j = 0 , ∈-resp-≈ (begin-equality lookup (insert γ i A) j ≡˘⟨ cong (lookup (insert γ i A)) (punchIn-punchOut i≢j) ⟩ lookup (insert γ i A) (punchIn i (punchOut i≢j)) ≡⟨ insert-punchIn γ i A (punchOut i≢j) ⟩ lookup γ (punchOut i≢j) ≡˘⟨ insert-punchIn γ i (K 0) (punchOut i≢j) ⟩ lookup (insert γ i (K 0)) (punchIn i (punchOut i≢j)) ≡⟨ cong (lookup (insert γ i (K 0))) (punchIn-punchOut i≢j) ⟩ lookup (insert γ i (K 0)) j ∎) w∈⟦e⟧ get-tag (μ e) A K tag mono i γ {w} (n , w∈⟦e⟧) = map₂ (n ,_) (⟦e⟧′-tag n w∈⟦e⟧) where ⟦e⟧′ : ℕ → Language _ → Language _ ⟦e⟧′ n A = Iter (λ X → ⟦ e ⟧ (X ∷ insert γ i A)) ∅ n ⟦e⟧′-monoʳ : ∀ n {X Y} → X ⊆ Y → ⟦e⟧′ n X ⊆ ⟦e⟧′ n Y ⟦e⟧′-monoʳ n X⊆Y = Iter-monoˡ (⟦⟧-mono-env e ∘ (_∷ (Pointwise-insert i i {fromWitness refl} X⊆Y (Pw.refl ⊆-refl)))) n ⊆-refl ⟦e⟧′-tag : ∀ m {w} → w ∈ ⟦e⟧′ m A → ∃[ n ] w ∈ ⟦e⟧′ m (K n) ⟦e⟧′-tag (suc m) {w} w∈⟦e⟧′ = n₁ + n₂ , ∈-resp-⊆ (⟦⟧-mono-env e ( ⟦e⟧′-monoʳ m (mono (m≤m+n n₁ n₂)) ∷ Pointwise-insert i i {fromWitness refl} (mono (m≤n+m n₂ n₁)) (Pw.refl ⊆-refl)) ) w∈⟦e⟧′₂ where n₁,w∈⟦e⟧′₁ : ∃[ z ] w ∈ ⟦ e ⟧ (⟦e⟧′ m (K z) ∷ insert γ i A) n₁,w∈⟦e⟧′₁ = get-tag e (⟦e⟧′ m A) (⟦e⟧′ m ∘ K) (⟦e⟧′-tag m) (⟦e⟧′-monoʳ m ∘ mono) zero (insert γ i A) w∈⟦e⟧′ n₁ = proj₁ n₁,w∈⟦e⟧′₁ w∈⟦e⟧′₁ = proj₂ n₁,w∈⟦e⟧′₁ n₂,w∈⟦e⟧′₂ : ∃[ z ] w ∈ ⟦ e ⟧ (⟦e⟧′ m (K n₁) ∷ insert γ i (K z)) n₂,w∈⟦e⟧′₂ = get-tag e A K tag mono (suc i) (⟦e⟧′ m (K n₁) ∷ γ) w∈⟦e⟧′₁ n₂ = proj₁ n₂,w∈⟦e⟧′₂ w∈⟦e⟧′₂ = proj₂ n₂,w∈⟦e⟧′₂ big-bit : ⟦ e ⟧ (⟦ μ e ⟧ γ ∷ γ) ⊆ ⟦ μ e ⟧ γ big-bit = sub (λ w∈⟦e⟧ → map suc id (get-tag e (⟦ μ e ⟧ γ) (Iter (⟦ e ⟧ ∘ (_∷ γ)) ∅) id (Iter-monoʳ (⟦⟧-mono-env e ∘ (_∷ Pw.refl ⊆-refl)) (⊆-min (⟦ e ⟧ (∅ ∷ γ)))) zero γ w∈⟦e⟧))