Provably Packed
- Have YOU ever wanted to know if you’re prepared to hike the Continental Divide Trail at COMPILE time?!
- Are you an ULTRALIGHT backpacker who wants a correct-by-construction packing list?
- Do you have an upcoming wedding you need to be provably dressed for?
Do you want to do ALL of this without leaving the comfort of your favorite Lean-compatible text-editor?
Well you have come to the right place.
provably-packed
is a Lean 4 eDSL for declaratively describing a correct-by-construction packing list using the power of dependent types.
Describe:
- your environment/conditions as custom sum types (e.g.,
Bugginess.T
,Precipitation.T
,Fashion.T
), - each item’s capabilities as a heterogeneous-list of lists of variants of your conditions,
- each item of gear you will carry, including its mass (looking at you my fellow gram counters )
- and the conditions you expect to face plus a weight limit.
Lean then checks, at compile time, that your gear can satisfy every expected condition and that your total mass is within bounds. If you see a red squiggly in your editor, you’re not ready for your trip.
How it works (Curry-Howard for hikers)
Thanks to the Curry-Howard Isomorphism, types can encode proofs. Constructing an Expedition.T
constitutes a proof that your packing list meets its spec.
ProvablyPacked/Lib/HList.lean
providesHList.T
, a heterogeneous list indexed by types, used to hold per-dimension properties.ProvablyPacked/Lib/Narrow.lean
providesNarrow.T α variants
, a type that only accepts a specified subset of a sum type’s constructors, plus a small tacticnrrw
to discharge subset proofs.ProvablyPacked/Lib/PropertyHList.lean
defines a genericProperty α
with a list of equipped values and operations to union properties across items.ProvablyPacked/Lib/PropertiesHListComparator.lean
defines a comparator where expectations are typed against the gear’s actual properties:propsToSigmaList
turns anHList
of properties into a value-level index.ExpectedForSigma sp := List (Narrow.T sp.1 sp.2.values)
ensures each expected value is drawn from precisely the equipped variants.PropertiesHListComparator.T actualProperties
storesexpectedProperties
with a shape tied to the actual gear.
ProvablyPacked/Models/Item.lean
definesItem.T types
withmassG
, anHList
ofproperties
, andunion/unionList
to combine multiple items’ mass and properties.ProvablyPacked/Models/Expedition.lean
definesExpedition.T actualItems
, which:- extends the comparator for the unioned gear properties,
- exposes
actualMassG
, - requires a
maxExpectedMassG
, and - includes a proof
has_valid_mass : actualMassG <= maxExpectedMassG
.
When Lean accepts your Expedition.T
value, you’ve proven that:
- every expected condition is a subset of your gear’s capabilities,
- you aren’t expecting something your items can’t handle, and
- your packed weight is within the declared limit.
Try it locally
Prereqs: Install Lean 4 and Lake. See the official instructions: https://lean-lang.org/get_started/
lake update
Then open ProvablyPacked/User/Example/ExampleScratchpad1.lean
in your editor (Lean 4 VS Code extension recommended). Watch Lean check the following:
- Item definitions with property lists per dimension (e.g., which
Bugginess.T
andPrecipitation.T
variants each item can handle). - The unioned gear properties and total mass via
Item.unionList
. - An
Expedition.T
that specifiesexpectedProperties
per dimension usingNarrow.T … (by nrrw)
and amaxExpectedMassG
with a proofhas_valid_mass
.
Try changing things and see the type checker help you:
- lower
maxExpectedMassG
to a value less thanactualMassG
→ thehas_valid_mass
proof won’t compile, - expect a value your gear doesn’t support →
nrrw
can’t find a proof and the file won’t typecheck.
Customize your own system
- Define your domain of conditions (enums work great) in something like
ProvablyPacked/User/MyDomain.lean
. - Create items as
Item.T [YourType1, YourType2, …]
with their equipped values per dimension. - Combine items with
Item.unionList
into a gear list. - Construct an
Expedition.T (actualItems := gearList)
with yourexpectedProperties
andmaxExpectedMassG
.
If it compiles, you have a machine-checked proof that your packing list meets the spec you wrote.
Status & roadmap
- Usable MVP (see
./User/
for examples) - More examples and docs coming (e.g., richer comparators, more complex example packing lists).
Related Projects: Sweaty Tictactoe, Arezzo
Notes mentioning this note
There are no notes linking to this note.