Documentation

LeanPool.IsoGraph.Canon.Monotone

The incumbent never gets worse #

The search keeps one leaf, St.best, and replaces it only when it finds a better one. This file makes that precise: whatever the search ends up holding is at least as good as anything it held on the way.

There is one place where the incumbent is dropped rather than improved — pruneNode, when the node's invariant path already beats the incumbent's. That is still monotone, but only because of Progress.lean: the node is then guaranteed to come back with a leaf of its own subtree (dfsNode_best, dfsNode_reach), and every leaf of that subtree beats what was dropped (pruneNode_cleared). dfsNode_mono_cleared packages the two, and dfsNode_prune_shift — that clearing the incumbent does not change what the node does next — is what lets it be applied to the whole dfsNode call rather than to its innards.

The comparison used throughout is compare k k' ≠ .gt on leafKeys, the same order BestKey is stated with.

Order helpers #

Domination #

k is no better than the leaf the state holds.

Equations
Instances For

    The incumbent never gets worse.

    Equations
    Instances For
      theorem IsoGraph.Canon.Dom.mono {st st' : St} {k : List (List UInt64)} (h : Dom st k) (hm : BestMono st st') :
      Dom st' k
      theorem IsoGraph.Canon.BestMono.trans {st st' st'' : St} (h : BestMono st st') (h' : BestMono st' st'') :
      BestMono st st''
      theorem IsoGraph.Canon.BestMono.of_best_eq {st st' : St} (h : st'.best = st.best) :
      BestMono st st'

      leafUpdate improves the incumbent #

      theorem IsoGraph.Canon.leafUpdate_best_ge (G : Graph) (path : Array ) (invPath : Array UInt64) (lab : Array ) (st : St) :
      (leafUpdate G path invPath lab st).best = st.best (leafUpdate G path invPath lab st).best = some { path := path, invPath := invPath, cert := certOf G lab, lab := lab } ∀ (b : Leaf), st.best = some blexCmpU64 invPath b.invPath = Ordering.gt lexCmpU64 invPath b.invPath = Ordering.eq lexCmpU64 (certOf G lab) b.cert = Ordering.gt
      theorem IsoGraph.Canon.leafUpdate_mono (G : Graph) (path : Array ) (invPath : Array UInt64) (lab : Array ) (st : St) :
      BestMono st (leafUpdate G path invPath lab st)

      pruneNode only discards a dominated incumbent #

      theorem IsoGraph.Canon.pruneNode_mono {invPath : Array UInt64} {st st' : St} (h : pruneNode invPath st = some st') :
      st'.best = st.best st'.best = none ∀ (b : Leaf), st.best = some blexCmpU64 invPath (b.invPath.extract 0 invPath.size) = Ordering.gt
      theorem IsoGraph.Canon.pruneNode_cleared {n : } {f : Bool} {invPath : Array UInt64} {p : Part} {st st' : St} {b : Leaf} {k : List (List UInt64)} (h : pruneNode invPath st = some st') (hnone : st'.best = none) (hb : st.best = some b) (hk : Reach n f invPath p k) :

      When pruneNode throws the incumbent away, every leaf below the node beats it.

      theorem IsoGraph.Canon.pruneNode_mono' {invPath : Array UInt64} {st st' : St} (h : pruneNode invPath st = some st') :
      st' = st st' = { best := none, first := st.first, autos := st.autos, nodes := st.nodes, abortTo := st.abortTo } ∀ (b : Leaf), st.best = some blexCmpU64 invPath (b.invPath.extract 0 invPath.size) = Ordering.gt
      theorem IsoGraph.Canon.dfsNode_prune_shift {G : Graph} {fuel : } {path : Array } {invPath : Array UInt64} {p : Part} {st st' : St} (habort : st.abortTo.isSome = false) (hprune : pruneNode invPath st = some st') (hnone : st'.best = none) :
      dfsNode G (fuel + 1) path invPath p st = dfsNode G (fuel + 1) path invPath p st'

      Discarding the incumbent at a node does not change what the node does next.

      theorem IsoGraph.Canon.dfsNode_mono_cleared (n : ) (f : Bool) (fuel : ) (path : Array ) (invPath : Array UInt64) (p : Part) (st st' : St) (hp : Part.WF n p) (hfuel : n + 1 numCells n p + fuel) (habort : st.abortTo.isSome = false) (hprune : pruneNode invPath st = some st') (hnone : st'.best = none) :
      BestMono st (dfsNode (Graph.ofOracle n f) fuel path invPath p st)

      The clearing case of monotonicity: if the node throws the incumbent away, the leaf it comes back with is one from below the node, and every such leaf beats what was thrown away.

      theorem IsoGraph.Canon.dfsNode_mono (n : ) (f : Bool) (fuel : ) (path : Array ) (invPath : Array UInt64) (p : Part) (st : St) :
      Part.WF n pn + 1 numCells n p + fuelBestMono st (dfsNode (Graph.ofOracle n f) fuel path invPath p st)

      The incumbent never gets worse.