Download code/decision_lab/data/schema.py from axondendriteplus/decipop-v7-r2-multi-entity: direct link, hf CLI and curl.
- Browser
- Download file 3.31 kB
-
https://huggingface.co/axondendriteplus/decipop-v7-r2-multi-entity/resolve/main/code/decision_lab/data/schema.py
- Command line
-
hf download hf://axondendriteplus/decipop-v7-r2-multi-entity/code/decision_lab/data/schema.py
-
curl -L -o schema.py https://huggingface.co/axondendriteplus/decipop-v7-r2-multi-entity/resolve/main/code/decision_lab/data/schema.py
3.31 kB
| from enum import StrEnum | |
| from typing import Self | |
| from pydantic import Field, model_validator | |
| from decision_lab.config import StrictModel | |
| class Label(StrEnum): | |
| TRUE = "TRUE" | |
| FALSE = "FALSE" | |
| UNKNOWN = "UNKNOWN" | |
| class Atom(StrictModel): | |
| predicate: str = Field(pattern=r"^[a-z][a-z_]*$") | |
| arguments: tuple[str, ...] | |
| negative: bool | |
| def validate_arity(self): | |
| if len(self.arguments) not in (1, 2) or any(not arg for arg in self.arguments): | |
| raise ValueError("Atoms require one or two nonempty arguments") | |
| return self | |
| def opposite(self) -> Self: | |
| return self.model_copy(update={"negative": not self.negative}) | |
| def ground(self, bindings: dict[str, str]) -> Self: | |
| arguments = tuple(bindings[arg] if arg.startswith("?") else arg for arg in self.arguments) | |
| return self.model_copy(update={"arguments": arguments}) | |
| class Rule(StrictModel): | |
| conditions: tuple[Atom, ...] | |
| conclusion: Atom | |
| def validate_conditions(self): | |
| if len(self.conditions) not in (1, 2): | |
| raise ValueError("Rules require one or two conditions") | |
| body_variables = { | |
| term for atom in self.conditions for term in atom.arguments if term.startswith("?") | |
| } | |
| head_variables = {term for term in self.conclusion.arguments if term.startswith("?")} | |
| if not head_variables <= body_variables: | |
| raise ValueError("Conclusion variables must occur in the conditions") | |
| return self | |
| class Theory(StrictModel): | |
| entities: tuple[str, ...] | |
| facts: tuple[Atom, ...] | |
| rules: tuple[Rule, ...] | |
| def validate_theory(self): | |
| if not self.entities or len(set(self.entities)) != len(self.entities): | |
| raise ValueError("Theory entities must be nonempty and unique") | |
| if any(term.startswith("?") for term in self.entities): | |
| raise ValueError("Entity names cannot be variables") | |
| if len(set(self.facts)) != len(self.facts) or len(set(self.rules)) != len(self.rules): | |
| raise ValueError("Duplicate facts or rules are not allowed") | |
| atoms = [*self.facts, *(a for r in self.rules for a in (*r.conditions, r.conclusion))] | |
| arities: dict[str, int] = {} | |
| for atom in atoms: | |
| arity = len(atom.arguments) | |
| if atom.predicate in arities and arities[atom.predicate] != arity: | |
| raise ValueError("A predicate cannot have multiple arities") | |
| arities[atom.predicate] = arity | |
| for term in atom.arguments: | |
| if not term.startswith("?") and term not in self.entities: | |
| raise ValueError(f"Undeclared entity: {term}") | |
| if any(term.startswith("?") for atom in self.facts for term in atom.arguments): | |
| raise ValueError("Initial facts must be ground") | |
| return self | |
| class Example(StrictModel): | |
| example_id: str | |
| family_id: str | |
| split: str | |
| theory: Theory | |
| query: Atom | |
| label: Label | |
| proof_depth: int | None | |
| theory_depth: int | |
| motif: str | |
| renderer_id: str | |
| theory_hash: str | |
| structure_hash: str | |
| facts: tuple[str, ...] | |
| rules: tuple[str, ...] | |
| question: str | |
| prompt: str | |