Part 2 — Advanced Proofs

Inductive types, dependent data structures, and the foundations of homotopy verification in Python.

What You'll Learn

Part 1 gave you the tools to write verified Python with refinement types and Z3. In Part 2, we go deeper: you'll use Python's Generic type system, dataclass-based inductive types, and Deppy's homotopy constructs to build programs whose correctness is guaranteed at a much richer level.

Where F*'s Part 2 introduces inductive types and dependent pattern matching, Deppy maps those ideas onto Python idioms — generics, dataclasses, protocols — and extends them with path types and cubical constructions that let you reason about equality of behaviour, not just equality of values.

Chapters at a Glance

#ChapterKey ideas
1 Generic Types Generic[T], TypeVar bounds, covariance proofs, universe polymorphism
2 Length-Indexed Lists Vec[T, N], safe head/tail, append proofs, map-preserves-length
3 Merkle Trees Hash integrity, membership proofs, tamper detection, path-type chains
4 Equality & Path Types Identity types, reflexivity, transport, function extensionality, univalence
5 Logical Connectives Curry-Howard, ∧ / ∨ / → / ¬ / ∀ / ∃, classical vs constructive
6 Simply Typed λ-Calculus STLC in Python, substitution, progress + preservation, full soundness proof

Prerequisites

Several chapters reference path types from homotopy type theory. The key chapter is Equality & Path Types — if you find path-based reasoning unfamiliar, read that chapter first and return to Merkle Trees and STLC afterwards.

How This Differs from F*

F*'s Part 2 introduces inductive types with ML-style type declarations and dependent pattern matching. Deppy achieves the same expressive power through:

F*

type vec (a:Type) : nat -> Type =
  | Nil  : vec a 0
  | Cons : a -> vec a n
          -> vec a (n+1)

Deppy

from __future__ import annotations

@dataclass(frozen=True)
class Vec(Generic[T, N]):
    # length encoded at the type level
    items: tuple[T, ...]
    # refined: len(items) == N

Running the Examples

Every code snippet in Part 2 can be verified with:

# Verify a single file
$ python -m deppy.pipeline.run_verify part2/vectors_example.py

# Run the test suite for this part
$ python -m pytest tests/test_part2/ -v
All source files are in the examples/part2/ directory of the repository. Each chapter section has a corresponding .py file you can edit and re-verify.

Inductive Types in Python

In F*, inductive types are declared with the type keyword. In Python, we build the same structures from @dataclass and Union:

from __future__ import annotations
from dataclasses import dataclass
from typing import Union, Generic, TypeVar

T = TypeVar('T')

# An inductive list: either Nil or Cons(head, tail)
@dataclass(frozen=True)
class Nil(Generic[T]):
    pass

@dataclass(frozen=True)
class Cons(Generic[T]):
    head: T
    tail: List[T]

List = Union[Nil[T], Cons[T]]

# Pattern matching with Python 3.10+ match/case
def length(lst: List[T]) -> int:
    match lst:
        case Nil():       return 0
        case Cons(_, tl): return 1 + length(tl)

Each @dataclass variant acts as a constructor; Python's match statement gives exhaustive pattern matching. Deppy verifies that all cases are covered and that recursive calls terminate.

Frozen dataclasses (frozen=True) ensure immutability — just like algebraic data types in ML or Haskell. Deppy requires frozen dataclasses for inductive types so that structural proofs remain valid.

Verification Levels in Part 2

Different chapters exercise different verification strategies:

ChapterPrimary verifierLevel
Generic TypesZ3 (subtyping constraints)Z3_VERIFIED
VectorsZ3 (linear arithmetic)Z3_VERIFIED
Merkle TreesZ3 + sidecar (hash axioms)Z3_VERIFIED
Equality TypesPath-type checker (cubical)Z3_VERIFIED
ConnectivesStructural (Curry-Howard)Z3_VERIFIED
STLCZ3 + structural inductionZ3_VERIFIED

A Roadmap

The chapters are designed to be read in order, but you can skip ahead if a topic interests you. The dependency graph is:

generics ──→ vectors ──→ merkle
                            │
          equality_types ◄──┘
               │
          connectives ──→ stlc

Equality & Path Types is the conceptual centrepiece — it connects the purely Pythonic material (generics, vectors, Merkle trees) with the homotopy foundations (connectives, STLC) that make Deppy unique.