from __future__ import annotations from dataclasses import asdict, dataclass from typing import Any COLORS = ("red", "blue", "green", "yellow") SHAPES = ("circle", "square", "triangle", "star") RELATIONS = ("left_of", "right_of", "above", "below") CLASSES = ("alpha", "beta", "gamma", "delta") OBJECT_IDS = ("obj1", "obj2", "obj3") PREDICATES = ("color", "shape", "left_of", "right_of", "above", "below", "implies_class") ENTITIES = OBJECT_IDS + COLORS + SHAPES + CLASSES SUBJECT_TO_ID = {value: index for index, value in enumerate(ENTITIES)} PREDICATE_TO_ID = {value: index for index, value in enumerate(PREDICATES)} OBJECT_TO_ID = SUBJECT_TO_ID @dataclass(frozen=True) class Fact: subject: str predicate: str object: str def to_dict(self) -> dict[str, str]: return asdict(self) @classmethod def from_dict(cls, value: dict[str, str]) -> "Fact": return cls(**value) @dataclass(frozen=True) class SceneObject: object_id: str color: str shape: str x: int y: int def to_dict(self) -> dict[str, Any]: return asdict(self)