# geometry_types.py - V1.0 (Geometric Sanity Engine — Type Contracts) # CTO NOTE: All coordinate arithmetic uses SymPy Rational to guarantee # exact arithmetic — no float drift, no rounding surprises. from dataclasses import dataclass, field from sympy import Rational, simplify, sqrt import logging logger = logging.getLogger(__name__) @dataclass class Point: name: str x: object # SymPy expression or numeric y: object def __eq__(self, other): if not isinstance(other, Point): return False return (simplify(self.x - other.x) == 0 and simplify(self.y - other.y) == 0) def __repr__(self): return f"{self.name}({self.x}, {self.y})" def distance_to(self, other: "Point"): """Exact SymPy distance between two points.""" return sqrt((self.x - other.x)**2 + (self.y - other.y)**2) @dataclass class Line: """Represents the line ax + by + c = 0.""" a: object b: object c: object def y_at(self, x_val): """Compute y given x (assuming b ≠ 0).""" if simplify(self.b) == 0: raise ValueError("[Line.y_at] Vertical line — b=0, y is undefined for a given x.") return Rational(-self.a * x_val - self.c, self.b) def contains(self, p: "Point") -> bool: """Returns True if point p satisfies ax + by + c = 0.""" val = simplify(self.a * p.x + self.b * p.y + self.c) return val == 0 def __repr__(self): return f"Line({self.a}x + {self.b}y + {self.c} = 0)" @dataclass class Segment: p1: Point p2: Point def midpoint(self) -> Point: """Returns the midpoint with exact rational arithmetic.""" from sympy import Rational as R mid_x = (self.p1.x + self.p2.x) / 2 mid_y = (self.p1.y + self.p2.y) / 2 return Point( name=f"mid_{self.p1.name}{self.p2.name}", x=simplify(mid_x), y=simplify(mid_y) ) def length(self): """Exact SymPy length of the segment.""" return self.p1.distance_to(self.p2) def __repr__(self): return f"Segment({self.p1.name}{self.p2.name})" @dataclass class Circle: center: Point radius: object # SymPy expression (can be symbolic) def contains(self, p: Point) -> bool: """Returns True if p lies exactly on the circle boundary.""" lhs = (p.x - self.center.x)**2 + (p.y - self.center.y)**2 return simplify(lhs - self.radius**2) == 0 def __repr__(self): return f"Circle(center={self.center}, r={self.radius})" @dataclass class GeometryAnchor: """ V1.0: The single source of truth for verified geometric facts. Populated by `constraint_checks.py` and consumed by `geometric_sanity.py`. """ points: list = field(default_factory=list) lines: list = field(default_factory=list) segments: list = field(default_factory=list) circles: list = field(default_factory=list) verified_facts: list = field(default_factory=list) warnings: list = field(default_factory=list) def add_fact(self, fact: str): logger.info(f"[GEO-ANCHOR] ✓ FACT: {fact}") self.verified_facts.append(fact) def add_warning(self, warning: str): logger.warning(f"[GEO-ANCHOR] ✗ WARNING: {warning}") self.warnings.append(warning) def is_clean(self) -> bool: """True if no geometric contradictions were detected.""" return len(self.warnings) == 0 def summary(self) -> dict: return { "verified_facts": self.verified_facts, "warnings": self.warnings, "has_contradictions": not self.is_clean() }