Repository navigation
Description
Agents: read the guide for agents in #310 first (order, difficulty, how to claim an issue, working method). The specification is in this description and in the comments below.
Goal
Each modeling has its own list of problems, discovered automatically, and each problem has a status per modeling (:draft or :valid). A problem is provided to users in a modeling only when it is valid there, and consistent with every other modeling where it is valid. Nothing that can be computed is written by hand.
Part of #310. Lands on main on the current API; no release needed (0.6.0-beta will follow with #283).
Current state (code to change)
src/OptimalControlProblems.jlmake_list_of_problems()(l. 49–69): list fromreaddir(ext/MetaData)minus a hard-codedproblems_to_exclude = [:bioreactor, :cart_pendulum, :moonlander].- l. 73–112: for each problem,
evalgeneratesp(backend, args...; kwargs...)andp_s(...), which throwExtensionError(weakdeps[T]);weakdeps = Dict(OptimalControlBackend => :OptimalControl, JuMPBackend => :JuMP). - Their docstrings are broken: a stray
```line ([Doc] Typo in the docstrings #172) and$(TYPEDSIGNATURES)interpolated into a plain string, printed asDocStringExtensions.TypedMethodSignatures()([Doc] Examples are not displayed correctly in the REPL #173).
ext/JuMPModels.jl:25andext/OptimalControlModels.jl:9,14,21include one file per problem ofproblems(), inJuMPModels/,OptimalControlModels/andOptimalControlModels_s/.- The three excluded problems are most likely excluded because of this rule: they have OptimalControl and JuMP files but no
_sfile, and the OptimalControl extension includes$(problem)_s.jlfor every problem. - Users of the list: both extensions; every test file (
LIST_OF_PROBLEMS,eval(f),eval(Symbol(f, :_s)));docs/problems.jl:429; CTBenchmarks (__problems() = OptimalControlProblems.problems()). - Docstrings of the 66 problem methods are hand-written; examples use
N=100instead ofgrid_size=100.
Design
Modelings
Three backends, each a dispatch tag, described by one table (the only place to edit to add a modeling, e.g. Corleone in #308):
| Backend | Directory | Weak dependency |
|---|---|---|
OptimalControlBackend |
ext/OptimalControlModels/ |
OptimalControl |
OptimalControlScalarizedBackend (new) |
ext/OptimalControlScalarizedModels/ (renamed from OptimalControlModels_s/, files renamed <p>.jl) |
OptimalControl |
JuMPBackend |
ext/JuMPModels/ |
JuMP |
- The
_svariants become theOptimalControlScalarizedBackendmodeling:beam(OptimalControlScalarizedBackend())replacesbeam_s(OptimalControlBackend()). No morep_sfunctions. If Description and problems #174 drops them, delete one directory and one table entry. - Generate the per-problem functions with the existing
@evalloop (no@generated: nothing depends on argument types).
Existence and status
-
A problem exists if
ext/MetaData/<p>.jlexists. It exists in a modeling if the file of that modeling exists. -
Its status is declared in the metadata, per modeling, for the modelings where it exists:
:status => (OptimalControl=:valid, OptimalControlScalarized=:valid, JuMP=:draft)
Status Meaning Tests ([Tests] Test layout per environment and consistency tests #304, [Tests] Crons per scope for the slow tests, with reports #305) :draftwritten, not validated yet run, failures reported but do not fail CI :validpasses its own tests and is consistent with every other modeling where it is :validfailures fail CI -
:notes(optionalString): why a problem is a draft. -
The three excluded problems: remove the exclusion list, try them in each modeling;
:validwhere their tests pass,:draftwith:notesotherwise.
API
problems() # problems valid in at least one modeling
problems(JuMPBackend()) # valid in JuMP
problems(OptimalControlBackend(), JuMPBackend()) # valid in both (comparison tests)
problems(JuMPBackend(); status=:draft) # drafts in JuMP
problems(; status=:all) # every existing problem
status(:beam) # (OptimalControl=:valid, …), from the metadataReturn sorted Vector{Symbol}.
Generic method of each problem (in src)
- Problem has no file for this modeling →
CTBase.IncorrectArgument("beam is not available for JuMPBackend; see problems(JuMPBackend())"). - File present but extension not loaded →
CTBase.ExtensionError(<weakdep>), as today. - Calling a draft works but emits a warning (
@warn "beam is a draft for JuMPBackend: …"with:notes), so drafts stay easy to develop on.
Generated docstrings
The 66 hand-written docstrings are replaced by docstrings generated from one template, per problem and per modeling:
- one sentence (first sentence of
ext/Descriptions/<p>.md); - a usage example for that modeling (OptimalControl: get the problem and
solve; JuMP: get the model,set_optimizer,optimize!), in non-executed```julia-replfences, withgrid_size, notN; - the default parameters (from the metadata) and the status;
- a link to the online page of the problem.
The generic method gets a docstring that lists the modelings where the problem exists and their status. This closes #172 and #173.
Stale precompilation cache
The lists are computed with readdir at precompile time; adding a file to ext/JuMPModels/ does not invalidate the cache (the same is already true for ext/MetaData/). Make the directories precompilation dependencies (include_dependency), or compute availability at run time, and add a test that shows it. Check behaviour on Julia 1.10 and 1.12.
Out of scope
- Test layout per environment and the full consistency suite: [Tests] Test layout per environment and consistency tests #304. Here, adapt the existing tests minimally: loop over
problems(backend)per modeling, comparisons over the intersection, noeval(Symbol(f, :_s)). - Documentation rewrite: [Doc] Rewrite the documentation: getting started, user guide, problems, developers #307. Only keep
docs/problems.jlbuilding. - CTBenchmarks: open a follow-up issue there (use
problems(backend), drop_snames).
Done when
- No list of problems written by hand in
src/,ext/,test/. - Adding
ext/MetaData/foo.jlandext/JuMPModels/foo.jlwithJuMP=:draftmakesfooappear inproblems(JuMPBackend(); status=:draft)and be tested, without touchingsrc/; switching it to:validmakes it appear inproblems(JuMPBackend()). - Three backends; no
p_sfunction left;OptimalControlModels_s/renamed. -
bioreactor,cart_pendulum,moonlanderare back, as:validor:draftwith notes. - Error messages and draft warning tested.
-
help?> beamrenders correctly ([Doc] Typo in the docstrings #172, [Doc] Examples are not displayed correctly in the REPL #173). - Precompilation cache test passes on Julia 1.10 and 1.12.
- Follow-up issue opened in CTBenchmarks.
Activity
ocots commentedon Nov 4, 2026
Decision (see #310): availability in a modeling is deduced from file presence:
ext/<Modeling>/<p>.jlexists ⇔p ∈ problems(<Backend>()). It is the single source of truth; nothing is declared by hand in the metadata. The consistency tests (#304) check the correspondence between model files, metadata and descriptions.This issue does not break the 0.5 API: it goes to
maindirectly, before the port to v2 (#283).[-][Dev] Per-modeling lists of problems, discovered automatically[/-][+][Dev] Per-modeling lists of problems, discovered automatically, with a status per modeling[/+]ocots commentedon Nov 4, 2026
Addition to the modeling table (decided in #310, used by #308):
ModelingToolkitBackend, directoryext/ModelingToolkitModels/, weak dependencyModelingToolkit. The problem is a continuous ModelingToolkit system; solving it (e.g. with Corleone) is not part of the modeling. Not needed in this issue, but the table must make adding it a one-line change.ocots commentedon Nov 4, 2026
Taken by an agent; draft PR to follow.
ocots commentedon Nov 4, 2026
Documentation (decision in #307): this issue also writes
ext/README.md(main README: the plan of the extensions, availability = file presence,:draft→:valid, how to add a problem, how to add a modeling = table entry + documentation adapter) and the README of eachext/<Modeling>/,ext/MetaData/andext/Descriptions/directory it touches. Procedures only, no hand-written list of problems or modelings. Add it to the 'Done when' checklist.test: add the OptimalControl and OptimalControlScalarized environments
ocots commentedon Nov 4, 2026
Implementation is in draft PR #320. The full Julia 1.12 package test suite passes; Julia 1.10 verification remains pending because that local channel is not installed.
ocots commentedon Nov 4, 2026
Implementation complete.
PR #320 is ready for review. It implements the three modeling backends, file-discovered problem lists, per-modeling statuses, draft warnings, generated docstrings, scalarized backend rename, and the associated test adaptations.
Validation completed:
The existing
mountain_carscalarized comparison remains an expected broken test; the complete suite exits successfully.test: add the OptimalControl and OptimalControlScalarized environments
test: use the per-modeling API of #303 in the environments
test: add the OptimalControl and OptimalControlScalarized environments
test: use the per-modeling API of #303 in the environments
ocots commentedon Nov 4, 2026
Closing: done in #320 (with #319, #321, #322)
Done
OptimalControlBackend,OptimalControlScalarizedBackend,JuMPBackend); availability read from the model files, status (:valid/:draft) from the metadata;problems(),problems(backend; status=…),problems(b1, b2, …)(intersections) andOptimalControlProblems.status(:p).src/,ext/,test/(the former exclusion list is gone; the modeling tests name no problem).OptimalControlModels_s/renamed toOptimalControlScalarizedModels/,p_sreplaced by the scalarized backend.bioreactor,cart_pendulum,moonlanderare back as:valid; checked against each other (JuMP vs OptimalControl,grid_size=20, same objectives to 1e-15).CTBase.IncorrectArgument; draft → warning (with:notes). Both tested, as is the absence of a warning on a valid problem and the file ⇔ status-key consistency.TYPEDSIGNATURESdefect ([Doc] Typo in the docstrings #172, [Doc] Examples are not displayed correctly in the REPL #173), tested for every problem. TheAbstractModelBackenddocstring (a code block by mistake) is fixed.statusis not exported (MOD8); the docs generator usesproblems(OptimalControlBackend(), JuMPBackend(); status=:all).CI.ymlnow fires onlabeled(fix(ci): trigger CI when the run label is added #321).Not done, tracked in #323
src/, and that the precompilation cache is invalidated (include_dependencyis in place, no test shows it).Left as is
Discovered
mountain_carwith the scalarized backend and MadNLP is infeasible atgrid_size=20but solves at its default grid; it stays:valid. At the default grid its objective differs from JuMP/OptimalControl by 1.6e-4 (tolerance 1e-4): to investigate ([Metadata] Computed features, reference objective, shared initial guess #306:known_failuresif intended).OptimalControlModelsextension does not precompile in a clean environment (ExaModels 0.9ExaModelsLinearAlgebraand CTParser both definezero(::Type{<:ExaModels.AbstractNode})); it predates this work and costs load time.