Source code on Github
module UTxOErr.HoareLogic where
open import Prelude.Init; open SetAsType
open import Prelude.General
open import Prelude.DecEq
open import Prelude.Decidable
open import Prelude.Semigroup
open import Prelude.Monoid
open import Prelude.InferenceRules
open import Prelude.Ord
open import Prelude.Functor
open import Prelude.Bifunctor
open import Prelude.Monad
open import Prelude.Apartness
open import UTxOErr.UTxO
open import UTxOErr.Ledger
open import Prelude.Maps
_[_↦_]∅ : S → TxOutputRef → TxOutput → Type
m [ k ↦ v ]∅ = m [ k ↦ v ] × ∀ k′ → k′ ≢ k → k′ ∉ᵈ m
Assertion = Pred₀ S
variable P P′ P₁ P₂ Q Q′ Q₁ Q₂ R : Assertion
private variable K V₁ V₂ : Type
emp : Assertion
emp m = ∀ k → k ∉ᵈ m
_∗_ : Op₂ Assertion
(P ∗ Q) s = ∃ λ s₁ → ∃ λ s₂ → ⟨ s₁ ⊎ s₂ ⟩≡ s × P s₁ × Q s₂
_↦_ : TxOutputRef → TxOutput → Assertion
or ↦ o = _[ or ↦ o ]∅
infixr 10 _∗_
infix 11 _↦_
weak↑ strong↑ : Pred₀ S → Pred₀ (Maybe S)
weak↑ = M.All.All
strong↑ = M.Any.Any
infixl 4 _↑∘_
_↑∘_ : Pred₀ S → (S → Maybe S) → Pred₀ S
P ↑∘ f = strong↑ P ∘ f
lift↑ = strong↑
pattern ret↑ x = M.Any.just x
map↑ : P ⊆¹ Q → lift↑ P ⊆¹ lift↑ Q
map↑ = M.Any.map
⟨_⟩_⟨_⟩ : Assertion → L → Assertion → Type
⟨ P ⟩ l ⟨ Q ⟩ = P ⊢ Q ↑∘ ⟦ l ⟧
⟨_⟩_⟨_⟩@_ : Assertion → L → Assertion → S → Type
⟨ P ⟩ l ⟨ Q ⟩@ s = P s → (Q ↑∘ ⟦ l ⟧) s
hoare-base :
──────────────
⟨ P ⟩ [] ⟨ P ⟩
hoare-base = ret↑
module _ (f : S → Maybe S) where
lift∘>>= : ∀ {ms}
→ lift↑ (lift↑ P ∘ f) ms
→ lift↑ P (ms >>= f)
lift∘>>= (ret↑ p) = p
lift∘>>=˘ : ∀ {ms : Maybe S}
→ lift↑ P (ms >>= f)
→ lift↑ (lift↑ P ∘ f) ms
lift∘>>=˘ {ms = just s} p = ret↑ p
lift∘=<< = lift∘>>=
lift∘=<<˘ = lift∘>>=˘
module _ (f g : S → Maybe S) where
lift²∘>=> : (P ↑∘ g ↑∘ f) ⊢ (P ↑∘ (f >=> g))
lift²∘>=> = lift∘=<< _
lift²∘>=>˘ : (P ↑∘ (f >=> g)) ⊢ (P ↑∘ g ↑∘ f)
lift²∘>=>˘ = lift∘=<<˘ _
hoare-step :
⟨ P ⟩ l ⟨ Q ⟩
──────────────────────────
⟨ P ↑∘ ⟦ t ⟧ ⟩ t ∷ l ⟨ Q ⟩
hoare-step {t = t} PlQ {s} = lift²∘>=> ⟦ t ⟧ _ {x = s} ∘ map↑ PlQ
consequence :
∙ P′ ⊢ P
∙ Q ⊢ Q′
∙ ⟨ P ⟩ l ⟨ Q ⟩
───────────────
⟨ P′ ⟩ l ⟨ Q′ ⟩
consequence ⊢P Q⊢ PlQ = map↑ Q⊢ ∘ PlQ ∘ ⊢P
weaken : P′ ⊢ P → ⟨ P ⟩ l ⟨ Q ⟩ → ⟨ P′ ⟩ l ⟨ Q ⟩
weaken {l = l} H = consequence {l = l} H id
strengthen : Q ⊢ Q′ → ⟨ P ⟩ l ⟨ Q ⟩ → ⟨ P ⟩ l ⟨ Q′ ⟩
strengthen {l = l} H = consequence {l = l} id H
axiom-base⋆ : ⟨ P ↑∘ ⟦ l ⟧ ⟩ l ⟨ P ⟩
axiom-base⋆ {P = P} {l = []} = weaken {P′ = P ↑∘ ⟦ [] ⟧} {l = []} (λ where (ret↑ p) → p) hoare-base
axiom-base⋆ {P = P} {l = t ∷ l} = map↑ id
hoare-step′ :
∙ ⟨ P ⟩ l ⟨ Q ⟩
∙ ⟨ Q ⟩ l′ ⟨ R ⟩
───────────────────
⟨ P ⟩ l ++ l′ ⟨ R ⟩
hoare-step′ {P}{l}{Q}{l′}{R} PlQ QlR
= begin
P
⊢⟨ PlQ ⟩
Q ↑∘ ⟦ l ⟧
⊢⟨ map↑ QlR ⟩
R ↑∘ ⟦ l′ ⟧ ↑∘ ⟦ l ⟧
⊢⟨ lift²∘>=> ⟦ l ⟧ ⟦ l′ ⟧ ⟩
R ↑∘ (⟦ l ⟧ >=> ⟦ l′ ⟧)
≗˘⟨ cong (lift↑ R) ∘ comp {l}{l′} ⟩
R ↑∘ ⟦ l ++ l′ ⟧
∎ where open ⊢-Reasoning
module HoareReasoning where
record ℝ⟨_⟩_⟨_⟩ (P : Assertion) (l : L) (Q : Assertion) : Type where
constructor mkℝ_
field begin_ : ⟨ P ⟩ l ⟨ Q ⟩
infix -2 begin_
open ℝ⟨_⟩_⟨_⟩ public
infix -2 mkℝ_
infixr -1 _~⟪_⟩_ _~⟨_⟫_ _~⟨_∶-_⟩_ _~⟨_∶-_⟩++_
infix 0 _∎
_~⟪_⟩_ : ∀ P′ → P′ ⊢ P → ℝ⟨ P ⟩ l ⟨ R ⟩ → ℝ⟨ P′ ⟩ l ⟨ R ⟩
_~⟪_⟩_ {l = l} _ H PlR = mkℝ weaken {l = l} H (begin PlR)
_~⟨_⟫_ : ∀ R′ → R ⊢ R′ → ⟨ P ⟩ l ⟨ R ⟩ → ⟨ P ⟩ l ⟨ R′ ⟩
_~⟨_⟫_ {l = l} _ H PlR = strengthen {l = l} H PlR
_~⟨_∶-_⟩_ : ∀ P′ t → ℝ⟨ P′ ⟩ [ t ] ⟨ P ⟩ → ℝ⟨ P ⟩ l ⟨ R ⟩ → ℝ⟨ P′ ⟩ t ∷ l ⟨ R ⟩
_~⟨_∶-_⟩_ {l = l} {R = R} P′ t H PlR = mkℝ go
where
go : P′ ⊢ R ↑∘ ⟦ t ∷ l ⟧
go {s} P′s with ⟦ t ⟧ s | (begin H) P′s
... | just _ | ret↑ Ps′ = (begin PlR) Ps′
_~⟨_∶-_⟩++_ : ∀ P′ → (l : L) → ℝ⟨ P′ ⟩ l ⟨ P ⟩ → ℝ⟨ P ⟩ l′ ⟨ R ⟩ → ℝ⟨ P′ ⟩ l ++ l′ ⟨ R ⟩
P′ ~⟨ l ∶- H ⟩++ PlR = mkℝ hoare-step′ {l = l} (begin H) (begin PlR)
_∎ : ∀ P → ℝ⟨ P ⟩ [] ⟨ P ⟩
p ∎ = mkℝ hoare-base {P = p}