Descriptions: encoding algorithms
One of the central ideas in CTBase.jl is the notion of a description. A description is simply a tuple of Symbols that encodes an algorithm or configuration in a declarative way.
Formally, CTBase defines:
const DescVarArg = Vararg{Symbol}
const Description = Tuple{DescVarArg}For example, the tuple
julia> using CTBase
julia> d = (:descent, :bfgs, :bisection)
(:descent, :bfgs, :bisection)
julia> typeof(d) <: CTBase.Description
truecan be read as “a descent algorithm, with BFGS directions and a bisection line search”. Higher-level packages in the control-toolbox ecosystem use descriptions to catalogue algorithms in a uniform way.
Building a library of descriptions
CTBase provides a few small functions to manage collections of descriptions:
CTBase.add(x, y)adds the descriptionyto the tuple of descriptionsx, rejecting duplicates with anIncorrectArgumentexception.CTBase.complete(list; descriptions=D)picks a complete description from a setDbased on a partial list of symbols.CTBase.remove(x, y)returns the set difference of two descriptions.
Here is a complete example of a small “algorithm library”:
julia> algorithms = ()
()
julia> algorithms = CTBase.add(algorithms, (:descent, :bfgs, :bisection))
((:descent, :bfgs, :bisection),)
julia> algorithms = CTBase.add(algorithms, (:descent, :gradient, :fixedstep))
((:descent, :bfgs, :bisection), (:descent, :gradient, :fixedstep))
julia> display(algorithms)
(:descent, :bfgs, :bisection)
(:descent, :gradient, :fixedstep)Given this library, we can complete a partial description:
julia> CTBase.complete((:descent,); descriptions=algorithms)
(:descent, :bfgs, :bisection)
julia> CTBase.complete((:gradient, :fixedstep); descriptions=algorithms)
(:descent, :gradient, :fixedstep)Internally, CTBase.complete scans the descriptions tuple from top to bottom. For each candidate description it computes:
- how many symbols it shares with the partial list, and
- whether the partial list is a subset of the full description.
If no description contains all the symbols from the partial list, AmbiguousDescription is thrown. Otherwise, among the descriptions that do contain the partial list, CTBase selects the one with the largest intersection; if several have the same score, the first one in the descriptions tuple wins. In other words, the order of descriptions encodes a priority from top to bottom.
With this mechanism in place, we can then analyse the remainder of a description by removing a prefix:
julia> full = CTBase.complete((:descent,); descriptions=algorithms)
(:descent, :bfgs, :bisection)
julia> CTBase.remove(full, (:descent, :bfgs))
(:bisection,)This “description language” lets higher-level packages refer to algorithms in a structured, composable way, while CTBase takes care of the low-level operations (adding, completing, and comparing descriptions).
Function Reference
| Function | Purpose | Returns | Throws |
|---|---|---|---|
add(x, y) | Add description y to collection x | Updated tuple | IncorrectArgument if duplicate |
complete(list; descriptions=D) | Find complete description matching partial list | Complete description | AmbiguousDescription if no match |
remove(x, y) | Remove symbols in y from description x | Remaining symbols | - |
Error Handling
The description system uses CTBase exceptions to signal problems:
Duplicate Descriptions
julia> using CTBasejulia> algorithms = CTBase.add((), (:a, :b))(:a, :b)julia> CTBase.add(algorithms, (:a, :b)) # Error: duplicateERROR: Control Toolbox Error ❌ Error: CTBase.Exceptions.IncorrectArgument, the description (:a, :b) is already in ((:a, :b),) 🔍 Got: (:a, :b), Expected: a unique description not in the catalog 📂 Context: description catalog management 💡 Suggestion: Check existing descriptions before adding, or use a different description
This throws IncorrectArgument because adding a duplicate would create ambiguity.
Ambiguous or Invalid Descriptions
julia> using CTBasejulia> D = ((:a, :b), (:c, :d))(:a, :b) (:c, :d)julia> CTBase.complete((:x,); descriptions=D) # Error: no matchERROR: Control Toolbox Error ❌ Error: CTBase.Exceptions.AmbiguousDescription, cannot find matching description ⚠️ Diagnostic: Unknown symbols - none of the requested symbols appear in any available description 🎯 Requested description: (:x,) 📋 Available descriptions: - (:a, :b) - (:c, :d) 📂 Context: description completion 💡 Suggestion: Choose from the available descriptions listed above
This throws AmbiguousDescription when no description in the library contains all the requested symbols.
Best Practices
- Order matters: Place more specific descriptions first in your library
- Use meaningful symbols: Choose symbols that clearly describe the algorithm
- Keep it simple: Descriptions should be short and focused
- Handle errors: Always catch
AmbiguousDescriptionwhen usingcomplete - Document your descriptions: Maintain a list of valid descriptions for your package
See Also
- Exception Handling: Understanding CTBase exceptions