Research source · python

check_cosingleton_reuse.py

tools/research/check_cosingleton_reuse.py

204 lines. Source is displayed for inspection; it is not executed by this page.

File fingerprint

SHA-256: 912ac0f853de40c1770f00c37e83a1c584f7a596d05c930aeedd70d3505d018c

#!/usr/bin/env python3
"""Finite oracle for co-singleton reuse; not a native-cost implementation.

Python sets, maps, integer arithmetic and copied snapshots are oracle machinery.
The written proof separately charges literal routing and all local operations.
"""
from itertools import product
from random import Random


def signature(row):
    xor = 0
    for value in row:
        xor ^= value
    return len(row), xor


class Oracle:
    def __init__(self, alias_count):
        self.rows = [set() for _ in range(alias_count)]
        self.classes = {}
        self.codes = {}
        self.free = set(range(alias_count))
        self.histogram = {}
        self.minimum = 0
        self.support = set()
        self.full_pool_reuses = 0

    def snapshot(self):
        return (tuple(frozenset(row) for row in self.rows),
                tuple(sorted(self.codes.items())),
                tuple(sorted(self.classes.items())))

    def insert(self, alias, target):
        row = self.rows[alias]
        if target in row:
            return
        degree = len(row)
        old_signature = signature(row)
        new_signature = signature(row | {target})
        candidate = min(self.free) if self.free else self.codes.get(alias)
        was_full = not self.free
        new_class = new_signature not in self.classes
        if degree:
            population, old_code = self.classes[old_signature]
            if population == 1:
                del self.classes[old_signature]
                self.free.add(old_code)
            else:
                self.classes[old_signature] = population - 1, old_code
            self.histogram[degree] -= 1
            if not self.histogram[degree]:
                del self.histogram[degree]
        row.add(target)
        if new_signature in self.classes:
            population, code = self.classes[new_signature]
            self.classes[new_signature] = population + 1, code
        else:
            assert candidate is not None and candidate in self.free
            code = candidate
            self.free.remove(code)
            self.classes[new_signature] = 1, code
            if was_full:
                assert degree and new_class
                self.full_pool_reuses += 1
        self.codes[alias] = code
        self.histogram[degree + 1] = self.histogram.get(degree + 1, 0) + 1
        if degree == 0:
            self.minimum = 1
        elif degree == self.minimum and degree not in self.histogram:
            self.minimum += 1
        self.support.add(target)
        self.check()

    def gate(self):
        return self.minimum >= len(self.support) - 1

    def check(self):
        assert self.minimum == min((len(row) for row in self.rows if row), default=0)
        degrees = {len(row) for row in self.rows if row}
        assert self.histogram == {d: sum(len(row) == d for row in self.rows) for d in degrees}
        expected = {}
        for alias, row in enumerate(self.rows):
            if row:
                sig = signature(row)
                expected[sig] = expected.get(sig, 0) + 1
                assert self.codes[alias] == self.classes[sig][1]
        assert expected == {sig: pop for sig, (pop, code) in self.classes.items()}
        live_codes = {code for pop, code in self.classes.values()}
        assert len(live_codes) == len(self.classes)
        assert self.free == set(range(len(self.rows))) - live_codes
        assert self.gate() == all(len(self.support - row) <= 1 for row in self.rows if row)


def check_snapshot(snapshot):
    rows, codes, classes = snapshot
    codes, classes = dict(codes), dict(classes)
    for alias, row in enumerate(rows):
        if row:
            assert codes[alias] == classes[signature(row)][1]
    for sig, (population, code) in classes.items():
        assert population == sum(signature(row) == sig for row in rows if row)


def pending_queries(oracle, selections, width):
    """Commit the previous pending class during the next selection."""
    assert oracle.gate()
    committed = None
    pending = None
    full = False
    actual = set()
    checks = 0
    for alias in selections:
        if pending is not None and not full:
            if committed is None:
                committed = pending
            elif oracle.codes[committed] != oracle.codes[pending]:
                full = True
        pending = alias if alias < len(oracle.rows) and oracle.rows[alias] else None
        if pending is not None:
            actual |= oracle.rows[pending]
        predicted = set(oracle.support) if full else set()
        if not full and committed is not None:
            predicted |= oracle.rows[committed]
        if pending is not None:
            predicted |= oracle.rows[pending]
        for query_width in (width - 1, width, width + 1):
            for target in range(1 << width):
                valid = query_width == width
                # Exact negative observation is SAT under the ordinary pins.
                assert (not (valid and target in predicted)) == (not (valid and target in actual))
                checks += 1
    return checks


def exhaustive():
    subsets = [{j for j in range(4) if mask >> j & 1} for mask in range(16)]
    states = pairs = 0
    for rows in product(subsets, repeat=4):
        support = set().union(*rows)
        observed = [row for row in rows if row]
        if any(len(support - row) > 1 for row in observed):
            continue
        states += 1
        for left in observed:
            for right in observed:
                assert (signature(left) == signature(right)) == (left == right)
                if signature(left) != signature(right):
                    assert left | right == support
                pairs += 1
    # The zero omission collides in XOR with FULL, but not in count.
    assert signature({0, 1, 2, 3})[1] == signature({1, 2, 3})[1]
    assert signature({0, 1, 2, 3}) != signature({1, 2, 3})
    return states, pairs


def streaming():
    steps = snapshots = queries = recoveries = reuses = 0
    for seed in range(400):
        rng = Random(seed)
        oracle = Oracle(8)
        retained = []
        previous_gate = True
        # Arbitrary interleaving, then complete every row to guarantee recovery.
        records = [(rng.randrange(8), rng.randrange(16)) for _ in range(100)]
        records += [(a, t) for a in range(8) for t in range(16)]
        for alias, target in records:
            retained.append(oracle.snapshot())
            oracle.insert(alias, target)
            steps += 1
            if oracle.gate() and not previous_gate:
                recoveries += 1
            previous_gate = oracle.gate()
            if oracle.gate():
                selections = [rng.randrange(9) for _ in range(6)]
                queries += pending_queries(oracle, selections, 4)
        for snapshot in retained:
            check_snapshot(snapshot)
            snapshots += 1
        reuses += oracle.full_pool_reuses
    # Explicitly saturate the slot pool before replacing a singleton class.
    oracle = Oracle(8)
    for alias in range(8):
        oracle.insert(alias, alias)
    snapshot = oracle.snapshot()
    oracle.insert(0, 1)
    assert oracle.full_pool_reuses == 1
    oracle.insert(1, 0)  # Join an extant signature class and release a slot.
    check_snapshot(snapshot)
    assert oracle.codes[0] == oracle.codes[1]
    return steps, snapshots, queries, recoveries, reuses + 1


def main():
    states, pairs = exhaustive()
    steps, snapshots, queries, recoveries, reuses = streaming()
    print({"gated_states": states, "row_pairs": pairs,
           "stream_records": steps, "retained_snapshots": snapshots + 1,
           "negative_query_checks": queries, "gate_recoveries": recoveries,
           "full_pool_reuses": reuses})


if __name__ == "__main__":
    main()