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
Copy file name to clipboardExpand all lines: Manual/VCGen.lean
+19-11Lines changed: 19 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -55,12 +55,12 @@ open Std.Do
55
55
56
56
## Preconditions and Postconditions
57
57
58
-
One style in which program specifications can be written is to provide a {deftech}_precondition_, which the program's caller is expected to ensure, and a {deftech}_postcondition_, which the program itself is expected to ensure.
59
-
The program is correct if running it when the precondition holds always results in the postcondition holding.
58
+
One style in which program specifications can be written is to provide a {deftech}_precondition_ $`P`, which the caller of a program`prog` is expected to ensure, and a {deftech}_postcondition_ $`Q`, which the `prog` is expected to ensure.
59
+
The program `prog` satisfies the specification if running it when the precondition $`P`holds always results in the postcondition $`Q` holding.
60
60
61
61
In general, many different preconditions might suffice for a program to ensure the postcondition.
62
-
After all, new preconditions can be generated by replacing a precondition $`P`with $`P \wedge Q`.
63
-
The {deftech}_weakest precondition_ is a precondition that is implied by all other preconditions.
62
+
After all, new preconditions can be generated by replacing a precondition $`P₁`with $`P₁ \wedge P₂`.
63
+
The {deftech}_weakest precondition_ $`\textbf{wp}⟦\texttt{prog}⟧(Q)` of a program `prog` and postcondition $`Q`is a precondition for which `prog` ensures the postcondition `Q` and is implied by all other such preconditions.
64
64
65
65
One way to prove something about the result of a program is to find the weakest precondition that guarantees the desired result, and then to show that this weakest precondition is simply true.
66
66
This means that the postcondition holds no matter what.
If {name}`mySum` is correct, then it is equal to {name}`Array.sum`.
84
84
In {name}`mySum`, the use of {keywordOf Lean.Parser.Term.do}`do` is an internal implementation detail—the function's signature makes no mention of any monad.
85
85
Thus, the proof first manipulates the goal into a form that is amenable to the use of {tactic}`mvcgen`, using the lemma {name}`Id.of_wp_run_eq`.
86
-
Thislemmastatesthatfactsabouttheresultofrunningacomputationinthe {name}`Id` monad that terminates normally (that is, does not use {ref "early-return"}[early return]) can be proved by showing that the {tech}[weakest precondition] that ensures the desired result is true.
86
+
Thislemmastatesthatfactsabouttheresultofrunningacomputationinthe {name}`Id` monad that terminates normally (`Id` computations never throw exceptions) can be proved by showing that the {tech}[weakest precondition] that ensures the desired result is true.
87
87
Next, the proof uses {tactic}`mvcgen` to replace the formulation in terms of weakest preconditions with a set of {tech}[verification conditions].
88
88
89
89
While {tactic}`mvcgen` is mostly automatic, it does require an invariant for the loop.
@@ -130,7 +130,7 @@ For example:
130
130
131
131
* `vc1.step` conveys that this {tech}[VC] proves the inductivestepfortheloop
* `vc3.a.post` is meant to prove that the postcondition of a specification (of {name}`forIn`) implies the desired property.
133
+
* `vc3.a.post.success` is meant to prove that the postcondition of a specification (of {name}`forIn`) implies the desired property.
134
134
:::
135
135
136
136
:::paragraph
@@ -257,13 +257,21 @@ end
257
257
```
258
258
:::
259
259
260
-
:::TODO
261
-
Note that the form `mvcgen invariants?` would hint that {name}`Invariant.withEarlyReturn` is a useful way to construct the invariant:
262
-
```
260
+
:::paragraph
261
+
Note that the form `mvcgen invariants?` will suggest an initial invariant using {name}`Invariant.withEarlyReturn`, so there is no need to memorize the exact syntaxfor specifying invariants:
262
+
```lean
263
+
/--
264
+
info: Try this:
265
+
[apply] invariants
266
+
·
267
+
Invariant.withEarlyReturn (onReturn := fun r letMuts => ⌜l.Nodup ∧ (r = true ↔ l.Nodup)⌝) (onContinue :=
When working in a state monad, preconditions may be parameterized over the value of the state prior to running the code.
420
-
Here, the universally quantified {name}`Nat` is used to _relate_ the initial state to the final state; the precondition is used to connect it the initial state.
428
+
Here, the universally quantified {name}`Nat` is used to _relate_ the initial state to the final state; the precondition is used to connect it to the initial state.
421
429
Similarly, the postcondition may also accept the final state as a parameter.
0 commit comments