Imports
General CLIQUE verifier: canonical lookup header
This module connects query loading to the graph edge suffix. The instance's vertex-count and target-size fields are skipped without disturbing the two persistent query counters.
noncomputable sectionopen StateTransitionnamespace CLRS.Chapter34.Turing.GeneralCliqueVerifier.EdgeLookupopen PolyBuilderprivate theorem map_prependCliqueTicks (count : Nat)
(suffix : List CliqueSym) :
(prependCliqueTicks count suffix).map some =
List.replicate count (some .tick) ++ suffix.map some := by
induction count with
| zero => rfl
| succ count ih =>
simp [prependCliqueTicks, List.replicate_succ, ih]Skip a canonical vertex-count field.
def vertexField_run (remaining left right : Nat)
(rest : List (Option CliqueSym))
(buffer₁ buffer₂ : Option (Option CliqueSym)) (test : Bool) :
EvalsToInTime (step program)
(cfg .vertexField buffer₁ buffer₂ test
(List.replicate remaining (some .tick) ++ some .fieldSep :: rest) []
(List.replicate left ()) (List.replicate right ()) [])
(some (cfg .targetField (some (some .fieldSep)) buffer₂ test rest []
(List.replicate left ()) (List.replicate right ()) []))
(remaining + 1) := by
induction remaining generalizing buffer₁ with
| zero =>
exact ⟨⟨1, by
simp [flip, step, program, cfg, stepOp]⟩, le_rfl⟩
| succ remaining ih =>
let after := cfg .vertexField (some (some .tick)) buffer₂ test
(List.replicate remaining (some .tick) ++ some .fieldSep :: rest) []
(List.replicate left ()) (List.replicate right ()) []
have first : EvalsToInTime (step program)
(cfg .vertexField buffer₁ buffer₂ test
(List.replicate (remaining + 1) (some .tick) ++
some .fieldSep :: rest) []
(List.replicate left ()) (List.replicate right ()) [])
(some after) 1 := by
exact ⟨⟨1, by
simp [flip, after, List.replicate_succ, step, program, cfg,
stepOp]⟩, le_rfl⟩
have restRun := ih (some (some .tick))
let full := EvalsToInTime.trans (step program)
1 (remaining + 1) _ after _ first restRun
simpa [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm] using fullSkip a canonical target-size field and enter the edge scanner.
def targetField_run (remaining left right : Nat)
(rest : List (Option CliqueSym))
(buffer₁ buffer₂ : Option (Option CliqueSym)) (test : Bool) :
EvalsToInTime (step program)
(cfg .targetField buffer₁ buffer₂ test
(List.replicate remaining (some .tick) ++ some .fieldSep :: rest) []
(List.replicate left ()) (List.replicate right ()) [])
(some (cfg .edges (some (some .fieldSep)) buffer₂ test rest []
(List.replicate left ()) (List.replicate right ()) []))
(remaining + 1) := by
induction remaining generalizing buffer₁ with
| zero =>
exact ⟨⟨1, by
simp [flip, step, program, cfg, stepOp]⟩, le_rfl⟩
| succ remaining ih =>
let after := cfg .targetField (some (some .tick)) buffer₂ test
(List.replicate remaining (some .tick) ++ some .fieldSep :: rest) []
(List.replicate left ()) (List.replicate right ()) []
have first : EvalsToInTime (step program)
(cfg .targetField buffer₁ buffer₂ test
(List.replicate (remaining + 1) (some .tick) ++
some .fieldSep :: rest) []
(List.replicate left ()) (List.replicate right ()) [])
(some after) 1 := by
exact ⟨⟨1, by
simp [flip, after, List.replicate_succ, step, program, cfg,
stepOp]⟩, le_rfl⟩
have restRun := ih (some (some .tick))
let full := EvalsToInTime.trans (step program)
1 (remaining + 1) _ after _ first restRun
simpa [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm] using fullExact cost of loading a canonical query and skipping the instance header.
def headerSteps (query : Nat × Nat) (I : CliqueInstance) : Nat :=
1 + (2 * query.1 + 1) + (2 * query.2 + 1) + 1 + 1 +
(I.vertexCount + 1) + (I.targetSize + 1)A canonical query-instance pair reaches the edge suffix with both query endpoints resident in counters one and two.
def header_run (query : Nat × Nat) (I : CliqueInstance) :
EvalsToInTime (step program)
(cfg .queryMark none none false
(pairEncoding (encodeCliqueEdge query) (encodeCliqueInstance I)) []
[] [] [])
(some (cfg .edges (some (some .fieldSep)) none false
((I.edges.flatMap encodeCliqueEdge).map some) []
(List.replicate query.1 ()) (List.replicate query.2 ()) []))
(headerSteps query I) := by
let instanceStream := (encodeCliqueInstance I).map some
let edgeStream := (I.edges.flatMap encodeCliqueEdge).map some
let targetStream :=
List.replicate I.targetSize (some CliqueSym.tick) ++
some .fieldSep :: edgeStream
let queryRightStream :=
List.replicate query.2 (some CliqueSym.tick) ++
some .recordEnd :: none :: instanceStream
let afterMark := cfg .queryLeft (some (some .edgeMark)) none false
(List.replicate query.1 (some .tick) ++
some .pairSep :: queryRightStream) [] [] [] []
have first : EvalsToInTime (step program)
(cfg .queryMark none none false
(pairEncoding (encodeCliqueEdge query) (encodeCliqueInstance I)) []
[] [] [])
(some afterMark) 1 := by
exact ⟨⟨1, by
simp [flip, afterMark, queryRightStream, instanceStream, pairEncoding,
encodeCliqueEdge, map_prependCliqueTicks, step, program, cfg,
stepOp, List.append_assoc]⟩, le_rfl⟩
have loadLeft := queryLeft_run query.1 0 0 queryRightStream
(some (some .edgeMark)) none false
have loadLeft' : EvalsToInTime (step program) afterMark
(some (cfg .queryRight (some (some .pairSep)) none false
queryRightStream [] (List.replicate query.1 ()) [] []))
(2 * query.1 + 1) := by
simpa [afterMark] using loadLeft
let throughLeft := EvalsToInTime.trans (step program)
1 (2 * query.1 + 1) _ afterMark _ first loadLeft'
have loadRight := queryRight_run query.1 query.2 0
(none :: instanceStream) (some (some .pairSep)) none false
have loadRight' : EvalsToInTime (step program)
(cfg .queryRight (some (some .pairSep)) none false queryRightStream []
(List.replicate query.1 ()) [] [])
(some (cfg .pairSeparator (some (some .recordEnd)) none false
(none :: instanceStream) [] (List.replicate query.1 ())
(List.replicate query.2 ()) []))
(2 * query.2 + 1) := by
simpa [queryRightStream] using loadRight
let throughRight := EvalsToInTime.trans (step program)
(1 + (2 * query.1 + 1)) (2 * query.2 + 1) _ _ _
(by simpa [Nat.add_comm] using throughLeft) loadRight'
let afterPair := cfg .instanceMark (some none) none false instanceStream []
(List.replicate query.1 ()) (List.replicate query.2 ()) []
have pairStep : EvalsToInTime (step program)
(cfg .pairSeparator (some (some .recordEnd)) none false
(none :: instanceStream) [] (List.replicate query.1 ())
(List.replicate query.2 ()) [])
(some afterPair) 1 := by
exact ⟨⟨1, by
simp [flip, afterPair, step, program, cfg, stepOp]⟩, le_rfl⟩
let throughPair := EvalsToInTime.trans (step program)
(1 + (2 * query.1 + 1) + (2 * query.2 + 1)) 1 _ _ _
(by simpa [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
using throughRight) pairStep
let afterInstance := cfg .vertexField (some (some .instanceMark)) none false
(List.replicate I.vertexCount (some .tick) ++
some .fieldSep :: targetStream) []
(List.replicate query.1 ()) (List.replicate query.2 ()) []
have instanceStep : EvalsToInTime (step program) afterPair
(some afterInstance) 1 := by
exact ⟨⟨1, by
simp [flip, afterPair, afterInstance, instanceStream, targetStream,
edgeStream, encodeCliqueInstance, map_prependCliqueTicks, step, program, cfg,
stepOp]⟩, le_rfl⟩
let throughInstance := EvalsToInTime.trans (step program)
(1 + (2 * query.1 + 1) + (2 * query.2 + 1) + 1) 1 _ _ _
(by simpa [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
using throughPair) instanceStep
have skipVertices := vertexField_run I.vertexCount query.1 query.2
targetStream (some (some .instanceMark)) none false
have skipVertices' : EvalsToInTime (step program) afterInstance
(some (cfg .targetField (some (some .fieldSep)) none false
targetStream [] (List.replicate query.1 ())
(List.replicate query.2 ()) []))
(I.vertexCount + 1) := by
simpa [afterInstance] using skipVertices
let throughVertices := EvalsToInTime.trans (step program)
(1 + (2 * query.1 + 1) + (2 * query.2 + 1) + 1 + 1)
(I.vertexCount + 1) _ _ _
(by simpa [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
using throughInstance) skipVertices'
have skipTarget := targetField_run I.targetSize query.1 query.2 edgeStream
(some (some .fieldSep)) none false
have skipTarget' : EvalsToInTime (step program)
(cfg .targetField (some (some .fieldSep)) none false targetStream []
(List.replicate query.1 ()) (List.replicate query.2 ()) [])
(some (cfg .edges (some (some .fieldSep)) none false edgeStream []
(List.replicate query.1 ()) (List.replicate query.2 ()) []))
(I.targetSize + 1) := by
simpa [targetStream] using skipTarget
let full := EvalsToInTime.trans (step program)
(1 + (2 * query.1 + 1) + (2 * query.2 + 1) + 1 + 1 +
(I.vertexCount + 1))
(I.targetSize + 1) _ _ _
(by simpa [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
using throughVertices) skipTarget'
simpa [headerSteps, edgeStream, Nat.add_assoc, Nat.add_comm,
Nat.add_left_comm] using fullend CLRS.Chapter34.Turing.GeneralCliqueVerifier.EdgeLookup