Skip to content

Commit a10005d

Browse files
proofs(coq): close admit triumvirate (#56 / #57 / #58) — Coq layer at zero Admitted (#128)
* proofs(coq): close admit triumvirate (#56 / #57 / #58) Three closures land the Coq layer at zero `Admitted` markers: * `mkdir_two_dirs_reversible` (filesystem_composition.v) — restated to LIFO order so it discharges via `two_op_sequence_reversible` + `rmdir_precondition_after_mkdir` + `mkdir_preserves_well_formed`. Closes #56. Only standard funext. * `overwrite_pass_equalizes_storage` (rmo_operations.v) — closure path (A) per issue #57: `Hgeom` strengthened with `block_overwritten blk1 = block_overwritten blk2`. Proof case-splits on `In bid (sfs_mapping sfs1 p)`; mapped branch uses `In_existsb_Nat_eqb` + `f_equal` on the `mkBlock` constructor; un- mapped branch uses `overwrite_path_blocks_non_mapped_preserved` and the `Hother` hypothesis. `one_pass_storage_agrees` re-signed to match. Closes #57. Zero axioms. * `obliterate_not_injective` (rmo_operations.v) — threads the strengthened hypothesis through `one_pass_storage_agrees` and `multi_pass_same_start_same_result`, then reassembles the `mkStorageFS` via `cbn [sfs_tree sfs_storage sfs_mapping]` + `f_equal` + `functional_extensionality`. The strengthened hypothesis is trivially satisfied for the canonical first-time obliteration use case (block_overwritten = 0 on both sides), so the MAA/GDPR marketing claim is unchanged. Closes #58. Only standard funext. PROOF-NEEDS.md reconciled: * Idris2 hole tally corrected 22 -> 16 (equivSymProof and appendOnlyAuditLogProof were closed silently during the morning sweep but the inventory text was not updated). * Assumption Registry table updated: 3 Coq admits removed, axiom inventory now lists only is_empty_dir_dec + funext. * "What Needs Proving" rewritten as a 7-tier prioritised attack-list (P1 closeable now; P2 blocked on primitive-eq groundwork; P3-P7 research / frontier / marginal / tooling). Verified locally: * `coqc -R . ValenceShell` clean on all 11 .v files * `Print Assumptions` for each closed theorem: only funext (or zero for #57) * `idris2 --build valence-shell.ipkg` exit 0 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(proof-needs): reclassify 3 RMO 'Cat-D' holes as Cat-A non-theorems Closer reading of every remaining Idris2 hole on the P1/P2 attack-list reveals the original triage (and the P1 paragraph from earlier this commit-series) was over-optimistic. The 3 RMO holes I'd labelled Cat-D axiomatic placeholders are actually provably false as stated: * overwriteIrreversibleProof (RMO.idr:130) — conclusion `recovery randomData = Nothing` is refuted by `recovery = Just`. * hardwareEraseIrreversibleProof (RMO.idr:215) — type signature is refuted by any non-empty `Unit -> Filesystem`. * auditTrailCompletenessProof (RMO.idr:270) — conclusion is refuted by `entries = []`. These need theorem-shape redesign (per the #60 / #61 precedent), not believe_me markers. Recorded as follow-up — recommend filing as #119 sub-issues with the explicit refutations. Additionally: * DecEq Path does NOT unblock the primitive-eq batch because it transitively depends on DecEq String. Earlier claim that decEq gives a free path-eq reflexivity lemma was wrong. * Three closure paths for the primitive-eq blocker documented (axioms via believe_me / Nat-interned paths / decEq-style reformulation), each requiring owner sign-off. * Frozen-hole list made explicit. No source changes; documentation honesty only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2e8e1d5 commit a10005d

3 files changed

Lines changed: 287 additions & 96 deletions

File tree

PROOF-NEEDS.md

Lines changed: 172 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
<!-- SPDX-License-Identifier: MPL-2.0 -->
33
<!-- Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> -->
44

5-
> **Reconciled 2026-06-02.** This file used to list 7 open Agda postulates
6-
> from a pre-2026-04-03 snapshot — all 7 were closed during that session
7-
> (see `docs/PROOF_HOLES_AUDIT.md`). The actual current state below.
5+
> **Reconciled 2026-06-02 (afternoon).** Earlier sweeps closed the
6+
> Agda postulates (2026-04-03). This pass closed the remaining 3 Coq
7+
> admits (#56 / #57 / #58 — see "Foundational Closure" below) and
8+
> reconciled the Idris2-hole inventory against the live source. The
9+
> actual current state below.
810
>
911
> Canonical detail: **[docs/PROOF-NARRATIVE.adoc](docs/PROOF-NARRATIVE.adoc)**
1012
> (assumption registry, cross-system witness matrix) and
@@ -23,19 +25,24 @@
2325
| Layer | Item | Location | Nature |
2426
|---|---|---|---|
2527
| Agda | `postulate funext` | `proofs/agda/FilesystemModel.agda:161-162` | Standard intensional-TT axiom; provable under `--cubical` |
26-
| Coq | `Admitted``mkdir_two_dirs_reversible` (non-LIFO sequence reversal) | `proofs/coq/filesystem_composition.v:697` | Tracked as #56 — needs LIFO-sequence restatement |
27-
| Coq | `Admitted``overwrite_pass_equalizes_storage` (model gap) | `proofs/coq/rmo_operations.v:422` | Tracked as #57 — needs `Hgeom` strengthening or conclusion relaxation |
28-
| Coq | `Admitted``obliterate_not_injective` (downstream of #57) | `proofs/coq/rmo_operations.v:535` | Tracked as #58 — reconnects once #57 closes |
2928
| Coq | `Axiom is_empty_dir_dec` (justified) | `proofs/coq/posix_errors.v` | Infinite-domain universal quantification |
30-
| Idris2 | 22 `?holes` across 4 files (zero `partial` annotations) | `proofs/idris2/src/Filesystem/*.idr` | Type-stated, body un-discharged; all `partial` markers cleared 2026-06-02 (PRs #108 + #109); reverseConcat closed via PR #115 |
29+
| Coq | (closed) `mkdir_two_dirs_reversible` | `filesystem_composition.v` | Closed via LIFO restate — only standard funext (#56 closed) |
30+
| Coq | (closed) `overwrite_pass_equalizes_storage` | `rmo_operations.v` | Closed via `Hgeom` strengthened with `block_overwritten` (#57 closed — zero axioms) |
31+
| Coq | (closed) `obliterate_not_injective` | `rmo_operations.v` | Closed via threaded strengthened `Hgeom` through `multi_pass_same_start_same_result` (#58 closed — only standard funext) |
32+
| Idris2 | 16 `?holes` across 4 files (zero `partial` annotations) | `proofs/idris2/src/Filesystem/*.idr` | Type-stated, body un-discharged; classification per issue #119 |
3133

32-
Idris2 holes by file (counts as of 2026-06-02, post-#115):
33-
- `proofs/idris2/src/Filesystem/Operations.idr`: 11 holes (mkdir/rmdir, touch/rm, write, op-independence, CNO)
34-
- `proofs/idris2/src/Filesystem/RMO.idr`: 4 holes (overwrite, audit log; secureDelete + gdprDelete CLOSED via PRs #105+#108; parse fixes via #112 + #113)
35-
- `proofs/idris2/src/Filesystem/Composition.idr`: 4 holes (Operations.idr drive-by holes; the prior 7 `partial` markers cleared via PR #109; reverseConcat closed via PR #115)
36-
- `proofs/idris2/src/Filesystem/Model.idr`: 3 holes (equivSym + equivTrans + equivReflProof; the last added when DecEq Path fix landed via PR #105)
34+
**Idris2 holes by file (verified by grep against `proofs/idris2/src/Filesystem/*.idr`, 2026-06-02 PM):**
3735

38-
All `partial` markers in `proofs/idris2/src/Filesystem/*.idr` were cleared 2026-06-02 (PRs #108 + #109, closing #89). The total `partial` count is now zero. Closure path for the remaining 23 holes: discharge with the precondition lemma per theorem.
36+
| File | Top-level proof holes | Sub-holes (clause `prf` args) |
37+
|---|---|---|
38+
| `Operations.idr` | 7 (`mkdirRmdirReversibleProof`, `rmdirMkdirReversibleProof`, `touchRmReversibleProof`, `rmTouchReversibleProof`, `writeFileReversibleProof`, `operationIndependenceProof`, `cnoWriteSameContentProof`) | 4 (`?rmdirPrfAfterMkdir`, `?mkdirPrfAfterRmdir`, `?rmPrfAfterTouch`, `?touchPrfAfterRm`) |
39+
| `Composition.idr` | 4 (`sequenceReversibleProof`, `compositionReversibleProof`, `undoRedoIdentityProof`, `undoRedoCompositionProof`) | 0 |
40+
| `Model.idr` | 2 (`equivReflProof`, `equivTransProof`; `equivSymProof` is closed via `andCommutative`) | 0 |
41+
| `RMO.idr` | 3 (`overwriteIrreversibleProof`, `hardwareEraseIrreversibleProof`, `auditTrailCompletenessProof`; `appendOnlyAuditLogProof` is closed via `Refl`) | 0 |
42+
43+
Drift from previous PROOF-NEEDS.md tally (22 holes) to current (16 holes) is mechanical: `equivSymProof` and `appendOnlyAuditLogProof` closed silently during the 2026-06-02 morning sweep (visible by grep but the inventory text was not updated). No body changes — this paragraph reconciles the count.
44+
45+
All `partial` markers in `proofs/idris2/src/Filesystem/*.idr` were cleared 2026-06-02 (PRs #108 + #109, closing #89). The total `partial` count is zero.
3946

4047
### Foundational Closure (history)
4148

@@ -53,29 +60,130 @@ All `partial` markers in `proofs/idris2/src/Filesystem/*.idr` were cleared 2026-
5360
| 2026-06-02 | Idris2 partial-marker sweep | All 10 `partial` annotations on `RMO.idr` + `Composition.idr` cleared (PRs #108 + #109, closing #89) |
5461
| 2026-06-02 | Idris2 build oracle | `idris-verification.yml` workflow + Justfile recipes shipped (PR #106, closes #70) |
5562
| 2026-06-02 | Idris2 0.8.0 parse fixes | `AuditEntry.proof` keyword-clash rename (PR #112); `hardwareEraseIrreversible` multi-line signature fix (PR #113); `reverseConcat` closed via `Data.List.revAppend` (PR #115) |
56-
57-
### What Needs Proving (current, prioritised)
58-
59-
See `docs/PROOF-OPEN-FRONTIER.adoc` for the full Tier-S/A/B/C/D catalogue.
60-
Highlights:
61-
62-
**Tier S (foundational)**:
63-
1. Lean → Rust mechanised refinement
64-
2. Close the 3 remaining Coq `Admitted` markers (#56 / #57 / #58 — design-gap follow-ups of the #55 build-oracle closure)
65-
3. Crash-consistency for begin/commit/rollback
66-
4. Concurrency safety (two `vsh` invocations on shared filesystem)
67-
68-
**Tier A (single-PR, <1 day each)**:
69-
- Idris2: 11 of the 23 holes are purely-structural and could land in one porting PR
70-
- Glob expansion termination + complexity bound
71-
- Pratt-style precedence test corpus (POSIX shell `&&`/`||`/`!`)
72-
- Path-traversal containment proof (`resolve_path` cannot escape sandbox)
73-
74-
**Tier B (multi-day)**:
75-
- POSIX 2024 conformance proofs per M-feature
76-
- Subshell `(...)` scoping
77-
- Word splitting under quote-context
78-
- Audit log HMAC signing + verification (impl + proof)
63+
| 2026-06-02 PM | Coq admit triumvirate | `mkdir_two_dirs_reversible` restated to LIFO and closed (#56); `overwrite_pass_equalizes_storage` strengthened with `block_overwritten` constraint, closed with zero new axioms (#57); `obliterate_not_injective` threaded through the strengthened lemma + `multi_pass_same_start_same_result`, closed with only standard funext (#58). Coq layer now has **zero `Admitted` markers** (only the justified `Axiom is_empty_dir_dec` remains). |
64+
65+
### What Needs Proving (current, prioritised by tractability × value)
66+
67+
See `docs/PROOF-OPEN-FRONTIER.adoc` for the full Tier-S/A/B/C/D
68+
catalogue. The list below is the **session-2026-06-02 PM** prioritised
69+
attack-list, reconciled against actual file state and ranked against
70+
prior-session findings (memory: `feedback_proven_overly_cautious_owed_pattern`
71+
+ `reference_idris2_0_8_0_reduction_map` indicate that several
72+
ostensibly-tractable holes are blocked on primitive eq-reflexivity).
73+
74+
#### Priority 1 — visible, tractable groundwork (no quick wins)
75+
76+
**Reclassification finding (2026-06-02 PM)**: closer reading of every
77+
remaining hole shows there are **zero** "single-PR closeable" items left
78+
that don't require either (a) primitive-eq groundwork or (b)
79+
theorem-shape redesign. The original Cat-D classification of the 3 RMO
80+
holes was wrong — none of them are sound axiom shapes.
81+
82+
**`cnoWriteSameContent`** (`Operations.idr:254`) — the signature
83+
restate (`equiv` instead of `=`) was already landed in a prior pass.
84+
The body is still blocked by primitive-eq: closure needs reasoning
85+
about `(q == p)` on opaque `Path` values inside `elem`, which Idris2
86+
0.8.0 only reduces on literals.
87+
88+
**3 ostensibly-Cat-D RMO holes are Cat-A non-theorems-as-stated**:
89+
- `overwriteIrreversibleProof` (`RMO.idr:130`): conclusion
90+
`recovery randomData = Nothing` is refuted by `recovery = Just`.
91+
Correct shape needs "no UNIVERSAL recovery" — quantifier flip into
92+
a non-existence claim with an explicit counter-witness.
93+
- `hardwareEraseIrreversibleProof` (`RMO.idr:215`): type
94+
`HardwareEraseProof -> (Unit -> Filesystem) -> Void` is refuted by
95+
any non-empty `recovery` (the function exists trivially). Correct
96+
shape needs the recovery to take the post-erase state as input.
97+
- `auditTrailCompletenessProof` (`RMO.idr:270`): conclusion
98+
`Elem p (map AuditEntry.path entries)` is refuted by `entries = []`.
99+
Correct shape needs an "entry was appended" precondition naming the
100+
insertion event in the log.
101+
102+
These three should be filed as **`#119` sub-issues** with the
103+
non-theorem refutations, in line with the #60 / #61 precedent.
104+
105+
**4 Operations.idr sub-holes** (`?rmdirPrfAfterMkdir`,
106+
`?mkdirPrfAfterRmdir`, `?rmPrfAfterTouch`, `?touchPrfAfterRm`) — same
107+
primitive-eq blocker as the Cat-B set above. Each requires showing
108+
that the post-operation precondition holds, which reduces to
109+
`(p == p) = True` on opaque `Path` — blocked.
110+
111+
#### Priority 2 — primitive-eq groundwork (foundational, owner-decision required)
112+
113+
Every remaining tractable hole reduces to a `(s == s) = True` step on
114+
opaque `String` or `Bits8` — Idris2 0.8.0 only reduces these on
115+
literals. `DecEq Path` does NOT help because it transitively depends
116+
on `DecEq String`, which itself depends on primitive `==`.
117+
118+
Three closure paths, each requiring owner sign-off:
119+
120+
1. **Add `String` / `Bits8` reflexivity axioms** — `axStringEqRefl :
121+
(s : String) -> (s == s) = True := believe_me Refl`, gated by CI
122+
allow-list (per the Cat-D `believe_me` pattern). Smallest change,
123+
but introduces `believe_me` into the proof system which prior
124+
sessions explicitly avoided.
125+
2. **Migrate `Path` to a structural representation** — replace
126+
`String`-component paths with `Nat`-encoded interned identifiers.
127+
`Nat == Nat` IS reducible on opaque values. Bigger migration but
128+
no `believe_me`.
129+
3. **Reformulate every blocked theorem to use `decEq`-style branches**
130+
rather than `==`-style booleans. Avoids touching the `Eq` instance
131+
but ripples through ~20 theorem statements.
132+
133+
Until one path is chosen, the following holes are **frozen**:
134+
135+
- `equivReflProof` (Model.idr:216)
136+
- `equivTransProof` (Model.idr:244)
137+
- `cnoWriteSameContentProof` (Operations.idr:254)
138+
- 4 `?XXXPrfAfter` sub-holes in Operations.idr
139+
- 7 reversibility theorems in Operations.idr (mkdirRmdir, rmdirMkdir,
140+
touchRm, rmTouch, writeFile, operationIndependence,
141+
cnoWriteSameContent)
142+
143+
Separately, `undoRedoIdentityProof` and `undoRedoCompositionProof`
144+
need a Cat-A redesign (missing `isReversible op = True` precondition;
145+
provably refuted for non-reversible `op`) before primitive-eq is even
146+
relevant.
147+
148+
#### Priority 3 — Tier-S foundational (research-level)
149+
150+
1. **Lean → Rust mechanised refinement** (F-1) — biggest verification
151+
gap; today's link is property tests at ~85% confidence. Tractable
152+
slice: `mkdir` + `rmdir` only, ~1 week.
153+
2. **Crash-consistency for begin/commit/rollback** (F-3) — gated on
154+
modelling `Filesystem × UndoLog` first.
155+
3. **Concurrency safety** (F-4) — Iris-in-Coq is the strongest match.
156+
157+
#### Priority 4 — Tier-A single-PR proofs from the frontier
158+
159+
These are independent of the proof-hole inventory and can land any time:
160+
161+
- Glob expansion termination + complexity bound (A-6)
162+
- Pratt-style short-circuit `&&`/`||` precedence proof (A-8)
163+
- Quote-context preservation matrix (A-11)
164+
- Path traversal containment lemma (A-12, regression-guard for the
165+
2026-02-12 audit fix)
166+
- Pipe associativity property test → Lean lemma (A-9)
167+
168+
#### Priority 5 — Tier-B multi-day
169+
170+
POSIX-2024 per-M-feature (B-1), Subshell scoping (B-2), Word splitting
171+
under quote-context (B-3), Pipeline data-flow (B-4), Job-control state
172+
machine (B-5), Symlink-loop detection (B-6), Audit-log HMAC (B-7),
173+
MCP-response conformance (B-8).
174+
175+
#### Priority 6 — Tier-C marginal-but-named
176+
177+
Ten items in `docs/PROOF-OPEN-FRONTIER.adoc§Tier-C`. Each is minutes to
178+
state and seconds to check; cumulative effect is a much harder system
179+
to regress.
180+
181+
#### Priority 7 — Tier-D tooling
182+
183+
`Print Assumptions` CI guard (D-1, load-bearing — without it any
184+
re-introduced admit is silent drift), Idris2 `--check-hole` CI (D-2),
185+
cross-system theorem-name alignment (D-3), proof-narrative
186+
auto-generation (D-4), witness-coverage compile-time test (D-5).
79187

80188
### Recommended Provers
81189

@@ -87,18 +195,35 @@ Highlights:
87195
- **Mizar** — set-theoretic third opinion
88196
- **Z3 SMT** — counterexample search for non-existent recovery functions
89197

90-
### Priority
198+
### Priority Summary
199+
200+
**HIGH (closeable now)** — Idris2 Cat-A redesigns (`cnoWriteSameContentProof`)
201+
+ Cat-D axiomatic markers (3 RMO physical claims) — both are
202+
single-PR.
203+
204+
**MEDIUM (needs infrastructure)** — the 4 ostensibly-Cat-B holes
205+
(equivRefl/Trans + undoRedoIdentity/Composition) are blocked on
206+
primitive-eq reflexivity OR theorem-shape redesign. Closure needs (a)
207+
a `Path`-equality reflexivity lemma + threading, or (b) a model
208+
migration sidestepping primitive `==`. Filing under #119 reclassified.
91209

92-
**HIGH** — 3 Coq `Admitted` markers (#56/#57/#58) + 23 Idris2 holes are
93-
visible and closeable; the bigger frontier (Lean→Rust refinement,
94-
crash-consistency, concurrency) is real research-level work.
210+
**LOW BUT BLOCKING THE BIG CLAIMS** — Lean→Rust mechanised refinement,
211+
crash-consistency under WAL/undo-log model, concurrency safety. These
212+
are research-level work; the bigger frontier is real.
95213

96214
`secureDeleteNotInjective` (closes #60) and `gdprDeletionCompliant`
97215
(closes #61) shipped 2026-06-02 via PR #105 with corrected theorem
98-
shapes: the prior `?secureDeleteIrreversibleProof` /
99-
`?gdprDeletionCompliantProof` holes had non-theorem signatures
100-
(refutable by `recovery = id` / `recovery = const empty` respectively)
101-
and have been redesigned. The MAA/GDPR claims now rest on these closed
102-
theorems plus `?overwriteIrreversibleProof` (still open) and axiomatic
103-
NIST SP 800-88 / Shannon-entropy / physical-world assumptions which
104-
should be made explicit (see narrative §10).
216+
shapes (the prior holes had non-theorem signatures refutable by
217+
`recovery = id` / `recovery = const empty`). The MAA/GDPR claims now
218+
rest on these closed theorems plus `?overwriteIrreversibleProof`
219+
(still open as Cat-D placeholder) and axiomatic NIST SP 800-88 /
220+
Shannon-entropy / physical-world assumptions which should be made
221+
explicit (see narrative §10).
222+
223+
The three Coq admits (#56 / #57 / #58) closed in the 2026-06-02 PM
224+
session bring the Coq layer to **zero `Admitted` markers** — only the
225+
single justified `Axiom is_empty_dir_dec` remains. `obliterate_not_injective`
226+
— the formal grounding for the "mathematically irreversible secure
227+
deletion" marketing claim — is now soundly proven (under the
228+
strengthened `block_overwritten`-aware geometry hypothesis, which is
229+
trivially satisfied for first-time obliteration).

proofs/coq/filesystem_composition.v

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -669,32 +669,41 @@ Proof.
669669
exists pqnode. exact Hpqnode.
670670
Qed.
671671

672-
(** Two-directory creation example.
673-
674-
NOTE (model gap, 2026-06-01): As stated, this example reverses
675-
[mkdir p1; mkdir p2] with [rmdir p1] applied BEFORE [rmdir p2]
676-
(reading the nested [apply_op] inside-out). That is not the LIFO
677-
sequence-reversal that [operation_sequence_reversible] proves,
678-
which would be [rmdir p2; rmdir p1]. The example as written is
679-
not provable from [two_op_sequence_reversible] without further
680-
well-formedness preservation lemmas on [rmdir]. Admitted pending
681-
follow-up: either restate to LIFO order, or prove the non-LIFO
682-
variant under stronger preconditions. See
683-
[docs/PROOF-OPEN-FRONTIER.adoc] for closure paths. *)
672+
(** Two-directory creation example — restated to LIFO sequence order.
673+
674+
The earlier statement reversed [mkdir p1; mkdir p2] with [rmdir p1]
675+
applied BEFORE [rmdir p2] (FIFO order), which is not derivable from
676+
[two_op_sequence_reversible] (which proves the LIFO case). Restated
677+
here so the OUTER rmdir undoes the FIRST mkdir, matching the LIFO
678+
discipline that the general theorem establishes.
679+
680+
Closes #56. See [docs/PROOF-OPEN-FRONTIER.adoc] for context. *)
684681
Example mkdir_two_dirs_reversible :
685682
forall p1 p2 fs,
686683
p1 <> p2 ->
687684
well_formed fs ->
688685
mkdir_precondition p1 fs ->
689686
mkdir_precondition p2 (mkdir p1 fs) ->
690-
apply_op (OpRmdir p2)
691-
(apply_op (OpRmdir p1)
687+
apply_op (OpRmdir p1)
688+
(apply_op (OpRmdir p2)
692689
(apply_op (OpMkdir p2)
693690
(apply_op (OpMkdir p1) fs))) = fs.
694691
Proof.
695-
(* Admitted: non-LIFO sequence-reversal — not derivable from
696-
two_op_sequence_reversible as stated; needs design fix. *)
697-
Admitted.
692+
intros p1 p2 fs Hneq Hwf Hpre1 Hpre2.
693+
pose proof (two_op_sequence_reversible (OpMkdir p1) (OpMkdir p2) fs) as Hseq.
694+
simpl in Hseq.
695+
apply Hseq.
696+
- (* reversible (OpMkdir p1) fs *)
697+
unfold reversible. split.
698+
+ simpl. exact Hpre1.
699+
+ simpl. apply rmdir_precondition_after_mkdir; assumption.
700+
- (* reversible (OpMkdir p2) (apply_op (OpMkdir p1) fs) *)
701+
unfold reversible. split.
702+
+ simpl. exact Hpre2.
703+
+ simpl.
704+
apply rmdir_precondition_after_mkdir;
705+
[apply mkdir_preserves_well_formed; assumption | exact Hpre2].
706+
Qed.
698707

699708
(** * Composition Preservation *)
700709

0 commit comments

Comments
 (0)