CvxLean
CvxLean is a convex optimization modeling framework written in Lean 4.
Problems are stated using definitions from mathlib and can be rigorously transformed both automatically and interactively. They can be solved by calling the backend solver MOSEK.
Our main contribution is a verified version of the disciplined convex programming (DCP) reduction algorithm.
Installation
You will need to install Lean 4 and MOSEK following these steps:
- Set up Lean 4 (see these instructions). The easiest way is to use the
elan
version manager. - If you're using VSCode, install the Lean 4 extension.
- Download MOSEK 10.0.12(BETA) and ensure that the
mosek
binary is available on your PATH. - Obtain a MOSEK license and place it in your home directory, i.e.
$HOME/mosek/mosek.lic
.
Finally, go into the top CvxLean
directory and run:
./build.sh
Usage
The best way to get started is to take a look at the examples in Test/Problems
. Here we follow the example in Test/Problems/SO.lean
.
Consider the optimization problem:
In CvxLean, it is defined as follows:
noncomputable def so1 :=
optimization (x y : ℝ)
maximize sqrt (x - y)
subject to
c1 : y = 2 * x - 3
c2 : x ^ 2 ≤ 2
c3 : 0 ≤ x - y
There are a couple of implementation details here. The definition needs to be marked as noncomputable
because it depends on the real numbers. Also, we require the extra condition 0 ≤ x - y
because the real square root in mathlib corresponds to the usual mathematical notion so it is only defined on nonnegative real numbers.
Once so1
has been defined, we can ask CvxLean to solve it.
solve so1
It will show MOSEK's output and its return code, which should be zero.
If successful, it will add several definitions to the environment:
so1.reduced
: the reduced version of the problem after applying DCP.so1.status
: the feasibility status of the primal and the dual problem, in this case"PRIMAL_AND_DUAL_FEASIBLE"
, i.e. optimal.so1.value
: if the problem is optimal, it corresponds to its optimal value.so1.solution
: if the problem is optimal, it corresponds to the optimal point.
Problems can also be reduced interactively using the reduction
command. As a simple example, suppose our problem has
reduction red/prob :
optimization (x y : ℝ)
maximize x + y
subject to
h : (exp x) * (exp y) ≤ 10 := by
conv_constr => rw [←Real.exp_add]
#print prob
-- def prob : Minimization (Real × Real) Real :=
-- optimization (x : Real) (y : Real)
-- maximize x + y
-- subject to
-- h : exp (x + y) ≤ 10
The transformation is done in a verified way using the lemma Real.exp_add
from mathlib, which says that
Troubleshooting
If ./build.sh
fails:
- Make sure that the version in
lean-toolchain
matches the output oflean --version
. - Try running
./build.sh
again. - Remove
lake-packages
and try again.
If MOSEK outputs code 255 in VSCode, try restarting VSCode.