Repository navigation
feat(stdlib): russian morphology answers a dictionary entry or a gap - #313
Merged
Merged
Conversation
the-homeless-god
force-pushed
the
a/russian-morphology-for-syllogisms
branch
2 times, most recently
from
October 4, 2026 17:09
7e5dbc3 to
8a452c1
Compare
flang/stdlib/ru-morphology.flang reads ONE russian word form and answers the
dictionary entry the sentence translator parses: word class, forms by number,
forms by gender. Where the form reads two ways it returns every reading plus
the words that tell them apart; where no rule derives a form it returns a
named gap with the list of what the rules would give. It never guesses
silently: a silent guess grows a false syllogism and nobody is told.
Measured 2026-10-04 with bootstrap/flang 0.7.24 built in this tree.
ru-morphology:probe words 83, agreements 14, refusals 60, diverged 0
check --proof 51 statements: 51 proved, 0 on a grid, 0 unproved
functions 112 with the import, all total, termination proved
ru-morphology:forgery code 1 - the probe reddens on a shifted corpus
No "--na-veru" key anywhere: the probe runs without consent to the unproven.
Getting there cost six weak length statements, traded for the examples of the
same functions, and two rewrites; ADR-0060 section 7 names all nine and the
price. The alternative was raising the run-verdict debt ceiling from 49 to 50.
Every corpus row carries a THIRD field: the bent form, on which the answer
must differ. A rule whose answer survives the bend checks nothing, and the
probe names it "pravilo ne provereno". Negative control taken: the word "kit"
with its own form as the bend gives diverged 1 and names the rule; reverting
gives diverged 0. Agreement is checked both ways and both reject the swapped
form; swapping wanted and rejected on one row gives diverged 2.
Two findings the owner needs before dropping the declarations:
- word CLASS is not readable from the form at the common endings. A bare
masculine short form is indistinguishable from a masculine noun: "kit"
reads both as a notion and as a property. 60 of 83 corpus words refuse.
Only a full adjective (-yj -aja -oe -ye) is decided by form alone.
- the PLURAL of a noun is derivable for no word at all. "kit" gives "kity"
by rule, "chelovek" gives "lyudi" by none, and the form does not say
which case it is. So the "Ponyatie: X, Xs" line stays needed in full.
The declaration is therefore not removed but demoted to a correction over the
derivation. A short adjective WITHOUT a fugitive vowel does collapse to one
word: "Svojstvo: mohnat" is enough, the other three forms follow by rule.
Animacy is never read, and that is a proved postcondition: the dash before a
predicate is placed by the word class, not by animacy.
The probe is called from .github/workflows/binary.yml next to the sentence
probe, the forgery in an "if" so the step fails when the probe stayed silent.
Not from ci.yml: that workflow is disabled_manually on GitHub, so a step put
there would never run at all.
docs/ru-grammar.md carries the mandatory "what this module cannot do" section;
ADR-0060 carries the decision and how a proper name differs from a notion by
form, and how it does not.
The library grew by one module, so the counted marks moved: stdlib files
53 to 54, lines 33153 to 34392, examples 3807 to 3917 and 3991 to 4101,
tree .flang files 1127 to 1128, library functions 1793 to 1904. All taken by
the instrument, not by hand.
Control run unchanged: the sentence probe still answers
"syllogism/sentences: probes 14, diverged 0", code 0, 16.0 s.
Broken doc links: 90 of 6941 on the base, 90 of 6947 on the branch - no gain.
flang/stdlib/ru-morphology.flang -> flang/experimental/ru-morphology.flang. An experimental module is NOT part of the promises of the standard library and may change the names of its functions without warning. The morphology is exactly that today, and keeping it in stdlib promised what is not there. The new directory is declared in docs/repository-layout.md and .ru.md: in the root map and in the prose about flang/. Every number below was taken by the instrument, not by arithmetic (prose-numbers-guard, 2026-10-04): files flang/stdlib/*.flang 54 -> 53 samples flang/stdlib/*.flang 3917 -> 3807 samples stdlib + core 4101 -> 3991 lines flang/stdlib/*.flang 34392 -> 33153 functions in stdlib (by source) 1904 -> 1793 Runs: ru-morphology:probe "words 83, agreements 14, refusals 60, diverged 0"; check --proof flang/experimental/ru-morphology.flang - 51 statements, 51 proved, code 0; prose-numbers-guard - 210 marks, 0 diverged; published-vs-tree --karta - agrees; inventory:check - agrees; proved-share-vs-tree - agrees.
flang/experimental/ru-syllogism-demo.fscript (run-script ru-syllogism:demo) takes INFORMAL russian with no declaration of a notion, a property or a name, fills the dictionary with the morphology, and hands the result to the same syllogism judge. It prints three things: what it read on its own, where the language reads two ways and one line from a human is needed, and the verdict in the judge's own words. Three texts next to it in flang/experimental/texts/. Measured 2026-10-04, bootstrap/flang 0.7.24 in this tree: exit code 0, orders 6, three texts. On texts/follows.txt the whole dictionary came out of the forms - "Imya: Barsik", "Ponyatie: mohnatyj, mohnatye", "Svojstvo: tih, tihi; ona tiha; ono tiho" - and the kernel answered DOKAZANO. On texts/asks-one-line.txt exactly ONE question was left and exactly one line was asked for. On texts/does-not-follow.txt the dictionary came out whole and the reasoning is wrong, and the place is named: sentence 3 is not derived from 1 and 2, with a counterexample. The word class is NOT chosen by the morphology: it is chosen by the place in the sentence, with the very words the morphology prints for two readings. That is syntax, so the rule lives in the demo, not in the module. The judge is spawned as a process, not called as a function: both modules declare a type "Reading", and a file importing both is refused - FLANG_DUPLICATE_NAME, 18 findings, code 1. Task 8337 carries the rename and the translator's move onto this dictionary. docs/tasks/8337-the-sentence-translator-asks-a-declaration-for-every-word.md: the translator asks a declaration for every word, while 40 declaration lines sit in 14 corpus texts by hand. docs/ru-grammar.md gets the run verbatim in a section of its own; ADR-0060 gets section 2 "why experimental, not standard" and section 10 with the same run. Runs: ru-syllogism:demo code 0; check flang/experimental/ru-syllogism-demo.fscript - no findings, 197 functions, termination proved for all; check --proof - 0 statements, code 0; lint - 0 over the limits; tasks:check - 183 tasks whole; tasks:numbers - 0 double numbers; inventory:check, scripts:check, file-extensions:check, proved-share-vs-tree, record-follows-its-source, guards-without-forgery-probe, version-derivations-guard - all agree.
the-homeless-god
force-pushed
the
a/russian-morphology-for-syllogisms
branch
from
October 4, 2026 19:00
726b37a to
6f13dc8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Модуль русской морфологии, на котором потом встанет снятие объявлений из текстов силлогизмов. Переводчик предложений не тронут ни строкой — его правку делает отдельная работа.
Что сделано
flang/stdlib/ru-morphology.flangчитает одну русскую словоформу и отвечает записью словаря того вида, который разбираетtranslator.flang: класс слова, формы по числу, формы по роду. Где форма читается двояко — все чтения и слова, чем их различить. Где правило формы не выводит — названная недостача со списком того, что дали бы правила. Молчаливой догадки нет нигде.ru-morphology:probeagreement.tsvru-morphology: слов 83, согласований 14, отказов 60, разошлось 0check --proof, код 0check: завершение доказано у всехru-morphology:forgeryпроб 14, разошлось 0, 16,0 сlinks:checkна обоих деревьяхУ каждой строки корпуса третье поле — подлог: подменённая форма, на которой ответ обязан отличаться. Правило, на подмене которого ответ не меняется, ничего не проверяет, и набор называет его словами «правило не проверено». Отрицательный контроль снят трижды: подлог, равный самой форме, на
кити насмертендаётразошлось 1и имя правила; перестановкаwantedиrejectedв согласовании даётразошлось 2. Корпус снимается планомSnapи воспроизводится им байт в байт.Два ответа на вопрос «что невозможно без словаря»
китчитается и понятием, и свойством. 60 слов из 83 отказываются; ровно одним чтением решаются 23. Однозначно решается формой только полное прилагательное (-ый -ая -ое -ые).кит→китыправило даёт,человек→людине даёт никакое, и по форме эти случаи одинаковы. СтрокаПонятие: X, Xsостаётся нужной целиком.Поэтому объявление не отменяется, а становится уточнением поверх вывода. Что снять всё-таки можно: у краткого прилагательного без беглой гласной три остальные формы выводятся —
Свойство: мохнат, мохнаты; она мохната; оно мохнатосводится кСвойство: мохнат. С беглой гласной (смертенпротивзелен) — нет, и там строка нужна по-прежнему.Одушевлённость не читается никогда (доказанное постусловие), и тире ставит не она, а класс слова: «окно — вещь» и «кит — животное» идут с тире одинаково.
Файлы
flang/stdlib/ru-morphology.flang— новый модульflang/proof/probes/ru-morphology/— набор проб:run.fscript,forms.tsv,agreement.tsvdocs/ru-grammar.md— что умеет и, обязательным разделом, чего не умеет (14 пунктов)docs/adr/0060-…— решение, состояние «предложено».flangrc— три короткие команды;.github/workflows/binary.yml— два шага рядом с пробой переводчика, подлог в условииifscripts/ledgers/proved-share-ledger.txt,scripts/ledgers/file-name-words.txt— по строкеprose-numbers-guardиpublished-vs-tree.shЧего в этой ветке нет
Шаг стоит в
binary.yml, а не вci.yml: работа «CI» на GitHub отключена вручную (gh workflow list→disabled_manually), и поставленный туда шаг не прогонялся бы вовсе. Модуля нет в справочникеdocs/site/stdlib.md(там только счёт поправлен) и нет ни в одном профилеflang/stdlib/profiles.flangrc. Составные понятия (морское животное,дышит жабрами) прибор не берёт — они остаются за человеком целиком.Дополнение: модуль переехал в опытные, и к нему есть живой пример
Просьба владельца: «про морфологию давай просто в экспериментальный модуль вынесем, сделаем в ./flang/experimental например и задачу и ADR заведем тоже, чтобы пример морфологии и силлогизмами уже показать что из этого выходит и как работает». Сделано тремя коммитами.
1.
flang/stdlib/ru-morphology.flang→flang/experimental/ru-morphology.flangОпытный каталог — не папка «на потом», а снятое обещание: имена функций в нём меняются без предупреждения. Что именно поедет, уже видно: тип
«Reading»и функция«Forms of»объявлены и в морфологии, и в переводчике предложений, и файл, ввозящий оба модуля, компилятор отвергает —FLANG_DUPLICATE_NAME, замечаний 18, код 1. Разводить имена придётся в морфологии: переводчик старше, и его зовёт набор проб. Вstdlibтакое переименование было бы ломающей правкой библиотеки.Каталог объявлен в
docs/repository-layout.mdи.ru.md— и в карте корня, и прозой: «опытные модули: не входят в обещания стандартной библиотеки, могут менять имена функций без предупреждения».Починено ссылок: 5 мест пути (
flang/proof/probes/ru-morphology/run.fscript,docs/ru-grammar.mdдважды,docs/adr/0060-…,.github/workflows/binary.yml) плюс строка вscripts/ledgers/proved-share-ledger.txt(отпечаток md5 тот же — содержимое не менялось, переехал только путь, и строка встала на своё место в сортировке).Числа библиотеки сняты прибором, а не арифметикой (
bootstrap/flang io scripts/guards/prose-numbers-guard.fscript --plan Check, 4 октября 2026) — 19 мест в 10 файлах:файлов flang/stdlib/*.flangпримеров-в flang/stdlib/*.flangпримеров-в flang/stdlib/*.flang,flang/core/*.flangстрок-в flang/stdlib/*.flangstdlib(счёт по исходнику)После правки:
примет 210: сошлось 210, разошлось 0.2. Задача 8337
docs/tasks/8337-the-sentence-translator-asks-a-declaration-for-every-word.md— переводчик предложений требует объявления на каждое слово, хотя морфология половину словаря выводит сама. Нужность снята прогоном: в 14 текстах корпуса силлогизмов стоит 40 строк объявлений, написанных руками. В задаче названы и шаги воспроизведения столкновения имён, и обходной путь, которым пользуется пример, и признак готовности:checkна файле с обоими ввозами отвечает «замечаний нет», объявлений в корпусе меньше 40, а все 14 приговоровexpected.tsvне изменились.3. Живой пример:
flang/experimental/ru-syllogism-demo.fscriptЗов —
bootstrap/flang run-script ru-syllogism:demo. Берёт русский текст без единого объявления, наполняет словарь морфологией, отдаёт готовый текст тому же судье силлогизмов (run.fscript --plan Judge, отдельным процессом) и печатает по-человечески: что понял сам, где язык двоится и нужна одна строка, где человек ошибся. Тексты —flang/experimental/texts/, три штуки.Класс слова (
понятиепротивсвойства) морфология не выбирает и не будет: выбирает место в предложении, и теми же словами, какие морфология печатает при двух чтениях. Это синтаксис, поэтому правило лежит в примере, а не в модуле.Прогон 4 октября 2026, код возврата 0, поручений 6. Ниже — поле
resultдословно (flang ioпечатает его одной строкой JSON; переносы в ней стоят как\n).Словарь выведен целиком, заключение следует
Словарь неполон — просьба ровно одной строкой
Словарь выведен целиком, а рассуждение неверно — названо где
Чего пример не умеет — названо и в
docs/ru-grammar.md, и примечанием в самом файле: составного сказуемого (дышит жабрами) он не берёт; род подлежащего считает мужским, и женское имя (Ксантиппа) проведёт неверно; строку-подсказку собирает из форм того же класса, найденных в этом же тексте, и при двух сломанных понятиях в одном тексте свела бы разные слова; из слов вывода знает только «Значит» и «Следовательно»; судью зовёт процессом, а не вызовом функции.Куда это вписано
docs/ru-grammar.md— новый раздел «Что выходит на живом тексте» с дословным выводом и перечнем того, чего пример не умеет.docs/adr/0060-…— раздел 2 «Почему опытный, а не стандартный» и раздел 10 «Что выходит на живом тексте» с тем же прогоном; раздел 9 теперь называет задачу 8337. Имя файла ADR не менялось.Прогоны
ru-syllogism:demo— код 0, поручений 6, текстов 3.ru-morphology:probe—слов 83, согласований 14, отказов 60, разошлось 0.check --proof flang/experimental/ru-morphology.flang— «ПРОВЕРЕНО САМОСТОЯТЕЛЬНО», утверждений 51: доказано 51, код 0.check flang/experimental/ru-syllogism-demo.fscript— замечаний нет, функций 197, завершение доказано у всех.lint— 0 строк сверх 120, 0 ветвлений сверх 2. Заслон перед пушем: все 21 проверки зелены за 53 с (prose-numbers-guard,proved-share-vs-tree,tree-inventory,task-ledger,shortcut-collector,lint-growth,no-growthи остальные). Сверх него:scripts:check,file-extensions:check,adr:numbers,tasks:numbers,cyrillic:check,transliteration:check,published-vs-tree.sh --карта— код 0 у каждого.links:checkкрасен 90 ссылками на всём дереве и был красен до этой ветки; ни одна из них не из этих файлов.