Research source · python
verify_two_sided_catenation.py
site/public/research-artifacts/foundations/verify_two_sided_catenation.py
159 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 8086e5e369df551f6e391f77477ca0b4cd47a4e32df18b5a650b8702752a1b17
#!/usr/bin/env python3
"""Handwritten symbolic obligations, not OCaml extraction or a Rocq rerun."""
import argparse
import hashlib
import json
from pathlib import Path
HASHES = {
"lib/cadeque_core.ml": "2a7e36a50e9cec5f3cc06226922ab26e039e1fa0dc1188e879e594f320ae003e",
"theory/Cadeque/Core.v": "32340da1cedd75eddee2e3205fee4ae4d99f71e347e807b993d528f3e6f1875f",
"theory/Cadeque/Types.v": "4beb995bd9634c6cc275aa053e009065a7ff699e2ad7b04fd2821df97bcd9e23",
"theory/Cadeque/Models.v": "d19612a21f4e506aedb31657393c437a07d1f2f8e5ed4ebcea4e408d6b05402f",
}
def word(*parts):
return tuple(x for part in parts for x in part)
def block(name):
# One stored entry has two formal factors, never implicitly one letter.
return (name + "0", name + "1")
def push(entry, chain):
return entry + chain
def inject(chain, entry):
return chain + entry
def push_vector(v, c):
for e in reversed(v):
c = push(e, c)
return c
def inject_vector(c, v):
for e in v:
c = inject(c, e)
return c
def stored_right(u, a, b, child, suffix, y, z):
# Transcribes inject2 followed by eject2 and Big construction.
big_prefix = word(u, a, b)
big = word(big_prefix, child, suffix)
return big, (y, z)
def stored_left(x, y, prefix, child, a, b, u):
big_suffix = word(a, b, u)
big = word(prefix, child, big_suffix)
return (x, y), big
def require_stored(prefix_rank, prefix_min, result_rank, child_rank=None, suffix_min=None):
assert result_rank == prefix_rank + 1, "stored rank must increase by one"
assert prefix_min >= 3, "stored prefix minimum is three"
if child_rank is not None:
assert child_rank == result_rank, "Big child rank mismatch"
assert suffix_min >= 3, "stored suffix minimum is three"
def require_orange(buffer_min):
assert buffer_min >= 6, "orange buffer minimum is six"
def run():
checks = []
def equation(name, output, expected):
assert output == expected, name
checks.append({"case": name, "normal_form": output})
p, s, c, l, r = map(block, ("P", "S", "C", "L", "R"))
a, b, x, y, z, u = map(block, ("A", "B", "X", "Y", "Z", "U"))
for n in range(7):
v = [block(f"e{i}") for i in range(n)]
equation(f"small_left_{n}", push_vector(v, r), word(*v, r))
equation(f"small_right_{n}", inject_vector(l, v), word(l, *v))
# Only conversions: independent pre-state is P C S' Y Z or X Y P' C S.
equation("left_of_only", word(p, inject(c, s), y, z), word(p, c, s, y, z))
equation("right_of_only", word(x, y, push(p, c), s), word(x, y, p, c, s))
big, tail = stored_right(u, a, b, r, s, y, z)
equation("stored_of_right", word(big, *tail), word(u, a, b, r, s, y, z))
front, big = stored_left(x, y, p, l, a, b, u)
equation("stored_of_left", word(*front, big), word(x, y, p, l, a, b, u))
for ending in (True, False):
big, tail = stored_right(z if ending else word(y, z), a, b, r, s, x, u)
prefix = inject(p, y) if ending else p
child = big if ending else inject(l, big)
equation(f"left_pair_{ending}", word(prefix, child, *tail),
word(p, () if ending else l, y, z, a, b, r, s, x, u))
front, big = stored_left(x, y, p, l, z, u, a if ending else word(a, b))
suffix = push(b, s) if ending else s
child = big if ending else push(big, r)
equation(f"right_pair_{ending}", word(*front, child, suffix),
word(x, y, p, l, z, u, a, b, () if ending else r, s))
equation("large_large", word(l, r), word(l, r))
# Affine minima: all omitted size parameters are arbitrary naturals.
occupancy = {"Small_after_removing_two": 5-2,
"Big_prefix_from_nonempty_plus_pair": 1+2,
"Big_suffix_after_removing_two": 5-2,
"ending_pair_orange_buffer": 5+1,
"side_buffer_after_ending_split": 7-2}
for key, lower in occupancy.items():
assert lower >= (6 if "orange" in key else 5 if "ending_split" in key else 3)
require_stored(0, 5-2, 1)
require_stored(0, 1+2, 1, 1, 5-2)
require_orange(5+1)
failures = []
bad = r
for e in (a, b):
bad = push(e, bad)
assert bad != word(a, b, r)
failures.append("left-folding prepend reverses the boundary")
assert word(r, l) != word(l, r)
failures.append("swapping large sides changes the word")
# These are explicit checks of selected typing obligations, not a type checker.
for label, operation in [
("omit stored wrapper", lambda: require_stored(0, 3, 0)),
("undersized stored buffer", lambda: require_stored(0, 2, 1)),
("omit boundary move to orange buffer", lambda: require_orange(5)),
]:
try:
operation()
except AssertionError as error:
failures.append(label + ": " + str(error))
else:
raise AssertionError("negative control accepted: " + label)
return checks, occupancy, failures
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("source", type=Path)
args = parser.parse_args()
for path, digest in HASHES.items():
assert hashlib.sha256((args.source/path).read_bytes()).hexdigest() == digest, path
checks, occupancy, failures = run()
print(json.dumps({
"scope": "Handwritten symbolic word equations and affine occupancy minima. Written proof supplies exhaustive source branch/color coverage; no automatic OCaml refinement, full type checker, buffer verification or Rocq rerun.",
"source_commit": "503c5d3ff7f9a20bad1cd7a8f8d7abf4e635d3a0",
"source_hashes": HASHES,
"checker_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),
"quantifiers": "Every natural level; arbitrary substituted word blocks; vector lengths zero through six exhaust the fixed shape bound.",
"word_obligations": checks,
"affine_occupancy_minima": occupancy,
"negative_controls": failures,
}, indent=2))