Skip to content

lawref.evaluator.facts

Факты дела в support: приём, ключи, замыкание домена.

ingest — assertions → accepted support (§71–§73, §78.1); check_keys — relation keys §45.1 / data quality §196; materialize_closures — closed-world declarations §70.

Attributes

NameDescription
ACCEPTED_ORIGINSNo description.

Functions

NameDescription
assertion_table§78.2.3.1 для assertion (errata E-0158): один StableId — одно содержание.
check_argument_typesАрность и типы аргументов утверждения против сигнатуры §189 (errata E-0046).
check_derived_typesТипы аргументов ВЫВЕДЕННОГО атома против сигнатуры §189 (errata E-0077).
check_judgment_answer§47.3.1 (errata E-0089): ответ судьи с объектом judgment принимается,
check_keysRelation keys §45.1 / data quality §196: два различных accepted-кортежа с
extracted_without_evidenceDECISION-0360: извлечённый факт (was_generated_by с extractor)
ingestAssertions → accepted support (§71–§73; §78.1 — тривиальная acceptance L0).
materialize_closuresClosed-world declarations §70: при deriveExplicitNegative отсутствие
prepare_closuresУстановка замыканий §70 — чистая функция от узлов: арности деклараций,
signature_indexИндекс сигнатур по узлам программы — то, что вид программы

ACCEPTED_ORIGINSattributemodule attribute#

ACCEPTED_ORIGINS = {'case_input', 'source_asserted', 'external_snapshot', 'adjudicated', 'derived'}

assertion_tablefunction#

def assertion_table(nodes: list[dict]) -> tuple[list[dict], list[dict]]

§78.2.3.1 для assertion (errata E-0158): один StableId — одно содержание.

Две записи одного id с побайтово равным каноническим содержанием §208 — одна запись (дубль сворачивается, первая остаётся на месте); с различным — fatal issue ASSERTION_ID_COLLISION, и результат не вычисляется. До errata обе реализации складывали утверждения в таблицу по id, и второе молча заменяло первое: перестановка входного массива меняла правовой вывод без единой issue. Форма и место — зеркало EVIDENCE_ID_COLLISION (evidence._table); правило одинаково для узла программы и записи дела.

Проверка стоит в ingest §71 ПЕРВОЙ — до приёмки §78.2, до разыменования констант §54 и до фильтров origin §73 и valid §72: иначе две реализации, поставившие её в разные места, разошлись бы байтами на деле, где первое утверждение отвергается политикой или окном. caseHash при этом НЕ пересчитывается — дедуплицируется рабочее представление ingest, а не предъявленное дело (гейт Astra).

Возвращает (узлы без дублей, коллизии); узлы иных видов проходят как есть.

check_argument_typesfunction#

def check_argument_types(node: dict, signatures: dict, constants: dict, bases: dict, issues: list[dict], aliases: dict | None = None) -> bool

Арность и типы аргументов утверждения против сигнатуры §189 (errata E-0046).

Тот же контракт, что у компилятора: assert born_on(42, 7) в акте отвергается LDC-E2104 («§48: неявных конверсий нет»), а через транспортный case-документ то же утверждение принималось молча и порождало правовой вывод о числе 42. Проверка не выбирает и не чинит — несогласованное утверждение не принимается, и причина названа.

check_derived_typesfunction#

def check_derived_types(literal: dict, rule_id: str, store: SupportStore, issues: list[dict]) -> bool

Типы аргументов ВЫВЕДЕННОГО атома против сигнатуры §189 (errata E-0077).

Та же дисциплина, что у дела (E-0046), — до правки два входных пути одного support жили под разной: утверждение дела с Rational в Decimal-слоте отвергалось громко, а голова правила клала ту же пару МОЛЧА (замер kz.tarify Н5: Money-слот принял Quantity[tenge_per_kWh] со статусом TRUE_ONLY; phys.zadachnik: Decimal-слот принял Rational 1/3). Отказ зеркален делу: несогласованный вывод НЕ принимается, причина названа. Арность здесь не сверяется — у выведенной головы её держит компилятор (§189, путь исходника), транспортного канала у вывода нет. entity_ref и неизвестные const_ref пропускаются, как у дела: проверка утверждает только то, что может доказать.

