# lawref.evaluator.effects

*module*

Effect materialization [§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power)–[§128](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#128-immunity) — второй шаг power-runtime.

Для каждой ACTIVE power-позиции с accepted exercise-событием проверяются
valid_when, temporal scope и применимые immunity ([§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power)-список), и только
затем constitutive-шаг создаёт legal effect (institutional факт в store,
proof-узел norm_creation с механизмом power_exercise).

Невалидная попытка ([§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power)): empirical event сохраняется как был accepted;
публикуется `invalidly_exercised(position)` (std-предикат) — никакого
автоматического `void ab initio`.

Immunity [§128](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#128-immunity) блокирует transformation, не attempted event. Соперничество
Power(E)/Immunity(E) решается rule-приоритетами создавших правил ([§106](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#106-priority-relation));
непобеждённая несравнимая пара — conservative materialization [§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power):
effect НЕ материализуется, default `no_effect_until_resolved`
(effect_conflict_policy профиля — вне v1), transformation-запрос по E
получает UNRESOLVED_NORMATIVE_CONFLICT (проброс через blocked-карту).

## lawref.evaluator.effects.NORM_STD

*attribute* · *module attribute*

```python
NORM_STD = 'urn:law:std#'
```

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

## lawref.evaluator.effects.VALID_WHEN_STATUS_TESTS

*attribute* · *module attribute*

```python
VALID_WHEN_STATUS_TESTS = ('established', 'not_known', 'refuted', 'unknown', 'supported', 'monotone')
```

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

## lawref.evaluator.effects.active_immunities

*function*

```python
def active_immunities(positions: list[dict]) -> list[dict]
```

[§128](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#128-immunity): ACTIVE-позиции иммунитета — общий срез обоих чтений (E-0120).

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

## lawref.evaluator.effects.exercise_literal

*function*

```python
def exercise_literal(exercise: dict) -> dict | None
```

Exercise-паттерн (Term, v1: CallTerm) → атом события.

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

## lawref.evaluator.effects.immunity_verdict

*function*

```python
def immunity_verdict(effect_literal: dict, payload: dict, pos_rule: str | None, immunities: list[dict], rule_gt) -> tuple[dict | None, bool, list[dict]]
```

[§128](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#128-immunity): применимые иммунитеты против ЭТОГО эффекта и исход их
соперничества с полномочием по приоритетам [§106](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#106-priority-relation).

Возвращает `(winner_block, conflict, applicable)`: `winner_block` —
иммунитет, победивший по [§106](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#106-priority-relation) (эффект блокирован), `conflict` —
непобеждённая несравнимая пара [§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power) (эффект тоже не создаётся,
conservative materialization), `applicable` — все иммунитеты, чей
`protected_effect` совпал (и `against`, если задан, направлен против
holder-а полномочия).

ОДНА функция на два чтения (E-0120): материализация эффекта здесь же и
путь запроса судье (`whynot.power_judgment_blockers`). Вторая копия
критерия применимости разошлась бы молча — ровно так канал суждения три
errata подряд не видел того, что видит материализация.

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

## lawref.evaluator.effects.materialize_effects

*function*

```python
def materialize_effects(store: SupportStore, positions: list[dict], registry: ProofRegistry, issues: list[dict], rule_reach: dict[str, set[str]], limits: dict | None = None, judgment_decls: dict[str, dict] | None = None) -> tuple[dict[str, dict], int]
```

Возвращает (blocked, created): blocked — literal_key(effect) →
{reason, positions} для transformation-запросов (reason == "conflict" →
UNRESOLVED_NORMATIVE_CONFLICT в query_truth); created — число
материализованных эффектов (прогресс [§143](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/19-part-xviii-norm-lifecycle-fulfillment-violation.ru.md#143-chains)-итерации).

`judgment_decls` — отношения суждения [§47.3](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/08-part-viii-type-system.ru.md#473-judgment) программы (E-0100): попытка
exercise при `valid_when`, не решённом ПО ПРИЧИНЕ судьи, не есть
недействительное осуществление — орган ещё не высказался.

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

## lawref.evaluator.effects.valid_when_conjuncts

*function*

```python
def valid_when_conjuncts(valid_when) -> list[tuple[str, dict]] | None
```

[§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power) `valid_when` → конъюнкты-пары (тест, литерал) в порядке записи
(E-0190, E-0191).

Исполнимое подмножество 0.1: литерал (в том числе под статусной обёрткой
[§65](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#65-status-tests)) либо `and` таких литералов; вложенные `and` читаются одним плоским
списком. Всё прочее (`or`, `not`, сравнение, терм) — None: форма вне
подмножества, о чём вызывающий обязан сказать `NON_EXECUTABLE_RULE`, а не
читать её как «условие не выполнено». Общий с путём запроса судье.

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

## lawref.evaluator.effects.valid_when_holds

*function*

```python
def valid_when_holds(test: str, status: str) -> bool
```

[§65](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#65-status-tests)/[§67](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#67-not_known) (E-0191): проходит ли статус пары литерала статус-тест.
Те же тесты, что у конъюнкта тела правила (`solver.solve`): `not_known` —
нет положительной опоры (NEITHER или FALSE_ONLY), `unknown` — ровно
NEITHER, `refuted` — ровно FALSE_ONLY, `supported`/`monotone` — любая
положительная опора, `established` — ровно TRUE_ONLY.

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

## lawref.evaluator.effects.valid_when_literal

*function*

```python
def valid_when_literal(valid_when) -> tuple[str, dict] | None
```

[§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power) `valid_when` → пара (статус-тест [§65](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/10-part-x-propositions-and-four-valued-support.ru.md#65-status-tests), ground-литерал).

Голый литерал — `established` ([§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)); статусная обёртка несёт свой тест
(E-0191): раньше читалась только её формула, и `not_known(c)` вычислялся
как «`c` установлено». Общий с путём запроса судьи
(`whynot.power_judgment_blockers`, E-0100): вторая копия списка допустимых
форм разошлась бы молча.

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

## lawref.evaluator.effects.valid_when_open_judgments

*function*

```python
def valid_when_open_judgments(conjuncts: list[tuple[str, dict]], store: SupportStore, judgment_decls: dict[str, dict]) -> list[dict] | None
```

[§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power)/[§47.3](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/08-part-viii-type-system.ru.md#473-judgment) (E-0100, E-0101, E-0191): литералы-отношения суждения, от
ответа судьи по которым зависит `valid_when`; None — условие выполнено.

Не прошедший конъюнкт с парой NEITHER — неопределённый (ответ судьи может
его решить); не прошедший конъюнкт с определённой парой — опровергнут, и
полномочие мертво, ответ судьи ничего не изменит (пустой список). Для
`established` это в точности прежнее «FALSE_ONLY или BOTH».

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