Bind-Match Normalization and Swap Tactics #
Do-notation like let (a, b) ← c; rest a b desugars to
SPComp.bind c (fun __discr => match __discr with | (a, b) => rest a b).
This match prefix blocks SPComp.isPure_bind_comm, which expects the
bind c₁ (fun a => bind c₂ (fun b => k a b)) form without intervening
matches.
This file provides:
SPComp.bind_pair_match— simp lemma replacing a pair-match inside a bind with explicit.1/.2projections.@[ssprove_bind_norm]simp attribute collecting the normalization.ssprove_bind_comm_ispure— tactic that normalizes pair/triple matches in both sides of the goal, then appliesisPure_bind_commto commute the first twoIsPurebinds.
With these tools, game-equality proofs that need to commute independent
IsPure samplings across do-notation match expressions become a single
tactic call.
Match-to-projection normalization #
Pair-match under a SPComp.bind reduces to .1/.2 projections.
This converts do-notation tuple destructuring back into the pattern
that isPure_bind_comm expects. Definitionally true by match-eta.
Tactic: commute two independent IsPure binds through matches #
ssprove_bind_comm_ispure c₁ c₂ hc₁ hc₂ commutes two IsPure
computations c₁, c₂ past any intervening do-notation pair-matches.
Equivalent to: normalize pair/triple matches via simp on
bind_pair_match / bind_triple_match, then rw [isPure_bind_comm c₁ c₂ _ hc₁ hc₂].
Typical usage:
theorem game_reorder (P : Params) :
realGame P = idealReduction P := by
unfold realGame idealReduction
ssprove_bind_comm_ispure P.keygen P.keygen P.keygen_isPure P.keygen_isPure
Equations
- One or more equations did not get rendered due to their size.
Instances For
Tactic: deep bind-comm on LHS via conv navigation #
ssprove_swap_binds_deep c₁ c₂ hc₁ hc₂ performs a rw [isPure_bind_comm]
even when the target pattern is nested below outer bind lambdas. It
navigates only the LHS (via conv_lhs), so divergence between LHS and
RHS outer structure is not an issue.
At each step, the tactic:
- Tries the rewrite at the current conv focus.
- On failure, drills into the continuation of the outermost
bindby navigatingarg 2(the function arg ofSPComp.bind) thenextto enter the lambda body. - Recurses on the new focus.
Because conv modifies only LHS (or only RHS, etc.), the sibling side is untouched. This makes the tactic safe to use even when LHS and RHS have fundamentally different outer structures.
ssprove_swap_binds_deep c₁ c₂ hc₁ hc₂ — apply bind-comm swap at any
depth within the LHS, up to 5 levels deep. The tactic enumerates depths
0–5, drilling through the bind chain via arg 2; ext _ at each step,
until the rewrite succeeds. All drilling happens inside a single
conv_lhs block so focus is preserved.
Equations
- One or more equations did not get rendered due to their size.
Instances For
ssprove_swap_at n c₁ c₂ hc₁ hc₂ — apply the IsPure bind-comm swap at
exactly depth n within the LHS. Unlike ssprove_swap_binds_deep, which finds
the first match, this variant forces the swap at the specified depth: it drills
through the bind chain with n repetitions of arg 2; ext _ inside a single
conv_lhs block, then rewrites with SPComp.isPure_bind_comm. Depth 0
rewrites at the top of the chain.
Equations
- One or more equations did not get rendered due to their size.