Закони у JSON

Тема ця дещо спірна, я знаю. Але уявіть: в ту саму мить, як “Урядовий кур’єр” публікує закон, всі алгоритми вже знають, що змінилося, і оновили свої бази. Але для цього парсити нормативку — не вихід.

Andrey Kostenko
Dead Lawyers Society

--

Ілюстрація Катерини Цібере

Этот текст можно читнуть на русском

Минулого разу я з ходу запропонував Закон України “Про судовий збір” розкласти на JSON-и, і вчиняти так з кожним законом.

У відповідь пролунали думки, що хороші парсери здатні вирішити проблему аналізу законів роботами без зайвих витрат на вигадування назв змінних, доповнення законів ще однією статтею і ускладнення законодавчої процедури. Але не все так однозначно: давайте не залишатися заручниками старих і перевірених підходів. Колись юристи друкували документи на друкувальній машинці, а хтось з виробників кнопкових мобіл не повірив у сенсорні екрани.

Українське законодавство сьогодні, як і майже 30 років тому, — це україномовні тексти. Для ефективної роботи лігалтек-проектів (і взагалі для розбудови потужної екосистеми e-урядування) потрібно не просто автоматизувати роботу різноманітних алгоритмів і ботів з текстами чинних законів. Слід спочатку гарантувати їх “читабельність” для алгоритмів будь-якої форми власності.

Якраз у середу на Facebook з’явився пост про те, що в Україні тепер #DigitalByDefault, бо “затверджено історичну Постанову для розвитку електронного урядування та цифрової економіки, яка передбачає впровадження принципу 🤟цифровий за замовченням”. Сказано про “цифрову експертизу законопроектів”, а також що “пріоритетним способом реалізації описаного в НПА процесу (послуга або будь-який адміністративний процес) за замовченням буде визначений саме електронний спосіб”. Текст постанови я поки що не побачив. Питання під постом залишив.

Парсери, регулярки і гроші

Комп’ютерні програми можуть аналізувати законодавчі тексти за допомогою парсерів. Парсер (він же синтаксичний аналізатор) — це алгоритм, який зі вхідних неструктурованих даних (текстів тощо) отримує необхідні структуровані дані.

Почну з відстороненого прикладу: нехай нам треба знаходити будь-які позначення грошових сум. Парсер грошових сум в реченні “Стартап потребує 100000 грн. на місяць.” має знайти фрагмент “100000 грн.”. Наприклад, якщо він на JavaScript, то його регулярний вираз матиме вигляд: \d+\s*грн\.

Можемо заточити його під популярні валюти, врахувавши ще деякі особливості написання: \d+\s*(грн\.*|гривен\w*|дол[л]*(\.|ар\w*)|(е|є)вро|usd|USD|eur|EUR).

Парсер з такою регуляркою вже знайде чимало потрібних даних. Колись про регулярки я написав тут, та й взагалі в інтернеті про них багато написано. Але щоб вона почала реагувати і на записи з позначками $, €, ₴, треба її розширювати.

Також не забуваймо, що люди ці значки розміщують по різні боки від цифр. І ще виключимо зімбабвійські долари:

([^zZ][€₴\$]+\s*\d+|\d+\s*(грн\.*|гривен\w*|дол[л]*(\.|ар\w*)|(е|є)вро|usd|USD|eur|EUR|[\$€₴]))

Бачте, цей парсер можна чепурити невпинно, по мірі виявлення інших способів позначення грошових сум. Звідси висновки:

парсери працюють настільки гарно, наскільки гарно прописані їх регулярки

ТА

вдосконалення парсера — це гра у квача з емпіричною невизначеністю

Думаю, в унісон з цим звучить коментар із соцмереж: “Если парсер “теряется”, что бы это ни значило, то это куйовый парсер”.

Але чи ідеальне це рішення для роботів? Чи можна завдяки існуванню парсерів і регулярок назвати законодавство машиночитабельним вже сьогодні? Розгляньмо дві ситуації.

Парсери і українська дійсність

