Public API

This page lists exported symbols of CTSolvers.Strategies.


From CTSolvers.Strategies

BypassValue

CTSolvers.Strategies.BypassValueType
struct BypassValue{T}

Wrapper type for option values that should bypass validation.

This type is used to explicitly skip validation for specific options when constructing strategies. It is particularly useful for passing backend-specific options that are not defined in the strategy's metadata.

Fields

  • value::T: The wrapped option value

Example

julia> val = bypass(42)
BypassValue(42)

See also: bypass

RoutedOption

CTSolvers.Strategies.RoutedOptionType
struct RoutedOption

Routed option value with explicit strategy targeting.

This type is created by route_to to disambiguate options that exist in multiple strategies. It wraps one or more (strategy_id => value) pairs, allowing the orchestration layer to route each value to its intended strategy.

Fields

  • routes::NamedTuple: NamedTuple of strategy_id => value mappings

Iteration

RoutedOption implements the collection interface and can be iterated like a dictionary:

  • keys(opt): Strategy IDs
  • values(opt): Option values
  • pairs(opt): (strategy_id, value) pairs
  • for (id, val) in opt: Direct iteration over pairs
  • opt[:strategy]: Index by strategy ID
  • haskey(opt, :strategy): Check if strategy exists
  • length(opt): Number of routes

Example

julia> using CTSolvers.Strategies

julia> # Single strategy
julia> opt = route_to(solver=100)
RoutedOption((solver = 100,))

julia> # Multiple strategies
julia> opt = route_to(solver=100, modeler=50)
RoutedOption((solver = 100, modeler = 50))

julia> # Iterate over routes
julia> for (id, val) in opt
           println("$id => $val")
       end
solver => 100
modeler => 50

See also: route_to

StrategyRegistry

CTSolvers.Strategies.StrategyRegistryType
struct StrategyRegistry

Registry mapping strategy families to their concrete types.

This type provides an explicit, immutable registry for managing strategy types organized by family. It enables:

  • Type lookup by ID: Find concrete types from symbolic identifiers
  • Family introspection: List all strategies in a family
  • Validation: Ensure ID uniqueness and type hierarchy correctness

Design Philosophy

The registry uses an explicit passing pattern rather than global mutable state:

  • Created once via create_registry
  • Passed explicitly to functions that need it
  • Thread-safe (no shared mutable state)
  • Testable (easy to create multiple registries)

Fields

  • families::Dict{Type{<:AbstractStrategy}, Vector{Type}}: Maps abstract family types to concrete strategy types

Example

julia> using CTSolvers.Strategies

julia> registry = create_registry(
           AbstractNLPModeler => (Modelers.ADNLP, Modelers.Exa),
           AbstractNLPSolver => (Solvers.Ipopt, Solvers.MadNLP)
       )
StrategyRegistry with 2 families

julia> strategy_ids(AbstractNLPModeler, registry)
(:adnlp, :exa)

julia> T = type_from_id(:adnlp, AbstractNLPModeler, registry)
Modelers.ADNLP

See also: create_registry, strategy_ids, type_from_id

available_parameters

CTSolvers.Strategies.available_parametersFunction
available_parameters(
    strategy_id::Symbol,
    family::Type{<:CTSolvers.Strategies.AbstractStrategy},
    registry::CTSolvers.Strategies.StrategyRegistry
) -> Vector{Type{<:CTSolvers.Strategies.AbstractStrategyParameter}}

Return all available strategy parameter types for a given (strategy_id, family).

This function is used by orchestration to validate that a global parameter token present in the method tuple is compatible with all selected strategies.

Arguments

  • strategy_id::Symbol: Strategy identifier (e.g. :madnlp).
  • family::Type{<:AbstractStrategy}: Family to search within.
  • registry::StrategyRegistry: Strategy registry.

Returns

  • Vector{Type{<:AbstractStrategyParameter}}: Supported parameter types. Returns an empty vector if the strategy is not parameterized.

See also: extract_global_parameter_from_method, get_parameter_type

build_strategy

CTSolvers.Strategies.build_strategyFunction
build_strategy(
    id::Symbol,
    family::Type{<:CTSolvers.Strategies.AbstractStrategy},
    registry::CTSolvers.Strategies.StrategyRegistry;
    mode,
    kwargs...
) -> Any

Build a strategy instance from its ID and options.

This function creates a concrete strategy instance by:

  1. Looking up the strategy type from its ID in the registry
  2. Constructing the instance with the provided options

Arguments

  • id::Symbol: Strategy identifier (e.g., :adnlp, :ipopt)
  • family::Type{<:AbstractStrategy}: Abstract family type to search within
  • registry::StrategyRegistry: Registry containing strategy mappings
  • mode::Symbol=:strict: Validation mode (:strict or :permissive)
  • kwargs...: Options to pass to the strategy constructor

Returns

  • Concrete strategy instance of the appropriate type

Throws

  • Exceptions.IncorrectArgument: If the strategy ID is not found in the registry for the given family

Example

julia> registry = create_registry(
           AbstractNLPModeler => (Modelers.ADNLP, Modelers.Exa)
       )

julia> modeler = build_strategy(:adnlp, AbstractNLPModeler, registry; backend=:sparse)
Modelers.ADNLP(options=StrategyOptions{...})

julia> modeler = build_strategy(:adnlp, AbstractNLPModeler, registry; 
           backend=:sparse, mode=:permissive)
Modelers.ADNLP(options=StrategyOptions{...})

See also: type_from_id

build_strategy(
    id::Symbol,
    parameter::Type{<:CTSolvers.Strategies.AbstractStrategyParameter},
    family::Type{<:CTSolvers.Strategies.AbstractStrategy},
    registry::CTSolvers.Strategies.StrategyRegistry;
    mode,
    kwargs...
) -> Any

Build a parameterized strategy instance from ID, parameter, and options.

This function creates a concrete parameterized strategy instance by:

  1. Looking up the parameterized strategy type from its ID and parameter
  2. Constructing the instance with the provided options

Arguments

  • id::Symbol: Strategy identifier (e.g., :madnlp)
  • parameter::Type{<:AbstractStrategyParameter}: Parameter type (e.g., GPU)
  • family::Type{<:AbstractStrategy}: Abstract family type to search within
  • registry::StrategyRegistry: Registry containing strategy mappings
  • mode::Symbol=:strict: Validation mode (:strict or :permissive)
  • kwargs...: Options to pass to the strategy constructor

Returns

  • Concrete parameterized strategy instance (e.g., MadNLP{GPU})

Throws

  • CTBase.Exceptions.IncorrectArgument: If the strategy-parameter combination is not found

Example

julia> registry = create_registry(
           AbstractNLPSolver => ((MadNLP, [CPU, GPU]),)
       )

julia> solver = build_strategy(:madnlp, GPU, AbstractNLPSolver, registry; max_iter=1000)
MadNLP{GPU}(options=StrategyOptions{...})

See also: build_strategy

build_strategy_options

CTSolvers.Strategies.build_strategy_optionsFunction
build_strategy_options(
    strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy};
    mode,
    kwargs...
) -> CTSolvers.Strategies.StrategyOptions

Build StrategyOptions from user kwargs and strategy metadata.

This function creates a StrategyOptions instance by:

  1. Validating the mode parameter (:strict or :permissive)
  2. Extracting known options from kwargs using the Options API
  3. Handling unknown options based on the mode
  4. Converting the extracted Dict to NamedTuple
  5. Wrapping in StrategyOptions

The Options.extract_options function handles:

  • Alias resolution to primary names
  • Type validation
  • Custom validators
  • Default values
  • Provenance tracking (:user, :default)

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type to build options for
  • mode::Symbol = :strict: Validation mode (:strict or :permissive)
    • :strict (default): Rejects unknown options with detailed error message
    • :permissive: Accepts unknown options with warning, stores with :user source (unvalidated)
  • kwargs...: User-provided option values

Returns

  • StrategyOptions: Validated options with provenance tracking

