# lawref.divergence

*module*

Divergence report [§158](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#158-conflicting-official-texts): расхождение аутентичных языковых редакций (D3).

Норма-повод: аутентичность нескольких языков одного акта (Конституция РК
ст. 9 — казахский и русский). [§158](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#158-conflicting-official-texts) требует не «сверить тексты», а показать,
что языковые редакции ведут к РАЗНЫМ ВЫВОДАМ: расхождение перевода значимо
ровно тогда, когда меняет результат применения нормы.

Механика — надстройка над интерпретациями [§152](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#152-interpretation)–[§157](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#157-extends), а не новая семантика:
`interpretation KkReading of ART_KK` привязывает набор правил к фрагменту
конкретной языковой редакции, а `interpretation_group` [§155](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#155-interpretation-group) делает выбор
обязательным. Отчёт вычисляет каждую языковую альтернативу ИЗОЛИРОВАННЫМ
прогоном (та же дисциплина, что у analysis mode [§156](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#156-evaluation-of-alternatives): альтернативы никогда
не смешиваются — смешение дало бы BOTH там, где на деле есть две разные
редакции) и сравнивает результаты.

Сравниваются РЕЗУЛЬТАТЫ, а не документы: manifest изолированных прогонов
различается выбором интерпретации всегда, и сверка документов целиком
объявляла бы расхождением сам факт выбора.

Отложено: divergence по частям одного результата (какой именно конъюнкт
разошёлся) — требует сопоставления proof-графов разных прогонов.

## lawref.divergence.divergence_report

*function*

```python
def divergence_report(ir: dict, case: dict, query: dict, evaluate: Callable[..., dict] | None = None, options: dict | None = None) -> dict
```

[§158](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/21-part-xx-interpretations-and-theories.ru.md#158-conflicting-official-texts): отчёт о расхождении аутентичных языковых редакций.

Каждый язык вычисляется изолированно (`selectedInterpretations` — только
его интерпретации), результаты сравниваются по проекции. Возвращает:

- `languages` — языки, для которых нашлись интерпретации-якоря;
- `byLanguage` — проекция результатов каждого языка;
- `diverged` — различаются ли выводы;
- `issuesByLanguage` — коды issues каждого прогона (расхождение бывает и
  в том, что один язык дал вывод, а другой остановился).

`diverged=False` при одном языке: расхождение требует минимум двух
аутентичных редакций, а не отсутствия второй.

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

## lawref.divergence.interpretation_languages

*function*

```python
def interpretation_languages(nodes: list[dict]) -> dict[str, str | None]
```

{id интерпретации: язык её якорей} — None, если языка нет либо якоря
указывают на разные языки (такая интерпретация не является языковой и в
отчёт не входит: молча выбрать один из языков значило бы решить за автора).

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

## lawref.divergence.language_groups

*function*

```python
def language_groups(nodes: list[dict]) -> dict[str, list[str]]
```

{язык: [интерпретации этого языка]}; порядок детерминирован.

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