Elamur Groupants⌕
☰

modelcheck-sections

The groupant beside tools/modelcheck/src/sections.rs in the Mova repository: what the code computes, what it never does, how to go back from its outputs, its invariants, cost and checks.

Facts

Implementation material. A Mova code model describes this code at one source revision: partial models, finite checks and their stated scope. It is not a reviewed general exposition, and its labels are shown as written, never raised.

Components

componentlabelwhere
approximantsource derivedForward
astpartialsyntax.json
compositionpartialComposition
costsymbolic unmeasuredCost
descriptantpresentDescriptant
invariantsource derivedInvariant
testsbounded executedTests

Obernants

The typed relations around the forward model: the behaviour complement (what the code never does), the reverse reconstruction (every input compatible with an output) and specialised views.

idtypelabelwhere
behavior_complementbehavior_complementpartial source derivedbehavior_complement
reverse_reconstructionreverse_reconstructionpartial source derivedreverse_reconstruction

Parts

Model text

Descriptant

sections.rs holds the narrow Markdown section grammar that groupant references and the one-file consolidation share: line splitting with fence state, plain H2 headings, section byte selection, file#Section splitting, GitHub-style anchors and heading demotion. It is not a Markdown renderer: no setext headings, HTML blocks, lists, containers or inline markup.

Epoch 2026-11-04 (source revision in the manifest): created when each groupant became one model.md with blocks. The fence automaton moved here from lib.rs; its fragment is section-fences.groupant.

Forward

For text T split at \n (CRLF terminators stripped from the line text, kept in spans):

Invariant

Only unfenced exact ## S lines select sections; a missing or duplicate heading never yields bytes. section_bytes is a substring of T that starts with ## S. demote changes only unfenced heading lines and only by inserting # characters, so removing the same k characters from those lines restores T. Fence state after a closed fence equals the initial state.

Cost

O(B) time over the B bytes of T for each call, O(L) line records for L lines; section_bytes scans twice (count, then selection). No allocation beyond the line vector, the heading string and the demoted output.

Composition

lib.rs uses heading_count, split_reference and section_bytes (through reference_bytes) for component sections and hash-bound section references. consolidate.rs uses all of the module: verbatim/wrapped decisions, collision anchors, demotion, unclosed-fence refusal and section rebinding. mova-correspondence uses split_reference and section_bytes for catalogue model bindings. The child section-fences.groupant refines the fence automaton range.

Tests

sections::tests::sections_follow_the_plain_h2_grammar (fenced heading ignored, duplicates rejected, unclosed fence detected, split and anchor) and sections::tests::demotion_is_reversible_and_skips_fences (fenced lines, non-headings and overflow). Integration: consolidate::tests and the groupant validation controls in lib.rs.

behavior_complement

The module never selects a section for zero or several matching headings, never treats a fenced, indented (≥4 spaces), padded or ##-without-space line as a heading, never rewrites non-heading lines in demote, and never resolves paths, reads files or interprets inline Markdown, HTML or setext headings.

reverse_reconstruction

Given section_bytes(T,S)=X, every T whose unique ## S section has exactly those bytes is compatible; the other sections, the preamble and trailing blank lines are unconstrained. Given demote(T,k)=D with known k, T is unique (remove k # from each unfenced heading line of D); with unknown k, every k with all heading levels of D above k is compatible. Given anchor(n)=a, all names differing only in case, removed punctuation or surrounding whitespace are compatible.

This page in Markdown → https://md.groupants.elamur.ai/free/en/mova/tools/modelcheck/src/sections.rs.groupant/