Throws

  • Exceptions.IncorrectArgument: If mode is not :strict or :permissive
  • Exceptions.IncorrectArgument: If an unknown option is provided in strict mode
  • Exceptions.IncorrectArgument: If type validation fails (both modes)
  • Exceptions.IncorrectArgument: If custom validation fails (both modes)

Example

# Define a minimal strategy for demonstration
julia> struct MyStrategy <: AbstractStrategy end
julia> Strategies.metadata(::Type{MyStrategy}) = StrategyMetadata(
           OptionDefinition(name=:max_iter, type=Int, default=100)
       )

# Strict mode (default) - rejects unknown options
julia> opts = build_strategy_options(MyStrategy; max_iter=200)
StrategyOptions with 1 option:
  max_iter = 200  [user]

# Permissive mode - accepts unknown options with warning
julia> opts = build_strategy_options(MyStrategy; max_iter=200, custom_opt=123, mode=:permissive)
┌ Warning: Unrecognized options passed to MyStrategy
│   Unvalidated options: [:custom_opt]
└ ...
StrategyOptions with 2 options:
  max_iter = 200  [user]
  custom_opt = 123  [user]

Notes

  • Known options are always validated (type, custom validators) regardless of mode
  • Unknown options in permissive mode are stored with source :user but bypass validation
  • Use permissive mode only when you need to pass backend-specific options not defined in CTSolvers metadata

See also: StrategyOptions, metadata, Options.extract_options

bypass

CTSolvers.Strategies.bypassFunction
bypass(val) -> CTSolvers.Strategies.BypassValue

Mark an option value to bypass validation.

This function creates a BypassValue wrapper around the provided value. When passed to a strategy constructor, this value will be accepted even if the option name is unknown (not in metadata) or if validation would otherwise fail.

This can be combined with route_to to bypass validation for specific strategies when routing ambiguous options.

Arguments

  • val: The option value to wrap

Returns

  • BypassValue: The wrapped value

Example

julia> using CTSolvers.Strategies

julia> # Pass an unknown option directly to strategy
julia> solver = Ipopt(
           max_iter=100, 
           custom_backend_option=bypass(42)  # Bypasses validation
       )
Ipopt(options=StrategyOptions{...})

julia> # Alternative syntax using force alias
julia> solver = Ipopt(
           max_iter=100, 
           custom_backend_option=force(42)  # Same as bypass(42)
       )
Ipopt(options=StrategyOptions{...})

julia> # Combine with routing for ambiguous options
julia> solve(ocp, method; 
           backend = route_to(ipopt=bypass(42))  # Route to ipopt AND bypass validation
       )

Notes

  • Use with caution! Bypassed options are passed directly to the backend.
  • Typos in option names will not be caught by validation.
  • Invalid values for the backend will cause backend-level errors.
  • Can be combined with route_to for strategy-specific bypassing
  • force is an alias for bypass - they are identical functions

See also: BypassValue, route_to, force

create_registry

CTSolvers.Strategies.create_registryFunction
create_registry(
    pairs::Pair...
) -> CTSolvers.Strategies.StrategyRegistry

Create a strategy registry from family-to-strategies mappings.

This function validates the registry structure and ensures:

  • All strategy IDs are unique within each family
  • All strategies are subtypes of their declared family
  • No duplicate family definitions

Arguments

  • pairs...: Pairs of family type => tuple of strategy types

Returns

  • StrategyRegistry: Validated registry ready for use

Validation Rules

  1. ID Uniqueness: Within each family, all strategy id() values must be unique
  2. Type Hierarchy: Each strategy must be a subtype of its family
  3. No Duplicates: Each family can only appear once in the registry

Example

julia> using CTSolvers.Strategies

julia> registry = create_registry(
           AbstractNLPModeler => (Modelers.ADNLP, Modelers.Exa),
           AbstractNLPSolver => (Solvers.Ipopt, Solvers.MadNLP, Solvers.Knitro)
       )
StrategyRegistry with 2 families

julia> strategy_ids(AbstractNLPModeler, registry)
(:adnlp, :exa)

