83 lines
2.2 KiB
Python
83 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import asdict, dataclass
|
|
from typing import Any
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Condition:
|
|
"""A predicate over immutable inputs or mutable simulator state."""
|
|
|
|
source: str
|
|
key: str
|
|
operator: str
|
|
value: Any
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class HiddenRule:
|
|
"""One executable rule in the hidden system language."""
|
|
|
|
id: str
|
|
on_event: str
|
|
conditions: tuple[Condition, ...]
|
|
probability: float
|
|
action: str
|
|
target: str
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class HiddenSystem:
|
|
"""The latent program. This object must never be sent to the renderer."""
|
|
|
|
initial_record: str
|
|
conflict_policy: str
|
|
rules: tuple[HiddenRule, ...]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class BehaviorCase:
|
|
"""Observable inputs and aggregate output from repeated independent trials."""
|
|
|
|
id: str
|
|
attributes: dict[str, Any]
|
|
events: tuple[str, ...]
|
|
trials: int
|
|
observed_present: int | None
|
|
observed_absent: int | None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class BehaviorSkeleton:
|
|
"""A hidden program plus its public behavioral evidence and answer-bearing query."""
|
|
|
|
id: str
|
|
family: str
|
|
complexity: int
|
|
event_vocabulary: tuple[str, ...]
|
|
attribute_vocabulary: dict[str, str]
|
|
observation_protocol: tuple[str, ...]
|
|
hidden_system: HiddenSystem
|
|
support_cases: tuple[BehaviorCase, ...]
|
|
query_case: BehaviorCase
|
|
answer_options: tuple[str, ...]
|
|
gold_answer: str
|
|
gold_present_probability: float
|
|
latent_trace: tuple[str, ...]
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return asdict(self)
|
|
|
|
def renderer_payload(self) -> dict[str, Any]:
|
|
"""Expose behavior only: no program, probability, trace, or answer."""
|
|
return {
|
|
"family": self.family,
|
|
"complexity": self.complexity,
|
|
"event_vocabulary": self.event_vocabulary,
|
|
"attribute_vocabulary": self.attribute_vocabulary,
|
|
"observation_protocol": self.observation_protocol,
|
|
"support_cases": [asdict(case) for case in self.support_cases],
|
|
"query_case": asdict(self.query_case),
|
|
"answer_options": self.answer_options,
|
|
}
|