Imports
import CLRSLean.Chapter_34.Section_34_4_NP_Completeness_Proofs.PolyBuilder.UnaryFrameStatefulMap
import Mathlib.Data.List.DropRight
import Mathlib.TacticDropping a fixed value suffix from unary-frame rows
Stack push routing removes a verifier-fixed number of values from the end of each runtime row. A left-to-right finite-state pass cannot decide that a value belongs to the suffix until it sees the row boundary. This controller therefore reverses the complete family, deletes the fixed value prefix of each reversed row, and reverses the result again. The middle pass still uses only finite control, so the complete construction is polynomial time.
noncomputable sectionnamespace CLRS.Chapter34.Turing.PolyBuilderRow-major input encoding with one outer marker after each value row.
def encodeUnaryFrameFixedSuffixDropInput (rows : List (List Nat)) :
List UnaryFrameSym :=
rows.flatMap fun row => encodeUnaryFrame row ++ [.frameEnd]
Row-major target after deleting amount values from the end of every row.
def encodeUnaryFrameFixedSuffixDropOutput (amount : Nat)
(rows : List (List Nat)) : List UnaryFrameSym :=
rows.flatMap fun row => encodeUnaryFrame (row.rdrop amount) ++ [.frameEnd]Unary values as they occur after reversing an ordinary unary frame: the separator precedes the ticks and the value order is already reversed.
def encodeReversedUnaryFrameValues (values : List Nat) :
List UnaryFrameSym :=
values.flatMap fun value => .separator :: List.replicate value .tick
@[simp] theorem encodeUnaryFrame_reverse (values : List Nat) :
(encodeUnaryFrame values).reverse =
encodeReversedUnaryFrameValues values.reverse := by
rw [show (encodeUnaryFrame values).reverse =
values.reverse.flatMap (List.reverse ∘ encodeUnaryFrameBlock) by
simp [encodeUnaryFrame, List.reverse_flatMap]]
unfold encodeReversedUnaryFrameValues
apply List.flatMap_congr
intro value hvalue
simp [encodeUnaryFrameBlock, List.reverse_append]Reversed row-family representation. Each row marker now precedes its separator-first reversed value stream.
def encodeUnaryFrameFixedSuffixDropReversed (rows : List (List Nat)) :
List UnaryFrameSym :=
rows.flatMap fun row => .frameEnd :: (encodeUnaryFrame row).reverse
theorem encodeUnaryFrameFixedSuffixDropInput_reverse
(rows : List (List Nat)) :
(encodeUnaryFrameFixedSuffixDropInput rows).reverse =
encodeUnaryFrameFixedSuffixDropReversed rows.reverse := by
rw [show (encodeUnaryFrameFixedSuffixDropInput rows).reverse =
rows.reverse.flatMap
(List.reverse ∘ fun row => encodeUnaryFrame row ++ [.frameEnd]) by
simp [encodeUnaryFrameFixedSuffixDropInput, List.reverse_flatMap]]
unfold encodeUnaryFrameFixedSuffixDropReversed
apply List.flatMap_congr
intro row hrow
simp [List.reverse_append]
theorem encodeUnaryFrameFixedSuffixDropOutput_reverse
(amount : Nat) (rows : List (List Nat)) :
(encodeUnaryFrameFixedSuffixDropOutput amount rows).reverse =
encodeUnaryFrameFixedSuffixDropReversed
((rows.map fun row => row.rdrop amount).reverse) := by
rw [show (encodeUnaryFrameFixedSuffixDropOutput amount rows).reverse =
rows.reverse.flatMap
(List.reverse ∘ fun row =>
encodeUnaryFrame (row.rdrop amount) ++ [.frameEnd]) by
simp [encodeUnaryFrameFixedSuffixDropOutput, List.reverse_flatMap]]
unfold encodeUnaryFrameFixedSuffixDropReversed
rw [← List.map_reverse]
rw [List.flatMap_map]
apply List.flatMap_congr
intro row hrow
simp [List.reverse_append]Finite-control modes for the separator-first middle pass.
inductive UnaryFrameReversedPrefixDropMode (amount : Nat)
| boundary
| dropping (remaining : Fin (amount + 1))
| droppingTicks (remaining : Fin (amount + 1))
| preserving
deriving DecidableEq, Fintypedef unaryFrameReversedPrefixDropInitialRemaining (amount : Nat) :
Fin (amount + 1) :=
⟨amount, by omega⟩private def unaryFrameReversedPrefixDropPred {amount : Nat}
(remaining : Fin (amount + 1)) (_hpositive : remaining.val ≠ 0) :
Fin (amount + 1) :=
⟨remaining.val - 1, by omega⟩One middle-pass action. A row boundary resets the fixed counter. While the counter is positive, separators and the ticks following them are erased. After the last deleted value, the remaining reversed row is copied exactly.
def unaryFrameReversedPrefixDropAction (amount : Nat)
(mode : UnaryFrameReversedPrefixDropMode amount)
(symbol : UnaryFrameSym) :
Option UnaryFrameSym × UnaryFrameReversedPrefixDropMode amount :=
match symbol with
| .frameEnd =>
(some .frameEnd,
.dropping (unaryFrameReversedPrefixDropInitialRemaining amount))
| .tick =>
match mode with
| .boundary => (some .tick, .boundary)
| .dropping remaining =>
if remaining.val = 0 then (some .tick, .preserving)
else (none, .dropping remaining)
| .droppingTicks remaining => (none, .droppingTicks remaining)
| .preserving => (some .tick, .preserving)
| .separator =>
match mode with
| .boundary => (some .separator, .boundary)
| .dropping remaining =>
if hzero : remaining.val = 0 then
(some .separator, .preserving)
else
(none, .droppingTicks
(unaryFrameReversedPrefixDropPred remaining hzero))
| .droppingTicks remaining =>
if hzero : remaining.val = 0 then
(some .separator, .preserving)
else
(none, .droppingTicks
(unaryFrameReversedPrefixDropPred remaining hzero))
| .preserving => (some .separator, .preserving)def unaryFrameReversedPrefixDropSpec (amount : Nat) :
UnaryFrameStatefulMapSpec (UnaryFrameReversedPrefixDropMode amount) :=
{ initial := .boundary
action := unaryFrameReversedPrefixDropAction amount }def rewriteUnaryFrameReversedPrefixDrop (amount : Nat)
(input : List UnaryFrameSym) : List UnaryFrameSym :=
rewriteUnaryFrameStateful (unaryFrameReversedPrefixDropSpec amount) inputprivate def IsUnaryFrameBoundaryTail : List UnaryFrameSym → Prop
| [] => True
| .frameEnd :: _ => True
| _ => Falseprivate theorem reversedPrefixDrop_mode_eq_boundary
(amount : Nat) (mode : UnaryFrameReversedPrefixDropMode amount)
(tail : List UnaryFrameSym) (htail : IsUnaryFrameBoundaryTail tail) :
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) mode tail =
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .boundary tail := by
cases tail with
| nil => rfl
| cons symbol rest =>
cases symbol <;>
simp_all [IsUnaryFrameBoundaryTail,
rewriteUnaryFrameStatefulFrom,
unaryFrameReversedPrefixDropSpec,
unaryFrameReversedPrefixDropAction]private theorem reversedPrefixDrop_preserving_ticks
(amount count : Nat) (tail : List UnaryFrameSym) :
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .preserving
(List.replicate count .tick ++ tail) =
List.replicate count .tick ++
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .preserving tail := by
induction count with
| zero => rfl
| succ count ih =>
simp only [List.replicate_succ, List.cons_append,
rewriteUnaryFrameStatefulFrom,
unaryFrameReversedPrefixDropSpec,
unaryFrameReversedPrefixDropAction]
exact congrArg (List.cons .tick) ihprivate theorem reversedPrefixDrop_dropping_ticks
(amount count : Nat) (remaining : Fin (amount + 1))
(tail : List UnaryFrameSym) :
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) (.droppingTicks remaining)
(List.replicate count .tick ++ tail) =
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) (.droppingTicks remaining)
tail := by
induction count with
| zero => rfl
| succ count ih =>
simp only [List.replicate_succ, List.cons_append,
rewriteUnaryFrameStatefulFrom,
unaryFrameReversedPrefixDropSpec,
unaryFrameReversedPrefixDropAction]
exact ih
private theorem reversedPrefixDrop_preserving_values
(amount : Nat) (values : List Nat) (tail : List UnaryFrameSym)
(htail : IsUnaryFrameBoundaryTail tail) :
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .preserving
(encodeReversedUnaryFrameValues values ++ tail) =
encodeReversedUnaryFrameValues values ++
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .boundary tail := by
induction values with
| nil =>
simpa [encodeReversedUnaryFrameValues] using
reversedPrefixDrop_mode_eq_boundary amount .preserving tail htail
| cons value rest ih =>
simp only [encodeReversedUnaryFrameValues, List.flatMap_cons]
simp only [unaryFrameReversedPrefixDropSpec]
change .separator ::
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .preserving
(List.replicate value .tick ++
encodeReversedUnaryFrameValues rest ++ tail) = _
rw [show List.replicate value UnaryFrameSym.tick ++
encodeReversedUnaryFrameValues rest ++ tail =
List.replicate value UnaryFrameSym.tick ++
(encodeReversedUnaryFrameValues rest ++ tail) by
simp [List.append_assoc]]
rw [reversedPrefixDrop_preserving_ticks amount value
(encodeReversedUnaryFrameValues rest ++ tail)]
rw [ih]
simp [encodeReversedUnaryFrameValues,
unaryFrameReversedPrefixDropSpec, List.append_assoc]
private theorem reversedPrefixDrop_droppingTicks_values_eq
(amount : Nat) (remaining : Fin (amount + 1))
(values : List Nat) (tail : List UnaryFrameSym)
(htail : IsUnaryFrameBoundaryTail tail) :
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) (.droppingTicks remaining)
(encodeReversedUnaryFrameValues values ++ tail) =
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) (.dropping remaining)
(encodeReversedUnaryFrameValues values ++ tail) := by
cases values with
| nil =>
simp only [encodeReversedUnaryFrameValues, List.flatMap_nil,
List.nil_append]
rw [reversedPrefixDrop_mode_eq_boundary amount
(.droppingTicks remaining) tail htail]
rw [reversedPrefixDrop_mode_eq_boundary amount
(.dropping remaining) tail htail]
| cons value rest =>
simp only [encodeReversedUnaryFrameValues, List.flatMap_cons,
List.cons_append, rewriteUnaryFrameStatefulFrom,
unaryFrameReversedPrefixDropSpec,
unaryFrameReversedPrefixDropAction]
private theorem reversedPrefixDrop_values
(amount : Nat) (remaining : Fin (amount + 1))
(values : List Nat) (tail : List UnaryFrameSym)
(htail : IsUnaryFrameBoundaryTail tail) :
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) (.dropping remaining)
(encodeReversedUnaryFrameValues values ++ tail) =
encodeReversedUnaryFrameValues (values.drop remaining.val) ++
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .boundary tail := by
induction values generalizing remaining with
| nil =>
simpa [encodeReversedUnaryFrameValues] using
reversedPrefixDrop_mode_eq_boundary amount
(.dropping remaining) tail htail
| cons value rest ih =>
simp only [encodeReversedUnaryFrameValues, List.flatMap_cons]
by_cases hzero : remaining.val = 0
· simp only [List.cons_append, rewriteUnaryFrameStatefulFrom,
unaryFrameReversedPrefixDropSpec,
unaryFrameReversedPrefixDropAction, hzero, ↓reduceDIte]
change .separator ::
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .preserving
(List.replicate value .tick ++
encodeReversedUnaryFrameValues rest ++ tail) = _
rw [show List.replicate value UnaryFrameSym.tick ++
encodeReversedUnaryFrameValues rest ++ tail =
List.replicate value UnaryFrameSym.tick ++
(encodeReversedUnaryFrameValues rest ++ tail) by
simp [List.append_assoc]]
rw [reversedPrefixDrop_preserving_ticks amount value
(encodeReversedUnaryFrameValues rest ++ tail)]
rw [reversedPrefixDrop_preserving_values amount rest tail htail]
simp only [List.drop_zero]
simp [encodeReversedUnaryFrameValues,
unaryFrameReversedPrefixDropSpec, List.append_assoc]
· simp only [List.cons_append, rewriteUnaryFrameStatefulFrom,
unaryFrameReversedPrefixDropSpec,
unaryFrameReversedPrefixDropAction, hzero, ↓reduceDIte]
change rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount)
(.droppingTicks
(unaryFrameReversedPrefixDropPred remaining hzero))
(List.replicate value .tick ++
encodeReversedUnaryFrameValues rest ++ tail) = _
rw [show List.replicate value UnaryFrameSym.tick ++
encodeReversedUnaryFrameValues rest ++ tail =
List.replicate value UnaryFrameSym.tick ++
(encodeReversedUnaryFrameValues rest ++ tail) by
simp [List.append_assoc]]
rw [reversedPrefixDrop_dropping_ticks amount value
(unaryFrameReversedPrefixDropPred remaining hzero)
(encodeReversedUnaryFrameValues rest ++ tail)]
rw [reversedPrefixDrop_droppingTicks_values_eq amount
(unaryFrameReversedPrefixDropPred remaining hzero) rest tail htail]
rw [ih (unaryFrameReversedPrefixDropPred remaining hzero)]
have hremaining :
remaining.val =
(unaryFrameReversedPrefixDropPred remaining hzero).val + 1 := by
simp [unaryFrameReversedPrefixDropPred]
omega
rw [hremaining]
simp only [List.drop_succ_cons]
simp only [encodeReversedUnaryFrameValues,
unaryFrameReversedPrefixDropSpec]
private theorem suffixDrop_reversed_family
(amount : Nat) (rows : List (List Nat)) :
rewriteUnaryFrameReversedPrefixDrop amount
(encodeUnaryFrameFixedSuffixDropReversed rows) =
encodeUnaryFrameFixedSuffixDropReversed
(rows.map fun row => row.rdrop amount) := by
unfold rewriteUnaryFrameReversedPrefixDrop rewriteUnaryFrameStateful
induction rows with
| nil => rfl
| cons row rest ih =>
simp only [encodeUnaryFrameFixedSuffixDropReversed, List.flatMap_cons,
List.map_cons]
rw [show
(.frameEnd :: (encodeUnaryFrame row).reverse) ++
rest.flatMap (fun item =>
.frameEnd :: (encodeUnaryFrame item).reverse) =
.frameEnd :: ((encodeUnaryFrame row).reverse ++
rest.flatMap (fun item =>
.frameEnd :: (encodeUnaryFrame item).reverse)) by simp]
simp only [rewriteUnaryFrameStatefulFrom,
unaryFrameReversedPrefixDropSpec,
unaryFrameReversedPrefixDropAction]
rw [encodeUnaryFrame_reverse]
change .frameEnd ::
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount)
(.dropping
(unaryFrameReversedPrefixDropInitialRemaining amount))
(encodeReversedUnaryFrameValues row.reverse ++
encodeUnaryFrameFixedSuffixDropReversed rest) = _
rw [reversedPrefixDrop_values amount
(unaryFrameReversedPrefixDropInitialRemaining amount) row.reverse
(encodeUnaryFrameFixedSuffixDropReversed rest)]
· change .frameEnd ::
(encodeReversedUnaryFrameValues (row.reverse.drop amount) ++
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .boundary
(encodeUnaryFrameFixedSuffixDropReversed rest)) = _
rw [show row.reverse.drop amount = (row.rdrop amount).reverse by
simp [List.rdrop_eq_reverse_drop_reverse]]
rw [← encodeUnaryFrame_reverse]
have ih' :
rewriteUnaryFrameStatefulFrom
(unaryFrameReversedPrefixDropSpec amount) .boundary
(encodeUnaryFrameFixedSuffixDropReversed rest) =
encodeUnaryFrameFixedSuffixDropReversed
(rest.map fun item => item.rdrop amount) := by
simpa [unaryFrameReversedPrefixDropSpec] using ih
rw [ih']
simp [encodeUnaryFrameFixedSuffixDropReversed]
· cases rest <;> simp [IsUnaryFrameBoundaryTail,
encodeUnaryFrameFixedSuffixDropReversed]Delete a fixed suffix from every row by reverse/filter/reverse.
def rewriteUnaryFrameFixedSuffixDrop (amount : Nat)
(input : List UnaryFrameSym) : List UnaryFrameSym :=
(rewriteUnaryFrameReversedPrefixDrop amount input.reverse).reverseExact semantics on every row-major unary-frame family.
theorem rewriteUnaryFrameFixedSuffixDrop_rows (amount : Nat)
(rows : List (List Nat)) :
rewriteUnaryFrameFixedSuffixDrop amount
(encodeUnaryFrameFixedSuffixDropInput rows) =
encodeUnaryFrameFixedSuffixDropOutput amount rows := by
unfold rewriteUnaryFrameFixedSuffixDrop
rw [encodeUnaryFrameFixedSuffixDropInput_reverse]
rw [suffixDrop_reversed_family]
rw [show (rows.reverse.map fun row => row.rdrop amount) =
(rows.map fun row => row.rdrop amount).reverse by simp]
rw [← encodeUnaryFrameFixedSuffixDropOutput_reverse]
simpDropping a verifier-fixed value suffix from every marked row is computed by a concrete polynomial-time TM2.
noncomputable def unaryFrameFixedSuffixDrop_computableInPolyTime
(amount : Nat) :
_root_.Turing.TM2ComputableInPolyTime id id
(rewriteUnaryFrameFixedSuffixDrop amount) := by
let reversed := reverse_computableInPolyTime (Γ := UnaryFrameSym)
let filtered := unaryFrameStatefulMap_computableInPolyTime
(unaryFrameReversedPrefixDropSpec amount)
let first := _root_.Turing.TM2Comp.TM2ComputableInPolyTime.comp_scratch
reversed filtered
let second := _root_.Turing.TM2Comp.TM2ComputableInPolyTime.comp_scratch
(Classical.choice first)
(reverse_computableInPolyTime (Γ := UnaryFrameSym))
let result := Classical.choice second
exact
{ tm := result.tm
inputAlphabet := result.inputAlphabet
outputAlphabet := result.outputAlphabet
time := result.time
outputsFun := fun input => by
have run := result.outputsFun input
simpa only [id_eq, Function.comp_apply,
rewriteUnaryFrameFixedSuffixDrop,
rewriteUnaryFrameReversedPrefixDrop] using run }end CLRS.Chapter34.Turing.PolyBuilder