Invocation
This skill is used when:
- •Verifying F* (.fst) or interface (.fsti) files
- •Debugging verification failures
- •Checking proof completeness
Core Operations
Basic Verification
bash
# Verify a single file fstar.exe Module.fst # With Pulse extension fstar.exe --include <PULSE_HOME>/out/lib/pulse Module.fst # With include paths fstar.exe --include <PULSE_HOME>/out/lib/pulse --include path/to/lib Module.fst
Diagnostic Options
bash
# Show query statistics (find slow/cancelled proofs) fstar.exe --query_stats Module.fst # Split queries for isolation fstar.exe --split_queries always Module.fst # Log SMT queries for analysis fstar.exe --log_queries Module.fst # Refresh Z3 between queries fstar.exe --z3refresh Module.fst # Combined debugging fstar.exe --include <PULSE_HOME>/out/lib/pulse --query_stats --split_queries always --z3refresh Module.fst
Resource Limits
bash
# Set rlimit (default varies, target ≤10 for robustness) # In file: #push-options "--z3rlimit 10" # Set fuel for recursive functions # In file: #push-options "--fuel 1 --ifuel 1"
Error Interpretation
"Could not prove post-condition"
Cause: SMT cannot establish the postcondition from available facts Solutions:
- •Add intermediate
assertstatements - •Call relevant lemmas explicitly
- •Use
Seq.equal/Set.equalfor collection equality - •Call
FS.all_finite_set_facts_lemma()for FiniteSet reasoning
"Identifier not found"
Cause: Symbol not in scope Solutions:
- •Check module imports (
open,module X = ...) - •Verify definition order (F* is order-sensitive)
- •Check for typos in names
"rlimit exhausted" / Query cancelled
Cause: Proof too complex for SMT within time limit Solutions:
- •Factor proof into smaller lemmas
- •Reduce fuel:
#push-options "--fuel 0 --ifuel 0" - •Add explicit type annotations
- •Use patterns on quantifiers
- •Make definitions
opaque_to_smtand instantiate manually
"Expected type X, got type Y" (Unification failure)
Cause: Type mismatch, often with refinements Solutions:
- •Add explicit type annotations
- •Cast values to base types
- •Check refinement predicates
"Application of stateful computation cannot have ghost effect"
Cause: Calling stateful function in ghost context (Pulse-specific) Solutions:
- •Ensure condition variables are concrete, not from
withbindings - •Read from actual data structures, not ghost sequences
- •Restructure to avoid ghost conditionals
Verification Strategy
For New Code
- •Start with admitted proofs to check structure
- •Remove admits one at a time
- •Add helper lemmas as needed
- •Verify interface (.fsti) before implementation (.fst)
For Failing Proofs
- •Use
--query_statsto identify slow queries - •Add
assertstatements to locate failure point - •Factor out failing assertion into separate lemma
- •Reduce proof to minimal failing case
- •Add explicit lemma calls or type annotations
For Robustness
- •Keep rlimits low (≤10)
- •Split large proofs into lemmas
- •Use explicit types over inference
- •Prefer
Seq.equalover==for sequences
Additional resources
Find the directory PoP-in-FStar on the local machine, or locate it here: https://github.com/FStarLang/PoP-in-FStar
This contains the sources to the Proof-oriented Programming in F* book. You can search through the book for various explanations, tips and common patterns.
Also look at FStar/ulib, FStar/doc, FStar/examples for sample code.