File size: 5,702 Bytes
767a051
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Event-driven continuation engine for the corrective 0.4 rebuild."""
from __future__ import annotations

import hashlib
from dataclasses import dataclass
from typing import Any, Mapping

from tom_world03.canonical import attach_hash, canonical_bytes

from .model import ContinuationWorld, OpenSegment, qmap_record
from .solver import next_event_set
from .transition import EventBundle, FinalizationBundle, apply_event_set, finalize_segment


@dataclass(frozen=True, slots=True)
class ContinuationRun:
    record: Mapping[str, Any]
    open_segments: tuple[OpenSegment, ...]
    bundles: tuple[EventBundle, ...]
    finalization: FinalizationBundle


def _semantic_chain(
    world: ContinuationWorld,
    open_segments: list[OpenSegment],
    bundles: list[EventBundle],
    finalization: FinalizationBundle,
) -> dict[str, Any]:
    realized_segments: list[dict[str, Any]] = []
    for segment, bundle in zip(open_segments, bundles):
        realized_segments.append({
            "sequence": segment.sequence,
            "domain": bundle.seal["realized_domain"],
            "start_state": qmap_record(segment.start_state),
            "rates": qmap_record(segment.rates),
            "end_state": bundle.seal["end_state"],
        })
    final_segment = open_segments[-1]
    realized_segments.append({
        "sequence": final_segment.sequence,
        "domain": finalization.seal["realized_domain"],
        "start_state": qmap_record(final_segment.start_state),
        "rates": qmap_record(final_segment.rates),
        "end_state": finalization.seal["end_state"],
    })

    event_sets = [
        {
            "event_time": bundle.event_set["event_time"],
            "event_order": list(bundle.event_set["event_order"]),
            "relation_order": list(bundle.event_set["relation_order"]),
            "pre_state": bundle.transition["pre_state"],
            "post_state": bundle.transition["post_state"],
            "pre_rates": bundle.transition["pre_rates"],
            "post_rates": bundle.transition["post_rates"],
            "fired_relations_after": list(bundle.successor.fired_relations),
        }
        for bundle in bundles
    ]
    return {
        "schema": "TOM-CONTINUATION-SEMANTIC-CHAIN-0.4.1",
        "world_hash": world.content_hash,
        "corrected_v03_zip_sha256": world.corrected_v03_zip_sha256,
        "corrected_interval_sha256": world.corrected_interval_sha256,
        "realized_segments": realized_segments,
        "event_sets": event_sets,
        "final_time": world.horizon.upper.to_record(),
        "final_state": finalization.transaction["final_state"],
        "fired_relations": list(final_segment.fired_relations),
        "boundary_policy": "event times are solver outputs; final boundary is the declared world horizon",
    }


def run_continuation(
    world: ContinuationWorld,
    *,
    planner: str = "indexed",
    max_event_sets: int | None = None,
    store: Any | None = None,
) -> ContinuationRun:
    max_sets = int(world.solver.get("max_event_sets", 64) if max_event_sets is None else max_event_sets)
    profile_max = int(world.solver.get("profile_max_event_sets", 1024))
    if max_sets < 0 or max_sets > profile_max:
        raise ValueError(f"max_event_sets {max_sets} outside 0..{profile_max}")

    current = world.initial_segment
    open_segments: list[OpenSegment] = [current]
    bundles: list[EventBundle] = []
    query_certificates: list[Mapping[str, Any]] = []
    while True:
        event_set = next_event_set(world, current, planner=planner)
        query_certificates.append(event_set)
        if event_set["status"] == "none":
            finalization = finalize_segment(world, current)
            if store is not None:
                store.commit_finalization(finalization)
            break
        if len(bundles) >= max_sets:
            raise ValueError("event-set budget exhausted before world horizon")
        bundle = apply_event_set(world, current, event_set)
        if store is not None:
            store.commit_event(bundle)
        bundles.append(bundle)
        current = bundle.successor
        open_segments.append(current)

    semantic = _semantic_chain(world, open_segments, bundles, finalization)
    semantic_hash = "sha256:" + hashlib.sha256(canonical_bytes(semantic)).hexdigest()
    record = attach_hash({
        "schema": "TOM-CONTINUATION-RUN-0.4.1",
        "world_hash": world.content_hash,
        "planner": planner,
        "status": "complete",
        "stop_reason": "no-later-event-and-horizon-sealed",
        "event_set_count": len(bundles),
        "realized_segment_count": len(open_segments),
        "open_segment_hashes": [segment.content_hash for segment in open_segments],
        "event_set_hashes": [bundle.event_set["content_hash"] for bundle in bundles],
        "transition_hashes": [bundle.transition["content_hash"] for bundle in bundles],
        "seal_hashes": [bundle.seal["content_hash"] for bundle in bundles] + [finalization.seal["content_hash"]],
        "transaction_hashes": [bundle.transaction["content_hash"] for bundle in bundles] + [finalization.transaction["content_hash"]],
        "query_certificate_hashes": [record["content_hash"] for record in query_certificates],
        "total_scanned_brackets": sum(int(record["scanned_brackets"]) for record in query_certificates),
        "total_candidate_relations": sum(int(record["total_candidate_relations"]) for record in query_certificates),
        "semantic_chain": semantic,
        "semantic_chain_sha256": semantic_hash,
        "journal_head": None if store is None else store.head,
    })
    return ContinuationRun(record, tuple(open_segments), tuple(bundles), finalization)