flang the compiler proves your program cannot hang 0.6.2 GitHub Русский

Diagnostics reference

The compiler refuses by code. The code is always the first word of the line:

FLANG_TYPE в файле type.flang, строка 6, столбец 3: функция «Удвоить» объявлена как число, а тело даёт строка

Find your code on this page: one line for what it means, one for what to do. Codes are grouped by the layer that produces them: parsing comes before types, types come before proofs.

Exit codes: 0 — checked, 1 — findings, 2 — bad invocation.

Three traps that cost a day

Read these before you look up your code. Each one refuses somewhere other than where the mistake is.

A postcondition calling a function of its own module breaks everyone who imports the module by list

The file is green on its own. The importer fails.

// ядро.flang
модуль «Ядро»

тотальная функция «Двойка»
  принимает н: число
  возвращает число
  н умножить на 2

тотальная функция «Учтено»
  принимает н: число
  возвращает число
  обеспечивает «не меньше двойки» результат не меньше («Двойка» от н)
  («Двойка» от н) плюс 1
// ввоз.flang
модуль «Ввоз»
использует «Ядро» только «Учтено»

тотальная функция «Проба»
  принимает н: число
  возвращает число
  «Учтено» от н
flang check ядро.flang
модуль «Ядро»: функций 2, из них с доказанным завершением 2; типов 0
ядро.flang: проверено — разбор, типы, завершаемость, ядро и примеры; замечаний нет
flang check ввоз.flang
модуль «Ввоз»: функций 2, из них с доказанным завершением 0; типов 0; файлов вместе с импортами 2
без доказанного завершения: «Учтено» «Проба»
FLANG_UNKNOWN_NAME, строка 12, столбец 4: неизвестная функция «Двойка»
FLANG_UNKNOWN_NAME, строка 11, столбец 50: неизвестная функция «Двойка»
FLANG_NOT_TOTAL, строка 12, столбец 4: тотальная функция «Учтено» вызывает неизвестную функцию «Двойка»: завершение доказать нельзя
ввоз.flang: не проверено — замечаний 3

The import только «Учтено» brings in one name. Both the body and the postcondition of «Учтено» call «Двойка», which the importer does not have. Column 50 points inside the postcondition — the line number belongs to the imported file, and no file is named because two files were checked together.

What to do — one of three:

fixhow
bring the companionиспользует «Ядро» только «Учтено», «Двойка»
import the whole moduleиспользует «Ядро»
take the call out of the postconditionsay the same in arithmetic: результат не меньше (н умножить на 2)

A green run does not mean the assertions are proved

flang check without flags checks parsing, types, termination and examples. A postcondition it can neither prove nor refute is passed over in silence. The postcondition «меньше двойки» above is false — and the file is green.

Ask directly:

flang check ядро.flang --proof
  постусловие «меньше двойки» функции «Учтено» — объявлено, не доказано: ни теоремы, ни примеров. Его считает рантайм после каждого возврата — на тех входах, которые придут

Read the words literally: «доказано» — about all inputs; «сетка N» — computed on N values, which is not a proof; «объявлено, не доказано» — the claim is stated and nothing stands behind it.

And second: while a FLANG_UNKNOWN_NAME stands, the function loses its тотальная promise and nobody proves its assertions. Names first, everything else after.

FLANG_BOUND_ON_NAN: «not a number» lives in the type число and stands outside the order

The most common false alarm. The claim looks obviously true and the kernel answers with a counterexample.

модуль «Проба»

тотальная функция «Прибавить один»
  принимает н: число
  возвращает число
  обеспечивает «результат больше довода» результат больше н
  н плюс 1
FLANG_BOUND_ON_NAN в файле nan.flang, строка 6, столбец 3: постусловие «результат больше довода» функции «Прибавить один» ЛОЖНО, и контрпример назван: «н» объявлен типом «число», а «не число» живёт в этом типе и стоит ВНЕ ПОРЯДКА — оно не больше и не меньше ничего, включая самоё себя.

The reason: the type число contains «not a number», every arithmetic operation carries it through, and any comparison with it is false both ways. A claim about order over raw arithmetic is therefore not true.

fixwhat to writewho pays
narrow the input typeпринимает н: неотрицательное or целоеnobody, «not a number» cannot get in
add a preconditionтребует «вход есть число» (н минус н) равен 0the caller
state the bound in the claim itselfобеспечивает «…» не ((н минус н) равен 0) или (результат больше н)nobody

Parsing

codewhat it meanswhat to do
FLANG_LEXa token did not form: unclosed quote, foreign characterclose the quote, remove the character
FLANG_PARSEtokens are fine, the construct is notlook at line and column: usually a missing иначе branch or a second function body
модуль «Проба»

тотальная функция «Удвоить»
  принимает н: число
  возвращает число
  если н больше 0 то н умножить на 2
FLANG_PARSE в файле parse.flang, строка 7, столбец 1: у 'если' нет ветки 'иначе'
FLANG_LEX в файле lex.flang, строка 5, столбец 3: не закрыта кавычка

Names and imports

codewhat it meanswhat to do
FLANG_UNKNOWN_NAMEthe name is not bound: no such function or variabledeclare it, import the module, or fix the spelling
FLANG_AMBIGUOUS_NAMEtwo imports bring the same namedrop one import or narrow it with только
FLANG_BAD_NAMEthe name is not spelled the way names are spelledrename: function names go in guillemets, parameters are plain words
FLANG_NAME_TAKENthe name belongs to another declarationpick another name
FLANG_DUPLICATE_NAMEthe same name is declared twice in one placeremove the second declaration
FLANG_IMPORT_NOT_FOUNDthe module was not foundcheck the module name and that the file sits next to yours or above
FLANG_IMPORT_CYCLEmodules import each other in a circlemove the shared part into a third module
FLANG_IMPORT_AMBIGUOUSone name arrives from two modulesnarrow the import with только
FLANG_IMPORT_NAMEthe только list names something the module does not declarecompare the list with the module's declarations
модуль «Проба»

тотальная функция «Удвоить»
  принимает н: число
  возвращает число
  «Утроить» от н
FLANG_UNKNOWN_NAME в файле unknown.flang, строка 6, столбец 3: неизвестная функция «Утроить»
FLANG_NOT_TOTAL в файле unknown.flang, строка 6, столбец 3: тотальная функция «Удвоить» вызывает неизвестную функцию «Утроить»: завершение доказать нельзя

An unknown name always drags a second refusal about termination behind it. Fix the first and the second goes away.

If the name is written as an operation, the compiler says so:

FLANG_UNKNOWN_NAME в файле pr4.flang, строка 10, столбец 14: имя «м» не связано: имя вводят 'принимает', 'пусть' или образец 'случай'; а действия языка ('плюс', 'минус', 'умножить на', 'делить на', 'остаток от') пишутся МЕЖДУ значениями — «3.14 умножить на р», а не «умножить 3.14 на р»

Types

codewhat it meanswhat to do
FLANG_TYPEthe declared type differs from what the body or the argument givesbring one in line with the other
FLANG_TYPE_ARGSa type was given arguments it does not takedrop them: types in this language are not parametric
FLANG_TYPE_PARAMa type parameter is not boundname the type in full
FLANG_APPLYthe call does not fit: wrong number of arguments, or the callee is not a functioncompare the call with the signature
FLANG_BUILTIN_ARGSa built-in operation got the wrong number of argumentscheck the operation's description
FLANG_MATCH_NOT_EXHAUSTIVEthe match does not cover every caseadd the missing случай
FLANG_MATCH_UNREACHABLEa case is shadowed by an earlier one and never firesremove it or move it up
FLANG_EXAMPLEan example did not match its expectationfix the body or fix the expectation
FLANG_TYPE в файле type.flang, строка 6, столбец 3: функция «Удвоить» объявлена как число, а тело даёт строка
FLANG_TYPE в файле dup.flang, строка 8, столбец 1: функция «Удвоить» объявлена дважды
FLANG_MATCH_NOT_EXHAUSTIVE в файле match.flang, строка 6, столбец 3: разбор списка не покрывает «пусто»
FLANG_EXAMPLE: пример «Двойка» функции «Удвоить»: значение не совпало с ожидаемым: ожидалось 5, получено 4

Termination and limits

codewhat it meanswhat to do
FLANG_NOT_TOTALthe function is declared тотальная and termination is not provedpass a PART of the argument into the recursion, not a recomputed number
FLANG_MEASUREthe declared measure does not decreasefix убывает or fix the call
FLANG_RECURSION_LIMITevaluation ran out of steps or depthraise --max-steps / --max-depth, or fix the recursion
FLANG_STEP_LIMITthe step limit ran out inside an examplesame --max-steps flag
FLANG_BUDGET_EXHAUSTEDthe budget given to the run ran outraise the budget or narrow the task
FLANG_MEMORYout of memoryshrink the data
FLANG_STOPPEDthe run was stopped from outsidestart it again
модуль «Проба»

тотальная функция «Считать»
  принимает н: число
  возвращает число
  если н равно 0 то 0 иначе («Считать» отплюс 1))
FLANG_NOT_TOTAL в файле total.flang, строка 6, столбец 30: тотальная функция «Считать»: рекурсивный вызов «Считать» не убывает — аргумент 1 («н» add 1) увеличивает параметр «н». Передавайте часть аргумента: хвост списка из образца «голова и хвост», поле варианта из образца, поле записи или элемент коллекции
flang run rec.flang --function "Вниз" --args '{"н":100}' --max-steps 5
FLANG_RECURSION_LIMIT: функция «Вниз» исчерпала лимит шагов (5) на глубине вызовов 1