Throws

  • ErrorException: If duplicate IDs are found within a family
  • ErrorException: If a strategy is not a subtype of its family
  • ErrorException: If a family appears multiple times

See also: StrategyRegistry, strategy_ids, type_from_id

extract_id_from_method

CTSolvers.Strategies.extract_id_from_methodFunction
extract_id_from_method(
    method::Tuple{Vararg{Symbol}},
    family::Type{<:CTSolvers.Strategies.AbstractStrategy},
    registry::CTSolvers.Strategies.StrategyRegistry
) -> Symbol

Extract the strategy ID for a specific family from a method tuple.

A method tuple contains multiple strategy IDs (e.g., (:collocation, :adnlp, :ipopt)). This function identifies which ID corresponds to the requested family.

Arguments

  • method::Tuple{Vararg{Symbol}}: Tuple of strategy IDs
  • family::Type{<:AbstractStrategy}: Abstract family type to search for
  • registry::StrategyRegistry: Registry containing strategy mappings

Returns

  • Symbol: The ID corresponding to the requested family

Throws

  • Exceptions.IncorrectArgument: If no ID or multiple IDs are found for the family

Example

julia> method = (:collocation, :adnlp, :ipopt)

julia> extract_id_from_method(method, AbstractNLPModeler, registry)
:adnlp

julia> extract_id_from_method(method, AbstractNLPSolver, registry)
:ipopt

See also: strategy_ids

filter_options

CTSolvers.Strategies.filter_optionsFunction
filter_options(
    nt::NamedTuple,
    exclude::Symbol
) -> NamedTuple

Filter a NamedTuple by excluding specified keys.

Arguments

  • nt::NamedTuple: NamedTuple to filter
  • exclude::Symbol: Single key to exclude

Returns

  • NamedTuple: New NamedTuple without the excluded key

Example

julia> opts = (max_iter=100, tol=1e-6, debug=true)
julia> filter_options(opts, :debug)
(max_iter = 100, tol = 1.0e-6)

See also: filter_options(::NamedTuple, ::Tuple)

filter_options(
    nt::NamedTuple,
    exclude::Tuple{Vararg{Symbol}}
) -> NamedTuple

Filter a NamedTuple by excluding specified keys.

Arguments

  • nt::NamedTuple: NamedTuple to filter
  • exclude::Tuple{Vararg{Symbol}}: Tuple of keys to exclude

Returns

  • NamedTuple: New NamedTuple without the excluded keys

Example

julia> opts = (max_iter=100, tol=1e-6, debug=true)
julia> filter_options(opts, (:debug, :tol))
(max_iter = 100,)

See also: filter_options(::NamedTuple, ::Symbol)

force

CTSolvers.Strategies.forceFunction

Force an option value to bypass validation.

This function is an alias for bypass and provides identical functionality. The name force may be more intuitive for users who prefer "force" semantics when bypassing validation.

Arguments

  • val: The option value to wrap

Returns

  • BypassValue: The wrapped value

Example

julia> using CTSolvers.Strategies

julia> # Force acceptance of unknown option
julia> solver = Ipopt(
           max_iter=100, 
           custom_backend_option=force(42)  # Forces validation bypass
       )
Ipopt(options=StrategyOptions{...})

julia> # Same as bypass(42)
julia> @test force(42) == bypass(42)
true

Notes

  • force and bypass are the same function: force === bypass
  • Choose the name that best fits your mental model
  • Both functions create BypassValue wrappers
  • Use with caution for the same reasons as bypass

See also: BypassValue, bypass, route_to

format_suggestion

CTSolvers.Strategies.format_suggestionFunction
format_suggestion(s::NamedTuple) -> String

Format a suggestion entry as a human-readable string.

Example

julia> format_suggestion((primary=:backend, aliases=(:adnlp_backend,), distance=1))
":backend (alias: adnlp_backend) [distance: 1]"

get_parameter_type

CTSolvers.Strategies.get_parameter_typeFunction
get_parameter_type(strategy_type::Type) -> Any

Extract the parameter type from a parameterized strategy type.

For parameterized strategies like MadNLP{CPU}, this returns the parameter type CPU. For non-parameterized strategies, this returns nothing.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type to extract parameter from

Returns

  • Union{Type{<:AbstractStrategyParameter}, Nothing}: Parameter type or nothing if non-parameterized

Examples

julia> get_parameter_type(MadNLP{CPU})
CPU

julia> get_parameter_type(MadNLP{GPU})
GPU

julia> get_parameter_type(Ipopt)
nothing

has_option

CTSolvers.Strategies.has_optionFunction
has_option(
    strategy::CTSolvers.Strategies.AbstractStrategy,
    key::Symbol
) -> Any

Check if an option exists in a strategy instance.

Returns true if the option is present in the strategy's options, false otherwise. This is useful for checking if unknown options were stored in permissive mode.

Arguments

  • strategy::AbstractStrategy: The strategy instance
  • key::Symbol: The option name

Returns

  • Bool: true if the option exists

Example

julia> using CTSolvers.Strategies

julia> strategy = MyStrategy(max_iter=200; mode=:permissive, custom_opt=123)
julia> has_option(strategy, :max_iter)
true

julia> has_option(strategy, :custom_opt)
true

julia> has_option(strategy, :nonexistent)
false

See also: option_value, option_source

option_default

CTSolvers.Strategies.option_defaultFunction
option_default(
    strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy},
    key::Symbol
) -> Any

Get the default value for a specific option.

Returns the value that will be used if the option is not explicitly provided by the user during strategy construction.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type
  • key::Symbol: The option name

Returns

  • The default value for the option (type depends on the option)

Example

julia> using CTSolvers.Strategies

julia> option_default(MyStrategy, :max_iter)
100

julia> option_default(MyStrategy, :tol)
1.0e-6

Throws

  • KeyError: If the option name does not exist

Notes

  • This function operates on types, not instances
  • If you have an instance, use option_default(typeof(strategy), key)

See also: option_defaults, option_type

option_defaults

CTSolvers.Strategies.option_defaultsFunction
option_defaults(
    strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy}
) -> NamedTuple

Get all default values as a NamedTuple.

Returns a NamedTuple containing the default value for every option defined in the strategy's metadata. This is useful for resetting configurations or understanding the baseline behavior.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type

Returns

  • NamedTuple: All default values keyed by option name

Example

julia> using CTSolvers.Strategies

julia> option_defaults(MyStrategy)
(max_iter = 100, tol = 1.0e-6)

julia> defaults = option_defaults(MyStrategy)
julia> defaults.max_iter
100

Notes

  • This function operates on types, not instances
  • If you have an instance, use option_defaults(typeof(strategy))

See also: option_default, option_names

option_description

CTSolvers.Strategies.option_descriptionFunction
option_description(
    strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy},
    key::Symbol
) -> String

Get the human-readable description for a specific option.

Returns the documentation string that explains what the option controls. This is useful for generating help messages and documentation.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type
  • key::Symbol: The option name

Returns

  • String: The option description

Example

julia> using CTSolvers.Strategies

julia> option_description(MyStrategy, :max_iter)
"Maximum number of iterations"

julia> option_description(MyStrategy, :tol)
"Convergence tolerance"

Throws

  • KeyError: If the option name does not exist

Notes

  • This function operates on types, not instances
  • If you have an instance, use option_description(typeof(strategy), key)

See also: option_type, option_default

option_is_computed

CTSolvers.Strategies.option_is_computedFunction
option_is_computed(
    strategy::CTSolvers.Strategies.AbstractStrategy,
    key::Symbol
) -> Bool

Check if an option value was computed from other options.

Returns true if the option was calculated based on other option values, false if it was provided by the user or is using the default.

Arguments

  • strategy::AbstractStrategy: The strategy instance
  • key::Symbol: The option name

Returns

  • Bool: true if the option source is :computed

Example

julia> using CTSolvers.Strategies

julia> strategy = MyStrategy()
julia> is_computed(strategy, :derived_value)
true

See also: is_user, is_default, option_source

option_is_default

CTSolvers.Strategies.option_is_defaultFunction
option_is_default(
    strategy::CTSolvers.Strategies.AbstractStrategy,
    key::Symbol
) -> Bool

Check if an option value is using its default.

Returns true if the option is using the default value from metadata, false if it was provided by the user or computed.

Arguments

  • strategy::AbstractStrategy: The strategy instance
  • key::Symbol: The option name

Returns

  • Bool: true if the option source is :default

Example

julia> using CTSolvers.Strategies

julia> strategy = MyStrategy(max_iter=200)
julia> is_default(strategy, :max_iter)
false

julia> is_default(strategy, :tol)
true

See also: is_user, is_computed, option_source

option_is_user

CTSolvers.Strategies.option_is_userFunction
option_is_user(
    strategy::CTSolvers.Strategies.AbstractStrategy,
    key::Symbol
) -> Bool

Check if an option value was provided by the user.

Returns true if the option was explicitly set by the user during construction, false if it's using the default value or was computed.

Arguments

  • strategy::AbstractStrategy: The strategy instance
  • key::Symbol: The option name

Returns

  • Bool: true if the option source is :user

Example

julia> using CTSolvers.Strategies

julia> strategy = MyStrategy(max_iter=200)
julia> is_user(strategy, :max_iter)
true

julia> is_user(strategy, :tol)
false

See also: is_default, is_computed, option_source

option_names

CTSolvers.Strategies.option_namesFunction
option_names(
    strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy}
) -> Tuple

Get all option names for a strategy type.

Returns a tuple of all option names defined in the strategy's metadata. This is useful for discovering what options are available without needing to instantiate the strategy.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type to introspect

Returns

  • Tuple{Vararg{Symbol}}: Tuple of option names

Example

julia> using CTSolvers.Strategies

julia> option_names(MyStrategy)
(:max_iter, :tol, :backend)

julia> for name in option_names(MyStrategy)
           println("Available option: ", name)
       end
Available option: max_iter
Available option: tol
Available option: backend

Notes

  • This function operates on types, not instances
  • If you have an instance, use option_names(typeof(strategy))

See also: option_type, option_description, option_default

option_source

CTSolvers.Strategies.option_sourceFunction
option_source(
    strategy::CTSolvers.Strategies.AbstractStrategy,
    key::Symbol
) -> Symbol

Get the source provenance of an option value.

Returns a symbol indicating where the option value came from:

  • :user - Explicitly provided by the user
  • :default - Using the default value from metadata
  • :computed - Calculated from other options

Arguments

  • strategy::AbstractStrategy: The strategy instance
  • key::Symbol: The option name

Returns

  • Symbol: The source provenance (:user, :default, or :computed)

Example

julia> using CTSolvers.Strategies

julia> strategy = MyStrategy(max_iter=200)
julia> option_source(strategy, :max_iter)
:user

julia> option_source(strategy, :tol)
:default

Throws

  • KeyError: If the option name does not exist

See also: option_value, is_user, is_default

option_type

CTSolvers.Strategies.option_typeFunction
option_type(
    strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy},
    key::Symbol
) -> Type

Get the expected type for a specific option.

Returns the Julia type that the option value must satisfy. This is useful for validation and documentation purposes.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type
  • key::Symbol: The option name

Returns

  • Type: The expected type for the option value

Example

julia> using CTSolvers.Strategies

julia> option_type(MyStrategy, :max_iter)
Int64

julia> option_type(MyStrategy, :tol)
Float64

Throws

  • KeyError: If the option name does not exist

Notes

  • This function operates on types, not instances
  • If you have an instance, use option_type(typeof(strategy), key)

See also: option_description, option_default

option_value

CTSolvers.Strategies.option_valueFunction
option_value(
    strategy::CTSolvers.Strategies.AbstractStrategy,
    key::Symbol
) -> Any

Get the current value of an option from a strategy instance.

Returns the effective value that the strategy is using for the specified option. This may be a user-provided value or the default value.

