From winning strategies to model graphs, part 1: BuildTree and PreState (Section 6.3) #
Builder Strategy Tree #
Winning Strategy Tree for Builder. At each step, we consider
- ALL rules R that prover may choose, followed immediately by
- ONE of the children then chosen by Builder
The type is actually similar to Tableau, as it also uses a history, but it does allow open leaves.
For choosing a local tableau end node the mutual RuleChoice is needed to avoid the error
"nested inductive datatypes parameters cannot contain local variables".
Instead of the .lpr constructor here we have .fpr because we only make a RuleTree when Builder
wins and thus we can never reach an lpr where Prover would win, but do allow free repeats.
As in Tableau note that the history is stored in reverse.
- loc
{H : History}
{X : Sequent}
(nbas : ¬X.basic)
(someLT : OpenLocalTableau.all X ≠ [])
(next : (lt : OpenLocalTableau X) → BuildChoice H X (endNodesOf ↑lt))
: BuildTree H X
Prover chooses local tab, we pick an end node (which must exist as otherwise prover wins).
- pdl
{H : List Sequent}
{X : Sequent}
(bas : X.basic)
(someR : PdlRule.all X ≠ [])
(next : (Y : Sequent) → PdlRule X Y → BuildTree (X :: H) Y)
: BuildTree H X
Prover chooses PDL rule, never branches, so continue with unique child.
- freeRepeat
{H : History}
{X : Sequent}
: FreeRepeat H X → BuildTree H X
Free repeat means builder wins.
- openLeaf
{H : History}
{X : Sequent}
(bas : X.basic)
(noRule : PdlRule.all X = [])
: BuildTree H X
Leaf that is (might be?!) not a repeat, but no rules can be applied.
Instances For
Manual replacement for sizeOf (bt : BuildTree) so we also count the next parts.
Equations
- (BuildTree.loc nbas someLT next).size = 1 + (List.map (fun (lt : OpenLocalTableau X) => (next lt).size) (OpenLocalTableau.all X)).sum
- (BuildTree.pdl bas someR next).size = 1 + (List.map (fun (x : (Y : Sequent) × PdlRule X Y) => match x with | ⟨Y, r⟩ => (next Y r).size) (PdlRule.all X)).sum
- (BuildTree.freeRepeat a).size = 1
- (BuildTree.openLeaf bas noRule).size = 1
Instances For
Equations
- (BuildChoice.pick a bt_Y).size = bt_Y.size
Instances For
The node picked by Builder is one of the given ones.
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Given the proof rep H X and that X is free, find a FreeRepeat value / data.
(Previously here we tried to go from rep H X and ¬Nonempty (LoadedPathRepeat H X)
to FreeRepeat which does not work as there might still be loaded non-lpr repeats.)
Equations
- FreeRepeat.of_rep_free rp free = ⟨rp.toFin, ⋯⟩
Instances For
Given a winning Builder strategy, compute its BuildTree.
NEW: note the Sum.inl p here. This ensure we start tree building from a Prover position, i.e.
- not allowing BuilderPos.lpr here (easy, was forbidden already anyway as prover wins there.)
- not allowing BuilderPos.ltab because we cannot use BuildTree.loc for a single fixed local tab.
Equations
- One or more equations did not get rendered due to their size.
- buildTree s h_2 = BuildTree.freeRepeat (FreeRepeat.of_rep_free ⋯ ⋯)
Instances For
Matches #
A match is a path inside a BuildTree. Analogous to PathIn for Tableau. In Game Theory
this could be called a "rollout", but note that it stays within the given Builder strategy tree
and it is not tracking all intermediate game positions.
- nil {H : History} {X : Sequent} {bt : BuildTree H X} : Match bt
- loc {H : History} {X : Sequent} {nbas : ¬X.basic} {someLT : OpenLocalTableau.all X ≠ []} {next : (lt : OpenLocalTableau X) → BuildChoice H X (endNodesOf ↑lt)} {lt : OpenLocalTableau X} : Match (next lt).6 → Match (BuildTree.loc nbas someLT next)
- pdl {H : List Sequent} {X : Sequent} {bas : X.basic} {someR : PdlRule.all X ≠ []} {next : (Y : Sequent) → PdlRule X Y → BuildTree (X :: H) Y} {Y : Sequent} {r : PdlRule X Y} : Match (next Y r) → Match (BuildTree.pdl bas someR next)
Instances For
Equations
- One or more equations did not get rendered due to their size.
- instDecidableEqMatch.decEq Match.nil Match.nil = isTrue ⋯
- instDecidableEqMatch.decEq Match.nil a_1.loc = isFalse ⋯
- instDecidableEqMatch.decEq Match.nil a_1.pdl = isFalse ⋯
- instDecidableEqMatch.decEq a_1.loc Match.nil = isFalse ⋯
- instDecidableEqMatch.decEq a_1.pdl Match.nil = isFalse ⋯
Instances For
Equations
- Match.all (BuildTree.loc nbas someLT next) = Match.nil :: do let ltX ← OpenLocalTableau.all X let __do_lift ← Match.all (next ltX).6 pure __do_lift.loc
- Match.all (BuildTree.pdl bas someR next) = Match.nil :: do let x ← PdlRule.all X match x with | ⟨Y, r⟩ => do let __do_lift ← Match.all (next Y r) pure __do_lift.pdl
- Match.all (BuildTree.freeRepeat a) = [Match.nil]
- Match.all (BuildTree.openLeaf bas noRule) = [Match.nil]
Instances For
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Get the FreeRepeat (rewind-index and same-sequent proof) of a Match.
Equations
Instances For
Roll back to the companion. Only possibe if we started with H=[] so we know the root.
The + 1 is there because the FreeRepeat values are indices of the history starting with 0,
but Match.rewind 0 would do nothing. (Same as the .succ in companionOf for PathIn.)
Equations
Instances For
Rewinding a Match by k steps gives the k-th element of the history,
where the end sequent of the match itself is counted as the 0-th element.
Inspired by PathIn.nodeAt_rewind_eq_toHistory_get.
The repeat ♥ companion relation on Match.
Equations
- m.companion n = ∃ (h : m.isFreeRepeat), n = m.companionOf h
Instances For
Going to the companion of a free repeat gives a strictly shorter Match.
Collecting Sequents for Pre-states #
As possible worlds for the model graph we want to define maximal paths inside the build tree that do not contain (M), (L+) or (L-) steps.
We collect the sequents along such paths directly by induction on the BuildTree.
Collect pre-states in the whole BuildTree. The local pre-states come from paths in a local tableau, and PDL pre-states each consist of just a single node.
Equations
- (BuildTree.loc nbas someLT next).collect = List.flatMap (fun (lt : OpenLocalTableau X) => (↑lt).pathsTo (next lt).4 ++ (next lt).6.collect) (OpenLocalTableau.all X)
- (BuildTree.pdl bas someR next).collect = [[X]] ++ List.flatMap (fun (x : (Y : Sequent) × PdlRule X Y) => match x with | ⟨Y, r⟩ => (next Y r).collect) (PdlRule.all X)
- (BuildTree.freeRepeat a).collect = []
- (BuildTree.openLeaf bas noRule).collect = [[X]]
Instances For
Any BuildTree that is not a free repeat collects at least one list containing its root.
Generalisation of BuildTree.collect_contains_root to non-empty histories.
Pre-states (Def 6.13) #
Collecting Formulas in Pre-state Sequents #
Λ(π) gets all formulas for a pre-state but keep the information what is loaded.
Returns the WhateverFormula type so that lemmas like 6.15 and 6.18 are sayable.
Instances For
Characterizing three different ways in which a formula can be in PreState.forms.
PreStates to Matches and back again #
To prove the existence lemmas we first make some helper definitions and lemmas that
allow us to switch between PreStates & Matches.
The result of BuildTree.collect in any sub-BuildTree reached by a Match
is also part of BuildTree.collect applied to the bigger BuildTree.
The Boolean predicate used by Match.toPreState: does the given list of sequents
contain a sequent that is setEqTo the end of the given Match?
Instances For
Reformulation of Match.existsPreState using Match.fitsPreState.
Thanks to Match.existsPreState the search for a fitting pre-state succeeds.
Pick a PreState for a given Match, using Match.existsPreState and List.find?.
Equations
- m.toPreState = ⟨(List.find? m.fitsPreState bt.collect).get ⋯, ⋯⟩
Instances For
The result of Match.toPreState indeed contains a sequent setEqTo the end of the Match.
Search for the node in bt at which the list p of sequents is collected, and return the
Match leading to that node. Auxiliary function for PreState.toMatch, defined for all lists
p of sequents. If p is not collected anywhere, then we return Match.nil as a dummy value.
Equations
- One or more equations did not get rendered due to their size.
- (BuildTree.freeRepeat a).toMatchAux x✝ = Match.nil
- (BuildTree.openLeaf bas noRule).toMatchAux x✝ = Match.nil
Instances For
Specification of PreState.toMatch, part three: the sequent at the node reached by the
match is the head of the pre-state. (Reformulation of PreState.toMatch_head.)
Not only the first sequent of a pre-state is reached by a Match (this is
PreState.toMatch), also the last sequent of a pre-state is reached by some Match.
Both ends of a pre-state are reached by matches, and the match reaching the last sequent
extends the one reaching the first sequent: the continuation c is a Match inside the
sub-BuildTree at which π was collected, and appending it to π.toMatch gives a Match in
the whole tree that ends at the last sequent of π.
Weak round-trip that always holds: going from a pre-state to a match and back gives a
pre-state that contains a sequent set-equal to the first sequent of π.
Round-trip: under the assumption that π is the only collected list that contains a
sequent set-equal to the sequent at the node where π is collected, going to the match
and back gives π again.
Example where the uniq assumption of PreState.toMatch_toPreState is satisfied:
an open leaf collects only one pre-state, so there the round-trip does hold.
Properties of Formula (Sets? Lists?) obtained from Pre-States #
Every basic formula of a pre-state already occurs in the last (basic) sequent of that
pre-state. Note that bothSides is used here, so this also covers formulas from the loaded
part of a sequent.
Lemma 6.14, weakened version. The original statement says that φ is principal in a rule
applied later on. We do not have the rule applications available along a pre-state, so instead
we make the case distinction on whether φ is basic, and give the actual content for the
first case: any basic formula of a pre-state occurs already in its last sequent.
(We also use Sequent.bothSides instead of ∈ to include the loaded formula.)
Lemma 6.15 free case. #
The helper lemmas needed for it are in Pdl/Sequent.lean, Pdl/LocalRules.lean and
Pdl/LocalTableauPaths.lean.
Lemma 6.15 loaded cases. #
The helper lemmas needed for these are in Pdl/Sequent.lean, Pdl/LocalRules.lean and
Pdl/LocalTableauPaths.lean.
Generic version of the loaded case of Lemma 6.15: a non-atomic loaded diamond in a
pre-state must have been unfolded by a LoadRule somewhere in the pre-state.
The two versions below are the special cases for AnyFormula.loaded and AnyFormula.normal.
(Generalised from bt : BuildTree [] X to an arbitrary history H, as needed for the
recursion into sub-BuildTrees.)
Lemma 6.15 loaded case with more than one loaded box
Lemma 6.15 loaded case with only one loaded box.