Source code on Github
module Class.MonotonePredicate.Core where
open import Class.Prelude
open import Class.HasOrder
open import Relation.Unary
open import Relation.Binary using (IsPreorder ; IsEquivalence)
open import Level
module _ {A : Type ℓ}
⦃ _ : HasPreorder {A = A} {_≈_ = _≡_} {ℓ} {ℓ} ⦄ where
open IsPreorder {ℓ} ≤-isPreorder
record Monotone {ℓ′} (P : Pred A ℓ′) : Type (ℓ ⊔ ℓ′ ⊔ ℓ) where
field
weaken : ∀ {a a′} → a ≤ a′ → P a → P a′
record Antitone {ℓ′} (P : Pred A ℓ′) : Type (ℓ ⊔ ℓ′ ⊔ ℓ″) where
field
strengthen : ∀ {a a′} → a′ ≤ a → P a → P a′
open Monotone ⦃...⦄
open Antitone ⦃...⦄
record ◇ (P : Pred A ℓ) (a : A) : Set ℓ where
constructor ◇⟨_,_⟩
field
{a′} : A
ι : a′ ≤ a
px : P a′
open ◇ public
record □ (P : Pred A ℓ) (a : A) : Set ℓ where
constructor necessary
field
□⟨_⟩_ : ∀ {a′} → (ι : a ≤ a′) → P a′
open □ public
module Operations where
extract : ∀ {P} → ∀[ □ P ⇒ P ]
extract px = □⟨ px ⟩ reflexive _≡_.refl
duplicate : ∀ {P} → ∀[ □ P ⇒ □ (□ P) ]
duplicate px = necessary λ ι → necessary λ ι′ → □⟨ px ⟩ trans ι ι′
return : ∀ {P} → ∀[ P ⇒ ◇ P ]
return px = ◇⟨ reflexive _≡_.refl , px ⟩
join : ∀ {P} → ∀[ ◇ (◇ P) ⇒ ◇ P ]
join ◇⟨ ι₁ , ◇⟨ ι₂ , px ⟩ ⟩ = ◇⟨ (trans ι₂ ι₁) , px ⟩
curry : ∀ {P Q} → ∀[ ◇ P ⇒ Q ] → ∀[ P ⇒ □ Q ]
curry f px = necessary (λ ι → f ◇⟨ ι , px ⟩)
uncurry : ∀ {P Q} → ∀[ P ⇒ □ Q ] → ∀[ ◇ P ⇒ Q ]
uncurry f ◇⟨ ι , px ⟩ = □⟨ f px ⟩ ι
_⇛_ : ∀ (P Q : Pred A ℓ) → Pred A ℓ
P ⇛ Q = □ (P ⇒ Q)
kripke-curry : {P Q R : Pred A ℓ} → ⦃ Monotone P ⦄ → ∀[ (P ∩ Q) ⇒ R ] → ∀[ P ⇒ (Q ⇛ R) ]
kripke-curry f px₁ = necessary (λ i px₂ → f (weaken i px₁ , px₂))
kripke-uncurry : {P Q R : Pred A ℓ} → ∀[ P ⇒ (Q ⇛ R) ] → ∀[ (P ∩ Q) ⇒ R ]
kripke-uncurry f (px₁ , px₂) = □⟨ f px₁ ⟩ reflexive _≡_.refl $ px₂