Skip to content

lawref.evaluator.events

Событие как исполнимое значение — SPEC §79.1, §81.1, §82.1 (DECISION-0156).

Здесь живут три вещи, которые свёртка §161.1 и активация §135.1 читают уже готовыми:

  • таблица значений-событий по id (§79.1): конструктор-запись §53 в константе пакета §54, константе дела §168 и аргументе утверждения §71 собирается в ОДНУ таблицу; два значения одного id с разным каноническим содержанием §208 — fatal EVENT_ID_CONFLICT, побайтово равные суть одно событие;
  • цепочки версий §81.1: supersedes даёт голову цепочки; цикл, две исправляющие версии, ссылка в неизвестный id либо в событие другого типа — fatal EVENT_VERSION_CHAIN_BROKEN;
  • политика темпорального разрешения §82.1: Date → [b(D), b(D+1)) по ФИКСИРОВАННОМУ смещению политики. Ни одна tz-база не читается (§82.1, детерминизм §211): смещение записано в самой политике, и zoneinfo здесь не импортируется намеренно.

Отказы поднимаются ТОЛЬКО когда разрешение потребовалось (§82.1): дело без единой даты в time исполняется при любом числе объявленных политик.

Attributes

NameDescription
DATE_TNo description.
EVENT_ROOTSNo description.
INSTANT_TNo description.

Classes

NameDescription
EventWorldМир событий документа: таблица по id, головы цепочек §81.1, время.
EventWorldRefusalFatal §79.1/§81.1: мир событий не однозначен, свёртка не выполнялась.
PolicySelectorЛенивый выбор политики §82.1 осью §168.2.
TemporalPolicyФиксированное смещение и граница гражданских суток (§82.1).
TemporalResolutionRefusalОтказ §82.1 до вывода: политики нет либо она неоднозначна.
TypeLatticeИерархия type_decl для проверки «носитель есть подтип on E» (§160.1).

Functions

NameDescription
build_worldСобрать мир событий из программы и дела (§79.1, §81.1).
parse_instantISO-мгновение → aware datetime. Смещение читается из САМОЙ строки —

DATE_Tattributemodule attribute#

DATE_T = 'urn:law:std#Date'

EVENT_ROOTSattributemodule attribute#

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

INSTANT_Tattributemodule attribute#

INSTANT_T = 'urn:law:std#Instant'

EventWorldclass#

class EventWorld(lattice: TypeLattice, policy: PolicySelector)

Мир событий документа: таблица по id, головы цепочек §81.1, время.

Область сбора — ровно та, которую называют §79.1 и §81.1: константы пакета §54, константы дела §168 и аргументы утверждений §71. Первые две приходят узлами symbol_decl вида constant (константы дела становятся эфемерными декларациями в prepared._build), третьи — атомами store.

latticeattributeinstance attribute#

lattice = lattice

policyattributeinstance attribute#

policy = policy

recordsattributeinstance attribute#

records: dict[str, dict] = {}

canonical_timemethod#

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

time → канонический Interval<Instant> §79.1 (три формы записи).

collectmethod#

def collect(value: Any) -> None

finalizemethod#

def finalize() -> None

Свести формы к записи на id и назвать ВСЕ конфликты §79.1.

Равенство содержания проверяется по СЕМАНТИЧЕСКОМУ канону, а не по байтам записи: 09:00+05:00 и 04:00Z суть один момент (E-0048), и §79.1 говорит о содержании, а не о форме его записи. Поле time приводится к каноническому интервалу §79.1 ДО сравнения, прочие поля сравниваются каноном §208.

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

headmethod#

def head(event_id: str) -> str

Голова цепочки версий §81.1 — версия, которую никто не исправляет.

resolve_versionsmethod#

def resolve_versions() -> None

start_ofmethod#

def start_of(event_id: str) -> datetime

Начало канонического интервала — ключ порядка истории §161.1.

supersededmethod#

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

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

EventWorldRefusalclass#

class EventWorldRefusal(issue: dict)

Bases: Exception

Fatal §79.1/§81.1: мир событий не однозначен, свёртка не выполнялась.

issueattributeinstance attribute#

issue = issue

PolicySelectorclass#

class PolicySelector(nodes: list[dict], options: dict)

Ленивый выбор политики §82.1 осью §168.2.

Ленивость нормативна, а не является оптимизацией: §82.1 говорит, что отказы поднимаются ТОЛЬКО когда разрешение потребовалось. Дело, в котором ни одна дата не сравнивалась с мгновением, исполняется при любом числе объявленных политик — выбирать было нечего, и гасить ответ незачем.

getmethod#

def get() -> TemporalPolicy

TemporalPolicyclass#

class TemporalPolicy(node: dict)

Фиксированное смещение и граница гражданских суток (§82.1).

day_boundaryattributeinstance attribute#

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

idattributeinstance attribute#

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

timezoneattributeinstance attribute#

timezone = node.get('timezone')

utc_offsetattributeinstance attribute#

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

day_startmethod#

def day_start(date_text: str) -> str

b(D) — начало гражданских суток D в этой политике (§82.1).

next_daymethod#

def next_day(date_text: str) -> str

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

TemporalResolutionRefusalclass#

class TemporalResolutionRefusal(issue: dict)

Bases: Exception

Отказ §82.1 до вывода: политики нет либо она неоднозначна.

issueattributeinstance attribute#

issue = issue

TypeLatticeclass#

class TypeLattice(nodes: list[dict])

Иерархия type_decl для проверки «носитель есть подтип on E» (§160.1).

declsattributeinstance attribute#

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

basesmethod#

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

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

Ребро Action <: Event ВСТРОЕНО (§80: «действие есть событие с выделенным агентом»), и объявлять его пакету нечем: оба корня стоят в urn:law:std, их type_decl в программе нет. Без этого ребра on Event не принимал бы носителя-действия — то есть §160.1 («E либо его подтип») читалось бы как «ровно E» ровно для той пары типов, ради которой §80 и написан.

is_event_typemethod#

def is_event_type(type_id: str) -> bool

is_subtypemethod#

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

build_worldfunction#

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

Собрать мир событий из программы и дела (§79.1, §81.1).

atoms — значения store.atoms: аргументы утверждений §71 и выводов §73 приходят именно оттуда, и обход по ним не зависит от порядка подачи дела.

parse_instantfunction#

def parse_instant(text: str) -> datetime

ISO-мгновение → aware datetime. Смещение читается из САМОЙ строки — tz-база не нужна и не читается (§82.1, §211).

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.