rocq/theories/HelloJoin.v
GNU Hello's greeting, and the whole program
HelloMain proves main from its entry up to the greeting at iw_1.join (main_to_join). This file proves the rest: the greeting block, which measures the greeting, allocates a wide buffer with xmalloc, converts the greeting into it with gnulib's rpl_mbsrtowcs (HelloConv's rpl_mbsrtowcs_spec), prints it with wprintf, frees it and exits, or reports a failed conversion with error(1, ...). It lives apart from HelloMain so that HelloMain does not wait for HelloConv: the two compile side by side, and this file after both.
The premises are those of the conversion, as HelloConv states them, and of the greeting's own calls. Like HelloMain's, each is what one call needs of the world interpretation wi, which stays abstract.
xmalloc's function, read from the linked module.
A block of xmalloc.
A 16-aligned address is 4-aligned.
Explore proof 6 tactics
Initial goal
intros H
apply Z.mod_divide ; lia |
apply Z.divide_trans4 16 b
2 openfocused goal
–exists 4
2 opendeferred goal
reflexivity
deferred goal
–apply Z.mod_divide ; lia | exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The traditional greeting's bytes, "hello, world".
setlocale returns a pointer.
Explore proof 1 tactics
Initial goal
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
setlocale(c, v), binding a pointer, fits setlocale's ABI.
Explore proof 1 tactics
Initial goal
split ; right ; exists d ; reflexivity | exists c, v ; reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The genv links Hello.
An allocation of a fresh object, with its pieces added, keeps wi.
memset has its contract, and zeroing eight bytes of a block the program owns keeps wi.
set_program_name's contracts.
set_program_name's cells: their layout and store premises.
setlocale has libc's contract. The world interpretation keeps every lent name where lent_at says, admits setlocale's precondition for a category and a string the program owns, and survives its return, which lends every category's new name and sets the codec piece.
A pointer store into a cell the program owns keeps wi.
atexit has a contract returning an int, which admits the call main makes, registering close_stdout, and whose return keeps the program's pieces and wi: the registration is libc's state.
argv: aligned, its argc + 1 slots in its region, argc a positive C int, each argument a C string.
getopt_long has libc's refined contract for this run's input, over the native parser's initialized and running representations, its allocation requests and the transition an ordinary return makes. Every path is proved whatever the transition, so the safety contract's own returns are the case of a transition that always holds.
wi ties libc's optarg and optind cells to the parser's state and the getopt token, as GetoptLogic.v's reads need.
wi keeps Hello's option literals in memory.
wi admits getopt_long's libc side where main owns argv and the arguments: the parser's representation, its private roots and reads, and their separation from the call's inputs and outputs.
getopt_long's private roots and libc's cells are apart from the program's objects, and it releases none of them.
A return of getopt_long from a memory that agrees with the ghost heap, with its live objects apart and the runtime ready, keeps wi, with argv's block holding what the memory then holds and the token naming the new optarg and optind.
libc's optarg cell is the global optarg, and both cells are at word addresses.
libc's optind cell is the global optind.
exit has a contract that admits any canonical status and never returns to main. The handlers it runs, close_stdout among them, are the ending's, not main's: in this language the call stalls.
libc's stdout: the world keeps its cell readable and holding the stream, as HelloVersion's footer assumes.
version_etc's premises, as HelloVersion's version_etc_spec takes them: the literal pieces main owns, the authors' lives among them, the six output contracts and the frame of its allocations, stores and snapshot.
libc's stderr: the world keeps its cell readable and holding the stream, as for stdout.
The output contracts of main's own calls and of the footer, as HelloVersion states the footer's: each is admitted with the literals' pieces (and, for a line naming the program, the arguments' strings, one of which holds its name), returns a canonical int and keeps the world interpretation, whether its output succeeded or not.
error(0, 0, fmt, text, arg), the diagnostic for an extra operand, has a contract that returns: admitted with the literals' and the arguments' pieces for an argument's string, it keeps the world interpretation and every piece main owns.
mbrtowc has Campaign 4's contract, whose state predicate valid admits the zero state and holds only of bytes.
The world interpretation makes libc ready, with the errno cell errno, keeps the codec piece current (codec_current) and libc's private state apart. A conversion learns the codec from the codec piece, which setlocale's setter set (wp_setlocale_set).
The audited codec premise: the world's codec is one of the audited profiles, C or C.UTF-8.
The world interpretation survives a return of mbrtowc into the output, state and errno blocks the program owns, holding whatever the memory holds there afterwards.
setlocale's query of a category whose name is lent, by a pointer whose address is null, as hard_locale and main's --help make it: admitted, it returns that name and changes nothing (LocaleLogic's locale_wi_pre and locale_wi_query, for libc's world).
strlen, memcpy and strcmp have their contracts.
The world interpretation survives a copy, a byte store and a four-byte store into a block the program owns.
The memchr contract, for strnlen1.
errno's lookup has Campaign 4's contract.
malloc has its contract.
The errno cell is at offset eo of an object eb that main owns, in the address space.
The greeting's literals: the format of the failed conversion's diagnostic and the wide format of the greeting's line. Main owns their pieces, join_ps.
error(1, errno, fmt), the diagnostic of a failed conversion, has the same contract as main's extra-operand diagnostic, error being one function: it is admitted with the literals' pieces and never returns, as its status is nonzero.
errno's lookup returns the errno cell, whose bytes main owns.
wprintf(fmt, buffer) is admitted where main owns the literals and a buffer holding a terminated wide string, returns a canonical int and keeps the world interpretation, whether its output succeeded or not.
free releases a heap object main owns, keeping the world interpretation.
The Iris proofs, under any invariant and ghost heap instance.
The Iris instance of the registry and wi.
The expressions of the language.
Enter a block of a function f, read from the linked module.
xmalloc(n): malloc's contract has no null return, as running out of memory is a resource ending, so xmalloc's call of xalloc_die, and the abort behind it, is never reached: xmalloc returns a fresh heap object of n bytes.
Proof 31 steps Qed
The base is not null: on to the join, not to xalloc_die.
One argument's string out of all of them, and back.
Proof 9 steps Qed
The greeting b4's cell holds in the loop is a string main owns: the default literal, the traditional one, or a suffix of an argument that getopt lent as optarg. It is given back after use.
Proof 23 steps Qed
A heap request's extent covers its size.
Proof 5 steps Qed
iw_1.join, the greeting: entered with pr.2 clear and optind at argc, main loads the greeting from b4's cell, measures it, allocates a buffer of that many wide characters and the NUL, and converts the greeting into it.
Proof 156 steps Qed
The greeting, from b4's cell.
Its length, and the buffer's: four bytes per character and the NUL.
xmalloc(4 * (len + 1)).
The buffer: its first 4 * (len + 1) bytes and slots.
rpl_mbsrtowcs(buffer, b4's cell, len + 1, b6's state).
The conversion failed: error(1, errno, ...), which never returns.
The conversion succeeded: wprintf, free, exit(0).
Main, every path: from its entry through the loop (HelloMain's main_to_join) to the greeting (main_join), owning what both need. Every path ends in a call that does not return, exit or a fatal error, or loops for good; none reaches abort.
Proof 10 steps Qed
--help's query of LC_MESSAGES, from the general query premise.
GNU Hello's main never fails: from a memory m, runtime state s and world w where R is ready, the live objects are apart, and an initial ghost heap h0 that agrees with m, satisfies wi with w and holds the pieces main_full needs, no labelled run of main, at any fuel, stops with a failure_ending: no panic, no stuck step, no contract violation, and so no abort. By heap_labelled_safe from main_full. The premises are the section's, the audited codec premise Haudit among them.