Research source · python
check_transfer_composition.py
site/public/research-artifacts/scaffold-proof-review/check_transfer_composition.py
197 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 729e49c659eeb12fa86643a7d0f22a9fd1df30c406732a1c496cd8099a908a52
#!/usr/bin/env python3
"""Finite audit for Run 09's timing, reversal, and empty-word interfaces.
The exhaustive families are deliberately small. They test the operational
interfaces and boundary cases; the universal statements are supplied by the
Lean theorems and the mathematical composition argument in run-09.md.
"""
from __future__ import annotations
import itertools
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
LEAN = ROOT / "public/formal/persistent-stacks/lean/FPRDTransfer"
TRANSFER_HTML = ROOT / (
"public/research-artifacts/scaffold-proof-review/history/objects/"
"0ced5ddcec85f089dd004170f8c335a6b5fb7819009388ea7869b8a6cc2e7515.txt"
)
MOVES = (-1, 0, 1)
WORDS = [word for n in range(6) for word in itertools.product((0, 1), repeat=n)]
OFFSETS = range(-7, 8)
def direct_step(tape, head, write, move):
tape = dict(tape)
tape[head] = write
return tape, head + move
def zipper_step(left, cur, right, write, move, blank=0):
left, right = list(left), list(right)
if move == 1:
return [write, *left], (right[0] if right else blank), right[1:]
if move == -1:
return left[1:], (left[0] if left else blank), [write, *right]
return left, write, right
def zipper_get(left, cur, right, offset, blank=0):
if offset == 0:
return cur
side = right if offset > 0 else left
index = abs(offset) - 1
return side[index] if index < len(side) else blank
def all_tables(domain, outputs):
for values in itertools.product(outputs, repeat=len(domain)):
yield dict(zip(domain, values))
def source_markers():
realtime = (LEAN / "RealtimeTransfer.lean").read_text()
main = (LEAN / "Theorem16/Main.lean").read_text()
normalize = (LEAN / "Theorem16/Normalize.lean").read_text()
corollaries = (LEAN / "Theorem16/Corollaries.lean").read_text()
html = TRANSFER_HTML.read_text()
return {
"machine_run_is_one_fold_step_per_letter":
"w.foldl N.stepConfig N.initConfig" in realtime,
"machine_to_scaffold_decision_equality":
"theorem realtime_transfer_decides" in realtime,
"machine_to_scaffold_tape_equality":
"theorem realtime_transfer_tape_contents" in realtime,
"compiled_automaton_is_distance_ok":
"theorem realtime_transfer_wellFormed" in realtime,
"scaffold_to_peg_reverses_once":
"InPEG (fun word => A.decides word.reverse = true)" in main,
"normalization_preserves_empty_and_nonempty_words":
"theorem normalize_decides" in normalize
and "including the empty word" in normalize,
"transfer_corollary_has_one_reverse":
"theorem revRT_multitape_subset_PEG" in corollaries
and "machine.decides word.reverse = true" in corollaries,
"epal_corollary_is_conditional_on_recognizer":
"theorem epal₂_inPEG_of_multitape_recognizer" in corollaries
and "hmachine" in corollaries,
"paper_excludes_advice_and_post_input_work":
"has no input-length advice, and performs no post-input computation" in html,
"paper_marks_palindrome_interface_imported":
"Classical palindrome interface (classical, imported)" in html,
}
def audit_control_and_orientation():
domain = tuple(itertools.product((0, 1), (0, 1)))
outputs = tuple(itertools.product((0, 1), MOVES))
executions = steps = empty_checks = normalization_checks = orientation_checks = 0
for table in all_tables(domain, outputs):
for accept_mask in range(4):
accepts = lambda q, mask=accept_mask: bool(mask & (1 << q))
for word in WORDS:
q = 0
tape, head = {}, 0
left, cur, right = [], 0, []
normalized = None
if not word:
empty_checks += 1
assert accepts(q) == accepts(0)
assert normalized is None
for symbol in word:
q_next, move = table[(q, symbol)]
tape, head = direct_step(tape, head, 0, move)
left, cur, right = zipper_step(left, cur, right, 0, move)
q = q_next
normalized = q_next
steps += 1
assert all(tape.get(head + z, 0) == zipper_get(left, cur, right, z)
for z in OFFSETS)
machine_answer = accepts(q)
stack_answer = accepts(q)
normalized_answer = accepts(0) if normalized is None else accepts(normalized)
peg_on_reverse = stack_answer
assert machine_answer == stack_answer == normalized_answer == peg_on_reverse
executions += 1
normalization_checks += 1
orientation_checks += 1
return {
"machine_tables": 6 ** 4,
"acceptance_sets_per_table": 4,
"words_per_machine": len(WORDS),
"executions": executions,
"letter_steps": steps,
"empty_word_checks": empty_checks,
"fresh_initial_normalization_checks": normalization_checks,
"single_reversal_checks": orientation_checks,
}
def audit_tape_zipper():
domain = tuple(itertools.product((0, 1), (0, 1)))
outputs = tuple(itertools.product((0, 1), MOVES))
executions = steps = offset_checks = stack_actions = 0
for table in all_tables(domain, outputs):
for word in WORDS:
tape, head = {}, 0
left, cur, right = [], 0, []
for symbol in word:
write, move = table[(symbol, tape.get(head, 0))]
tape, head = direct_step(tape, head, write, move)
left, cur, right = zipper_step(left, cur, right, write, move)
steps += 1
stack_actions += 2
for offset in OFFSETS:
assert tape.get(head + offset, 0) == zipper_get(
left, cur, right, offset
)
offset_checks += 1
executions += 1
return {
"machine_tables": 6 ** 4,
"words_per_machine": len(WORDS),
"executions": executions,
"letter_steps": steps,
"stack_actions": stack_actions,
"tape_offset_checks": offset_checks,
"offset_window": [min(OFFSETS), max(OFFSETS)],
}
def main():
markers = source_markers()
assert all(markers.values()), markers
result = {
"status": "pass",
"scope": (
"Exhaustive small-machine interface checks and exact source markers; "
"the universal result is proved by the cited Lean theorems and Run 09."
),
"proved_composition": {
"machine_to_scaffold_is_letter_synchronous": True,
"machine_to_scaffold_preserves_language_without_reversal": True,
"scaffold_to_peg_introduces_exactly_one_reversal": True,
"empty_word_is_preserved_at_every_layer": True,
"compiler_does_not_strictify_a_slower_source_machine": True,
"palindrome_strict_realtime_recognizer_remains_an_imported_premise": True,
},
"control_orientation_family": audit_control_and_orientation(),
"tape_zipper_family": audit_tape_zipper(),
"source_markers": markers,
}
print(json.dumps(result, indent=2, sort_keys=True))
if __name__ == "__main__":
main()