Denotational equivalence of statements #
StmtWithHoles.EquivInLens a b l: b, running on wide states, does what a does on the narrow
state l projects to. StmtWithHoles.Equiv is the case l = Lens.id, plain denotational
equivalence. The relation is a congruence for the statement formers, and a Hoare triple can be
moved along it (hoareStmt_iff_of_equivInLens).
The statement rewriters (TacticMisc.flattenSeq, HoareSplit.splitSeq, the inliner in
Inline.lean) prove their results equivalent to their inputs with these lemmas.
Lens helpers #
Denotational equivalence along a lens #
Push a state map through a denotation's result: (u, τ) ↦ (u, f τ).
Instances For
b, running on the wide state t, is denotationally equivalent to a, running on the
narrow state s, in the lens l : Lens s t: from any wide state, running b and projecting the
result with l.get gives the same subdistribution as running a from the projected state.
Nothing is assumed about the part of the wide state that l does not see — in particular the
frame of a flattened callee, which the flattened code resets before it reads it.
Equations
- a.EquivInLens b l = ∀ (sa : s) (sb : t), sa = l.get sb → GaudisCrypt.SubProbability.mapState l.get (b sb) = a sa
Instances For
The statement-level relation. programDenotation needs a hole-free statement and the
rewrites here leave hole indices untouched, so the instantiation is quantified — the same one on
both sides.
Equations
- a.EquivInLens b l = ∀ (inst : hCtx.Instantiation), (GaudisCrypt.programDenotation (a.instantiate inst)).EquivInLens (GaudisCrypt.programDenotation (b.instantiate inst)) l
Instances For
Denotational equivalence without renaming — what flattenSeq proves.
Equations
- a.Equiv b = a.EquivInLens b GaudisCrypt.Lens.id
Instances For
The primitives, applied at a state #
EquivInLens is a congruence #
What the flattener needs along the path down to the call it is rewriting.
pure is equivalent to itself.
Diverging is equivalent to diverging.
Reading through the composed getter is equivalent to reading through the original one.
Writing through the composed setter is equivalent to writing through the original one.
A state-blind draw is equivalent to itself.
Bind congruence — the seq case, and the heart of the path congruences. Note the
continuation hypothesis is over wide states, which is exactly what EquivInLens provides.
Projecting twice is projecting along the composite.
Equivalences compose: through l, then through m, is through m.chain l.
mapState is ω-continuous — what the loop congruence needs.
Equivalence passes to ω-suprema of chains — the limit step of the loop congruence.
Loop congruence (Kleene/ωSup argument again): equivalent conditions and equivalent bodies give equivalent loops.
Every program is equivalent to itself, in the identity lens.
The same, at statement level #
Sequencing.
Branching; the condition is re-targeted by composing it with the lens.
Looping; the condition is re-targeted by composing it with the lens.
Statement equivalences compose — how the flattener's passes are stitched together.
Reflexivity of the renaming-free relation.
Sequencing is associative, denotationally.
Deterministic statements #
An assignment, run at a state: a deterministic write.
An assignment is a read followed by a write.
skip is the identity state map.
Sequencing is bind.
Two deterministic statements in sequence: their state maps compose.
At the identity lens #
What flattenSeq rewrites with (and StmtWithHoles.Equiv.seq_assoc, above).
A leading skip can be dropped.
A trailing skip can be dropped.
An assignment to _ does nothing.
A leading assignment to _ can be dropped (a call with no parameters writes its argument
() to _).
A trailing assignment to _ can be dropped (a call whose result is discarded stores it to
_).
Branching, at the identity lens.
Looping, at the identity lens.
Transitivity, at the identity lens (Lens.id.chain Lens.id is Lens.id).
Symmetry, at the identity lens (the one lens at which the relation is symmetric).
Hoare triples #
A statement triple is a triple about any statement equivalent to its own, with the conditions read
through the lens of the equivalence: so it can be proved about a rewritten statement instead
(hoare_inline, hoare_split).
A triple about an equivalent statement: along s.EquivInLens s' l, the triple about s
is the triple about s' with both conditions read through l.
hoareStmt_iff_of_equivInLens, backwards, with the conditions given up to an equation: what
hoare_inline applies, the equations being those of the cleaning pass.
A triple about an equivalent statement, without renaming: the conditions stay as they are.