# lawref.evaluator.interpretations

*module*

Interpretations [§152](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#152-interpretation)–[§157](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#157-extends) — выбор альтернатив и изоляция теорий.

Membership правила: node.interpretations ([§101](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/15-part-xiv-rules.ru.md#101-rule-identity)-поле) ∪ interpretation.includes
([§152](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#152-interpretation)), с композицией extends/excludes [§157](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#157-extends) (set composition, не mutation).
Правило с непустой принадлежностью активно ТОЛЬКО при выбранной интерпретации;
пустая принадлежность — base theory, активна всегда.

Выбор — options.selectedInterpretations (семантически активен: попадает в
EvaluationInputManifest.interpretations). Группа [§155](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#155-interpretation-group) exactly_one без ровно
одного выбранного из alternatives — INTERPRETATION_REQUIRED ([§156](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#156-evaluation-of-alternatives)): правила
всех её альтернатив исключаются (результаты НЕ смешиваются), запрос получает
evaluationStatus INTERPRETATION_REQUIRED. selection any_of — любое подмножество;
compose_explicitly — вне v1 (правила исключаются с предупреждением).

## lawref.evaluator.interpretations.CARRIER_CODES

*attribute* · *module attribute*

```python
CARRIER_CODES = ('TYPE_ERROR', 'JUDGMENT_AUTHORITY_MISMATCH', 'JUDGMENT_PAYLOAD_MISMATCH', 'PRIORITY_CONFLICT')
```

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L316-L317)

## lawref.evaluator.interpretations.carrier_issue_scope

*function*

```python
def carrier_issue_scope(nodes: list[dict], case: dict, issues: list[dict], query: dict) -> None
```

[§181.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#1812-total-outcome-при-блокирующей-диагностике) (errata E-0243, E-0244, E-0245): issue `TYPE_ERROR`,
`JUDGMENT_AUTHORITY_MISMATCH`, `JUDGMENT_PAYLOAD_MISMATCH` и
`PRIORITY_CONFLICT` уровня `error` блокируют только результат, чей вопрос
читает предикат носителя по графу [§110](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#110-stratification) — тем же замыканием вперёд, что у
E-0192, E-0210 и E-0236. В документе независимого результата issue
сохраняет код, сообщение, `relatedNodes` и `details`, но несёт `warning`.
Разбор по КАЖДОЙ issue отдельно; граница — по ПРОГРАММЕ, а не по делу.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L365-L394)

## lawref.evaluator.interpretations.constraint_scope

*function*

```python
def constraint_scope(nodes: list[dict], constraint_ids: set[str], query: dict) -> set[str]
```

[§181.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#1812-total-outcome-при-блокирующей-диагностике) (errata E-0236): от каких из нарушенных ограничений [§93](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/13-part-xiii-context-scope-applicability.ru.md#93-material-и-personal-scope) результат
вопроса ЗАВИСИТ. Возвращает подмножество `constraint_ids`: их
`CONSTRAINT_VIOLATED`/`CONSTRAINT_CONFLICTED` остаётся блокирующей, у
остальных — `warning`.

Тот же механизм, что у `key_conflict_scope` (E-0210), с одним отличием —
началом замыкания: у конфликта ключа это само отношение, у ограничения —
множество предикатов его клауз `scope`, `when` и `require`, поэтому вопрос
о любом из них зависим всегда. Разбор по КАЖДОМУ ограничению отдельно:
носитель issue назван `relatedNodes`, и зависимость от одного ограничения
не делает блокирующей issue другого. Ограничение, которого нет в узлах
(носитель не разобран), считается зависимым — ошибка в безопасную сторону.
Рёбра строятся ОДИН раз на все ограничения; порядок обхода — [§208](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/28-part-xxvii-canonical-legal-ir.ru.md#208-canonical-serialization)-порядок
идентификаторов, результат от него не зависит (множество).

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L278-L311)

## lawref.evaluator.interpretations.constraint_seed

*function*

```python
def constraint_seed(node: dict) -> set[str]
```

Предикаты, которые читает ограничение [§93](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/13-part-xiii-context-scope-applicability.ru.md#93-material-и-personal-scope) — `scope`, `when`
(`antecedent`) и `require` (`requirement`). Обход один и тот же у обеих
реализаций: `literal_predicates` по каждой из трёх клауз.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L266-L275)

## lawref.evaluator.interpretations.dependent_positions

*function*

```python
def dependent_positions(nodes: list[dict], blocked_interps: set[str], membership: dict[str, set[str]], dependent: set[str]) -> bool
```

[§134](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/19-part-xviii-norm-lifecycle-fulfillment-violation.ru.md#134-positioninstance-statuses)/[§156](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#156-evaluation-of-alternatives) (E-0140, дополнение): зависят ли нормативные позиции от
неразрешённой группы. Да, если хотя бы одно правило-производитель позиции
(голова `norm_template_ref`) заблокировано — под другой альтернативой
позиция существовала бы, — либо активный производитель читает зависимый
предикат: его посылки под другой альтернативой были бы другими.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L149-L168)

## lawref.evaluator.interpretations.dependent_predicates

*function*

```python
def dependent_predicates(nodes: list[dict], blocked_interps: set[str], membership: dict[str, set[str]]) -> set[str]
```

[§156](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#156-evaluation-of-alternatives) (errata E-0140): предикаты, чей ответ ЗАВИСИТ от неразрешённой
группы — замыкание по телам правил от голов узлов заблокированных
альтернатив.

Считается над ПОЛНЫМ набором узлов (включая исключённые): зависимость —
свойство программы, а не выбора. Ребро берётся тем же извлекателем, что
у стратификации [§110](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#110-stratification) (`rules._predicate_edges`: потребитель ← продюсер по
каждому конъюнкту тела, включая негатив, not_known и кванторы), поэтому
«зависит» здесь значит «есть путь по телам правил», и он один у обеих
реализаций.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L97-L129)

## lawref.evaluator.interpretations.forward_closure

*function*

```python
def forward_closure(edges: list[tuple], seed: set[str]) -> set[str]
```

Замыкание вперёд по рёбрам предикатного графа [§110](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#110-stratification) — общий ход [§181.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#1812-total-outcome-при-блокирующей-диагностике).

То же, что у [§156](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#156-evaluation-of-alternatives) (`dependent_predicates`): от предикатов `seed` по рёбрам
(каждый конъюнкт тела, включая негатив, `not_known`, статус-тесты и
кванторы; голова дефитера [§95.3](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/15-part-xiv-rules.ru.md#953-defeater) — поражаемый литерал), вперёд, до
неподвижной точки. `seed` входит в результат.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L171-L186)

## lawref.evaluator.interpretations.key_conflict_scope

*function*

```python
def key_conflict_scope(nodes: list[dict], predicates: set[str], query: dict) -> set[str]
```

[§181.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#1812-total-outcome-при-блокирующей-диагностике) (errata E-0210): какие из отношений с конфликтом ключа [§45.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/08-part-viii-type-system.ru.md#451-relation-keys)
результат вопроса ЧИТАЕТ. Возвращает подмножество `predicates`, от которых
он зависит: их `KEY_CONFLICT` остаётся блокирующей, у остальных — `warning`.

Тот же механизм, что у `term_error_scope` (E-0192), с одним отличием —
началом замыкания: у ошибки терма это голова упавшего правила, у конфликта
ключа само отношение, поэтому вопрос о нём зависим всегда. Разбор по
КАЖДОМУ отношению отдельно: носитель issue — отношение, и зависимость от
одной таблицы не делает блокирующей issue другой. Рёбра строятся ОДИН раз
на все отношения; порядок обхода — [§208](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/28-part-xxvii-canonical-legal-ir.ru.md#208-canonical-serialization)-порядок предикатов, результат от
него не зависит (множество).

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L245-L263)

## lawref.evaluator.interpretations.literal_predicates

*function*

```python
def literal_predicates(value) -> set[str]
```

Все предикаты литералов внутри произвольного поддерева CLIR — тела
правила, comprehension-терма запроса. Обход одинаков у обеих реализаций:
объект с `kind == "literal"` и строковым `predicate` даёт предикат, всё
остальное обходится рекурсивно.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L132-L146)

## lawref.evaluator.interpretations.query_reads

*function*

```python
def query_reads(query: dict, tainted: set[str]) -> bool
```

Читает ли вопрос хоть один предикат из `tainted` — вторая половина
разбора [§181.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#1812-total-outcome-при-блокирующей-диагностике). `truth`/`why_not`/`focused_truth` — по предикату литерала
(у `focused_truth` вопрос тот же, что у полного `truth`, [§181.3](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#1813-полнота-относительно-вопроса-focused_truth-decision-0368)), `collect`
и `formula` — по любому предикату терма вопроса; `positions` и прочие виды,
у которых зависимость не разбирается, читают всё.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L189-L201)

## lawref.evaluator.interpretations.resolve_interpretations

*function*

```python
def resolve_interpretations(nodes: list[dict], options: dict, issues: list[dict]) -> tuple[list[dict], list[str], bool, set[str], bool]
```

→ (эффективные nodes, sorted selected для манифеста, interpretation_required,
зависимые предикаты [§156](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#156-evaluation-of-alternatives)/E-0140, зависимость позиций [§134](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/19-part-xviii-norm-lifecycle-fulfillment-violation.ru.md#134-positioninstance-statuses)).

Исключает из исполнения узлы с непустой интерпретационной принадлежностью,
не покрытой выбором; при неразрешённой exactly_one-группе — исключает все
её альтернативы и поднимает флаг [§156](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#156-evaluation-of-alternatives).

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L30-L94)

## lawref.evaluator.interpretations.term_error_scope

*function*

```python
def term_error_scope(nodes: list[dict], failed_rules: set[str], query: dict) -> set[str]
```

[§181.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#1812-total-outcome-при-блокирующей-диагностике) (errata E-0192, E-0242): от каких из правил, чей терм [§58](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/09-part-ix-values-terms-expressions.ru.md#58-arithmetic) не
вычислился, результат вопроса ЗАВИСИТ. Возвращает подмножество
`failed_rules`: issue их ошибок остаётся блокирующей, у остальных — `warning`.

Замыкание — `forward_closure` от ГОЛОВЫ правила. Разбор по КАЖДОМУ правилу
отдельно (errata E-0242): носитель issue — правило `relatedNodes: [R]`, и
зависимость от одного упавшего правила не делает блокирующей issue другого.
Граница — по ПРОГРАММЕ, не по делу. Правило с головой вне литерала
(производитель позиции [§135](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/19-part-xviii-norm-lifecycle-fulfillment-violation.ru.md#135-activation)) и носитель, которого среди правил нет
(позиция [§105.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#1052-обнаружение-и-разрешение-конфликта-позиций)), зависимы для любого вопроса — ошибка в безопасную
сторону; `positions` и прочие виды вопроса, у которых зависимость не
разбирается, зависимы. Рёбра строятся ОДИН раз, замыкание — один раз на
предикат головы; результат от порядка обхода не зависит (множество).

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/evaluator/interpretations.py#L204-L242)
