Lean 4.27.0 on FreeBSD 15.0-RELEASE

Table of Contents

1. Overview

Validation of Lean4 theorem prover on FreeBSD 15.0-RELEASE, updated from the 14.3 validation document.

1.1. Version Information

Component Version
OS FreeBSD 15.0-RELEASE-p1
Lean 4.27.0-pre
Lake 5.0.0-src
Package lean4-4.25.2.20251201

2. Prerequisites

2.1. procfs (Required)

Lean4 requires procfs to be mounted.

mount | grep proc
procfs on /proc (procfs, local)
linprocfs on /compat/linux/proc (linprocfs, local)

Ensure it's in /etc/fstab:

proc /proc procfs rw 0 0

3. Installation

pkg install lean4

Verify installation:

lean --version
lake --version
Lean (version 4.27.0-pre, x86_64-unknown-freebsd15.0, Release)
Lake version 5.0.0-src (Lean version 4.27.0, commit )

4. Basic Validation

4.1. Theorem Proving

theorem test : 1 + 1 = 2 := rfl
#check test

4.2. Evaluation

#eval 2 + 2

4.3. Standard Library Access

#check Nat.add_comm

5. Example: Natural Numbers

-- Natural number examples on FreeBSD 15.0

-- Basic theorem
theorem add_zero (n : Nat) : n + 0 = n := rfl

-- Proof by induction
theorem add_succ (n m : Nat) : n + Nat.succ m = Nat.succ (n + m) := rfl

-- Commutativity (from stdlib)
#check Nat.add_comm

-- Simple evaluation
#eval (List.range 10).map (· * 2)

6. Example: Propositional Logic

-- Propositional logic examples

-- Modus ponens
theorem modus_ponens (P Q : Prop) (hp : P) (hpq : P  Q) : Q :=
  hpq hp

-- Conjunction introduction
theorem and_intro (P Q : Prop) (hp : P) (hq : Q) : P  Q :=
  ⟨hp, hq⟩

-- Conjunction elimination
theorem and_left (P Q : Prop) (h : P  Q) : P :=
  h.left

theorem and_right (P Q : Prop) (h : P  Q) : Q :=
  h.right

-- Disjunction
theorem or_intro_left (P Q : Prop) (hp : P) : P  Q :=
  Or.inl hp

-- Double negation (classical)
theorem dne (P : Prop) : ¬¬P  P := by
  intro hnnp
  by_contra hnp
  exact hnnp hnp

7. Example: List Operations

-- List operations and proofs

def myLength : List α  Nat
  | [] => 0
  | _ :: xs => 1 + myLength xs

def myReverse : List α  List α
  | [] => []
  | x :: xs => myReverse xs ++ [x]

-- Prove length is preserved by reverse
theorem reverse_length (xs : List α) : (myReverse xs).length = xs.length := by
  induction xs with
  | nil => rfl
  | cons x xs ih =>
    simp [myReverse, List.length_append]
    omega

-- Map preserves length
theorem map_length (f : α  β) (xs : List α) : (xs.map f).length = xs.length := by
  induction xs with
  | nil => rfl
  | cons x xs ih => simp [ih]

#eval myReverse [1, 2, 3, 4, 5]
#eval myLength ["a", "b", "c"]

8. Example: Type Classes

-- Type class examples

class Monoid (α : Type) where
  unit : α
  op : α  α  α
  left_unit :  x, op unit x = x
  right_unit :  x, op x unit = x
  assoc :  x y z, op (op x y) z = op x (op y z)

-- Natural numbers under addition form a monoid
instance : Monoid Nat where
  unit := 0
  op :=+ ·)
  left_unit := Nat.zero_add
  right_unit := Nat.add_zero
  assoc := Nat.add_assoc

-- List concatenation forms a monoid
instance : Monoid (List α) where
  unit := []
  op :=++ ·)
  left_unit := List.nil_append
  right_unit := List.append_nil
  assoc := List.append_assoc

-- Generic fold using monoid
def mconcat [Monoid α] (xs : List α) : α :=
  xs.foldl Monoid.op Monoid.unit

#eval mconcat [[1,2], [3,4], [5,6]]  -- [1, 2, 3, 4, 5, 6]
#eval mconcat [1, 2, 3, 4, 5]        -- 15

