Local rules and local rule applications #
One-sided local rules #
Local rules replace a given set of formulas by other sets, one for each branch. The list of resulting branches can be empty, representing that the given set is closed. In the Haskell prover this is done in "ruleFor" in the Logic.PDL.Prove.Tree module.
- bot : OneSidedLocalRule [⊥] ∅
- not (φ : Formula) : OneSidedLocalRule [φ, ~φ] ∅
- neg (φ : Formula) : OneSidedLocalRule [~~φ] [[φ]]
- con (φ ψ : Formula) : OneSidedLocalRule [φ ⋀ ψ] [[φ, ψ]]
- nCo (φ ψ : Formula) : OneSidedLocalRule [~(φ ⋀ ψ)] [[~φ], [~ψ]]
- box (α : Program) (φ : Formula) (notAtom : ¬α.isAtomic) : OneSidedLocalRule [⌈α⌉φ] (unfoldBox α φ)
- dia (α : Program) (φ : Formula) (notAtom : ¬α.isAtomic) : OneSidedLocalRule [~⌈α⌉φ] (unfoldDiamond α φ)
Instances For
Equations
- instDecidableEqOneSidedLocalRule.decEq OneSidedLocalRule.bot OneSidedLocalRule.bot = isTrue instDecidableEqOneSidedLocalRule.decEq._proof_1
- instDecidableEqOneSidedLocalRule.decEq (OneSidedLocalRule.not a_2) (OneSidedLocalRule.not a_2) = isTrue ⋯
- instDecidableEqOneSidedLocalRule.decEq (OneSidedLocalRule.neg a_2) (OneSidedLocalRule.neg a_2) = isTrue ⋯
- instDecidableEqOneSidedLocalRule.decEq (OneSidedLocalRule.con a_2 a_3) (OneSidedLocalRule.con a_2 a_3) = isTrue ⋯
- instDecidableEqOneSidedLocalRule.decEq (OneSidedLocalRule.nCo a_2 a_3) (OneSidedLocalRule.nCo a_2 a_3) = isTrue ⋯
- instDecidableEqOneSidedLocalRule.decEq (OneSidedLocalRule.box a_2 a_3 a_4) (OneSidedLocalRule.box a_2 a_3 b) = ⋯ ▸ isTrue ⋯
- instDecidableEqOneSidedLocalRule.decEq (OneSidedLocalRule.dia a_2 a_3 a_4) (OneSidedLocalRule.dia a_2 a_3 b) = ⋯ ▸ isTrue ⋯
Instances For
Equations
- instReprOneSidedLocalRule = { reprPrec := instReprOneSidedLocalRule.repr }
Equations
- One or more equations did not get rendered due to their size.
- instReprOneSidedLocalRule.repr OneSidedLocalRule.bot prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "OneSidedLocalRule.bot")).group prec✝
Instances For
Loaded Rules #
The loaded diamond rule, given by unfoldDiamondLoaded.
In MB page 19 these were multiple rules ¬u, ¬; ¬* and ¬?.
It replaces the loaded formula by up to one loaded formula and a list of normal formulas.
It's a bit annoying to need the rule twice here due to the definition of LoadFormula
and the extra definition of unfoldDiamondLoaded'.
- dia {α : Program} {χ : LoadFormula} (notAtom : ¬α.isAtomic) : LoadRule (~'⌊α⌋AnyFormula.loaded χ) (unfoldDiamondLoaded α χ)
- dia' {α : Program} {φ : Formula} (notAtom : ¬α.isAtomic) : LoadRule (~'⌊α⌋AnyFormula.normal φ) (unfoldDiamondLoaded' α φ)
Instances For
Equations
- instDecidableEqLoadRule.decEq (LoadRule.dia a_4) (LoadRule.dia b) = ⋯ ▸ isTrue ⋯
- instDecidableEqLoadRule.decEq (LoadRule.dia' a_4) (LoadRule.dia' b) = ⋯ ▸ isTrue ⋯
Instances For
Equations
- instReprLoadRule = { reprPrec := instReprLoadRule.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
Given a LoadRule application, define the equivalent unloaded rule application.
This allows re-using oneSidedLocalRuleTruth to prove loadRuleTruth.
Equations
- (LoadRule.dia notAtom).unload = ⋯ ▸ OneSidedLocalRule.dia α χ_2.unload notAtom
- (LoadRule.dia' notAtom).unload = ⋯ ▸ OneSidedLocalRule.dia α φ notAtom
Instances For
The loaded unfold rule is sound and invertible. In the notes this is part of localRuleTruth.
Local Rules #
A local rule is a OneSidedLocalRule, a left-right contradiction, or a LoadRule.
Note that formulas can be in four places: left, right, loaded left, loaded right.
We do not have neg/contradiction rules between loaded and unloaded formulas (i.e.
between ({unload χ}, ∅, some (Sum.inl ~χ)) and (∅, {unload χ}, some (Sum.inr ~χ)))
because in any such case we could also close the tableau before or without loading.
The YS_def arguments in non-terminal rules enables deriving DecidableEq for LocalRule.
- oneSidedL {precond : List Formula} {ress : List (List Formula)} {YS : List (List Formula × List Formula × Option (NegLoadFormula ⊕ NegLoadFormula))} (orule : OneSidedLocalRule precond ress) (YS_def : YS = List.map (fun (res : List Formula) => (res, ∅, none)) ress) : LocalRule (precond, ∅, none) YS
- oneSidedR {precond : List Formula} {ress : List (List Formula)} {YS : List (List Formula × List Formula × Option (NegLoadFormula ⊕ NegLoadFormula))} (orule : OneSidedLocalRule precond ress) (YS_def : YS = List.map (fun (res : List Formula) => (∅, res, none)) ress) : LocalRule (∅, precond, none) YS
- LRnegL (ϕ : Formula) : LocalRule ([ϕ], [~ϕ], none) ∅
- LRnegR (ϕ : Formula) : LocalRule ([~ϕ], [ϕ], none) ∅
- loadedL {ress : List (List Formula × Option NegLoadFormula)} {YS : List Sequent} (χ : LoadFormula) (lrule : LoadRule (~'χ) ress) (YS_def : YS = List.map (fun (x : List Formula × Option NegLoadFormula) => match x with | (X, o) => (X, ∅, Option.map Sum.inl o)) ress) : LocalRule (∅, ∅, some (Sum.inl (~'χ))) YS
- loadedR {ress : List (List Formula × Option NegLoadFormula)} {YS : List Sequent} (χ : LoadFormula) (lrule : LoadRule (~'χ) ress) (YS_def : YS = List.map (fun (x : List Formula × Option NegLoadFormula) => match x with | (X, o) => (∅, X, Option.map Sum.inr o)) ress) : LocalRule (∅, ∅, some (Sum.inr (~'χ))) YS
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- instReprLocalRule = { reprPrec := instReprLocalRule.repr }
Equations
- One or more equations did not get rendered due to their size.
- instDecidableEqLocalRule.decEq (LocalRule.oneSidedL orule YS_def) (LocalRule.oneSidedR orule_1 YS_def_1) = isFalse ⋯
- instDecidableEqLocalRule.decEq (LocalRule.oneSidedR orule YS_def) (LocalRule.oneSidedL orule_1 YS_def_1) = isFalse ⋯
- instDecidableEqLocalRule.decEq (LocalRule.LRnegL a_2) (LocalRule.LRnegL a_2) = isTrue ⋯
- instDecidableEqLocalRule.decEq (LocalRule.LRnegR a_2) (LocalRule.LRnegR a_2) = isTrue ⋯
Instances For
Helper originally written for Lemma 6.14 but currently unused.
Equations
- principalFormulaForLocalRule (LocalRule.oneSidedL OneSidedLocalRule.bot YS_def_2) = AnyFormula.normal Formula.bottom
- principalFormulaForLocalRule (LocalRule.oneSidedL (OneSidedLocalRule.con φ ψ) YS_def_2) = AnyFormula.normal (φ ⋀ ψ)
- principalFormulaForLocalRule (LocalRule.oneSidedL (OneSidedLocalRule.not φ) YS_def_2) = AnyFormula.normal φ
- principalFormulaForLocalRule (LocalRule.oneSidedL (OneSidedLocalRule.neg φ) YS_def_2) = AnyFormula.normal (~~φ)
- principalFormulaForLocalRule (LocalRule.oneSidedL (OneSidedLocalRule.nCo φ ψ) YS_def_2) = AnyFormula.normal (~(φ ⋀ ψ))
- principalFormulaForLocalRule (LocalRule.oneSidedL (OneSidedLocalRule.dia α φ notAtom) YS_def_2) = AnyFormula.normal (~⌈α⌉φ)
- principalFormulaForLocalRule (LocalRule.oneSidedL (OneSidedLocalRule.box α φ notAtom) YS_def_2) = AnyFormula.normal (⌈α⌉φ)
- principalFormulaForLocalRule (LocalRule.oneSidedR OneSidedLocalRule.bot YS_def_2) = AnyFormula.normal Formula.bottom
- principalFormulaForLocalRule (LocalRule.oneSidedR (OneSidedLocalRule.con φ ψ) YS_def_2) = AnyFormula.normal (φ ⋀ ψ)
- principalFormulaForLocalRule (LocalRule.oneSidedR (OneSidedLocalRule.not φ) YS_def_2) = AnyFormula.normal φ
- principalFormulaForLocalRule (LocalRule.oneSidedR (OneSidedLocalRule.neg φ) YS_def_2) = AnyFormula.normal (~~φ)
- principalFormulaForLocalRule (LocalRule.oneSidedR (OneSidedLocalRule.nCo φ ψ) YS_def_2) = AnyFormula.normal (~(φ ⋀ ψ))
- principalFormulaForLocalRule (LocalRule.oneSidedR (OneSidedLocalRule.dia α φ notAtom) YS_def_2) = AnyFormula.normal (~⌈α⌉φ)
- principalFormulaForLocalRule (LocalRule.oneSidedR (OneSidedLocalRule.box α φ notAtom) YS_def_2) = AnyFormula.normal (⌈α⌉φ)
- principalFormulaForLocalRule (LocalRule.LRnegL φ) = AnyFormula.normal φ
- principalFormulaForLocalRule (LocalRule.LRnegR φ) = AnyFormula.normal φ
- principalFormulaForLocalRule (LocalRule.loadedL φ lrule YS_def) = AnyFormula.loaded φ
- principalFormulaForLocalRule (LocalRule.loadedR φ lrule YS_def) = AnyFormula.loaded φ
Instances For
Applying a LoadRule on the left will leave the right unchanged.
Applying a LoadRule on the right will leave the left unchanged.
Applying a LoadRule on the left preserves satisfiability of the left,
even together with any other list of formulas as context.
Applying a LoadRule on the right preserves satisfiability of the right,
even together with any other list of formulas as context.
Local Rule Applications #
Equations
- One or more equations did not get rendered due to their size.
Instances For
If we can apply a local rule to a sequent then it cannot be basic.
For a given non-basic formula in the left list L,
construct a LocalRuleApp using an appropriate OneSidedLocalRule.
Equations
- One or more equations did not get rendered due to their size.
- localRuleApp_of_nonbasic_in_L L R O (·n) f_in_2 f_nonBas_2 = ⋯.elim
- localRuleApp_of_nonbasic_in_L L R O (~Formula.bottom) f_in_3 f_nonBas_3 = ⋯.elim
- localRuleApp_of_nonbasic_in_L L R O (~·n) f_in_3 f_nonBas_3 = ⋯.elim
Instances For
For a given non-basic formula in the right list R,
construct a LocalRuleApp using an appropriate OneSidedLocalRule.
Equations
- One or more equations did not get rendered due to their size.
- localRuleApp_of_nonbasic_in_R L R O (·n) f_in_2 f_nonBas_2 = ⋯.elim
- localRuleApp_of_nonbasic_in_R L R O (~Formula.bottom) f_in_3 f_nonBas_3 = ⋯.elim
- localRuleApp_of_nonbasic_in_R L R O (~·n) f_in_3 f_nonBas_3 = ⋯.elim
Instances For
A sequent is basic iff no local rule can be applied.
Note that in the paper (L+) and (L-) are also local rules and had to be excluded
here, but here in the Lean formalization they are PdlRules anyway.
Local rule applications preserve atomic formulas #
Every formula at the source of a local rule is either retained by a chosen child or is the principal formula and has the closure data required for saturatedness in that child.
Saturated and Locally Consistent Sets of Formulas #
A set of formulas is saturated if it is closed under:
removing double negations, splitting (negated) conjunctions,
unfolding boxes using any test profile, and unfolding diamonds using H.
Part of Def 6.2
Equations
- One or more equations did not get rendered due to their size.
Instances For
LocalRuleApp preserves saturatedness backwards.
A free diamond at the source of a local rule application is either kept in the chosen child,
or it is the principal formula, and then the child contains one of its unfoldings.
Analogous to LocalRuleApp.formula_preserved_or_expanded, but for Sequent.wForms, i.e. here
we also know that the formulas in the child occur unloaded. (This is why we cannot obtain this
lemma from LocalRuleApp.formula_preserved_or_expanded: the latter uses Sequent.bothSides,
where a formula may also come from unloading the loaded formula of a sequent.)
A loaded diamond at the source of a local rule application is either kept in the chosen child,
or it is the principal formula, and then the child contains one of the results of the LoadRule
that was applied to it.
This is the loaded analogue of LocalRuleApp.wForms_negBox_preserved_or_unfolded.
The only LoadRule applicable to ~'⌊α⌋χ for a loaded χ is LoadRule.dia.
The only LoadRule applicable to ~'⌊α⌋φ for a normal φ is LoadRule.dia'.
Local rule applications preserve basic formulas: no local rule with children can have
a basic formula as its principal formula.
Note that ⊥ is not basic, for that case see LocalRuleApp.preserve_bottom_down.
Local rules never load a formula: if the sequent we apply a local rule to is free,
then so are all children. (The rules loadedL and loadedR are not applicable to a free
sequent, and all other local rules leave the Olf component unchanged.)