How to decompose a lattice operator head … s⃗ on the RHS of an entailment: the distribution and
unfolding rewrites that saturate it, and the terminal ⊑-introduction terminals that close the
reduced form. head keys the split in the latticeOps table.
- head : Name
Head constant of the operator this split decomposes. Keys the
latticeOpstable. - numConst : Nat
The number of leading arguments held constant during rule construction: the operator's carrier type and its typeclass instances. The operands and excess state arguments after them become the rule's schematic parameters.
2for a connective over aCompleteLatticecarrier;0for a monomorphic operator. Distribution and unfolding equalities that saturate the operator applied to state arguments.
The operator's terminal
⊑-introduction rule, ornonewhen it saturates to another operator's terminal.Whether the split applies to this RHS. Ops without a terminal decline shapes their rewrites cannot reduce.
Instances For
Lattice split rules #
Backward rules that decompose a lattice operator on the RHS of an entailment pre ⊑ op … s⃗. The
operator is saturated with distribution and unfolding rewrites, a terminal ⊑-introduction rule
fires on the reduced form, and any state arguments the terminal leaves over-applied are point-framed
onto the precondition.
The built-in splits cover the lattice connectives ⊓/⇨/⌜·⌝/⊤/iInf and the magic-wand
residual upperAdjoint.
The lattice meet ⊓: distributes via meet_apply, closes with le_meet.
Equations
Instances For
The pure assertion ⌜·⌝: distributes via ofProp_apply, closes with the ⊤-fixed
top_le_ofProp.
Equations
Instances For
The magic-wand residual upperAdjoint f b: point-framed, closes with le_upperAdjoint.
Equations
- Lean.Elab.Tactic.VCGen.LatticeOp.upperAdjoint = { head := `Lean.Order.PreservesSup.upperAdjoint, terminal? := some `Lean.Order.PreservesSup.le_upperAdjoint }
Instances For
The projection (⊥/⊤ : _ × _).fst of an exception-postcondition tuple: reduces to the bare
⊥/⊤ via Prod.fst_bot/Prod.fst_top and the pointwise bot_apply/top_apply. numConst := 3
holds the tuple operand concrete, since which rewrite fires depends on it; only the excess state
arguments go schematic. No terminal: the ⊥ residual becomes the subgoal, the ⊤ residual closes
with le_top. applies? declines every other operand, whose projection the rewrites cannot
reduce.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The projection (⊥/⊤ : _ × _).fst of an exception-postcondition tuple: reduces to the bare
⊥/⊤ via Prod.fst_bot/Prod.fst_top and the pointwise bot_apply/top_apply. numConst := 3
holds the tuple operand concrete, since which rewrite fires depends on it; only the excess state
arguments go schematic. No terminal: the ⊥ residual becomes the subgoal, the ⊤ residual closes
with le_top. applies? declines every other operand, whose projection the rewrites cannot
reduce.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The built-in connective splits, whose rewrites and terminals seed every saturation.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Lattice splits of the built-in connectives, keyed by operator head. splitLatticeOp? looks a
head up here.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Build a reusable backward rule decomposing pre ⊑ op … s⃗ for a lattice operator. The operator's
value arguments are made schematic; rewrites saturate the operator through its distribution and
unfolding equalities, the terminal keyed by the reduced head fires, and any state arguments left
over-applied by the terminal are point-framed onto the precondition. When the reduced head has no
registered terminal, the saturated pre ⊑ reduced is handed back as the sole subgoal. Throws when the
operator neither reduces nor has a terminal, since its rule would be the identity; the operator's
applies? filter keeps such shapes away from rule construction.
For ⊓, produces ∀ a b s⃗ pre, pre ⊑ a s⃗ → pre ⊑ b s⃗ → pre ⊑ (a ⊓ b) s⃗. For the opaque residual
upperAdjoint f b, produces ∀ f b s⃗ pre, f (fun u⃗ => ⌜u⃗ = s⃗⌝ ⊓ pre) ⊑ b → pre ⊑ upperAdjoint f b s⃗.
Equations
- One or more equations did not get rendered due to their size.