Assertions and proof

Requirements, promises and theorems.

codewhat it meanswhat to do
FLANG_PROPERTYa postcondition was violated during evaluationeither the claim or the body is wrong — look at the input it broke on
FLANG_PRECONDITIONthe precondition is written wrongcheck the form требует «имя» <утверждение>
FLANG_PRECONDITION_CALLthe caller did not discharge the callee's preconditionprove the condition at the call site or narrow the argument type
FLANG_BOUND_ON_NANan order claim is false because of «not a number»see the third trap above
FLANG_PROOFthe kernel did not accept the proofthe FLANG_PROOF_* codes below say why
FLANG_PROOF_NO_GOALthe theorem closes nothing: no postcondition carries that namename the theorem exactly like the postcondition
FLANG_PROOF_AMBIGUOUSthe theorem would close two postconditions at oncegive the postconditions different names
FLANG_PROOF_CLAIM_MISMATCHутверждаем differs from the postcondition word for wordcopy the postcondition text verbatim
FLANG_PROOF_DUPLICATEtwo theorems prove one postconditionkeep one
FLANG_PROOF_STEPa step is unjustified, or there are no steps at alladd по свойству «…», по примеру «…» or по предположению
FLANG_PROOF_UNFINISHEDthe proof is not closedadd следовательно доказано
FLANG_PROOF_UNKNOWN_VARthe claim mentions an unbound nameintroduce it with дано
FLANG_PROOF_VAR_TYPEthe theorem's variable type differs from the parameter'smatch дано to the function signature
FLANG_PROOF_INDUCTION_TYPEthere is no induction over that typeinduction runs over a declared sum or over the range неотрицательное
FLANG_PROOF_INDUCTION_CASESnot every case of the principle is coveredadd the missing случай
FLANG_PROOF_INDUCTION_BRANCHa case branch is not reduced to the goaljustify the branch
FLANG_PROOF_INDUCTION_STEPthe step is not reduced to the hypothesisadd по предположению and make the sides match sign for sign
FLANG_PROOF_INDUCTION_DESCENTthe descent is not strict: the step is not by onemake the step exactly one down
FLANG_INITIAL_FAILUREno induction principle was generated for the typecheck that the type is declared as a sum of variants
FLANG_UNCOVERED_FAILUREa failure path is not covered by the matchadd a case for the failure
модуль «Проба»

тотальная функция «Удвоить»
  принимает н: число
  возвращает число
  обеспечивает «удвоенное неотрицательно» если н не меньше 0 то (результат не меньше 0) иначе да
  н умножить на 2

теорема «удвоенное неотрицательно»
  дано н: число
  утверждаем если н не меньше 0 то (результат не меньше 0) иначе да
  следовательно доказано
FLANG_PROOF_STEP: теорема «удвоенное неотрицательно»: ни одного шага
FLANG_PROOF_NO_GOAL в файле pr1.flang, строка 9, столбец 1: теорема «удвоенное неотрицательно» ничего не закрывает: постусловия «удвоенное неотрицательно» нет ни у одной функции модуля. Теорема доказывает названное утверждение, а не утверждение вообще — назовите её так же, как постусловие, которое она закрывает
FLANG_PROOF_AMBIGUOUS в файле pa.flang, строка 15, столбец 1: теорема «неотрицательно» закрывала бы сразу 2 постусловия («Удвоить», «Утроить»), и выбрать нельзя. Дайте постусловиям разные имена
FLANG_PROOF_CLAIM_MISMATCH в файле pm.flang, строка 11, столбец 3: теорема «неотрицательно» утверждает не то, что обещает функция «Удвоить»: утверждение теоремы и постусловие обязаны совпадать слово в слово. Ядро не решает, что два разных утверждения означают одно и то же

A postcondition the checker passed over is counted by the runtime:

flang run prop.flang --function "Половина" --args '{"н":0}'
FLANG_PROPERTY: нарушено свойство «результат меньше довода» функции «Половина»

Laws of declared structures

These laws are COMPUTED on a finite grid of the author's values, not proved. A refusal means a violation was found — there is always a counterexample.

