-
Notifications
You must be signed in to change notification settings - Fork 232
What is verified, what is extracted?
(This page is accurate for F* versions after January 9th, 2017.)
Consider the following situation:
-
Main.fst
has an interfaceMain.fsti
-
Main.fsti
depends onLib
-
Lib.fst
has an interfaceLib.fsti
- everything depends on
Prims
which only hasPrims.fst
The complete, non-transitive dependency graph (minus Prims) is:
Lib.fsti <- Main.fsti
^ ↙ ^
| ↙ |
Lib.fst Main.fst
The partial, non-transitive dependency graph (minus Prims) is:
Lib.fsti <- Main.fsti
^ ^
| |
Lib.fst Main.fst
-
By default, only modules passed on the command-line are verified. By default, the dependency graph is partial and does not take dependencies on implementations.
Example:
fstar Main.fst
performs a partial dependency discovery that stops atLib.fsti
. F* lax-checksPrims
andLib
(interface only), then interleavesMain.fst
withMain.fsti
and verifiesMain
. (Note: F* then drops the interleaving, and verifies the interface only, then stops.) -
The
--verify_module
option overrides the verification behavior but does not change the discovery behavior. Only the specified modules are verified, but the dependency discovery is still partial.Example:
fstar Main.fsti --verify_module Lib
performs a partial dependency discovery that stops atLib.fsti
. F* lax-checksPrims
, verifiesLib
(still interface only). (Note: F* then lax-checksMain
, interface only.)Example:
fstar Main.fsti Lib.fst --verify_module Lib
performs a partial dependency discover that includesLib.fst
. F* lax-checksPrims
, interleavesLib.fst
withLib.fsti
, then verifiesLib
. (Note: F* then drops the interleaving, verifiesLib.fsti
alone, then moves on and lax-checksMain.fsti
.) -
The
--verify_all
option overrides both the verification behavior and the discovery dependency behavior. All the modules are verified, and the dependency discovery visits implementations too.Example:
fstar Main.fsti --verify_all
performs a complete dependency discovery that discoversLib.fst
. F* verifiesPrims
, interleavesLib.fst
withLib.fsti
, then verifiesLib
; F* drops the interleaving, then verifiesLib.fsti
alone; finally, F* verifiesMain
(interface only).Example:
fstar Main.fst --verify_all
performs a complete dependency discovery that discoversLib.fst
. F* verifiesPrims
, interleavesLib.fst
withLib.fsti
, then verifiesLib
; F* drops the interleaving, then verifiesLib.fsti
alone; F* verifies the interleaving ofMain.fst
andMain.fsti
; F* drops the interleaving, then verifiesMain.fsti
alone.
Note: --verify_module
and --verify_all
are mutually exclusive.
Extraction is triggered by the presence of a --codegen
flag.
-
By default, the dependency discovery is partial. All the modules in the dependency graph are extracted. All the extracted modules are written out to disk.
Example:
fstar --codegen OCaml Main.fsti
will write to disk the interleaving ofLib.fsti
and Lib.fstas
Lib.mland the extracted interface
Main.fstias
Main.ml-- most likely,
Main.mlwill contain a bunch of
failwith "Not implemented"` -
--extract_all
controls the dependency discovery; when present, F* performs a complete dependency discovery that takes dependencies on implementations too, as above.Example:
fstar --codegen OCaml Main.fst
will write to disk the interleaving ofLib.fsti
and Lib.fstas
Lib.mland the interleaving of
Main.fstiand
Main.fstas
Main.ml` -
--no_extract M
affects which modules are written out to disk; it just instructs F* to skip writing out a specific file to disk.Example:
fstar --codegen OCaml --no_extract Lib Main.fst
will only write to disk the interleaving ofMain.fsti
andMain.fst
asMain.ml
. Note: there is always an implicit--no_extract Prims
. -
--extract_module
affects which modules are written out to disk; it instructs F* to only extract modules that are specified with--extract_module
.Example:
fstar --codegen OCaml --extract_module Main Main.fst
will only write to disk the interleaving ofMain.fsti
andMain.fst
asMain.ml
.
Note: --no_extract
and --extract_module
are mutually exclusive, while (--no_extract
or --extract_module
) and --extract_all
are not mutually exclusive.
Note: there is no way to skip the in-memory extraction of a module in the dependency graph; it does not make sense, as it would create unbound references (in the in-memory extracted code) that are required for extracting later modules. We could devise a lax-extraction
mode that only brings into the extraction environment the types of top-level declarations without actually extracting their bodies, but this is for later.