Imports
Shape invariants for list-valued terminal stack routes
The ordinary-list stack representation is useful to a source compiler only when every intermediate push/pop route keeps the canonical fixed-capacity shape. This module packages that invariant and proves it for typed source wires, each primitive action, and the complete selected-action fold.
noncomputable sectionnamespace CLRS.Chapter34.Turing.CookLevinCanonical list shape of one stack block at a fixed workspace capacity.
def TransitionStackValueBlock.HasShape
(tm : _root_.Turing.FinTM2) (k : tm.K) (height : Nat)
(block : TransitionStackValueBlock) : Prop :=
block.heightValues.length = height + 1 ∧
block.cellRows.length = height ∧
∀ row ∈ block.cellRows,
row.length = (reachableAlphabet tm k).card + 1Erasing typed stack wires always produces a canonically shaped block.
theorem TransitionStackValueBlock.hasShape_ofWires
(tm : _root_.Turing.FinTM2) (k : tm.K) (height : Nat)
(source : StackWires tm height k) :
(TransitionStackValueBlock.ofWires source).HasShape tm k height := by
simp [TransitionStackValueBlock.HasShape,
TransitionStackValueBlock.ofWires,
transitionStackHeightWireValues, transitionStackCellWireRows]A pushed symbol row has exactly the machine-fixed alphabet width.
@[simp] theorem transitionPushedSymbolWireRow_length
(tm : _root_.Turing.FinTM2) (k : tm.K)
(falseWire : Nat) (symbol : SymbolWires tm k) :
(transitionPushedSymbolWireRow tm k falseWire symbol).length =
(reachableAlphabet tm k).card + 1 := by
simp [transitionPushedSymbolWireRow]A blank row appended by pop has the same machine-fixed alphabet width.
@[simp] theorem transitionBlankSymbolWireRow_length
(tm : _root_.Turing.FinTM2) (k : tm.K)
(falseWire trueWire : Nat) :
(transitionBlankSymbolWireRow tm k falseWire trueWire).length =
(reachableAlphabet tm k).card + 1 := by
simp [transitionBlankSymbolWireRow]Fixed-capacity push preserves the complete list shape.
theorem TransitionStackValueBlock.HasShape.push
(tm : _root_.Turing.FinTM2) (k : tm.K)
(height falseWire : Nat) (symbol : SymbolWires tm k)
(source : TransitionStackValueBlock)
(hsource : source.HasShape tm k height) :
(source.push tm k height falseWire symbol).HasShape tm k height := by
rcases hsource with ⟨hheight, hcells, hrows⟩
cases height with
| zero =>
simp [TransitionStackValueBlock.push,
TransitionStackValueBlock.HasShape]
| succ height =>
constructor
· simp [TransitionStackValueBlock.push, List.length_take, hheight]
· constructor
· simp [TransitionStackValueBlock.push, List.length_take, hcells]
· intro row hrow
simp only [TransitionStackValueBlock.push, List.mem_cons] at hrow
rcases hrow with rfl | hrow
· simp
· exact hrows row (List.mem_of_mem_take hrow)Fixed-capacity pop preserves the complete list shape.
theorem TransitionStackValueBlock.HasShape.pop
(tm : _root_.Turing.FinTM2) (k : tm.K)
(height falseWire trueWire start : Nat)
(source : TransitionStackValueBlock)
(hsource : source.HasShape tm k height) :
(source.pop tm k height falseWire trueWire start).HasShape tm k height := by
rcases hsource with ⟨hheight, hcells, hrows⟩
cases height with
| zero =>
simpa [TransitionStackValueBlock.pop] using
⟨hheight, hcells, hrows⟩
| succ height =>
constructor
· simp [TransitionStackValueBlock.pop, List.length_drop, hheight]
· constructor
· simp [TransitionStackValueBlock.pop, hcells]
· intro row hrow
simp only [TransitionStackValueBlock.pop, List.mem_append,
List.mem_singleton] at hrow
rcases hrow with hrow | rfl
· exact hrows row (List.mem_of_mem_drop hrow)
· simpThe list semantics of either selected primitive action preserves shape.
theorem TransitionStmtSelectedStackAction.evalValues_hasShape
(tm : _root_.Turing.FinTM2) (k : tm.K)
(originStart height falseWire trueWire : Nat)
(source : TransitionStackValueBlock)
(action : TransitionStmtSelectedStackAction tm k)
(hsource : source.HasShape tm k height) :
(action.evalValues tm k originStart height falseWire trueWire source).HasShape
tm k height := by
cases action with
| push symbolOffsets => exact hsource.push tm k height falseWire _
| pop heightWireOffset => exact hsource.pop tm k height falseWire trueWire _Every intermediate block in the complete fixed action fold has the same canonical capacity and row width as its source.
theorem transitionStmtSelectedStackActionValues_eval_hasShape
(tm : _root_.Turing.FinTM2) (k : tm.K)
(originStart height falseWire trueWire : Nat)
(source : TransitionStackValueBlock)
(actions : List (TransitionStmtSelectedStackAction tm k))
(hsource : source.HasShape tm k height) :
(transitionStmtSelectedStackActionValues_eval tm k originStart height
falseWire trueWire source actions).HasShape tm k height := by
induction actions generalizing source with
| nil => exact hsource
| cons action rest ih =>
apply ih
exact action.evalValues_hasShape tm k originStart height falseWire
trueWire source hsource
private theorem sum_map_length_eq_mul_of_forall
(rows : List (List Nat)) (width : Nat)
(hrows : ∀ row ∈ rows, row.length = width) :
(rows.map List.length).sum = rows.length * width := by
induction rows with
| nil => simp
| cons row rest ih =>
have hrow := hrows row (by simp)
have hrest : ∀ item ∈ rest, item.length = width := by
intro item hitem
exact hrows item (by simp [hitem])
simp [hrow, ih hrest, Nat.add_mul, Nat.add_comm]A shaped block has exactly the canonical flattened stack width.
theorem TransitionStackValueBlock.HasShape.flatten_length
(tm : _root_.Turing.FinTM2) (k : tm.K) (height : Nat)
(block : TransitionStackValueBlock)
(hshape : block.HasShape tm k height) :
block.flatten.length =
height + 1 + height * ((reachableAlphabet tm k).card + 1) := by
rcases hshape with ⟨hheight, hcells, hrows⟩
unfold TransitionStackValueBlock.flatten
rw [List.length_append, List.length_flatten]
rw [sum_map_length_eq_mul_of_forall block.cellRows
((reachableAlphabet tm k).card + 1) hrows]
rw [hheight, hcells]The same width stated using the canonical tableau stack-width function.
theorem TransitionStackValueBlock.HasShape.flatten_length_eq_cfgStackBitWidth
(tm : _root_.Turing.FinTM2) (k : tm.K) (height : Nat)
(block : TransitionStackValueBlock)
(hshape : block.HasShape tm k height) :
block.flatten.length = cfgStackBitWidth tm height k := by
simpa [cfgStackBitWidth] using hshape.flatten_length tm k height blockend CLRS.Chapter34.Turing.CookLevin