Download src/python/tom_learner05/learner.py from c0mbatduckzz/TOMK: direct link, hf CLI and curl.
- Browser
- Download file 13.3 kB
-
https://huggingface.co/c0mbatduckzz/TOMK/resolve/main/src/python/tom_learner05/learner.py
- Command line
-
hf download hf://c0mbatduckzz/TOMK/src/python/tom_learner05/learner.py
-
curl -L -o learner.py https://huggingface.co/c0mbatduckzz/TOMK/resolve/main/src/python/tom_learner05/learner.py
13.3 kB
| """Deterministic observation-to-hypothesis pipeline for TOM Learner 0.1.""" | |
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| import hashlib | |
| from typing import Any, Iterable, Mapping | |
| from tom_world03.canonical import attach_hash, canonical_bytes, require_hash | |
| from tom_world03.rational import Q | |
| from .affine import ( | |
| candidate_coefficients, | |
| counterexamples_from_evidence, | |
| derive_candidates, | |
| evaluate_candidate, | |
| find_contradictions, | |
| select_from_training, | |
| ) | |
| from .model import ObservationSet, PROFILE | |
| from .split import deterministic_split | |
| DECISION_SCHEMA = "TOM-LEARNER-ACCEPTANCE-DECISION-0.1" | |
| CERTIFICATE_SCHEMA = "TOM-LEARNING-CERTIFICATE-0.1" | |
| LEARNED_DEFINITION_SCHEMA = "TOM-LEARNED-AFFINE-DEFINITION-0.1" | |
| REJECTION_LINEAGE_SCHEMA = "TOM-REJECTED-CANDIDATE-LINEAGE-0.1" | |
| def _hash_values(value: Any) -> str: | |
| return "sha256:" + hashlib.sha256(canonical_bytes(value)).hexdigest() | |
| def _selected_candidate( | |
| selection: Mapping[str, Any], | |
| candidates: Iterable[Mapping[str, Any]], | |
| ) -> Mapping[str, Any] | None: | |
| selected_hash = selection.get("selected_candidate_hash") | |
| if selected_hash is None: | |
| return None | |
| for candidate in candidates: | |
| if candidate.get("content_hash") == selected_hash: | |
| return candidate | |
| raise ValueError("selection references a candidate absent from enumeration") | |
| def _evidence_for( | |
| candidate: Mapping[str, Any] | None, | |
| candidates: list[Mapping[str, Any]], | |
| evidence: list[Mapping[str, Any]], | |
| ) -> Mapping[str, Any] | None: | |
| if candidate is None: | |
| return evidence[0] if evidence else None | |
| wanted = candidate["content_hash"] | |
| for item in evidence: | |
| if item.get("candidate_hash") == wanted: | |
| return item | |
| raise ValueError("selected candidate has no residual evidence") | |
| def _decision( | |
| dataset: ObservationSet, | |
| split: Mapping[str, Any], | |
| selection: Mapping[str, Any], | |
| candidate: Mapping[str, Any] | None, | |
| evidence: Mapping[str, Any] | None, | |
| contradictions: list[Mapping[str, Any]], | |
| ) -> dict[str, Any]: | |
| reasons: list[str] = [] | |
| checks: list[dict[str, Any]] = [] | |
| def check(name: str, passed: bool, detail: str) -> None: | |
| checks.append({"name": name, "passed": bool(passed), "detail": detail}) | |
| if not passed: | |
| reasons.append(detail) | |
| counts = split["counts"] | |
| check("minimum training observations", int(counts["train"]) >= 2, | |
| "training split has fewer than two observations") | |
| check("minimum validation observations", int(counts["validation"]) >= 1, | |
| "validation split is empty") | |
| check("minimum holdout observations", int(counts["holdout"]) >= 1, | |
| "holdout split is empty") | |
| check("selected exact training candidate", candidate is not None, | |
| str(selection.get("reason", "no exact training candidate"))) | |
| if candidate is not None: | |
| check("model complexity", | |
| int(candidate["complexity"]) <= dataset.acceptance_policy.max_model_complexity, | |
| "selected model exceeds the declared complexity budget") | |
| else: | |
| check("model complexity", False, "no selected model exists") | |
| if evidence is None: | |
| check("exact training residuals", False, "no residual evidence exists") | |
| check("exact validation residuals", False, "no validation residual evidence exists") | |
| check("exact holdout residuals", False, "no holdout residual evidence exists") | |
| else: | |
| train_exact = bool(evidence["splits"]["train"]["metrics"]["exact"]) | |
| validation_exact = bool(evidence["splits"]["validation"]["metrics"]["exact"]) | |
| holdout_exact = bool(evidence["splits"]["holdout"]["metrics"]["exact"]) | |
| check("exact training residuals", train_exact, | |
| "selected/best candidate has a nonzero training residual") | |
| check("exact validation residuals", | |
| validation_exact or not dataset.acceptance_policy.require_exact_validation, | |
| "selected candidate has a nonzero validation residual") | |
| check("exact holdout residuals", | |
| holdout_exact or not dataset.acceptance_policy.require_exact_holdout, | |
| "selected candidate has a nonzero holdout residual") | |
| check("no exact-input contradictions", | |
| not contradictions or not dataset.acceptance_policy.reject_contradictions, | |
| "observation set contains contradictory exact outputs for one input") | |
| accepted = all(item["passed"] for item in checks) | |
| return attach_hash({ | |
| "schema": DECISION_SCHEMA, | |
| "profile": PROFILE, | |
| "observation_set_id": dataset.id, | |
| "observation_set_hash": dataset.content_hash, | |
| "split_certificate_hash": split["content_hash"], | |
| "acceptance_policy_hash": dataset.acceptance_policy.content_hash, | |
| "selection_certificate_hash": selection["content_hash"], | |
| "selected_candidate_hash": None if candidate is None else candidate["content_hash"], | |
| "evidence_hash": None if evidence is None else evidence["content_hash"], | |
| "contradiction_hashes": [item["content_hash"] for item in contradictions], | |
| "checks": checks, | |
| "accepted": accepted, | |
| "reasons": reasons, | |
| "policy_boundary": { | |
| "fit_and_selection_splits": ["train"], | |
| "validation_role": "acceptance gate only", | |
| "holdout_role": "final acceptance audit only", | |
| }, | |
| }) | |
| def _learned_definition( | |
| dataset: ObservationSet, | |
| candidate: Mapping[str, Any], | |
| certificate_hash: str, | |
| ) -> dict[str, Any]: | |
| a, b = candidate_coefficients(candidate) | |
| suffix = hashlib.sha256(canonical_bytes({ | |
| "dataset": dataset.id, | |
| "candidate": candidate["content_hash"], | |
| })).hexdigest()[:24] | |
| return attach_hash({ | |
| "schema": LEARNED_DEFINITION_SCHEMA, | |
| "profile": PROFILE, | |
| "id": f"definition:learned-affine:{suffix}", | |
| "kind": "learned-exact-affine-relation", | |
| "domain": { | |
| "input": dataset.input_name, | |
| "output": dataset.output_name, | |
| "numeric": "exact-rational", | |
| }, | |
| "codomain": "exact-rational-residual", | |
| "relation_interface": "SDF0@Def", | |
| "model": "y=a*t+b", | |
| "coefficients": {"a": a.to_record(), "b": b.to_record()}, | |
| "expression": { | |
| "op": "sub", | |
| "args": [ | |
| {"op": "field", "name": dataset.output_name}, | |
| { | |
| "op": "add", | |
| "args": [ | |
| { | |
| "op": "mul", | |
| "args": [ | |
| {"op": "const", "value": a.to_record()}, | |
| {"op": "field", "name": dataset.input_name}, | |
| ], | |
| }, | |
| {"op": "const", "value": b.to_record()}, | |
| ], | |
| }, | |
| ], | |
| }, | |
| "zero_locus": f"{dataset.output_name} = a*{dataset.input_name} + b", | |
| "source_observation_set_hash": dataset.content_hash, | |
| "source_candidate_hash": candidate["content_hash"], | |
| "source_learning_certificate_hash": certificate_hash, | |
| "base_world_hash": dataset.base_world_hash, | |
| "base_handoff_hash": dataset.base_handoff_hash, | |
| "provenance": { | |
| "class": "deterministically-induced-and-held-out-verified", | |
| "learner": PROFILE, | |
| }, | |
| }) | |
| class LearningRun: | |
| dataset: ObservationSet | |
| split_certificate: Mapping[str, Any] | |
| candidates: tuple[Mapping[str, Any], ...] | |
| enumeration: Mapping[str, Any] | |
| evidence: tuple[Mapping[str, Any], ...] | |
| selection: Mapping[str, Any] | |
| contradictions: tuple[Mapping[str, Any], ...] | |
| counterexamples: tuple[Mapping[str, Any], ...] | |
| decision: Mapping[str, Any] | |
| certificate: Mapping[str, Any] | |
| learned_definition: Mapping[str, Any] | None | |
| rejection_lineage: Mapping[str, Any] | None | |
| def accepted(self) -> bool: | |
| return bool(self.decision["accepted"]) | |
| def all_records(self) -> list[Mapping[str, Any]]: | |
| values: list[Mapping[str, Any]] = [ | |
| *self.dataset.source_records(), | |
| self.split_certificate, | |
| *self.candidates, | |
| self.enumeration, | |
| *self.evidence, | |
| self.selection, | |
| *self.contradictions, | |
| *self.counterexamples, | |
| self.decision, | |
| self.certificate, | |
| ] | |
| if self.learned_definition is not None: | |
| values.append(self.learned_definition) | |
| if self.rejection_lineage is not None: | |
| values.append(self.rejection_lineage) | |
| return values | |
| def summary(self) -> dict[str, Any]: | |
| candidate = self.learned_definition | |
| return { | |
| "observation_set_id": self.dataset.id, | |
| "observation_set_hash": self.dataset.content_hash, | |
| "accepted": self.accepted, | |
| "selected_candidate_hash": self.selection.get("selected_candidate_hash"), | |
| "learned_definition_hash": None if candidate is None else candidate["content_hash"], | |
| "candidate_count": len(self.candidates), | |
| "counterexample_count": len(self.counterexamples), | |
| "contradiction_count": len(self.contradictions), | |
| "decision_hash": self.decision["content_hash"], | |
| "certificate_hash": self.certificate["content_hash"], | |
| } | |
| def learn_observation_set(dataset: ObservationSet) -> LearningRun: | |
| split = deterministic_split(dataset) | |
| candidates, enumeration = derive_candidates(dataset, split) | |
| evidence = [evaluate_candidate(dataset, split, candidate) for candidate in candidates] | |
| selection = select_from_training(dataset, split, candidates, evidence) | |
| selected = _selected_candidate(selection, candidates) | |
| selected_evidence = _evidence_for(selected, candidates, evidence) | |
| contradictions = find_contradictions(dataset) | |
| counterexamples = [] if selected_evidence is None else counterexamples_from_evidence(dataset, selected_evidence) | |
| decision = _decision(dataset, split, selection, selected, selected_evidence, contradictions) | |
| certificate = attach_hash({ | |
| "schema": CERTIFICATE_SCHEMA, | |
| "profile": PROFILE, | |
| "observation_set_id": dataset.id, | |
| "observation_set_hash": dataset.content_hash, | |
| "base_world_hash": dataset.base_world_hash, | |
| "base_handoff_hash": dataset.base_handoff_hash, | |
| "split_certificate_hash": split["content_hash"], | |
| "assignment_basis_hash": split["assignment_basis_hash"], | |
| "candidate_enumeration_hash": enumeration["content_hash"], | |
| "fit_input_hash": enumeration["fit_input_hash"], | |
| "selection_certificate_hash": selection["content_hash"], | |
| "selected_candidate_hash": selection.get("selected_candidate_hash"), | |
| "selected_evidence_hash": None if selected_evidence is None else selected_evidence["content_hash"], | |
| "contradiction_hashes": [item["content_hash"] for item in contradictions], | |
| "counterexample_hashes": [item["content_hash"] for item in counterexamples], | |
| "acceptance_decision_hash": decision["content_hash"], | |
| "accepted": decision["accepted"], | |
| "phase_trace": [ | |
| "parse-observations", | |
| "deterministic-id-only-split", | |
| "fit-train-only", | |
| "select-train-only", | |
| "validation-gate", | |
| "holdout-audit", | |
| "contradiction-gate", | |
| "candidate-certificate", | |
| ], | |
| "causal_boundary": "certificate is a proposal record; it is not authoritative world state", | |
| }) | |
| learned_definition = None | |
| rejection_lineage = None | |
| if decision["accepted"]: | |
| if selected is None: | |
| raise AssertionError("accepted decision has no selected candidate") | |
| learned_definition = _learned_definition(dataset, selected, certificate["content_hash"]) | |
| else: | |
| rejection_lineage = attach_hash({ | |
| "schema": REJECTION_LINEAGE_SCHEMA, | |
| "profile": PROFILE, | |
| "observation_set_id": dataset.id, | |
| "observation_set_hash": dataset.content_hash, | |
| "learning_certificate_hash": certificate["content_hash"], | |
| "acceptance_decision_hash": decision["content_hash"], | |
| "candidate_hashes": [candidate["content_hash"] for candidate in candidates], | |
| "counterexample_hashes": [item["content_hash"] for item in counterexamples], | |
| "contradiction_hashes": [item["content_hash"] for item in contradictions], | |
| "reasons": list(decision["reasons"]), | |
| "retention": "rejected candidates and counterexamples remain in append-only lineage", | |
| }) | |
| return LearningRun( | |
| dataset=dataset, | |
| split_certificate=split, | |
| candidates=tuple(candidates), | |
| enumeration=enumeration, | |
| evidence=tuple(evidence), | |
| selection=selection, | |
| contradictions=tuple(contradictions), | |
| counterexamples=tuple(counterexamples), | |
| decision=decision, | |
| certificate=certificate, | |
| learned_definition=learned_definition, | |
| rejection_lineage=rejection_lineage, | |
| ) | |