Skip to content

Commit 031bcbb

Browse files
proof(SafeYAML): DISCHARGE isScalarCorrect via 9-arm case-split (proven#90, #107) (#112)
\`\`\`idris public export isScalarCorrect : (val : YAMLValue) -> isScalar val = True -> not (isCollection val) = True isScalarCorrect YNull _ = Refl isScalarCorrect (YBool _) _ = Refl isScalarCorrect (YInt _) _ = Refl isScalarCorrect (YFloat _) _ = Refl isScalarCorrect (YString _) _ = Refl isScalarCorrect (YArray _) Refl impossible isScalarCorrect (YObject _) Refl impossible isScalarCorrect (YBinary _) _ = Refl isScalarCorrect (YTimestamp _) _ = Refl \`\`\` 7 scalar constructors → \`Refl\` (each reduces \`not (not True) = True\`). 2 collection constructors (YArray, YObject) → \`Refl impossible\` (premise \`isScalar val = True\` reduces to \`False = True\` which is uninhabited). This is a slightly different shape from the prior [proven#107](#107) PRs — here the OWED comment correctly identified the 9-arm case-split discharge, the work was just OWED to be done. Refs #90 #107 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent da929da commit 031bcbb

1 file changed

Lines changed: 19 additions & 13 deletions

File tree

src/Proven/SafeYAML/Proofs.idr

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -237,19 +237,25 @@ parsedTypesCorrect (YTimestamp _) = Refl
237237
||| Held back by Idris2 0.8.0 not reducing `not . not . isScalar val`
238238
||| to `isScalar val` by Refl when `val` is abstract. The composition
239239
||| `(not . isScalar) val` only unfolds to `not (isScalar val)` once
240-
||| Idris splits on `val`'s constructor (so it can pattern-match
241-
||| `isScalar` to a literal `True`/`False`); for an abstract `val`
242-
||| the outer `not` keeps `not (isScalar val)` stuck, and the second
243-
||| `not` then keeps the whole expression stuck. Same blocker family
244-
||| as the `Data.Bool` involution gap noted in SafeChecksum's
245-
||| `xorChecksum [x,x] = 0` OWED. Discharge by case-analysis on the
246-
||| nine `YAMLValue` constructors (each branch reduces to `not (not
247-
||| True) = True` by Refl), or by a `boolDoubleNegation` lemma over
248-
||| `Bool`.
249-
export
250-
0 isScalarCorrect : (val : YAMLValue) ->
251-
isScalar val = True ->
252-
not (isCollection val) = True
240+
||| DISCHARGED via 9-arm case-split on `val`'s constructor — each
241+
||| scalar arm reduces `not (isCollection val) = True` to `Refl`
242+
||| (since `isCollection = not . isScalar` and `isScalar = True` on
243+
||| scalars means `not (not True) = True`). The two collection arms
244+
||| (`YArray`, `YObject`) have the premise `isScalar val = True`
245+
||| reduce to `False = True` which is uninhabited (`impossible`).
246+
public export
247+
isScalarCorrect : (val : YAMLValue) ->
248+
isScalar val = True ->
249+
not (isCollection val) = True
250+
isScalarCorrect YNull _ = Refl
251+
isScalarCorrect (YBool _) _ = Refl
252+
isScalarCorrect (YInt _) _ = Refl
253+
isScalarCorrect (YFloat _) _ = Refl
254+
isScalarCorrect (YString _) _ = Refl
255+
isScalarCorrect (YArray _) Refl impossible
256+
isScalarCorrect (YObject _) Refl impossible
257+
isScalarCorrect (YBinary _) _ = Refl
258+
isScalarCorrect (YTimestamp _) _ = Refl
253259

254260
--------------------------------------------------------------------------------
255261
-- Deserialization Safety Proofs

0 commit comments

Comments
 (0)