Наприклад, парсер розмірів ставок судового збору в тексті “1,5 відсотка ціни позову, але не менше 1 розміру прожиткового мінімуму для працездатних осіб і не більше 350 розмірів прожиткового мінімуму для працездатних осіб” має угледіти таке:

  1. що в родовому відмінку записана деяка специфічна константа (“розмір прожиткового мінімуму для працездатних осіб”, далі — рПМПО), яка визначена не цим законом взагалі;
  2. що в родовому відмінку записана ще одна змінна — “ціна позову”;
  3. що цими прекрасними словами сформульоване таке загальне правило: судовий_збір = 0,015 * ціна_позову;
  4. і що в цього правила є два винятки:
  • якщо 0,015 * ціна_позову < 1*рПМПО, тоді судовий_збір = 1*рПМПО;
  • якщо 0,015 * ціна_позову > 350*рПМПО, тоді судовий_збір = 350*рПМПО.

Такий парсер можна створити, але, знову ж таки, це буде початок гри у квача з емпіричною невизначеністю.

Людська мова вельми багата на слова. Слова “не менше/не більше” можна замінити на “дорівнює або більше/дорівнює або менше”, “досягає/не перевищує”, “не нижче/не вище” (і таке різноманіття можна зустріти в одному і тому самому НПА, наприклад у Цивільному кодексі України). У реченні слова можна розставляти по-різному.

Така ж проблема виникне і з парсингом розділу 2 Конституції України. Там вжиті різні мовні прийоми для закріплення переліку прав і свобод людини та громадянина:

  • “має/мають право на …”
  • “має/мають [прикметник] право на …”
  • “мають … права…”
  • “[громадянин України / жоден / ніхто] не може бути …”
  • “кожному гарантується …”

До того ж, ці формулювання комбінуються ще й з різними групами осіб: кожен, кожна людина; громадяни; громадяни України; ті, хто працює; ніхто; тощо. Все це створює деяку складність для розумного парсингу юридичного вмісту. В низці інших ситуацій ці проблеми стануть ще глибшими.

JSON-и і конституціоналізм

Якщо ми відкладемо в бік парсинг і спробуємо все ж уявити машиночитабельне законодавство, то як це може виглядати?

Більша частина правових норм (можливо і всі, але всі я ще не перевірив) створюють різні логічні зв’язки, наприклад:

  1. присвоєння (“assignment”) якогось значення якомусь явищу (“Строком є певний період у часі, зі спливом якого пов’язана дія чи подія, яка має юридичне значення”, ЦК);
  2. наділення якоюсь властивістю (чи кількома) якогось явища (“Україна є суверенна і незалежна, демократична, соціальна, правова держава”, КУ);
  3. наділення якимось правом чи обов’язком якогось суб’єкта (“Член виробничого кооперативу має право на вихід із кооперативу”, ЦК).

Ці ж зв’язки можна викласти у вигляді коду, наприклад шляхом оголошення змінної:

const strok = “певний період у часі, зі спливом якого пов’язана дія чи подія, яка має юридичне значення”;

Але раціональніше робити це у вигляді JSON, бо в юридичних явищ може бути багато параметрів і властивостей:

  1. const strokDefinition = ‘{“title”: “строк”, “definition”: “певний період у часі, зі спливом якого пов’язана дія чи подія, яка має юридичне значення”}’;
  2. const Ukraine = ‘{“title”: “Україна”, “type”: “держава”, “parameters”: [“суверенна”, “незалежна”, “демократична”, “соціальна”, “правова”]}’;
  3. const chlenVyrobnychogoCooperatyvu = ‘{“title”: “член виробничого кооперативу”, “hasRights”: [“право на вихід із кооперативу”]}’;

Для алгоритмів аналіз JSON-ів — це значно більш комфортний і надійний спосіб взаємодії з юридичними сенсами, ніж парсинг чистого тексту (до речі, за іронією долі цей “аналіз JSON-ів” технарі називають парсингом JSON-ів, але я так не казатиму, бо тоді точно вас заплутаю). JSON-и можуть бути основним будівельним матеріалом для машиночитабельного законодавства. Але є ще кілька фундаментальних концепцій програмування: область видимості і глобальна змінна. Про них я розкажу наступного разу, і матимемо повну картину.

так може виглядати головний JSON України

Розв’язка

А можливо, все ж правий автор цієї тези:

“Это всё красиво только в вакууме, в реальности это будет сильно вонять через пару месяцев после старта.”

А що думаєте ви? (= чекаю на коменти під текстом)

Текст зайшов як діти в школу? Хочте ще таких? Так ставайте хутчіш нашими патронами:

--

--