# lawref.evaluator.strict

*module*

Strict closure — SPEC [§103](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#103-strict-closure), и temporal scope правила — [§87](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#87-rule-temporal-qualifiers).

Наименьшая неподвижная точка строгих правил над accepted-входами; выводы
получают origin derived ([§73](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/11-part-xi-assertions-facts-evidence.ru.md#73-origin)) и proof-узел rule_application ([§180](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#180-rule-application-proof)).

## lawref.evaluator.strict.SemiPlan

*attribute* · *module attribute*

```python
SemiPlan = tuple[list[tuple[str, dict]], list[dict]] | None
```

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

## lawref.evaluator.strict.StrictPrep

*attribute* · *module attribute*

```python
StrictPrep = tuple[list[tuple[dict, list[tuple[str, dict]]]], dict[str, int] | None, list[tuple[str, dict]], list[dict], set, dict, dict[str, frozenset[str]], frozenset[str]]
```

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

## lawref.evaluator.strict.negative_addend

*function*

```python
def negative_addend(aggregates: list[dict], subst: dict[str, dict], store: SupportStore, registry: ProofRegistry, issues: list[dict], rule_id: str, env: Any = None) -> bool
```

[§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-0116): есть ли под монотонным гардом ОТРИЦАТЕЛЬНОЕ
слагаемое `sum` на этой подстановке. Если есть — issue
`MONOTONE_GUARD_NEGATIVE_ADDEND` (error, адрес правила) и правило на
подстановке не срабатывает: сумма отрицательных слагаемых над растущим
множеством УБЫВАЕТ, и least fixed point [§103](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#103-strict-closure) по такому гарду не определён.

ОБЩАЯ функция обоих слоёв (дописано 03.09.2026): до этой правки проверка
стояла только здесь, в строгом слое, и та же сумма под тем же гардом у
правила `defeasible`/`defeater` [§104](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#104-defeasible-candidate) считалась молча — ноль issue при
неопределённом фикспойнте. Слой знака слагаемых не меняет: [§111](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#111-порядок-evaluation-strata) говорит о
монотонности гарда, а не о силе правила. Единственная дуга здесь та же,
что у `strict_closure`: `defeasible` зовёт `strict`, обратной нет.

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

## lawref.evaluator.strict.prepare_strict

*function*

```python
def prepare_strict(nodes: list[dict]) -> StrictPrep
```

Установка строгого слоя — чистая функция от узлов программы:
(исполнимые правила с конъюнктами, ранги [§110](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#110-stratification) либо None, предупреждения
NON_EXECUTABLE_RULE по id правила, issues рангов). Вид программы
(`evaluator.prepared`) считает её один раз; до 02.09.2026 классификация
2124 правил kz-income-tax, их страты и анализ агрегатов повторялись в
каждом из трёх вызовов `strict_closure` на КАЖДОЕ дело (0,7 с + 0,46 с).
Issues записаны, а не выброшены: `strict_closure` воспроизводит их в том
же порядке и тем же числом раз, что и до кэша, — байты документа целы.

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

## lawref.evaluator.strict.strict_closure

*function*

```python
def strict_closure(store: SupportStore, nodes: list[dict], legal_time: str, registry: ProofRegistry, issues: list[dict], limits: dict | None = None, env: Any = None, prepared: StrictPrep | None = None) -> None
```

Strict closure [§103](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#103-strict-closure): наименьшая неподвижная точка строгих правил над
accepted-входами; head-выводы получают origin derived ([§73](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/11-part-xi-assertions-facts-evidence.ru.md#73-origin)) и proof-узел
rule_application ([§180](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#180-rule-application-proof)). V1-ограничения (issue NON_EXECUTABLE + пропуск
правила): только strength=strict, head-Literal позитивной полярности,
scope=true, body из established-конъюнктов.

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

## lawref.evaluator.strict.strict_ranks

*function*

```python
def strict_ranks(rules: list[tuple[dict, list[tuple[str, dict]]]], issues: list[dict], derived: set[str] | frozenset[str] = frozenset()) -> dict[str, int] | None
```

Ранги [§110](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#110-stratification) внутри строгого слоя (DECISION-0088 [§2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/01-part-i-audit.ru.md#2-что-необходимо-исправить)): монотонное чтение
(`supported`/`monotone`) конъюнктом — ранг производителя, статусно-
чувствительное (голый атом, `established`, `not_known`, `unknown`,
`refuted`) и перечисление (generator агрегата или домена квантора —
ребро `completion`, errata E-0112, обёртка `monotone` его не снимает) —
ранг производителя + 1; правила одной головы обеих полярностей — в одной
страте ([§110](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#110-stratification) п. 5). Несходимость — `NON_EXECUTABLE_UNSTRATIFIED`.
Позитивной программе ранги не нужны — все нули (`_needs_strata`).

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