codewhich law is broken
FLANG_EQUALITY_NOT_REFLEXIVEthe declared equality is not reflexive
FLANG_EQUALITY_NOT_SYMMETRICnot symmetric
FLANG_EQUALITY_NOT_TRANSITIVEnot transitive
FLANG_EQUALITY_NOT_CONGRUENTcomposition does not respect the equality
FLANG_ORDER_NOT_REFLEXIVEthe order is not reflexive
FLANG_ORDER_NOT_ANTISYMMETRICnot antisymmetric
FLANG_ORDER_NOT_TRANSITIVEnot transitive
FLANG_CATEGORY_NOT_CLOSEDthe category is not closed under composition
FLANG_CATEGORY_NO_IDENTITYan object has no identity
FLANG_CATEGORY_NOT_ASSOCcomposition is not associative
FLANG_COMPOSE_MISMATCHthe ends of a composition do not meet
FLANG_MORPHISM_SHAPEthe morphism is declared wrong
FLANG_FUNCTOR_NOT_TOTALthe functor is not defined on every object
FLANG_FUNCTOR_SQUAREthe functor square does not commute
FLANG_TRANSFORM_SHAPEthe transformation is declared wrong
FLANG_TRANSFORM_COMPONENTa component of the transformation is missing
FLANG_TRANSFORM_NOT_TOTALthe transformation is not defined on every object
FLANG_TRANSFORM_NOT_NATURALthe naturality square does not commute
FLANG_ISO_NOT_INVERSEthe two arrows are not inverse to each other
FLANG_EMBED_SHAPEthe embedding is declared wrong
FLANG_EMBED_NOT_INJECTIVEthe embedding glues distinct values together
FLANG_MONOIDthe monoid declaration is incomplete
FLANG_MONOID_ASSOCthe monoid operation is not associative
FLANG_MONOID_IDENTITYthe identity is not an identity
FLANG_GROUP_INVERSEthe inverse is not an inverse
FLANG_MONADthe monad declaration is incomplete
FLANG_MONAD_ASSOCbind is not associative
FLANG_MONAD_LEFT_UNITthe left unit law fails
FLANG_MONAD_RIGHT_UNITthe right unit law fails
FLANG_NOT_COMMUTATIVEdeclared commutativity is broken
FLANG_NOT_DISTRIBUTIVEdistributivity is broken
FLANG_NOT_IDEMPOTENTidempotence is broken
FLANG_NOT_MONOTONEmonotonicity is broken
FLANG_MEET_NAME_TAKENthe set name is already taken
FLANG_MEET_NO_UNIVERSEthe declared sets share no carrier
FLANG_MEET_SAME_SIDEan intersection of a set with itself
FLANG_MEET_TWICEthe same pair is declared twice

Orders and input/output

Refusals from flang io. A plan returns a DESCRIPTION of an action and the host performs it; the FLANG_IO_* family says the host refused.

codewhat it meanswhat to do
FLANG_PLANthe plan is declared wrongcheck the plan form
FLANG_UNKNOWN_PLANno plan by that name in the filename one that exists: --plan 'Имя'
FLANG_PLAN_UNSUPPORTEDthis kind of order is not carried out by this runnerreplace the order, or run where it exists
FLANG_IO_NO_HOSTthere is no host: nobody to hand the order torun through flang io, not by evaluating a function
FLANG_IO_NOT_TEXTa text read hit something that is not textread octets instead
FLANG_IO_UNSUPPORTEDa capability was withdrawn by a flag, or the action is not supportedgive the capability back: drop --no-read, --no-write, --no-net and friends
FLANG_LOCKthe lock file is damaged or its seal does not matchrebuild the lock
FLANG_PACKAGEthe package is damaged: its list does not match its contentsrebuild the package

Capabilities are narrowed one at a time; the default is "everything allowed":

flang io план.flang --plan 'Разбор' --no-net --in-dir

Processes

codewhat it meanswhat to do
FLANG_PROCESSthe process is declared wrongcheck the declaration
FLANG_PROCESS_ACCEPTSa process received a message it does not acceptadd the message kind to принимает
FLANG_PROCESS_LIMITthe process count limit was hitraise the limit or spawn fewer
FLANG_MAILBOX_FULLthe mailbox is full: the reader is behindread more often or throttle the sender
FLANG_LINK_DOWNa link to a node or process is brokenhandle the break in supervision
FLANG_CONC_UNSUPPORTEDthis process feature is not supportedsee the processes page
FLANG_HOTSWAP_REFUSEDa hot code swap was refusedmake the new code fit the previous declarations

Command line and internals

codewhat it meanswhat to do
FLANG_CLIbad invocation: unknown flag or missing argumentflang <команда> --help
FLANG_INTERNALthe compiler itself brokereport it: this is a tool failure, not your program's
FLANG_SELF_EVAL_UNSUPPORTEDthe form is outside what this evaluation path handlesevaluate with the ordinary flang run
FLANG_SELF_REPL_UNSUPPORTEDthe shell does not take this form — использует, for exampleput the code in a file and run flang check
FLANG_FACTCHECK_НЕТ_ОТВЕТАthe fact check got no evaluator answer for a callsupply the answer in the fact set
flang check --неткого
flang check: непонятный ключ «--неткого»

The exit code is 2.

Next: The kernel refused: whose mistake is it — how to read a proof refusal and when the author is not to blame.