# lawref.evaluator.support

*module*

Пара поддержки (t, f) на ground-атом — SPEC [§61](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#61-literal)–[§63](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#63-explicit-negation).

Хранилище фактов оракула: стороны поддержки раздельны ([§61](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#61-literal)), статус атома —
проекция пары ([§62](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#62-support-pair)/[§63](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#63-explicit-negation)), established и surviving defeasible ([§108](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#108-surviving-support)) считаются
вместе. Здесь же `term_error` — донесение ошибки вычисления терма [§58](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/09-part-ix-values-terms-expressions.ru.md#58-arithmetic), которое
дедуплицируется по `store.term_errors` и потому принадлежит store, а не
конкретному замыканию.

## lawref.evaluator.support.SupportStore

*class*

```python
class SupportStore
```

Пара поддержки (t, f) на ground-атом (SPEC [§62](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#62-support-pair)); стороны хранятся раздельно ([§61](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#61-literal)).

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

### lawref.evaluator.support.SupportStore.apply_counters

*attribute* · *instance attribute*

```python
apply_counters: dict[str, int] = {}
```

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

### lawref.evaluator.support.SupportStore.atoms

*attribute* · *instance attribute*

```python
atoms: dict[str, dict] = {}
```

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

### lawref.evaluator.support.SupportStore.closures_done

*attribute* · *instance attribute*

```python
closures_done: set[str] = set()
```

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

### lawref.evaluator.support.SupportStore.derived_seen

*attribute* · *instance attribute*

```python
derived_seen: set[tuple[str, bytes]] = set()
```

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

### lawref.evaluator.support.SupportStore.derived_type_errors

*attribute* · *instance attribute*

```python
derived_type_errors: set[tuple[str, str, int, str]] = set()
```

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

### lawref.evaluator.support.SupportStore.dnegative

*attribute* · *instance attribute*

```python
dnegative: dict[str, list[str]] = {}
```

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

### lawref.evaluator.support.SupportStore.dpositive

*attribute* · *instance attribute*

```python
dpositive: dict[str, list[str]] = {}
```

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

### lawref.evaluator.support.SupportStore.negative

*attribute* · *instance attribute*

```python
negative: dict[str, list[str]] = {}
```

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

### lawref.evaluator.support.SupportStore.norm_counters

*attribute* · *instance attribute*

```python
norm_counters: dict[str, int] = {}
```

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

### lawref.evaluator.support.SupportStore.norm_seen

*attribute* · *instance attribute*

```python
norm_seen: set[tuple[str, bytes]] = set()
```

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

### lawref.evaluator.support.SupportStore.positive

*attribute* · *instance attribute*

```python
positive: dict[str, list[str]] = {}
```

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

### lawref.evaluator.support.SupportStore.predicate_versions

*attribute* · *instance attribute*

```python
predicate_versions: dict[str, int] = {}
```

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

### lawref.evaluator.support.SupportStore.rule_stamps

*attribute* · *instance attribute*

```python
rule_stamps: dict[str, int] = {}
```

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

### lawref.evaluator.support.SupportStore.sig_aliases

*attribute* · *instance attribute*

```python
sig_aliases: dict[str, str] = {}
```

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

### lawref.evaluator.support.SupportStore.sig_bases

*attribute* · *instance attribute*

```python
sig_bases: dict[str, str] = {}
```

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

### lawref.evaluator.support.SupportStore.sig_constants

*attribute* · *instance attribute*

```python
sig_constants: dict[str, str | None] = {}
```

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

### lawref.evaluator.support.SupportStore.signatures

*attribute* · *instance attribute*

```python
signatures: dict[str, list[tuple[str, str | None]]] = {}
```

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

### lawref.evaluator.support.SupportStore.stamp

*attribute* · *instance attribute*

```python
stamp: int = 0
```

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

### lawref.evaluator.support.SupportStore.stamps

*attribute* · *instance attribute*

```python
stamps: dict[str, int] = {}
```

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

### lawref.evaluator.support.SupportStore.term_errors

*attribute* · *instance attribute*

```python
term_errors: set[tuple[str, str]] = set()
```

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

### lawref.evaluator.support.SupportStore.warned_rules

*attribute* · *instance attribute*

```python
warned_rules: set[str] = set()
```

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

### lawref.evaluator.support.SupportStore.accepted_positive_keys

*method*

```python
def accepted_positive_keys(predicate: str) -> list[str]
```

Ключи атомов предиката, у которых есть ВХОДНАЯ positive-опора
(assertion или strict-вывод), в возрастающем порядке ключа.

Отличие от `established_positive` — не фильтр статуса, а сторона:
[§45.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/08-part-viii-type-system.ru.md#451-relation-keys)/[§196](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/27-part-xxvi-static-semantics-and-diagnostics.ru.md#196-data-quality-checks) смотрят на `positive`, как halt E-0001 и closure [§70](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#70-closed-world-declarations), и
defeasible-опоры (`dpositive`) в счёт не идут. Индекс `_by_predicate`
держит объединение сторон, поэтому отбор по `positive` остаётся.

Множество и порядок те же, что давал `sorted(self.positive)` с отбором
по предикату: порядок ключей тотален, и фильтрация глобально
отсортированной последовательности совпадает с сортировкой
отфильтрованного подмножества (тот же аргумент, что у индекса выше).

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

### lawref.evaluator.support.SupportStore.add

*method*

```python
def add(literal: dict, assertion_id: str) -> None
```

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

### lawref.evaluator.support.SupportStore.add_defeasible

*method*

```python
def add_defeasible(literal: dict, proof_id: str) -> None
```

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

### lawref.evaluator.support.SupportStore.conflicts

*method*

```python
def conflicts() -> list[str]
```

Ключи атомов с одновременной accepted-поддержкой обеих полярностей.

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

### lawref.evaluator.support.SupportStore.established_positive

*method*

```python
def established_positive(predicate: str, bound: tuple[tuple[int, bytes], ...] = (), min_stamp: int = -1) -> list[dict]
```

Ground-атомы предиката со статусом TRUE_ONLY (established, [§65](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#65-status-tests)/[§66](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#66-rule-body-default)) —
база для grounding строгих правил ([§103](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#103-strict-closure)). Порядок детерминирован.
`min_stamp` — как у `supported_positive`.

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

### lawref.evaluator.support.SupportStore.established_side

*method*

```python
def established_side(literal: dict) -> list[str]
```

Опоры БЕЗ defeasible ([§107](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#107-defeat) правило 1: только strict/assertions
побеждают кандидата безусловно).

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

### lawref.evaluator.support.SupportStore.status_only

*method*

```python
def status_only(literal: dict) -> str
```

truth_status без списков опор: та же [§62](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#62-support-pair)-проекция, [§63](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#63-explicit-negation)-зеркало
для negative-литерала. Байтам документа не виден — оба пути обязаны
давать один статус (сверяется в selftest).

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

### lawref.evaluator.support.SupportStore.support_sides

*method*

```python
def support_sides(literal: dict) -> tuple[list[str], list[str]]
```

Стороны пары [§62](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#62-support-pair) литерала — опоры `t` и `f`, отсортированные; [§63](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#63-explicit-negation):
у negative-литерала стороны зеркалятся. Одна сборка для
`truth_status` и для составного условия цели (errata E-0218).

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

### lawref.evaluator.support.SupportStore.supported_positive

*method*

```python
def supported_positive(predicate: str, bound: tuple[tuple[int, bytes], ...] = (), min_stamp: int = -1) -> list[dict]
```

Ground-атомы предиката с ЛЮБОЙ positive-опорой ([§65](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#65-status-tests) supported —
монотонный перечислитель: BOTH не исключается; [§103](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#103-strict-closure) разрешает
рекурсию строгих правил только через такие рёбра). `min_stamp ≥ 0` —
только атомы, получившие опору позже этого штампа (semi-naive);
подсписок того же упорядоченного списка, порядок цел.

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

### lawref.evaluator.support.SupportStore.term_bytes

*method*

```python
def term_bytes(term: dict) -> bytes
```

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

### lawref.evaluator.support.SupportStore.truth_status

*method*

```python
def truth_status(literal: dict) -> tuple[str, list[str]]
```

[§62](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#62-support-pair): (t,f) → TRUE_ONLY | FALSE_ONLY | BOTH | NEITHER; [§63](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#63-explicit-negation): запрос negative-
литерала — это neg(t,f), т.е. статусы зеркалятся. Пары считаются по
объединению established и surviving defeasible supports ([§108](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#108-surviving-support)/[§111.7](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#111-порядок-evaluation-strata)).

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

## lawref.evaluator.support.literal_key

*function*

```python
def literal_key(literal: dict) -> str
```

Ключ ground-атома: predicate + канонические args (полярность отдельно, [§61](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#61-literal)–[§62](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#62-support-pair)).

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

## lawref.evaluator.support.pair_status

*function*

```python
def pair_status(pos: list[str], neg: list[str]) -> tuple[str, list[str]]
```

[§62](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#62-support-pair): стороны пары → статус и его опоры (у BOTH — сначала `t`, потом `f`).

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

## lawref.evaluator.support.term_error

*function*

```python
def term_error(store: SupportStore, issues: list[dict], rule_id: str, where: str, exc: 'vals.ValueError_') -> None
```

[§58](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/09-part-ix-values-terms-expressions.ru.md#58-arithmetic): ошибка вычисления терма при применении правила. Не превращается в
UNKNOWN и не публикует факт — доносится issue с адресом правила: `error`,
кроме `MISSING_PARAMETER_VALUE` — `warning` ([§175](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/25-part-xxiv-queries-and-results.ru.md#175-evaluationstatus), errata E-0171).

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

## lawref.evaluator.support.term_error_issue

*function*

```python
def term_error_issue(rule_id: str, where: str, exc: 'vals.ValueError_') -> dict
```

Полезная нагрузка issue ошибки терма [§58](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/09-part-ix-values-terms-expressions.ru.md#58-arithmetic) — одна сборка на оба пути:
немедленный (`term_error`) и УДЕРЖИВАЕМЫЙ до закрытия страты [§111](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#111-порядок-evaluation-strata)
(errata E-0198, `strict.strict_closure`). Две копии разошлись бы молча, а
текст issue — байтовый контракт с движком.

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