Arguments

  • strategy::AbstractStrategy: The strategy instance
  • key::Symbol: The option name

Returns

  • The current option value (type depends on the option)

Example

julia> using CTSolvers.Strategies

julia> strategy = MyStrategy(max_iter=200)
julia> option_value(strategy, :max_iter)
200

julia> option_value(strategy, :tol)  # Uses default
1.0e-6

Throws

  • KeyError: If the option name does not exist

See also: option_source, options

options_dict

CTSolvers.Strategies.options_dictFunction
options_dict(
    strategy::CTSolvers.Strategies.AbstractStrategy
) -> Dict{Symbol, Any}

Extract strategy options as a mutable Dict, ready for modification.

This is a convenience method that combines three steps into one:

  1. Getting StrategyOptions from the strategy
  2. Extracting raw values (unwrapping OptionValue)
  3. Converting to Dict for modification

Arguments

  • strategy::AbstractStrategy: Strategy instance (solver, modeler, etc.)

Returns

  • Dict{Symbol, Any}: Mutable dictionary of option values

Example

julia> using CTSolvers

julia> solver = Solvers.Ipopt(max_iter=1000, tol=1e-8)

julia> options = Strategies.options_dict(solver)
Dict{Symbol, Any} with 6 entries:
  :max_iter => 1000
  :tol => 1.0e-8
  ...

julia> options[:print_level] = 0  # Modify as needed
0

julia> solve_with_ipopt(nlp; options...)

Notes

This function is particularly useful in solver extensions and modelers where you need to extract options and potentially modify them before passing to backend solvers or model builders.

See also: options, Options.extract_raw_options

resolve_alias

CTSolvers.Strategies.resolve_aliasFunction
resolve_alias(
    meta::CTSolvers.Strategies.StrategyMetadata,
    key::Symbol
) -> Union{Nothing, Symbol}

Resolve an alias to its primary key name.

Searches through strategy metadata to find if a given key is either:

  1. A primary option name
  2. An alias for a primary option name

Arguments

  • meta::StrategyMetadata: Strategy metadata to search in
  • key::Symbol: Key to resolve (can be primary name or alias)

Returns

  • Union{Symbol, Nothing}: Primary key if found, nothing otherwise

Example

julia> meta = metadata(MyStrategy)
julia> resolve_alias(meta, :max_iter)  # Primary name
:max_iter

julia> resolve_alias(meta, :max)  # Alias
:max_iter

julia> resolve_alias(meta, :unknown)  # Not found
nothing

See also: StrategyMetadata, OptionDefinition

route_to

CTSolvers.Strategies.route_toFunction
route_to(; kwargs...)

Create a disambiguated option value by explicitly routing it to specific strategies.

This function resolves ambiguity when the same option name exists in multiple strategies (e.g., both modeler and solver have max_iter). It creates a RoutedOption that tells the orchestration layer exactly which strategy should receive which value.

Arguments

  • kwargs...: Named arguments where keys are strategy identifiers (:solver, :modeler, etc.) and values are the option values to route to those strategies

Returns

  • RoutedOption: A routed option containing the strategy => value mappings

Throws

  • Exceptions.PreconditionError: If no strategies are provided

Example

julia> using CTSolvers.Strategies

julia> # Single strategy
julia> route_to(solver=100)
RoutedOption((solver = 100,))

julia> # Multiple strategies with different values
julia> route_to(solver=100, modeler=50)
RoutedOption((solver = 100, modeler = 50))

Usage in solve()

# Without disambiguation - error if max_iter exists in multiple strategies
solve(ocp, method; max_iter=100)  # ❌ Ambiguous!

# With disambiguation - explicit routing
solve(ocp, method; 
    max_iter = route_to(solver=100)              # Only solver gets 100
)

solve(ocp, method; 
    max_iter = route_to(solver=100, modeler=50)  # Different values for each
)

Notes

  • Strategy identifiers must match the actual strategy IDs in your method tuple
  • You can route to one or multiple strategies in a single call
  • This is the recommended way to disambiguate options
  • The orchestration layer will validate that the strategy IDs exist

