Закони у JSON
Тема ця дещо спірна, я знаю. Але уявіть: в ту саму мить, як “Урядовий кур’єр” публікує закон, всі алгоритми вже знають, що змінилося, і оновили свої бази. Але для цього парсити нормативку — не вихід.
Этот текст можно читнуть на русском
Минулого разу я з ходу запропонував Закон України “Про судовий збір” розкласти на 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 розмірів прожиткового мінімуму для працездатних осіб” має угледіти таке:
- що в родовому відмінку записана деяка специфічна константа (“розмір прожиткового мінімуму для працездатних осіб”, далі — рПМПО), яка визначена не цим законом взагалі;
- що в родовому відмінку записана ще одна змінна — “ціна позову”;
- що цими прекрасними словами сформульоване таке загальне правило: судовий_збір = 0,015 * ціна_позову;
- і що в цього правила є два винятки:
- якщо 0,015 * ціна_позову < 1*рПМПО, тоді судовий_збір = 1*рПМПО;
- якщо 0,015 * ціна_позову > 350*рПМПО, тоді судовий_збір = 350*рПМПО.
Такий парсер можна створити, але, знову ж таки, це буде початок гри у квача з емпіричною невизначеністю.
Людська мова вельми багата на слова. Слова “не менше/не більше” можна замінити на “дорівнює або більше/дорівнює або менше”, “досягає/не перевищує”, “не нижче/не вище” (і таке різноманіття можна зустріти в одному і тому самому НПА, наприклад у Цивільному кодексі України). У реченні слова можна розставляти по-різному.
Така ж проблема виникне і з парсингом розділу 2 Конституції України. Там вжиті різні мовні прийоми для закріплення переліку прав і свобод людини та громадянина:
- “має/мають право на …”
- “має/мають [прикметник] право на …”
- “мають … права…”
- “[громадянин України / жоден / ніхто] не може бути …”
- “кожному гарантується …”
До того ж, ці формулювання комбінуються ще й з різними групами осіб: кожен, кожна людина; громадяни; громадяни України; ті, хто працює; ніхто; тощо. Все це створює деяку складність для розумного парсингу юридичного вмісту. В низці інших ситуацій ці проблеми стануть ще глибшими.
JSON-и і конституціоналізм
Якщо ми відкладемо в бік парсинг і спробуємо все ж уявити машиночитабельне законодавство, то як це може виглядати?
Більша частина правових норм (можливо і всі, але всі я ще не перевірив) створюють різні логічні зв’язки, наприклад:
- присвоєння (“assignment”) якогось значення якомусь явищу (“Строком є певний період у часі, зі спливом якого пов’язана дія чи подія, яка має юридичне значення”, ЦК);
- наділення якоюсь властивістю (чи кількома) якогось явища (“Україна є суверенна і незалежна, демократична, соціальна, правова держава”, КУ);
- наділення якимось правом чи обов’язком якогось суб’єкта (“Член виробничого кооперативу має право на вихід із кооперативу”, ЦК).
Ці ж зв’язки можна викласти у вигляді коду, наприклад шляхом оголошення змінної:
const strok = “певний період у часі, зі спливом якого пов’язана дія чи подія, яка має юридичне значення”;
Але раціональніше робити це у вигляді JSON, бо в юридичних явищ може бути багато параметрів і властивостей:
- const strokDefinition = ‘{“title”: “строк”, “definition”: “певний період у часі, зі спливом якого пов’язана дія чи подія, яка має юридичне значення”}’;
- const Ukraine = ‘{“title”: “Україна”, “type”: “держава”, “parameters”: [“суверенна”, “незалежна”, “демократична”, “соціальна”, “правова”]}’;
- const chlenVyrobnychogoCooperatyvu = ‘{“title”: “член виробничого кооперативу”, “hasRights”: [“право на вихід із кооперативу”]}’;
Для алгоритмів аналіз JSON-ів — це значно більш комфортний і надійний спосіб взаємодії з юридичними сенсами, ніж парсинг чистого тексту (до речі, за іронією долі цей “аналіз JSON-ів” технарі називають парсингом JSON-ів, але я так не казатиму, бо тоді точно вас заплутаю). JSON-и можуть бути основним будівельним матеріалом для машиночитабельного законодавства. Але є ще кілька фундаментальних концепцій програмування: область видимості і глобальна змінна. Про них я розкажу наступного разу, і матимемо повну картину.
Розв’язка
А можливо, все ж правий автор цієї тези:
“Это всё красиво только в вакууме, в реальности это будет сильно вонять через пару месяцев после старта.”
А що думаєте ви? (= чекаю на коменти під текстом)
Текст зайшов як діти в школу? Хочте ще таких? Так ставайте хутчіш нашими патронами: