Every .lean file in this repo — CompPoly.lean, CompPoly/**, tests/**, and
bench/** — uses the Lean 4 module system. lakefile.lean is the only exception.
The reference for the module system is here.
New library modules should use the narrowest import and exposure modifiers that their public API requires:
/-
Copyright (c) 2026 CompPoly. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: ...
-/
module
import Mathlib.Tactic.Ring
public import CompPoly.Data.Array.Lemmas
/-!
# Module docstring
-/
public sectionmodulegoes on the line after the copyright header, before the imports.- Use plain
importfor proof and implementation dependencies. Usepublic importonly when the current module deliberately re-exports the imported API or a public declaration requires it. - Use
public sectionfor exported declarations. Keep definition bodies opaque by default, and put@[expose]on individual definitions only when downstream definitional reduction is an intentional part of their interface.
Proof and correctness modules in this package may need to unfold an implementation without exposing it to every downstream importer. Import the private scope alongside the public API in that case:
module
import all CompPoly.Univariate.Raw.Ops
public import CompPoly.Univariate.Raw.Ops
public sectionThe plain import all is an explicit same-package implementation dependency; the
separate public import preserves the intended re-export. Prefer a characterization
lemma when ordinary downstream code only needs a behavioral fact. The
CompPoly.Univariate.Raw modules are the first migrated example of this pattern.
Definitions implemented with a where recursion may require targeted @[expose]
when a separate correctness module refers to the generated .go declaration by
name. Do not restore file-wide exposure for this case.
#guard and #eval run compiled code during elaboration, so any module whose
definitions they evaluate must be imported as meta. Test files that contain
#guard/#eval therefore use:
module
public meta import CompPoly.Fields.KoalaBear.Fast
public meta sectionImmediately post-migration, this may be @[expose]d.
A file may need both forms. tests/CompPolyTests/Fields/Extension/Arithmetic.lean
mixes #guards (which need the meta imports) with example : Algebra .. := inferInstance declarations (which are ordinary declarations and need a plain
public import of the same module). Repeating the import with a different modifier
is legal and is the intended fix.
The pratt tactic in ../../CompPoly/Fields/PrattCertificate.lean
is currently the one place in the library proper with meta code. Meta definitions may only
call other meta definitions from the same module, so the whole elaboration
pipeline (powMod, factor, computePrattCertificate, verifyCertificate, ...)
is meta def. Theorems that end up inside generated proof terms via q(...) must
stay ordinary declarations.
When a proof breaks after modulization, it is almost always one of these:
| Symptom | Cause | Fix |
|---|---|---|
rfl/simp [Foo] fails, "Expected a definition with an exposed body" |
Unfolding a library definition whose body is not exposed (Vector.ofFn, Array.rightpad, AddMonoidAlgebra.mul') |
Use a characterisation lemma (Array.size_rightpad, List.rightpad_toArray, AddMonoidAlgebra.mul_def) or ext/cases first |
Unknown identifier X plus a "would need to be public" note |
private declaration used from an exposed body or another module |
Remove private |
tactic execution is stuck, goal contains metavariables |
Notation or cast (by exact h) x whose type is opaque |
Type-ascribe the term, or pass the proof term directly instead of by exact |
Unknown constant Std....Internal.... |
Internal lemmas are no longer re-exported transitively | Import the specific internal module, e.g. Std.Data.DTreeMap.Internal.Lemmas |
rw/erw "did not find an occurrence" on a pattern that is visibly present |
Over-specialised rewrite (lemma (p := p + q)) no longer matches syntactically |
Use the unspecialised simp only [lemma] |
Duplicate declaration after removing private |
Two modules had identically named private helpers |
Keep one and delete the duplicate |
../../scripts/update-lib.sh emits a modulized root
file (module, blank line, one public import per tracked source file). See
generated-files.md.