Skip to content

refactor(DOCP): dispatch-based contract, no builders/callables#155

Merged
ocots merged 3 commits into
mainfrom
refactor/docp-dispatch
Jun 27, 2026
Merged

refactor(DOCP): dispatch-based contract, no builders/callables#155
ocots merged 3 commits into
mainfrom
refactor/docp-dispatch

Conversation

@ocots

@ocots ocots commented Jun 26, 2026

Copy link
Copy Markdown
Member

Context

The discretization path went through a closure-factory → builder-accessor → callable indirection: a (discretizer)(ocp) callable (CTDirect) returned 4 closures wrapped in a DiscretizedModel{4 builders}, which modelers reopened via get_*_builder accessors. Problems: implicit temporal coupling (exa_getter = nothing mutated as a side effect), scattered contract, ~120 lines of AbstractBuilder boilerplate, struct coupled to backends (4 type-params), and AbstractDiscretizer owned by CTDirect while CTSolvers used it.

This PR replaces that with direct multiple dispatch, problem-first, no callables, no builders. It makes the DOCP boundary consistent with the upcoming ODE Integrators boundary (same CommonSolve.solve(prob, alg) idiom).

Behaviour-preserving reorganization — solving semantics unchanged; only internal structures and contract method names move.

Changes

Core

  • DiscretizedModel slimmed to {ocp, discretizer, cache} with cache <: CTBase.Core.AbstractCache
  • AbstractDiscretizer moved into DOCP/ (DOCP/abstract_discretizer.jl)
  • new DOCP/contract.jl: discretize stub (NotImplemented), implemented downstream (CTDirect)
  • Optimization.build_model / build_solution become NotImplemented stubs, implemented by dispatch on (problem, modeler) in the providing package
  • removed Optimization/builders.jl, Optimization/contract.jl, DOCP/contract_impl.jl and all AbstractBuilder / get_*_builder boilerplate
  • removed modeler callables

Part C — solvers

  • dropped the (solver)(nlp) callable in favor of CommonSolve.solve(nlp, solver) methods (generic NotImplemented stub in core, typed methods in the Ipopt/Knitro/MadNLP/MadNCL/Uno extensions)

Tests — rewritten around the new contract; full suite green (2442 passed, 0 failed, 0 errored).

Downstream

Requires the companion CTDirect PR (implements CTSolvers.discretize / build_model / build_solution for Collocation / DirectShooting). Merge CTSolvers first, then CTDirect.

Out of scope (separate increments)

  • NLPModels/SolverCore hard→weak demotion (Part B)
  • Integrators submodule import from CTFlows

🤖 Generated with Claude Code

ocots and others added 2 commits June 26, 2026 20:48
Replace the closure-factory → builder-accessor → callable indirection with a
thin DiscretizedModel and named, problem-first contract methods.

CTSolvers:
- DiscretizedModel slimmed to {ocp, discretizer, cache} (cache <: CTBase.Core.AbstractCache)
- AbstractDiscretizer moved into DOCP (DOCP/abstract_discretizer.jl)
- new DOCP/contract.jl: discretize stub (NotImplemented), implemented downstream
- Optimization.build_model / build_solution become NotImplemented stubs
  (implemented by dispatch on (problem, modeler) in the providing package)
- remove Optimization/builders.jl, Optimization/contract.jl, DOCP/contract_impl.jl
  and all AbstractBuilder / get_*_builder boilerplate
- remove modeler callables; modelers now only carry options + metadata

Part C — solvers: drop the (solver)(nlp) callable in favor of
CommonSolve.solve(nlp, solver) methods (generic NotImplemented stub in core,
typed methods in the Ipopt/Knitro/MadNLP/MadNCL/Uno extensions).

Behavior-preserving reorganization; tests updated in a follow-up commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rewrite tests around the new build_model / build_solution contract and
CommonSolve.solve(nlp, solver), removing all builder/accessor and callable usages:

- test_docp / test_optimization / test_error_cases: fake discretizer + cache,
  contract by dispatch, NotImplemented stubs
- shared problems/*.jl: OptimizationProblem implements build_model/build_solution
- test_real_problems / test_end_to_end: build via Optimization.build_model(prob, init, modeler)
- solver tests: (solver)(nlp) -> CommonSolve.solve(nlp, solver)
- extension tests: builder extraction -> build_model, solver callable -> CommonSolve.solve

Full suite green: 2442 passed, 0 failed, 0 errored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ractOptimizationProblem

The problem argument is always an AbstractOptimizationProblem (same module), so
constrain the generic stubs accordingly. The modeler stays untyped here: its type
(Modelers.AbstractNLPModeler) lives in the Modelers submodule, which is loaded
after Optimization and depends on it, so Optimization cannot reference it. Fine-
grained modeler typing already exists downstream (DOCP/building.jl and the
concrete CTDirect methods).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ocots
ocots merged commit c29603b into main Jun 27, 2026
5 checks passed
@ocots
ocots deleted the refactor/docp-dispatch branch June 27, 2026 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant