module TotalParserCombinators.Semantics where
open import Codata.Musical.Notation
open import Data.List hiding (drop)
open import Data.List.Relation.Binary.BagAndSetEquality
using (bag) renaming (_∼[_]_ to _List-∼[_]_)
open import Data.Maybe using (Maybe); open Data.Maybe.Maybe
open import Data.Product
open import Data.Unit using (⊤; tt)
open import Function
open import Function.Consequences.Propositional
open import Function.Related.Propositional as Related using (Related)
open import Level
import Relation.Binary.HeterogeneousEquality as H
open import Relation.Binary.PropositionalEquality as P using (_≡_)
open import Relation.Nullary
open import TotalParserCombinators.Parser
infix 60 <$>_
infixl 50 _⊛_ [_-_]_⊛_
infixl 10 _>>=_ [_-_]_>>=_
infix 4 _∈_·_
data _∈_·_ {Tok} :
∀ {R xs} → R → Parser Tok R xs → List Tok → Set₁ where
return : ∀ {R} {x : R} → x ∈ return x · []
token : ∀ {x} → x ∈ token · [ x ]
∣-left : ∀ {R x xs₁ xs₂ s}
{p₁ : Parser Tok R xs₁} {p₂ : Parser Tok R xs₂}
(x∈p₁ : x ∈ p₁ · s) → x ∈ p₁ ∣ p₂ · s
∣-right : ∀ {R x xs₂ s} xs₁
{p₁ : Parser Tok R xs₁} {p₂ : Parser Tok R xs₂}
(x∈p₂ : x ∈ p₂ · s) → x ∈ p₁ ∣ p₂ · s
<$>_ : ∀ {R₁ R₂ x s xs} {p : Parser Tok R₁ xs} {f : R₁ → R₂}
(x∈p : x ∈ p · s) → f x ∈ f <$> p · s
_⊛_ : ∀ {R₁ R₂ f x s₁ s₂ fs xs}
{p₁ : ∞⟨ xs ⟩Parser Tok (R₁ → R₂) (flatten fs)}
{p₂ : ∞⟨ fs ⟩Parser Tok R₁ (flatten xs)} →
(f∈p₁ : f ∈ ♭? p₁ · s₁)
(x∈p₂ : x ∈ ♭? p₂ · s₂) →
f x ∈ p₁ ⊛ p₂ · s₁ ++ s₂
_>>=_ : ∀ {R₁ R₂ x y s₁ s₂ xs} {f : Maybe (R₁ → List R₂)}
{p₁ : ∞⟨ f ⟩Parser Tok R₁ (flatten xs)}
{p₂ : (x : R₁) → ∞⟨ xs ⟩Parser Tok R₂ (apply f x)}
(x∈p₁ : x ∈ ♭? p₁ · s₁)
(y∈p₂x : y ∈ ♭? (p₂ x) · s₂) →
y ∈ p₁ >>= p₂ · s₁ ++ s₂
nonempty : ∀ {R xs x y s} {p : Parser Tok R xs}
(x∈p : y ∈ p · x ∷ s) → y ∈ nonempty p · x ∷ s
cast : ∀ {R xs₁ xs₂ x s}
{xs₁≈xs₂ : xs₁ List-∼[ bag ] xs₂} {p : Parser Tok R xs₁}
(x∈p : x ∈ p · s) → x ∈ cast xs₁≈xs₂ p · s
[_-_]_⊛_ : ∀ {Tok R₁ R₂ f x s₁ s₂} xs fs
{p₁ : ∞⟨ xs ⟩Parser Tok (R₁ → R₂) (flatten fs)}
{p₂ : ∞⟨ fs ⟩Parser Tok R₁ (flatten xs)} →
f ∈ ♭? p₁ · s₁ → x ∈ ♭? p₂ · s₂ → f x ∈ p₁ ⊛ p₂ · s₁ ++ s₂
[ xs - fs ] f∈p₁ ⊛ x∈p₂ = _⊛_ {fs = fs} {xs = xs} f∈p₁ x∈p₂
[_-_]_>>=_ : ∀ {Tok R₁ R₂ x y s₁ s₂} (f : Maybe (R₁ → List R₂)) xs
{p₁ : ∞⟨ f ⟩Parser Tok R₁ (flatten xs)}
{p₂ : (x : R₁) → ∞⟨ xs ⟩Parser Tok R₂ (apply f x)} →
x ∈ ♭? p₁ · s₁ → y ∈ ♭? (p₂ x) · s₂ →
y ∈ p₁ >>= p₂ · s₁ ++ s₂
[ f - xs ] x∈p₁ >>= y∈p₂x = _>>=_ {xs = xs} {f = f} x∈p₁ y∈p₂x
infix 4 _∼[_]_ _≈_ _≅_ _≲_ _≲→_
open Data.List.Relation.Binary.BagAndSetEquality public
using (Kind)
renaming ( bag to parser
; set to language
; subbag to subparser
; subset to sublanguage
; superbag to superparser
; superset to superlanguage
)
_∼[_]_ : ∀ {Tok R xs₁ xs₂} →
Parser Tok R xs₁ → Kind → Parser Tok R xs₂ → Set₁
p₁ ∼[ k ] p₂ = ∀ {x s} → Related k (x ∈ p₁ · s) (x ∈ p₂ · s)
_≈_ : ∀ {Tok R xs₁ xs₂} → Parser Tok R xs₁ → Parser Tok R xs₂ → Set₁
p₁ ≈ p₂ = p₁ ∼[ language ] p₂
_≅_ : ∀ {Tok R xs₁ xs₂} → Parser Tok R xs₁ → Parser Tok R xs₂ → Set₁
p₁ ≅ p₂ = p₁ ∼[ parser ] p₂
_≲_ : ∀ {Tok R xs₁ xs₂} → Parser Tok R xs₁ → Parser Tok R xs₂ → Set₁
p₁ ≲ p₂ = p₁ ∼[ sublanguage ] p₂
_≲→_ : ∀ {Tok R xs₁ xs₂} → Parser Tok R xs₁ → Parser Tok R xs₂ → Set₁
p₁ ≲→ p₂ = ∀ {x s} → x ∈ p₁ · s → x ∈ p₂ · s
≲⇔≲→ :
∀ {Tok R xs₁ xs₂} {p₁ : Parser Tok R xs₁} {p₂ : Parser Tok R xs₂} →
p₁ ≲ p₂ ⇔ p₁ ≲→ p₂
≲⇔≲→ = mk⇔
(λ f {x = x} {s = s} → Func.to (f {x = x} {s = s}))
(λ f {x = x} {s = s} → mk⟶ (f {x = x} {s = s}))
≈⇔≲≳ : ∀ {Tok R xs₁ xs₂}
{p₁ : Parser Tok R xs₁} {p₂ : Parser Tok R xs₂} →
p₁ ≈ p₂ ⇔ (p₁ ≲ p₂ × p₂ ≲ p₁)
≈⇔≲≳ = mk⇔
(λ p₁≈p₂ →
((λ {x s} → mk⟶ (Equivalence.to (p₁≈p₂ {x = x} {s = s})))
, λ {x s} → mk⟶ (Equivalence.from (p₁≈p₂ {x = x} {s = s}))))
(λ p₁≲≳p₂ → λ {x s} →
mk⇔ (Func.to (proj₁ p₁≲≳p₂ {s = s}))
(Func.to (proj₂ p₁≲≳p₂ {s = s})))
≅⇒≈ : ∀ {Tok R xs₁ xs₂}
{p₁ : Parser Tok R xs₁} {p₂ : Parser Tok R xs₂} →
p₁ ≅ p₂ → p₁ ≈ p₂
≅⇒≈ p₁≅p₂ = Related.↔⇒ p₁≅p₂
¬≈⇒≅ : ¬ (∀ {Tok R xs₁ xs₂}
{p₁ : Parser Tok R xs₁} {p₂ : Parser Tok R xs₂} →
p₁ ≈ p₂ → p₁ ≅ p₂)
¬≈⇒≅ hyp with inverseʳ⇒injective _ (Inverse.inverseʳ p₁≅p₂)
{∣-left return} {∣-right [ tt ] return} (lemma _ _)
where
p₁ : Parser ⊤ ⊤ _
p₁ = return tt ∣ return tt
p₂ : Parser ⊤ ⊤ _
p₂ = return tt
p₁≲p₂ : p₁ ≲→ p₂
p₁≲p₂ (∣-left return) = return
p₁≲p₂ (∣-right ._ return) = return
p₁≅p₂ : p₁ ≅ p₂
p₁≅p₂ = hyp $ mk⇔ p₁≲p₂ ∣-left
lemma : ∀ {x s} (x∈₁ x∈₂ : x ∈ p₂ · s) → x∈₁ ≡ x∈₂
lemma return return = P.refl
... | ()
cast∈ : ∀ {Tok R xs} {p p′ : Parser Tok R xs} {x x′ s s′} →
x ≡ x′ → p ≡ p′ → s ≡ s′ → x ∈ p · s → x′ ∈ p′ · s′
cast∈ P.refl P.refl P.refl x∈ = x∈