Uh oh!
There was an error while loading. Please reload this page.
[Lean Squad] feat(fv): Task 2 — informal spec for CommandLineParser.ParseOptionAndSeparators - #7919
Conversation
…Separators
Extracts a precise informal specification for the ParseOptionAndSeparators
local function in CommandLineParser. Documents:
- Pure string-split function: first-occurrence of ':' or '=' delimiter
- 16 named properties across 5 groups (no-delimiter, delimiter-present,
reconstructibility, determinism, edge cases)
- TrimStart('-') normalization of option-name prefix
- Edge case: empty option name when delimiter immediately follows dashes
(e.g. '--:value' produces currentOption = '')
- Interaction with TryUnescape (caller passes currentArg after Trim())
- Approximations for Lean 4 model (List.dropWhile, List.findIdx?)
- 5 concrete Lean examples for #eval tests
Advances CommandLineParser.ParseOptionAndSeparators from phase 1 to phase 2.
Updates TARGETS.md to reflect current phase state of all 7 targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>There was a problem hiding this comment.
Pull request overview
Adds/updates Lean Squad formal-verification documentation for command-line parsing, specifically capturing an informal spec for the CommandLineParser.ParseOptionAndSeparators split semantics and reflecting that progress in the FV target tracker.
Changes:
- Added an informal specification doc for
CommandLineParser.ParseOptionAndSeparators. - Updated
formal-verification/TARGETS.mdto mark additional targets as Phase 2 (informal spec extracted) and refreshed priority notes.
Show a summary per file
| File | Description |
|---|---|
| formal-verification/specs/commandlineparser_parseoptionandseparators_informal.md | New informal spec describing split behavior on : / = and Lean modeling notes |
| formal-verification/TARGETS.md | Updates FV target phases/status and priority-order notes |
Copilot's findings
Comments suppressed due to low confidence (3)
formal-verification/specs/commandlineparser_parseoptionandseparators_informal.md:180
- The “Open Question 2” section includes an in-line correction (“Wait — actually …”) and intermediate reasoning that makes the spec harder to read. Consider rewriting it as a concise, final statement of the intended behavior (e.g., “splits at the first raw
:/=; quoting is not interpreted by this function”).
### Open Question 2 — Delimiter within quoted value
`"--option='a:b'"` produces `currentOption = "option"` and `currentArg = "'a:b'"`. The colon is inside quotes, but `ParseOptionAndSeparators` does NOT understand quoting — it splits on the first raw `:`. For `"--option:a"`, split occurs before seeing quotes. For `"--option='a:b'"`, the first `:` is index 9 (before `'a`), so `currentArg = "'a:b'"`. Wait — actually `"--option='a:b'"` has `=` at index 8, not `:` first. So `currentOption = "option"`, `currentArg = "'a:b'"`. This is correct. But `"--option:'a:b'"` would split at the first `:` (index 8), giving `currentOption = "option"` and `currentArg = "'a:b'"`. The second `:` is preserved in the value. This seems correct.
formal-verification/specs/commandlineparser_parseoptionandseparators_informal.md:114
- Property 12 says “Delimiter priority is lexicographic order”, but the behavior described is positional/leftmost.
IndexOfAnydoes not choose based on character ordering; it returns the smallest index of any of the searched characters, regardless of whether it’s:or=.
11. **Purity**: `ParseOptionAndSeparators` is a pure function — same input always yields same output.
12. **Delimiter priority is lexicographic order**: `IndexOfAny` finds the leftmost occurrence of either delimiter character. The type of delimiter (`:` vs `=`) is irrelevant; only position matters.
13. **Which delimiter came first determines the split**: If `arg = "x=y:z"`, then `currentOption = "x"` and `currentArg = "y:z"`. If `arg = "x:y=z"`, then `currentOption = "x"` and `currentArg = "y=z"`.
formal-verification/specs/commandlineparser_parseoptionandseparators_informal.md:173
- The recommendation in “Issue 1 — Empty option name not rejected” suggests setting
currentOption = null, but earlier sections (Data Model/Invariants) assertcurrentOptionis never null. Please align the recommendation with the stated model (e.g., keepcurrentOptionnon-null and report an error via the parse result), or update the invariants/model to reflect a nullable option name if that’s the intended contract.
### Issue 1 — Empty option name not rejected
**Observation**: The function does not validate that `currentOption` is non-empty after `TrimStart('-')`. Inputs like `"--:value"` or `"--="` produce `currentOption = ""`, which is then treated as a valid option name by the caller. The caller does not re-validate.
**Consequence**: The parser silently creates a `CommandLineParseOption` with option name `""` instead of reporting an error. Attempting to look up this option in the registered options table will fail to find a match (but may produce an unhelpful error message downstream).
**Severity**: Minor / edge case. In practice, callers pass well-formed command lines. The preconditions exclude `--:` inputs via the `arg[2] != '-'` check only if we consider `:` as a non-dash character — which it is — but the preconditions do NOT exclude `--:` specifically.
**Recommendation**: Add a post-split guard: `if (string.IsNullOrEmpty(currentOption)) { errors.Add(...); currentOption = null; }`.
- Files reviewed: 2/2 changed files
- Comments generated: 2
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot's findings
Comments suppressed due to low confidence (2)
formal-verification/specs/commandlineparser_parseoptionandseparators_informal.md:146
- Invariant 3 (“The function never throws”) is only true under the non-null input precondition. As written, it reads like a total guarantee; passing
nullforargwould throw atarg.IndexOfAny(...). Please scope this invariant explicitly toarg != null(or restate it as “does not throw for any non-nullarg”).
1. `currentOption` is never `null` — it is always a `string` (possibly empty).
2. `currentArg` is `null` if and only if no delimiter character appears in `arg`.
3. The function never throws (no index-out-of-bounds; `arg[..delimiterIndex]` with `delimiterIndex ≥ 0` is always valid; `arg[(delimiterIndex + 1)..]` when `delimiterIndex = arg.Length - 1` yields `""`).
4. `currentOption` contains no `:` and no `=`.
formal-verification/specs/commandlineparser_parseoptionandseparators_informal.md:176
- The “Open Question 2” section contains a self-correction (“Wait — actually …”) and an intermediate incorrect index claim. For a formal-verification spec, this is confusing and easy to misread; please rewrite this paragraph to present the final, correct reasoning directly (optionally with one precise worked example per delimiter style).
### Open Question 2 — Delimiter within quoted value
`"--option='a:b'"` produces `currentOption = "option"` and `currentArg = "'a:b'"`. The colon is inside quotes, but `ParseOptionAndSeparators` does NOT understand quoting — it splits on the first raw `:`. For `"--option:a"`, split occurs before seeing quotes. For `"--option='a:b'"`, the first `:` is index 9 (before `'a`), so `currentArg = "'a:b'"`. Wait — actually `"--option='a:b'"` has `=` at index 8, not `:` first. So `currentOption = "option"`, `currentArg = "'a:b'"`. This is correct. But `"--option:'a:b'"` would split at the first `:` (index 8), giving `currentOption = "option"` and `currentArg = "'a:b'"`. The second `:` is preserved in the value. This seems correct.
- Files reviewed: 2/2 changed files
- Comments generated: 2
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Amaury Levé (Evangelink)
commented
Apr 29, 2026
Copilot resolve the merge conflicts in this pull request |
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
…arseOptionAndSeparators (#7919) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Extract a precise informal specification for CommandLineParseResult.Equals, the structural-equality implementation for the command-line parse result type.
The spec documents:
Next: Task 3 — write ArgumentArity.lean (highest priority Lean target)
🔬 Lean Squad — automated FV agent
Fixes#7911#7907