Imports
Family-level parallel marked-row interleaving
The two local row-transfer theorems are lifted here to aligned row families. The result is an exact run which consumes both physical output stacks and places the reverse of the semantic interleaving on the merger scratch stack.
noncomputable sectionopen Computability StateTransitionnamespace CLRS.Chapter34.Turing.PolyBuilder
Raw frameEnd-delimited stream represented by a list of rows.
def encodeUnaryFrameMarkedRows (rows : List (List UnaryFrameSym)) :
List UnaryFrameSym :=
rows.flatMap fun row => row ++ [.frameEnd]@[simp] theorem encodeUnaryFrameMarkedRows_nil :
encodeUnaryFrameMarkedRows [] = [] := rfl@[simp] theorem encodeUnaryFrameMarkedRows_cons
(row : List UnaryFrameSym) (rows : List (List UnaryFrameSym)) :
encodeUnaryFrameMarkedRows (row :: rows) =
row ++ .frameEnd :: encodeUnaryFrameMarkedRows rows := by
simp [encodeUnaryFrameMarkedRows]namespace UnaryFrameMarkedRowParallelInterleavevariable {α Γ : Type} [Fintype Γ]variable {encode : α → List Γ}variable {leftFamily rightFamily : α → UnaryFrameMarkedRowFamily}variable
(M₁ : _root_.Turing.TM2ComputableInPolyTime encode
encodeUnaryFrameMarkedRowFamily leftFamily)
(M₂ : _root_.Turing.TM2ComputableInPolyTime encode
encodeUnaryFrameMarkedRowFamily rightFamily)The control state after processing all rows. An empty family performs no step; every nonempty aligned family ends immediately after a right boundary.
def mergeRowsFinalState (startState : ExtraState Γ) :
List (List UnaryFrameSym) → ExtraState Γ
| [] => startState
| _ :: _ => ExtraState.mergeSymbol UnaryFrameSym.frameEndExact number of symbol-transfer steps before the final empty-stack probe.
def mergeAlignedRowsSteps
(left right : List (List UnaryFrameSym)) : Nat :=
(encodeUnaryFrameMarkedRows left).length +
(encodeUnaryFrameMarkedRows right).lengthAligned delimiter-free row families are physically consumed in alternating order. Both source stacks become empty and the scratch contains the reverse of the semantic interleaving followed by its previous contents.
def merge_aligned_rows_run
(left right : List (List UnaryFrameSym))
(haligned : left.length = right.length)
(hleftFree : ∀ row ∈ left, ∀ symbol ∈ row,
symbol ≠ UnaryFrameSym.frameEnd)
(hrightFree : ∀ row ∈ right, ∀ symbol ∈ row,
symbol ≠ UnaryFrameSym.frameEnd)
{values : ∀ k : K M₁ M₂, List (StackAlphabet M₁ M₂ k)}
{temp : List UnaryFrameSym} (state : ExtraState Γ)
(hleft : values (firstOutputK M₁ M₂) =
List.map M₁.outputAlphabet.invFun
(encodeUnaryFrameMarkedRows left))
(hright : values (outputK M₁ M₂) =
List.map M₂.outputAlphabet.invFun
(encodeUnaryFrameMarkedRows right))
(htemp : values (outputTempK M₁ M₂) = temp) :
EvalsToInTime (machine M₁ M₂).step
(mergeCfg M₁ M₂ ExtraΛ.mergeLeft state values)
(some (mergeCfg M₁ M₂ ExtraΛ.mergeLeft
(mergeRowsFinalState state left)
(Function.update
(Function.update
(Function.update values (firstOutputK M₁ M₂) [])
(outputK M₁ M₂) [])
(outputTempK M₁ M₂)
((encodeUnaryFrameMarkedRows
(interleaveUnaryFrameMarkedRows left right)).reverse ++ temp))))
(mergeAlignedRowsSteps left right) := by
induction left generalizing right values temp state with
| nil =>
have hrightNil : right = [] :=
List.eq_nil_of_length_eq_zero haligned.symm
subst right
have hcollapse :
Function.update
(Function.update
(Function.update values (firstOutputK M₁ M₂) [])
(outputK M₁ M₂) [])
(outputTempK M₁ M₂) temp = values := by
funext key
by_cases h₁ : key = firstOutputK M₁ M₂
· subst key
simp [Function.update, hleft]
· by_cases h₂ : key = outputK M₁ M₂
· subst key
simp [Function.update, hright]
· by_cases h₃ : key = outputTempK M₁ M₂
· subst key
simp [Function.update, htemp]
· simp [Function.update, h₁, h₂, h₃]
refine ⟨⟨0, ?_⟩, le_rfl⟩
change some (mergeCfg M₁ M₂ ExtraΛ.mergeLeft state values) =
some (mergeCfg M₁ M₂ ExtraΛ.mergeLeft state
(Function.update
(Function.update
(Function.update values (firstOutputK M₁ M₂) [])
(outputK M₁ M₂) [])
(outputTempK M₁ M₂) temp))
exact congrArg
(fun stackValues => some
(mergeCfg M₁ M₂ ExtraΛ.mergeLeft state stackValues))
hcollapse.symm
| cons leftRow leftRows ih =>
cases right with
| nil => simp at haligned
| cons rightRow rightRows =>
have htailAligned : leftRows.length = rightRows.length := by
simpa using Nat.succ.inj haligned
have hleftRowFree : ∀ symbol ∈ leftRow,
symbol ≠ UnaryFrameSym.frameEnd := by
intro symbol hsymbol
exact hleftFree leftRow (by simp) symbol hsymbol
have hrightRowFree : ∀ symbol ∈ rightRow,
symbol ≠ UnaryFrameSym.frameEnd := by
intro symbol hsymbol
exact hrightFree rightRow (by simp) symbol hsymbol
have hleftRowsFree : ∀ row ∈ leftRows, ∀ symbol ∈ row,
symbol ≠ UnaryFrameSym.frameEnd := by
intro row hrow symbol hsymbol
exact hleftFree row (by simp [hrow]) symbol hsymbol
have hrightRowsFree : ∀ row ∈ rightRows, ∀ symbol ∈ row,
symbol ≠ UnaryFrameSym.frameEnd := by
intro row hrow symbol hsymbol
exact hrightFree row (by simp [hrow]) symbol hsymbol
let leftBlock := leftRow ++ [UnaryFrameSym.frameEnd]
let rightBlock := rightRow ++ [UnaryFrameSym.frameEnd]
let leftTail := encodeUnaryFrameMarkedRows leftRows
let rightTail := encodeUnaryFrameMarkedRows rightRows
let valuesLeft := Function.update
(Function.update values (firstOutputK M₁ M₂)
(List.map M₁.outputAlphabet.invFun leftTail))
(outputTempK M₁ M₂) (leftBlock.reverse ++ temp)
let valuesRight := Function.update
(Function.update valuesLeft (outputK M₁ M₂)
(List.map M₂.outputAlphabet.invFun rightTail))
(outputTempK M₁ M₂)
(rightBlock.reverse ++ leftBlock.reverse ++ temp)
let afterLeft := mergeCfg M₁ M₂ ExtraΛ.mergeRight
(ExtraState.mergeSymbol UnaryFrameSym.frameEnd) valuesLeft
let afterRight := mergeCfg M₁ M₂ ExtraΛ.mergeLeft
(ExtraState.mergeSymbol UnaryFrameSym.frameEnd) valuesRight
have hleftSource : values (firstOutputK M₁ M₂) =
List.map M₁.outputAlphabet.invFun
(leftRow ++ UnaryFrameSym.frameEnd :: leftTail) := by
simpa [leftTail] using hleft
have hleftIt : EvalsToInTime (machine M₁ M₂).step
(mergeCfg M₁ M₂ ExtraΛ.mergeLeft state values)
(some afterLeft) (leftRow.length + 1) :=
⟨⟨leftRow.length + 1, by
simpa [afterLeft, valuesLeft, leftBlock] using
merge_left_row_phase M₁ M₂ state hleftRowFree hleftSource
htemp⟩, le_rfl⟩
have hrightSource : valuesLeft (outputK M₁ M₂) =
List.map M₂.outputAlphabet.invFun
(rightRow ++ UnaryFrameSym.frameEnd :: rightTail) := by
simp [valuesLeft, rightTail, Function.update, hright]
have hleftTemp : valuesLeft (outputTempK M₁ M₂) =
leftBlock.reverse ++ temp := by
simp [valuesLeft]
have hrightIt : EvalsToInTime (machine M₁ M₂).step
afterLeft (some afterRight) (rightRow.length + 1) :=
⟨⟨rightRow.length + 1, by
simpa [afterLeft, afterRight, valuesRight,
rightBlock] using
merge_right_row_phase M₁ M₂
(ExtraState.mergeSymbol UnaryFrameSym.frameEnd)
hrightRowFree hrightSource hleftTemp⟩, le_rfl⟩
have hleftTail : valuesRight (firstOutputK M₁ M₂) =
List.map M₁.outputAlphabet.invFun leftTail := by
simp [valuesRight, valuesLeft, Function.update]
have hrightTail : valuesRight (outputK M₁ M₂) =
List.map M₂.outputAlphabet.invFun rightTail := by
simp [valuesRight, Function.update]
have hrightTemp : valuesRight (outputTempK M₁ M₂) =
rightBlock.reverse ++ leftBlock.reverse ++ temp := by
simp [valuesRight]
have hrest := ih rightRows htailAligned hleftRowsFree hrightRowsFree
(state := ExtraState.mergeSymbol UnaryFrameSym.frameEnd)
(values := valuesRight)
(temp := rightBlock.reverse ++ leftBlock.reverse ++ temp)
hleftTail hrightTail hrightTemp
let firstTwo := EvalsToInTime.trans (machine M₁ M₂).step
(leftRow.length + 1) (rightRow.length + 1)
(mergeCfg M₁ M₂ ExtraΛ.mergeLeft state values)
afterLeft (some afterRight) hleftIt hrightIt
let full := EvalsToInTime.trans (machine M₁ M₂).step
((rightRow.length + 1) + (leftRow.length + 1))
(mergeAlignedRowsSteps leftRows rightRows)
(mergeCfg M₁ M₂ ExtraΛ.mergeLeft state values)
afterRight _ firstTwo hrest
have hstate : mergeRowsFinalState (Γ := Γ)
(ExtraState.mergeSymbol (Γ := Γ) UnaryFrameSym.frameEnd)
leftRows =
ExtraState.mergeSymbol (Γ := Γ)
UnaryFrameSym.frameEnd := by
cases leftRows <;> rfl
have hcollapse :
Function.update
(Function.update
(Function.update valuesRight (firstOutputK M₁ M₂) [])
(outputK M₁ M₂) [])
(outputTempK M₁ M₂)
((encodeUnaryFrameMarkedRows
(interleaveUnaryFrameMarkedRows leftRows rightRows)).reverse ++
(rightBlock.reverse ++ leftBlock.reverse ++ temp)) =
Function.update
(Function.update
(Function.update values (firstOutputK M₁ M₂) [])
(outputK M₁ M₂) [])
(outputTempK M₁ M₂)
((encodeUnaryFrameMarkedRows
(interleaveUnaryFrameMarkedRows
(leftRow :: leftRows) (rightRow :: rightRows))).reverse ++
temp) := by
funext key
by_cases h₁ : key = firstOutputK M₁ M₂ <;>
by_cases h₂ : key = outputK M₁ M₂ <;>
by_cases h₃ : key = outputTempK M₁ M₂ <;>
simp [valuesRight, valuesLeft, Function.update, h₁, h₂, h₃,
leftBlock, rightBlock, encodeUnaryFrameMarkedRows,
interleaveUnaryFrameMarkedRows, List.reverse_append,
List.append_assoc]
have hsteps : mergeAlignedRowsSteps leftRows rightRows +
((rightRow.length + 1) + (leftRow.length + 1)) =
mergeAlignedRowsSteps (leftRow :: leftRows)
(rightRow :: rightRows) := by
simp [mergeAlignedRowsSteps, encodeUnaryFrameMarkedRows]
omega
rw [hstate, hcollapse] at full
simpa only [mergeRowsFinalState, hsteps] using fullend UnaryFrameMarkedRowParallelInterleaveend CLRS.Chapter34.Turing.PolyBuilder