# lawref.evaluator.events

*module*

Событие как исполнимое значение — SPEC [§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156), [§81.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#811-версии-исправления-и-провенанс-decision-0156), [§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156) (DECISION-0156).

Здесь живут три вещи, которые свёртка [§161.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/22-part-xxi-procedures.ru.md#1611-свёртка-истории-decision-0156) и активация [§135.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/19-part-xviii-norm-lifecycle-fulfillment-violation.ru.md#1351-активация-событием-decision-0156) читают уже
готовыми:

- **таблица значений-событий** по `id` ([§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156)): конструктор-запись [§53](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/09-part-ix-values-terms-expressions.ru.md#53-термы) в
  константе пакета [§54](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/09-part-ix-values-terms-expressions.ru.md#54-const), константе дела [§168](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/24-part-xxiii-cases-snapshots-evaluation.ru.md#168-case-file) и аргументе утверждения [§71](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/11-part-xi-assertions-facts-evidence.ru.md#71-assertion)
  собирается в ОДНУ таблицу; два значения одного `id` с разным каноническим
  содержанием [§208](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/28-part-xxvii-canonical-legal-ir.ru.md#208-canonical-serialization) — fatal `EVENT_ID_CONFLICT`, побайтово равные суть одно
  событие;
- **цепочки версий** [§81.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#811-версии-исправления-и-провенанс-decision-0156): `supersedes` даёт голову цепочки; цикл, две
  исправляющие версии, ссылка в неизвестный `id` либо в событие другого типа —
  fatal `EVENT_VERSION_CHAIN_BROKEN`;
- **политика темпорального разрешения** [§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156): `Date` → `[b(D), b(D+1))` по
  ФИКСИРОВАННОМУ смещению политики. Ни одна tz-база не читается ([§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156),
  детерминизм [§211](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/29-part-xxviii-compiler-pipeline.ru.md#211-determinism)): смещение записано в самой политике, и `zoneinfo` здесь
  не импортируется намеренно.

Отказы поднимаются ТОЛЬКО когда разрешение потребовалось ([§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156)): дело без
единой даты в `time` исполняется при любом числе объявленных политик.

## lawref.evaluator.events.DATE_T

*attribute* · *module attribute*

```python
DATE_T = 'urn:law:std#Date'
```

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

## lawref.evaluator.events.EVENT_ROOTS

*attribute* · *module attribute*

```python
EVENT_ROOTS = ('urn:law:std#Event', 'urn:law:std#Action')
```

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

## lawref.evaluator.events.INSTANT_T

*attribute* · *module attribute*

```python
INSTANT_T = 'urn:law:std#Instant'
```

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

## lawref.evaluator.events.EventWorld

*class*

```python
class EventWorld
```

Мир событий документа: таблица по `id`, головы цепочек [§81.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#811-версии-исправления-и-провенанс-decision-0156), время.

Область сбора — ровно та, которую называют [§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156) и [§81.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#811-версии-исправления-и-провенанс-decision-0156): константы
пакета [§54](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/09-part-ix-values-terms-expressions.ru.md#54-const), константы дела [§168](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/24-part-xxiii-cases-snapshots-evaluation.ru.md#168-case-file) и аргументы утверждений [§71](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/11-part-xi-assertions-facts-evidence.ru.md#71-assertion). Первые две
приходят узлами `symbol_decl` вида `constant` (константы дела становятся
эфемерными декларациями в `prepared._build`), третьи — атомами store.

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

### lawref.evaluator.events.EventWorld.lattice

*attribute* · *instance attribute*

```python
lattice = lattice
```

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

### lawref.evaluator.events.EventWorld.policy

*attribute* · *instance attribute*

```python
policy = policy
```

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

### lawref.evaluator.events.EventWorld.records

*attribute* · *instance attribute*

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

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

### lawref.evaluator.events.EventWorld.canonical_time

*method*

```python
def canonical_time(event_id: str) -> tuple[datetime, datetime, bool, bool]
```

`time` → канонический `Interval<Instant>` [§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156) (три формы записи).

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

### lawref.evaluator.events.EventWorld.collect

*method*

```python
def collect(value: Any) -> None
```

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

### lawref.evaluator.events.EventWorld.finalize

*method*

```python
def finalize() -> None
```

Свести формы к записи на `id` и назвать ВСЕ конфликты [§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156).

Равенство содержания проверяется по СЕМАНТИЧЕСКОМУ канону, а не по
байтам записи: `09:00+05:00` и `04:00Z` суть один момент (E-0048), и
[§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156) говорит о содержании, а не о форме его записи. Поле `time`
приводится к каноническому интервалу [§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156) ДО сравнения, прочие поля
сравниваются каноном [§208](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/28-part-xxvii-canonical-legal-ir.ru.md#208-canonical-serialization).

Конфликты собираются ВСЕ: `relatedNodes` называет каждый спорный `id`,
отсортированный по id. Отказ на первом встреченном ставил бы состав
ответа в зависимость от порядка обхода дела — ровно то, что развилка
F16 и снимает.

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

### lawref.evaluator.events.EventWorld.head

*method*

```python
def head(event_id: str) -> str
```

Голова цепочки версий [§81.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#811-версии-исправления-и-провенанс-decision-0156) — версия, которую никто не исправляет.

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

### lawref.evaluator.events.EventWorld.resolve_versions

*method*

```python
def resolve_versions() -> None
```

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

### lawref.evaluator.events.EventWorld.start_of

*method*

```python
def start_of(event_id: str) -> datetime
```

Начало канонического интервала — ключ порядка истории [§161.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/22-part-xxi-procedures.ru.md#1611-свёртка-истории-decision-0156).

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

### lawref.evaluator.events.EventWorld.superseded

*method*

```python
def superseded(event_id: str) -> str | None
```

`id` исправленной версии, если носитель есть голова непустой цепочки.

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

## lawref.evaluator.events.EventWorldRefusal

*class*

```python
class EventWorldRefusal(Exception)
```

Bases: `Exception`

Fatal [§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156)/[§81.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#811-версии-исправления-и-провенанс-decision-0156): мир событий не однозначен, свёртка не выполнялась.

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

### lawref.evaluator.events.EventWorldRefusal.issue

*attribute* · *instance attribute*

```python
issue = issue
```

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

## lawref.evaluator.events.PolicySelector

*class*

```python
class PolicySelector
```

Ленивый выбор политики [§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156) осью [§168.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/24-part-xxiii-cases-snapshots-evaluation.ru.md#1682-оси-контекста-transport-среза).

Ленивость нормативна, а не является оптимизацией: [§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156) говорит, что
отказы поднимаются ТОЛЬКО когда разрешение потребовалось. Дело, в котором
ни одна дата не сравнивалась с мгновением, исполняется при любом числе
объявленных политик — выбирать было нечего, и гасить ответ незачем.

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

### lawref.evaluator.events.PolicySelector.get

*method*

```python
def get() -> TemporalPolicy
```

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

## lawref.evaluator.events.TemporalPolicy

*class*

```python
class TemporalPolicy
```

Фиксированное смещение и граница гражданских суток ([§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156)).

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

### lawref.evaluator.events.TemporalPolicy.day_boundary

*attribute* · *instance attribute*

```python
day_boundary = str(node.get('dayBoundary', '00:00:00'))
```

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

### lawref.evaluator.events.TemporalPolicy.id

*attribute* · *instance attribute*

```python
id = str(node.get('id', ''))
```

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

### lawref.evaluator.events.TemporalPolicy.timezone

*attribute* · *instance attribute*

```python
timezone = node.get('timezone')
```

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

### lawref.evaluator.events.TemporalPolicy.utc_offset

*attribute* · *instance attribute*

```python
utc_offset = str(node.get('utcOffset', '+00:00'))
```

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

### lawref.evaluator.events.TemporalPolicy.day_start

*method*

```python
def day_start(date_text: str) -> str
```

`b(D)` — начало гражданских суток `D` в этой политике ([§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156)).

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

### lawref.evaluator.events.TemporalPolicy.next_day

*method*

```python
def next_day(date_text: str) -> str
```

`D + 1 calendar_day` — арифметика над датой, а не над мгновением.

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

## lawref.evaluator.events.TemporalResolutionRefusal

*class*

```python
class TemporalResolutionRefusal(Exception)
```

Bases: `Exception`

Отказ [§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156) до вывода: политики нет либо она неоднозначна.

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

### lawref.evaluator.events.TemporalResolutionRefusal.issue

*attribute* · *instance attribute*

```python
issue = issue
```

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

## lawref.evaluator.events.TypeLattice

*class*

```python
class TypeLattice
```

Иерархия `type_decl` для проверки «носитель есть подтип `on E`» ([§160.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/22-part-xxi-procedures.ru.md#1601-on-e--условие-валидности-перехода-decision-0156)).

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

### lawref.evaluator.events.TypeLattice.decls

*attribute* · *instance attribute*

```python
decls = {str(n['id']): n for n in nodes if n.get('kind') == 'type_decl' and isinstance(n.get('id'), str)}
```

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

### lawref.evaluator.events.TypeLattice.bases

*method*

```python
def bases(type_id: str) -> list[str]
```

Цепочка баз от самого типа вверх; цикл в объявлениях обрывается.

Ребро `Action <: Event` ВСТРОЕНО ([§80](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#80-action-declaration): «действие есть событие с
выделенным агентом»), и объявлять его пакету нечем: оба корня стоят в
`urn:law:std`, их `type_decl` в программе нет. Без этого ребра
`on Event` не принимал бы носителя-действия — то есть [§160.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/22-part-xxi-procedures.ru.md#1601-on-e--условие-валидности-перехода-decision-0156) («`E`
либо его подтип») читалось бы как «ровно `E`» ровно для той пары
типов, ради которой [§80](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#80-action-declaration) и написан.

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

### lawref.evaluator.events.TypeLattice.is_event_type

*method*

```python
def is_event_type(type_id: str) -> bool
```

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

### lawref.evaluator.events.TypeLattice.is_subtype

*method*

```python
def is_subtype(type_id: str, of_id: str) -> bool
```

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

## lawref.evaluator.events.build_world

*function*

```python
def build_world(nodes: list[dict], atoms: Any, options: dict) -> EventWorld
```

Собрать мир событий из программы и дела ([§79.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#791-исполнимая-форма-экземпляра-decision-0156), [§81.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#811-версии-исправления-и-провенанс-decision-0156)).

`atoms` — значения `store.atoms`: аргументы утверждений [§71](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/11-part-xi-assertions-facts-evidence.ru.md#71-assertion) и выводов [§73](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/11-part-xi-assertions-facts-evidence.ru.md#73-origin)
приходят именно оттуда, и обход по ним не зависит от порядка подачи дела.

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

## lawref.evaluator.events.parse_instant

*function*

```python
def parse_instant(text: str) -> datetime
```

ISO-мгновение → aware datetime. Смещение читается из САМОЙ строки —
tz-база не нужна и не читается ([§82.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#821-политика-темпорального-разрешения-decision-0156), [§211](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/29-part-xxviii-compiler-pipeline.ru.md#211-determinism)).

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