You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make keyword completeness decidable, not corpus-witnessed (#51)
The keyword/operator obligation was the one class still checked by the
grammar-derived corpus (leaf coverage). Replace it with a structural,
a-priori discharge: `literalDischarge` confirms every alphabetic literal the
grammar consumes (collectLiterals over every rule + the prec/led tables)
appears, as a scoped word, in some REACHABLE pattern whose scope is a keyword
family — a finite scan of the emitted artifact, no corpus. 248/248 across the
six grammars; non-vacuous (stripping `class` from its patterns reports it
undischarged).
Completeness is now a decidable structural check end to end — token discharge
(census, incl. neuter) + keyword-literal discharge + repository reachability,
952/952 = 100%, no corpus. The leaf-coverage corpus pass is demoted to a
redundant differential cross-check on the soundness axis; `tm-mutation`'s
structural layer now also kills a dropped/neutered keyword corpus-free.
COMPLETENESS.md draws the line correctly: COMPLETENESS (present + reachable +
scoped) is decidable — finite G, finite gen-tm(G), an obligation taxonomy
bounded by TextMate's finite construct kinds, per-token discharge by
structural identity (the flat `match` IS the token's own pattern) — and ∀ G by
structural induction over the finite combinator algebra. SOUNDNESS (do the
present constructs paint correctly on all inputs — wrong-role, pattern
ordering) is the undecidable residual (CFG vs regex-stack-machine over infinite
input). The earlier "a-priori completeness is unavailable" was an
over-concession: that was soundness's wall, mistaken for completeness's.
`a structural check on the emitted artifact, no corpus. Leaf cross-check (corpus, redundant): ${sum.lp}/${sum.lf}. `+
482
534
`${num===den ? '**0 open completeness gaps.**' : `**${den-num} OPEN GAP(S).**`}`);
483
535
L.push('');
484
536
L.push('<!-- COMPLETENESS-LEDGER:END -->');
@@ -519,14 +571,16 @@ async function main(): Promise<void> {
519
571
consttc=tokenCensus(g,tmJson);
520
572
check(`token-completeness(${cfg.name}): every non-skip token has a discharge path`,tc.orphans.length===0,`orphans: ${tc.orphans.join(' ')}`);
521
573
check(`token-completeness(${cfg.name}): no flat token is neutered to the bare root scope`,tc.neutered.length===0,`neutered: ${tc.neutered.join(' ')}`);
574
+
constld=literalDischarge(g,tmJson);
575
+
check(`literal-completeness(${cfg.name}): every keyword literal/operator is in a reachable keyword-scoped pattern`,ld.gaps.length===0,`undischarged: ${ld.gaps.join(' ')}`);
0 commit comments