See also: RoutedOption, route_all_options

strategy_ids

CTSolvers.Strategies.strategy_idsFunction
strategy_ids(
    family::Type{<:CTSolvers.Strategies.AbstractStrategy},
    registry::CTSolvers.Strategies.StrategyRegistry
) -> Tuple{Vararg{Symbol}}

Get all strategy IDs for a given family.

Returns a tuple of symbolic identifiers for all strategies registered under the specified family type. The order matches the registration order.

Arguments

  • family::Type{<:AbstractStrategy}: The abstract family type
  • registry::StrategyRegistry: The registry to query

Returns

  • Tuple{Vararg{Symbol}}: Tuple of strategy IDs in registration order

Example

julia> using CTSolvers.Strategies

julia> ids = strategy_ids(AbstractNLPModeler, registry)
(:adnlp, :exa)

julia> for strategy_id in ids
           println("Available: ", strategy_id)
       end
Available: adnlp
Available: exa

Throws

  • ErrorException: If the family is not found in the registry

See also: type_from_id, create_registry

suggest_options

CTSolvers.Strategies.suggest_optionsFunction
suggest_options(
    key::Symbol,
    strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy};
    max_suggestions
) -> Vector{@NamedTuple{primary::Symbol, aliases::Tuple{Vararg{Symbol}}, distance::Int64}}

Suggest similar option names for an unknown key using Levenshtein distance.

For each option, the distance is the minimum over the primary name and all its aliases. Results are grouped by primary option name and sorted by this minimum distance.

Arguments

  • key::Symbol: Unknown key to find suggestions for
  • strategy_type::Type{<:AbstractStrategy}: Strategy type to search in
  • max_suggestions::Int=3: Maximum number of suggestions to return

Returns

  • Vector{@NamedTuple{primary::Symbol, aliases::Tuple{Vararg{Symbol}}, distance::Int}}: Suggested options sorted by distance (closest first), each with primary name, aliases, and distance.

Example

julia> suggest_options(:max_it, MyStrategy)
1-element Vector{...}:
 (primary = :max_iter, aliases = (), distance = 2)

julia> suggest_options(:adnlp_backen, MyStrategy)
1-element Vector{...}:
 (primary = :backend, aliases = (:adnlp_backend,), distance = 1)

Note

The distance of an option to the key is min(dist(key, primary), dist(key, alias1), ...). This ensures that options with a close alias are suggested even if the primary name is far.

See also: resolve_alias, levenshtein_distance

suggest_options(
    key::Symbol,
    meta::CTSolvers.Strategies.StrategyMetadata;
    max_suggestions
) -> Vector{@NamedTuple{primary::Symbol, aliases::Tuple{Vararg{Symbol}}, distance::Int64}}

Suggest similar option names from a StrategyMetadata using Levenshtein distance.

See suggest_options(::Symbol, ::Type{<:AbstractStrategy}) for details.

type_from_id

CTSolvers.Strategies.type_from_idFunction
type_from_id(
    strategy_id::Symbol,
    family::Type{<:CTSolvers.Strategies.AbstractStrategy},
    registry::CTSolvers.Strategies.StrategyRegistry;
    parameter
) -> Type

Lookup a strategy type from its ID within a family.

Searches the registry for a strategy with the given symbolic identifier within the specified family. This is the core lookup mechanism used by the builder functions to convert symbolic descriptions to concrete types.

Arguments

  • strategy_id::Symbol: The symbolic identifier to look up
  • family::Type{<:AbstractStrategy}: The family to search within
  • registry::StrategyRegistry: The registry to query

Returns

  • Type{<:AbstractStrategy}: The concrete strategy type matching the ID

Example

julia> using CTSolvers.Strategies

julia> T = type_from_id(:adnlp, AbstractNLPModeler, registry)
Modelers.ADNLP

julia> id(T)
:adnlp

Throws

  • Exceptions.IncorrectArgument: If the family is not found in the registry
  • Exceptions.IncorrectArgument: If the ID is not found within the family (includes suggestions)

See also: strategy_ids, build_strategy