Hoare triple specifications for select functions #
This module contains Hoare triple specifications for some functions in Core.
A pointer at a specific location in a list. List cursors are used in loop invariants for the
mvcgen tactic.
Moving the cursor to the left or right takes time linear in the current position of the cursor, so this data structure is not appropriate for run-time code.
- prefix : List α
The elements before to the current position in the list.
- suffix : List α
The elements starting at the current position. If the position is after the last element of the list, then the suffix is empty; otherwise, the first element of the suffix is the current element that the cursor points to.
Appending the prefix to the suffix yields the original list.
Instances For
Creates a cursor at position n in the list l.
The prefix contains the first n elements, and the suffix contains the remaining elements.
If n is larger than the length of the list, the cursor is positioned at the end of the list.
Instances For
Creates a cursor at the beginning of the list (position 0). The prefix is empty and the suffix is the entire list.
Equations
- List.Cursor.begin l = List.Cursor.at l 0
Instances For
Creates a cursor at the end of the list. The prefix is the entire list and the suffix is empty.
Equations
- List.Cursor.end l = List.Cursor.at l l.length
Instances For
Advances the cursor by one position, moving the current element from the suffix to the prefix.
Requires that the cursor is not already at the end of the list.
Equations
Instances For
Lifting MonadStateOf #
Lifting MonadReaderOf #
Lifting MonadExceptOf #
The type of loop invariants used by the specifications of for ... in ... loops.
A loop invariant is a PostCond that takes as parameters
- A
List.Cursor xsrepresenting the iteration state of the loop. It is parameterized by the list of elementsxsthat theforloop iterates over. - A state tuple of type
β, which will be a nesting ofMProds representing the elaboration oflet mutvariables and early return.
The loop specification lemmas will use this in the following way:
Before entering the loop, the cursor's prefix is empty and the suffix is xs.
After leaving the loop, the cursor's prefix is xs and the suffix is empty.
During the induction step, the invariant holds for a suffix with head element x.
After running the loop body, the invariant then holds after shifting x to the prefix.
Equations
- Std.Do.Invariant xs β ps = Std.Do.PostCond (xs.Cursor × β) ps
Instances For
Helper definition for specifying loop invariants for loops with early return.
for ... in ... loops with early return of type γ elaborate to a call like this:
forIn (β := MProd (Option γ) ...) (b := ⟨none, ...⟩) collection loopBody
Note that the first component of the MProd state tuple is the optional early return value.
It is none as long as there was no early return and some r if the loop returned early with r.
This function allows to specify different invariants for the loop body depending on whether the loop
terminated early or not. When there was an early return, the loop has effectively finished, which is
encoded by the additional ⌜xs.suffix = []⌝ assertion in the invariant. This assertion is vital for
successfully proving the induction step, as it contradicts with the assumption that
xs.suffix = x::rest of the inductive hypothesis at the start of the loop body, meaning that users
won't need to prove anything about the bogus case where the loop has returned early yet takes
another iteration of the loop body.
Equations
- One or more equations did not get rendered due to their size.