9. Lake Project Setup

9.1. Creating Projects

lake new creates a new project in a subdirectory:

lake new myproject
cd myproject && lake build
info: myproject: no previous manifest, creating one from scratch
info: toolchain not updated; no toolchain information found
✔ [8/8] Built myproject:exe
Build completed successfully (8 jobs).

9.2. Initializing in Existing Directory

lake init initializes a project in the current directory:

mkdir -p /tmp/existingdir
cd /tmp/existingdir
lake init myproj

9.3. Common Mistake

Passing a path to lake init fails because it interprets the entire path as a package name:

lake init /tmp/test 2>&1 || true
error: illegal package name '/tmp/test'

Correct usage: navigate to directory first, then run lake init projectname.

9.4. Building a Project

cd myproject && lake build 2>&1 | head -10
info: myproject: no previous manifest, creating one from scratch
info: toolchain not updated; no toolchain information found
✔ [2/8] Built Myproject.Basic
✔ [3/8] Built Myproject.Basic:c.o
✔ [4/8] Built Myproject
✔ [5/8] Built Myproject:c.o
✔ [6/8] Built Main
✔ [7/8] Built Main:c.o
✔ [8/8] Built myproject:exe
Build completed successfully (8 jobs).

10. Mathlib4 (Optional)

For advanced mathematics, add Mathlib4:

-- In lakefile.lean, add:
require mathlib from git
  "https://github.com/leanprover-community/mathlib4"

Then:

lake update
lake build

Note: Mathlib4 takes significant time to build (~30-60 min).

11. Emacs Integration

11.1. lean4-mode Setup

;; Lean4 mode for Emacs

(use-package lean4-mode
  :straight (lean4-mode
             :type git
             :host github
             :repo "leanprover/lean4-mode"
             :files ("*.el" "data"))
  :commands lean4-mode
  :mode ("\\.lean\\'" . lean4-mode)
  :config
  (setq lean4-keybinding-lean4-toggle-info "C-c C-i"))

11.2. Org-Babel Support

;; Add to init.el for org-babel lean4 support
(defun org-babel-execute:lean4 (body params)
  "Execute Lean4 code in org-babel."
  (let ((tmp-file (make-temp-file "lean4-" nil ".lean")))
    (with-temp-file tmp-file
      (insert body))
    (shell-command-to-string
     (format "lean --run %s 2>&1 || lean %s 2>&1" tmp-file tmp-file))))

(add-to-list 'org-babel-load-languages '(lean4 . t))

12. Validation Summary

Test Status Notes
Installation pkg install lean4
procfs mounted Required for Lean
lean --version 4.27.0-pre
lake --version 5.0.0-src
Theorem proving rfl, induction work
#eval Evaluation works
Standard library Nat, List, etc. accessible
lake new Creates project in subdirectory
lake init Initializes in current dir
lake build Compiles projects successfully

13. Comparison: 14.3 vs 15.0

Aspect FreeBSD 14.3 FreeBSD 15.0
Lean version 4.23.0 4.27.0-pre
Lake version 4.x 5.0.0-src
procfs Required Required
Core proving
Lake projects
Package size 1.90 GiB 2.20 GiB

14. Full Diagnostic Commands

echo "=== Full System Info ==="
echo "OS: $(uname -srm)"
echo "Lean: $(lean --version 2>&1)"
echo "Lake: $(lake --version 2>&1)"
echo "procfs: $(mount | grep 'procfs on /proc' || echo 'NOT MOUNTED')"
echo "pkg: $(pkg info lean4 2>&1 | grep Version || echo 'NOT INSTALLED')"
=== Full System Info ===
OS: FreeBSD 15.0-RELEASE amd64
Lean: Lean (version 4.27.0-pre, x86_64-unknown-freebsd15.0, Release)
Lake: Lake version 5.0.0-src (Lean version 4.27.0, commit )
procfs: procfs on /proc (procfs, local)
pkg: Version        : 4.25.2.20251201

15. References

Author: Jason Walsh

j@wal.sh

Last Updated: 2026-01-25 16:35:38

build: 2026-02-02 00:49 | sha: 7414ae7