Hoare/Core.lean
Defines Hoare triples for monadic kernels and proves the core proof rules: consequence, sequential composition, skip, conjunction, and disjunction.
Triple
A Hoare triple {P} f {Q} means: for every input satisfying P, every possible output of f satisfies Q. The quantification is over the support — the same possibilistic (reachability-based) layer used throughout the framework. Think of it as a contract with a precondition.
def Triple [Monad M] [Support M]
(P : α → Prop) (f : Kernel M α β) (Q : β → Prop) : Prop :=
∀ a : α, P a → ∀ b : β, Support.support (f a) b → Q b triple_consequence
Rule of consequence: you can weaken the precondition (accept more inputs) and strengthen the postcondition (promise less about outputs). If the original triple holds, the weakened one does too.
triple_comp
Sequential composition (the COMP rule): if {P} f {R} and {R} g {Q}, then {P} f;g {Q}. Uses support_bind to decompose the composite's support into an intermediate value.
theorem triple_comp [Monad M] [LawfulMonad M] [Support M]
{P : α → Prop} {R : β → Prop} {Q : γ → Prop}
{f : Kernel M α β} {g : Kernel M β γ}
(hf : Triple P f R) (hg : Triple R g Q)
: Triple P (Kernel.comp f g) Q triple_skip
The skip rule: the identity kernel preserves any predicate. Uses support_pure to show the only possible output is the input itself.
triple_post_and
AND rule: if f preserves Q and R separately, it preserves both simultaneously.
triple_pre_or
OR rule: if the triple holds from precondition P1 and from P2, it holds from their disjunction.
Connections
- Handshake.lean — imported; triples are built on top of the contract/kernel infrastructure
- Hoare/WP.lean — weakest precondition transformer, equivalent to triples
- Hoare/Bridge.lean — connects triples to ContractPreserving
- Hoare/Comp.lean — chains the full pipeline through COMP
- Hoare/Graded.lean — adds cost bounds (grades) to triples