check_judgment_answerfunction#

def check_judgment_answer(node: dict, nodes: list[dict], issues: list[dict]) -> bool

§47.3.1 (errata E-0089): ответ судьи с объектом judgment принимается, только если орган совпадает с декларацией отношения, а payload — с request_schema (тот же тест вида, что у аргумента утверждения дела, E-0046). Ответ без judgment — утверждение самого отношения, как до errata (v1-совместимость). Непринятый ответ не даёт опоры: результат остаётся REQUIRES_JUDGMENT с тем же JudgmentRequest.

check_keysfunction#

def check_keys(store: SupportStore, nodes: list[dict], issues: list[dict]) -> None

Relation keys §45.1 / data quality §196: два различных accepted-кортежа с одинаковой key-проекцией — KEY_CONFLICT; evaluator ничего не выбирает и не удаляет, конфликт попадает в отчёт.

extracted_without_evidencefunction#

def extracted_without_evidence(node: dict) -> bool

DECISION-0360: извлечённый факт (was_generated_by с extractor) при origin case_input и пустом evidence. Принимается в поддержку; вызывающий получает warning, а не новый origin и не отказ.

ingestfunction#

def ingest(store: SupportStore, nodes: list[dict], mode: str, legal_time: str, issues: list[dict], signature_index: tuple[dict, dict, dict, dict] | None = None, acceptance=None) -> dict[str, dict]

Assertions → accepted support (§71–§73; §78.1 — тривиальная acceptance L0). assumed_for_simulation принимается только в mode=simulation (§73); assertion с valid-интервалом вне legal_time не участвует в support (§72, ось valid).

При выбранной EvidencePolicy (acceptance) утверждение ЗАЩИЩЁННОГО предиката §78.2.4 не принимается ни при каком origin и ни из какого носителя: ни из дела, ни из программы, ни из импорта, ни из snapshot-а. Проверка стоит ПЕРВОЙ — раньше origin, valid и типов: обход границы доверия не должен зависеть от того, прошло ли утверждение остальные сита. Причина уходит в типизированный отчёт и одним info-issue в документ: молчание здесь и есть тот отказ, ради которого политика заводится.

materialize_closuresfunction#

def materialize_closures(store: SupportStore, nodes: list[dict], registry: 'ProofRegistry', issues: list[dict], legal_time: str | None = None, prepared: tuple | None = None) -> None

Closed-world declarations §70: при deriveExplicitNegative отсутствие positive-записи для члена pinned-домена порождает explicit negative с closure-сертификатом в proof (§231.1). Errata E-0087: закрытый предикат — любой арности, домен — предикат ТОЙ ЖЕ арности (его установленные кортежи и есть закрытая область), effective §87 уважается — вне legal_time замыкание не порождает ни одного негатива. Домен — const_ref на предикат; eager-материализация (lazy anti-join §231.1 — оптимизация вехи M4+).

prepare_closuresfunction#

def prepare_closures(nodes: list[dict]) -> tuple[dict[str, int], list[dict], list[list[dict]] | None]

Установка замыканий §70 — чистая функция от узлов: арности деклараций, политики в порядке id и их УРОВНИ (errata E-0113) — группы политик по возрастанию уровня, внутри группы порядок id. Вид программы (evaluator.prepared) считает её один раз; на kz-income-tax (9790 узлов) это было 0,5 с на КАЖДЫЙ вызов. None в третьей позиции — цикл между замыканиями (страховка: его называет stratification_problem).

signature_indexfunction#

def signature_index(nodes: list[dict]) -> tuple[dict, dict, dict, dict]

Индекс сигнатур по узлам программы — то, что вид программы (evaluator.prepared) считает один раз; утверждения дела в него не входят по построению (_signature_index читает только декларации).

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.