con un clic
specreview
Review F*/Pulse specifications for completeness, strength, and usability
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Review F*/Pulse specifications for completeness, strength, and usability
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
| name | specreview |
| description | Review F*/Pulse specifications for completeness, strength, and usability |
This skill is used when:
For each function with a specification, verify:
❌ Weak: ensures (result >= 0) — proves a type property, not correctness
✅ Strong: ensures (result == factorial n) — proves functional correctness
❌ Weak: ensures (is_valid_flow result) — proves a structural property
✅ Strong: ensures (flow_value result == max_flow graph) — proves optimality
Every imperative implementation should have a postcondition referencing the corresponding pure spec function:
fn sort_impl (arr: array int) (n: SizeT.t)
(#s: erased (Seq.seq int))
requires A.pts_to arr s ** pure (SZ.v n == Seq.length s)
ensures exists* s'.
A.pts_to arr s' **
pure (
Seq.length s' == Seq.length s /\ // same length
sorted s' /\ // result is sorted
permutation s s' // result is a permutation of input
)
NOT just: ensures exists* s'. A.pts_to arr s' ** pure (sorted s')
(This doesn't prove the output is related to the input!)
Check the .fsti file:
.fsti hides the postcondition, callers cannot reason about the result// BAD .fsti: hides the correctness property
val dijkstra (g: graph) (src: vertex) : ST (array nat) ...
// No ensures clause visible!
// GOOD .fsti: exposes the spec connection
val dijkstra (g: graph) (src: vertex) : ST (array nat)
(requires ...)
(ensures fun dist -> forall v.
dist.[v] == shortest_path_weight g src v)
Verify that the postcondition is stated in terms a caller can work with:
For algorithm implementations, check against the algorithm's mathematical guarantees:
| Algorithm | Must Prove |
|---|---|
| Sorting | Output is sorted AND a permutation of input |
| Shortest path | Distances are actual shortest paths, not just "some path" |
| MST | Result is a spanning tree AND has minimum weight |
| Search | Returns correct index AND element equality |
| Union-Find | Operations maintain equivalence relation correctly |
| Max-flow | Flow value equals the max-flow (not just "a valid flow") |
// WEAK: proves nothing about what the function computes
val lookup : table -> key -> option value
// STRONG: proves the lookup matches the logical model
val lookup : t:table -> k:key -> r:option value{r == Table.find (model t) k}
// WEAK: only proves the output is a tree, not that it's the MST
ensures (is_spanning_tree result graph)
// STRONG: proves it's minimal among all spanning trees
ensures (is_spanning_tree result graph /\
forall t. is_spanning_tree t graph ==> weight result <= weight t)
// WEAK: uses implementation-internal predicate
ensures (imp_valid_state result)
// STRONG: connects to spec via a correspondence lemma
ensures (model result == Spec.expected_state input)
// WEAK: sorting — doesn't prove output relates to input
ensures (sorted result)
// STRONG: proves it's a sorted permutation of the input
ensures (sorted result /\ permutation_of result input)
When reviewing a .fsti file:
requires/ensuresFor the pure spec module:
Use the F* MCP server for interactive, incremental typechecking of F* and Pulse code
Verify F* and Pulse code with fstar.exe and interpret errors
Extract verified F*/Pulse code to C via KaRaMeL (.krml intermediate representation)
Structure a new F*/Pulse verification project with Makefile and directory layout
Systematic workflows for debugging F*/Pulse verification failures
Debug F* queries sent to Z3, diagnosing proof instability and performance issues