Tutorial Book — v0.1

Deppy

Python with Dependent Types

Deppy brings formal verification to the world's most popular language. Using dependent type theory, Z3 SMT solving, and sidecar proofs, you can verify existing Python code — without rewriting a single line.

Start Reading →

About This Book

This book is a tutorial and reference for Deppy, a proof-oriented verification system for Python. It is modeled after the F* Tutorial Book, but with a crucial difference: where F* is a language you write new code in, Deppy verifies the Python code you already have.

We cover everything from basic refinement types and Z3 integration to advanced topics: homotopy-theoretic path types, Čech decomposition for modular verification, the cubical heap with epoch-tagged mutation and transport-based reads, coalgebraic generators / coroutines, and GIL-aware concurrency proofs.

Sidecar metadata can be written in two equivalent forms — a separate .deppy file (best for verifying third-party libraries) or decorator-based annotations inline with Python (@foundation, @axiom, @verify, @psdl_proof; best when you write the module yourself). Both feed the same kernel.

Deppy does not require you to modify your source code. Specifications and proofs live either in sidecar .deppy files alongside your Python modules, or in proof decorators stamped on the functions they describe — your choice.

A Quick Example

Here is a simple Python function and its Deppy verification. The source code remains untouched — the specification lives in a sidecar file.

my_math.py

# Ordinary Python — no Deppy imports needed if you use a sidecar.
def abs_val(x: int) -> int:
    if x >= 0:
        return x
    return -x

my_math.deppy (sidecar form)

# Separate-file YAML-shaped sidecar; sits beside my_math.py
module: my_math

spec my_math.abs_val:
  guarantee: "abs_val(x) >= 0"

verify abs_val_nonneg:
  function: my_math.abs_val
  property: "abs_val(x) >= 0"
  via: "z3"

Or, with the equivalent decorator form (when you write the module yourself):

from deppy.proofs.sidecar_decorators import verify, psdl_proof

@verify(
    property="abs_val(x) >= 0",
    via="z3",
    binders={"x": "int"},
)
@psdl_proof("""
if x >= 0:
    assert x >= 0, "z3"
else:
    assert -x >= 0, "z3"
""")
def abs_val(x: int) -> int:
    return x if x >= 0 else -x

Run the verifier — both forms feed the same kernel and the same Lean-export round-trip:

$ python -m deppy.pipeline.run_verify my_math.deppy --out my_math.lean
$ python -m deppy.pipeline.run_verify --from-module my_math --out my_math.lean

  ────────────────────────────────────────────────
  deppy.lean.lean_runner round-trip:       OK
  ────────────────────────────────────────────────
  ✓ CERTIFIED — top-level certify_or_die: PASS

Why Deppy?

Existing proof-oriented systems require you to learn a new language and rewrite your code. Deppy meets Python developers where they are.

Feature F* Dafny Liquid Haskell Deppy
Verifies existing code ✗ (new lang) ✗ (new lang) ~ (annotations) ✓ sidecar proofs
Target language F* → C / Rust Dafny → C# / Go Haskell Python (unmodified)
Dynamic typing support ✓ path types
Duck typing / protocols ✗ (type classes) ✓ homotopy paths
Homotopy type theory ✓ cubical HoTT
SMT automation ✓ Z3 ✓ Z3 ✓ Z3 ✓ Z3
Heap reasoning ~ (Steel/Pulse) ✓ cubical heap
Concurrency (GIL-aware) ✓ runtime
Learning curve Steep Moderate Steep Gentle

Table of Contents

A Taste of Verification

Deppy supports several styles of specification. Here's a richer example using the @guarantee decorator for inline annotation, refined for refinement types, and Nat() as the canonical non-negative integer type:

from deppy import guarantee, Nat, refined
from deppy.types import PyIntType

# Nat() is shorthand for refined(PyIntType(), "x >= 0", "x")
Nat_t = Nat()

@guarantee("result == n * (n + 1) // 2")
def triangle(n: int) -> int:
    """Sum of integers from 0 to n."""
    return n * (n + 1) // 2
$ python -m deppy.pipeline.run_verify triangle.deppy --out triangle.lean

  ────────────────────────────────────────────────
  deppy.lean.lean_runner round-trip:       OK
  ────────────────────────────────────────────────
  ✓ CERTIFIED — top-level certify_or_die: PASS

Verification is fast. Z3 handles arithmetic obligations automatically, and Deppy decomposes complex proofs into manageable pieces using Čech decomposition from algebraic topology.

Getting Started

Ready to dive in? We recommend reading the pages in order:

  1. Structure of this Book — understand the six parts and prerequisites
  2. Introduction — the key ideas behind Deppy
  3. Getting Started — install Deppy and verify your first function
If you're familiar with F* or Dafny, you can skip to Part 3: Python Specifics to see what makes Deppy different.