F* Documentation

repository·master·Indexed 25 days ago

https://github.com/fstarlang/fstar

F* is a proof-oriented programming language designed for formal verification, allowing developers to write code mathematically proven to satisfy specific properties. It supports extraction into executable languages such as OCaml, F#, C, and Rust. The ecosystem includes Pulse, a DSL for concurrent and imperative programming, and the 'Proof-oriented Programming in F*' educational resource.

Tokens
53.2K
Snippets
95
Records
369
Agent score
85%

What's inside F*

  1. Overview of Pulse: Proof-oriented Programming in Concurrent Separation Logic

    master

    Pulse is a domain-specific language (DSL) embedded in F*. It inherits F*'s higher-order features and dependent types while providing built-in support for programming with mutable state and concurrency. Pulse uses specifications and proofs based on Concurrent Separation Logic (CSL).

    Key characteristics:

    • Embedded in F*: Uses F*'s lemmas, dependent types, and refinement types.
    • Concurrency Support: Built-in primitives for parallel execution (e.g., the par combinator).
    • Logic Foundation: Based on PulseCore, a logic formalized within F* that is inspired by the Iris separation logic.
  2. Overview of F* capabilities

    master

    F* is a dependently typed programming language designed for several roles:

    • General-purpose programming: Encourages higher-order functional programming with effects (ML family tradition).
    • Compiler: Translates F* programs to OCaml, F#, C, or Wasm.
    • Proof assistant: Used to state and prove properties of programs.
    • Program verification engine: Leverages SMT solvers to partially automate proofs.
    • Metaprogramming system: Supports programmatic construction of F* programs and proof automation.

    Key design elements include a core language of total functions with full dependent types, a system of user-defined indexed effects, built-in encoding of logic for SMT solvers, and a reflection system for metaprogramming (Meta-F*).

  3. Overview of Proof-oriented Programming in F*

    master

    F* is a dependently typed programming language and proof assistant designed for proof-oriented programming. This paradigm involves co-designing programs and proofs to provide mathematical guarantees regarding:

    • Functional correctness: Precisely characterizing input/output behavior.
    • Security properties: Ensuring programs do not leak secrets.
    • Resource usage: Providing bounds on how resources are consumed.

    While F* is a functional language at its core, it supports multiple programming paradigms including:

    • Pure, total functions.
    • Low-level programming (e.g., C and assembly).
    • Concurrent programming (shared memory and message-passing).
    • Distributed programming.
  4. Use ulibfs for F* code exported to F#

    master
    The ulibfs library is a runtime library required when F* code has been exported to F#. If you are consuming F* logic within an F# environment via exported code, ensure this runtime library is available to handle the necessary execution context.
  5. Understand Layered Effects (Indexed Effects) in F*

    master
    F* supports layered effects, also known as indexed effects. These allow for more granular control over program state and side effects by associating effects with specific indices. For a theoretical foundation, refer to the paper at https://www.fstar-lang.org/papers/indexedeffects.
  6. Understand F* Universe Stratification and Russell's Paradox

    master
    F* uses a stratified universe system to prevent logical paradoxes like Russell's Paradox. In F*, a type resides only in the universe immediately above it (e.g., Type u#i : Type u#(i + 1)). Breaking this stratification—for example, by introducing an axiom that allows a type to be 'lowered' into a smaller universe and then 'projected' back—can lead to unsoundness where one can prove False.
  7. Use higher-order functions like map and find

    master

    F* supports first-class functions, allowing for higher-order patterns:

    • map: Takes a function f and a list l, applying f to every element to produce a new list.
    • find: Takes a predicate function f and a list l, returning Some x for the first element where f x is true, or None if no such element exists.
    • fold_left: Reduces a list using a function f and an accumulator a from left to right.
  8. Understand Constructive vs Classical Connectives in F*

    master

    In F*, logical connectives exist in two flavors:

    1. Constructive: Defined as inductive or arrow types. These provide a direct way to build and manipulate proofs using standard type theory (e.g., pair for conjunction, sum for disjunction).
    2. Propositional (Classical): Represented by symbols like `/

    , /, ==>`, etc. These are typically used in proofs where the SMT solver handles the heavy lifting. Their meaning is determined by SMT encoding rather than explicit constructors.

    All basic types and connectives are defined in the Prims module, which is the first module in all F* programs.

  9. Understand F* Primitive Effects

    master

    F* uses an effect system to model behaviors beyond pure mathematical functions. While users can define custom effects, F* provides several primitive effects to manage specific computational behaviors:

    • Ghost: Describes parts of a program with no observable behavior that do not influence the returned result. This allows the compiler to erase computationally irrelevant parts during optimization.
    • Divergence: Encapsulates computations that may run forever. The effect system ensures that potentially divergent computations cannot be used as proofs.
    • Partiality: Represents partial functions that are only defined over a subset of their domain.
  10. Understand Mutable Reference Types in Pulse

    master

    Pulse supports three kinds of mutable references for explicit memory management:

    1. Stack references: Allocated in the current function's stack frame and implicitly reclaimed when the function returns.
    2. Heap references (boxes): Allocated in the heap and must be explicitly reclaimed using drop or free.
    3. Ghost references: Used exclusively for specification and proof; they do not exist at runtime.

    The basic type for mutable references is Pulse.Lib.Reference.ref t. Most operations are agnostic to whether the reference is on the stack or the heap.

  11. Understand the Imperative Language Syntax and Semantics

    master

    The tutorial defines a small imperative language used to demonstrate Floyd-Hoare logic. The language includes:

    • Expressions: Integer constants, global variables (natural numbers), and arithmetic (e.g., addition).
    • Assignments (EAssign x e): Assigns the result of expression e to global variable x.
    • Sequence (Seq): Composes programs sequentially.
    • Conditional (If): Composes programs conditionally.
    • Repeat (Repeat n p): A primitive recursion construct that repeats program p, n times (where n is a non-negative integer).

    Operational semantics are implemented via an interpreter using a state type and a state monad st a. The interpreter is a total, recursive function run of type st unit.