With AI
An AI assistant can learn the syntax of the OptimalControl.jl DSL from its documentation, and then translate a problem written in standard mathematics into this DSL. Here is a typical prompt, pointing to the abstract syntax page:
Learn the syntax of OptimalControl.jl DSL described at the link below
to translate math into this DSL (Julia language):
https://control-toolbox.org/OptimalControl.jl/dev/modelling/abstract-syntaxHere is an extract of the answer of an assistant (here claude.ai) to the request below:
Translate the problem below into this DSL:
minimise the final time tf
under the constraint q''(t) = u(t)
with -1 <= u(t) <= 1,
q(0) = 1, q'(0) = -2, q(tf) = 3, q'(tf) = 1, and q'(t) <= 1.ocp = @def begin
tf ∈ R, variable
t ∈ [0, tf], time
x = (q, v) ∈ R², state
u ∈ R, control
# Variable constraint
tf ≥ 0
# Control constraint
-1 ≤ u(t) ≤ 1
# Initial conditions
q(0) == 1
v(0) == -2
# Final conditions
q(tf) == 3
v(tf) == 1
# Path constraint
v(t) ≤ 1
# Dynamics (q'' = u becomes first-order system)
ẋ(t) == [v(t), u(t)]
# Objective: minimize final time
tf → min
endThe answer is correct: this page builds it when the documentation is built, and it solves:
sol = solve(ocp; display=false)
println("tf = ", objective(sol))tf = 6.500080505861524The answer can then be refined by further requests, for instance:
Use a form compatible with examodels.The assistant writes the dynamics coordinate by coordinate:
ocp_exa = @def begin
tf ∈ R, variable
t ∈ [0, tf], time
x = (q, v) ∈ R², state
u ∈ R, control
# Variable constraint
tf ≥ 0
# Control constraint
-1 ≤ u(t) ≤ 1
# Initial conditions
q(0) == 1
v(0) == -2
# Final conditions
q(tf) == 3
v(tf) == 1
# Path constraint
v(t) ≤ 1
# Dynamics (coordinate-wise for ExaModels)
∂(q)(t) == v(t)
∂(v)(t) == u(t)
# Objective: minimize final time
tf → min
endThis form is valid, but it was not needed: the :exa modeler (ExaModels) also accepts the vector form of the first answer. Both solve with it:
sol_vector = solve(ocp, :exa; display=false)
sol_coord = solve(ocp_exa, :exa; display=false)
println("tf: vector form = ", objective(sol_vector), ", coordinatewise = ", objective(sol_coord))tf: vector form = 6.500080505237342, coordinatewise = 6.500080505237342It is also possible to feed the model directly with math definitions (here from a snapshot), as in the example below:
translate the problem below into OptimalControl.jl DSL:
This prompt generates the following code, which is also built and solved here:
# Parameters
h₀ = 1
v₀ = 0
m₀ = 1
g₀ = 1
Tc = 3.5
hc = 500
vc = 620
mc = 0.6
# Derived constants
Dc = 0.5 * vc * m₀ / g₀
mf = mc * m₀
c = 0.5 * sqrt(g₀ * h₀)
Tmax = Tc * m₀ * g₀
# Auxiliary functions
D(h, v) = Dc * v^2 * exp(-hc * (h - h₀) / h₀)
g(h) = g₀ * (h₀ / h)^2
rocket = @def begin
# Variable (free final time)
tf ∈ R, variable
# Time
t ∈ [0, tf], time
# State: (altitude, velocity, mass)
x = (h, v, m) ∈ R³, state
# Control: thrust
T ∈ R, control
# Dynamics
∂(h)(t) == v(t)
∂(v)(t) == (T(t) - D(h(t), v(t)) - m(t) * g(h(t))) / m(t)
∂(m)(t) == -T(t) / c
# Initial conditions
h(0) == h₀
v(0) == v₀
m(0) == m₀
# Final condition
m(tf) == mf
# State constraints
h(t) ≥ h₀
v(t) ≥ v₀
mf ≤ m(t) ≤ m₀
# Control constraint
0 ≤ T(t) ≤ Tmax
# Variable constraint
tf ≥ 0
# Objective: maximize final altitude h(tf)
-h(tf) → min
endsol = solve(rocket; display=false)
println("h(tf) = ", -objective(sol), ", tf = ", variable(sol))h(tf) = 1.0128374467369907, tf = 0.198850669489703This is the Goddard problem, also solved in the guided tour, with the same final altitude.
See also
Abstract syntax (
@def) — what the AI is being taught.Example gallery — more worked problems.
Guided tour — the Goddard rocket, solved in depth.