Skip to content

EXPERIMENTAL: These features are experimental and should not be used in production systems.

The Math Optimization Library (mathopt) Reference

This is the reference documentation for the Math Optimization Library.

Module: rel:mathopt

View source
rel:mathopt

Building mathematical optimization models and integration of external mathematical optimization solvers within Rel.

variables

View source
rel:mathopt:variables[R]

The rel:mathopt:variables[R] relation is used to declare variables. This relation takes the following argument:

  • R - a relation that contains the variables to declare.

The relation R must contain triples (Symbol, String, D) that represent the variable name, the variable type or bound declaration, and the domain, respectively. The string entry of the triples in R must be one of the following:

  • "continuous" - a continuous variable.
  • "integer" - an integer variable.
  • "binary" - a binary variable.
  • "lower_bound" - a lower bound on a continuous, integer, or binary variable.
  • "upper_bound" - an upper bound on a continuous, integer, or binary variable.

The domain D, a relation or number. If the variable is being declared with "continuous", "integer", or "binary", then D must be a relation that contains the domain of the variable. If the variable is being bounded by using the string "lower_bound" or "upper_bound" variable, then D must be a number that represents the bound on the variable. See rel:mathopt:named_variables for an example of declaring variables with names inferred by the data used in declaring the variables.

Example:

    def model:variables = rel:mathopt:variables[{
        // Declare continuous variables with no bounds.
        :w, "continuous", range[1, 2, 1];
 
        // Declare continuous variable with a single lower bound.
        :x, "continuous", ();
        :x, "lower_bound", 0.0;
 
        // Declare binary variables with no bounds.
        :y, "binary", range[1, 2, 1];
 
        // Declare integer variables with both lower and upper bounds.
        :z, "integer", range[1, 2, 1];
        :z, "lower_bound", 0.0;
        :z, "upper_bound", 50.0
    }]

named_variables

View source
rel:mathopt:named_variables[R]

The rel:mathopt:named_variables relation is used to declare variables with names inferred by the data used in declaring the variables. This relation takes the following argument:

  • R - a relation that contains the variables to declare.

See rel:mathopt:variables for more information on the relation R.

export

View source
rel:mathopt:export[Model, Config]

Export the Model to a file format specified in Config. See rel:mathopt:optimize for more information on the Model relation. The Config relation is an optional relation that can be used to override values from mathopt:SolverConfigDefaults. Use {} when no configuration is needed. See rel:mathopt:SolverConfigDefaults for more information on the configuration options and their default values.

Inputs:

  • Model: a relation with variables (created using rel:mathopt:variables or rel:mathopt:named_variables), an objective function specified by maximize (or minimize), and constraints; the latter two being created by using the mathopt:Solver:Solve DSL.
  • Config: a relation to override values from mathopt:SolverConfigDefaults. Use {} when no configuration is needed.

Output:

  • An opaque binary string containing the result of the solver. Use the rel:mathopt:extract_result function to extract detailed information from the result.

Example:

// Export the model to a MPS-file format.
def result = rel:mathopt:export[model, { :file_format, "mps" }]
 
// Extract and output the resulting information.
def output = rel:mathopt:extract_result[result, model:variables]

optimize

View source
rel:mathopt:optimize[Model, Config]

Optimize the Model relation. The model objective function is specified with either maximize or minimize in Model and is created using the mathopt:Solver:Solve DSL. The constraints are also created using the mathopt:Solver:Solve DSL and must be specified in the Model module as constraints. The variables of the model are specified with variables and must be declared with rel:mathopt:variables or rel:mathopt:named_variables. The Config is an optional relation that can be used to override values from mathopt:SolverConfigDefaults. Use {} when no configuration is needed.

Inputs:

  • Model: a relation with variables (created using rel:mathopt:variables or rel:mathopt:named_variables), an objective function specified by maximize (or minimize), and constraints; the latter two being created by using the mathopt:Solver:Solve DSL.
  • Config: a relation to override values from mathopt:SolverConfigDefaults. Use {} when no configuration is needed.

Output:

  • An opaque binary string containing the result of the solver. Use the rel:mathopt:extract_result function to extract detailed information from the result.

Example:

// Define the data. This is the data that will be used to create the model.
module data
    def products    = "bands" ; "coils"
    def production_rate   = { ("bands", 200.0) ; ("coils", 140.0) }
    def avail       = 40.0
    def product_profit = { ("bands", 25.0) ; ("coils", 30.0) }
    def product_market_demand = { ("bands", 6000.0) ; ("coils", 4000.0) }
end
 
@inline
module model
    // Bring the mathopt:Solver DSL into scope.
    with mathopt:Solver:Solve use sum, foreach, *, , /
 
    // Bring the data into scope.
    with data use products, product_profit, product_market_demand, production_rate, avail
 
    // Define the model variables.
    def variables = rel:mathopt:variables[
        {:x_make, "continuous", (products)};
        {:x_make, "lower_bound", 0.0}
    ]
    // Bring the variables into scope.
    with variables use x_make
 
    // Define the model objective.
    def maximize = sum[product_profit[p] * x_make[p] for p in products] // (the total profit)
 
    // Define the model constraints.
    module constraints
        def time = sum[(1/production_rate[p]) * x_make[p] for p in products]  avail
        def market = foreach[p in products: { x_make[p]  product_market_demand[p] }]
    end
end
 
// Optimize the model.
def result = rel:mathopt:optimize[model, {}]
 
// Extract the result of the optimization process.
def extracted = rel:mathopt:extract_result[result, model:variables]

extract_result

View source
rel:mathopt:extract_result[Result, Variables]

Extract detailed information from the result of a call to a mathematical optimization solver (optimize or export). The result must be a materialized relation.

Inputs:

  • result: a relation that contains the result of a rel:mathopt:optimize or rel:mathopt:export call. It must be materialized.
  • Variables: the relation that declares the model variables, created with rel:mathopt:variables.

Output:

  • A function from variable keys to the float value assigned by the solver, if any. The keys depend on the variable specification in Variables.

Example:

// Optimize the model.
def result = rel:mathopt:optimize[model, {}]
 
// Extract the result of the optimization process.
def extracted = rel:mathopt:extract_result[result, model:variables]

serialize

View source
rel:mathopt:serialize[Model]

Serialize a Model relation into a mathopt-specific binary format. Validate the correctness of Model.

Inputs:

  • Model: a relation specifying the optimization problem using the rel:mathopt DSL.

Required relations:

  • minimize or maximize: definition of the objective.
  • variables: variables used in the optimization.

Optional relations:

  • constraints: constraints used in the optimization.
  • config: configuration for the solver.

Output:

  • A binary string containing the serialization result.

Example:

module model
    with mathopt:Solver:Solve use +, *, =
 
    def variables = rel:mathopt:variables[
        {:x, "integer", ()};
        {:x, "lower_bound", 0.0};
        {:y, "integer", ()}
    ]
 
    with variables use x,y
 
    def minimize = 2 * x + y
 
    module constraints
         def c1 = x + 3 * y = 1
         def c2 = x + y >= 1
    end
 
    module config
        def solver_attributes = "time_limit", 10.0
    end
end
 
def output = rel:mathopt:serialize[model]

Module: mathopt:SolverConfigDefaults

View source
mathopt:SolverConfigDefaults

mathopt:SolverConfigDefaults defines the default values for the configuration parameters used by the rel:mathopt:optimize function. These values can be overridden by defining a relation named config in the module that calls rel:mathopt:optimize. The relation must have the same schema as mathopt:SolverConfigDefaults.

solver

View source Set solver backend to be used. Currently "HiGHS" (MIP and QP formulations), "DAQP" (MIP and QP formulations), and "Pavito" (MIQP formulations) are accepted. Support for "Gurobi" is planned and under development. The default solver is "HiGHS".

Example:

// Override the default solver with the "Pavito" solver.
module config
    def solver = "Pavito"
end

solver_attributes

View source Key value pairs of solver-specific attributes. These are sent directly to the solver backend. The keys must be strings and the values must be strings, floats, or integers. The specific attributes and values are specified by the solver being used. The default attributes are empty.

Example:

// Provide a solution timeout limit and turn off presolve while using `"HiGHS"`.
module config
    def solver_attributes = {("time_limit", 60.0); ("presolve", "off")}
end

file_format

View source A string specifying the format of the optimization model to be returned as a single string. The available formats are "lp", "mps", "mof", and "nl". The default file format is "lp".

Example:

// Override the default file format to be `"mps"`.
module config
    def file_format = "mps"
end

Module: mathopt:Solver

View source
mathopt:Solver

mathopt:Solver is a domain-specific language (DSL) designed for specifying mathematical optimization problems. It provides primitives for defining model constraints and model objective functions, as well as operations for mathematical computation and logic.

Module: Solve

View source
mathopt:Solver:Solve

The mathopt:Solver:Solve module contains functions for defining mathematical and logical operations within an optimization model. These functions translate into solver-compatible operations and are used to define the model’s constraints and objective function.

+

View source
mathopt:Solver:Solve:(+)
mathopt:Solver:Solve:(-)
mathopt:Solver:Solve:(*)
mathopt:Solver:Solve:(/)

mathopt:Solver:Solve:(+), mathopt:Solver:Solve:(-), mathopt:Solver:Solve:(*), and mathopt:Solver:Solve:(/) operators are used to formulate mathematical expressions in the constraints and the objective function of a optimization model.

=

View source
mathopt:Solver:Solve:(=)
mathopt:Solver:Solve:()
mathopt:Solver:Solve:()

mathopt:Solver:Solve:(=), mathopt:Solver:Solve:(≼), and `mathopt:Solver:Solve:(≽) operators are used to specify the relationships among the variables in the constraints.

View source
mathopt:Solver:Solve:()
mathopt:Solver:Solve:()

mathopt:Solver:Solve:(∧) and mathopt:Solver:Solve:(∨) operators are used to combine conditions in constraints.

sum

View source
mathopt:Solver:Solve:sum[R]

mathopt:Solver:Solve:sum[R] specifies the summation of a variable over a domain relation.

Example:

// Bring sum operator into scope.
with mathopt:Solver:Solve use sum
 
// Summation over a domain relation.
def model:maximize = sum[x[i] for i in domain]

foreach

View source
mathopt:Solver:Solve:foreach[R]

mathopt:Solver:Solve:foreach[R] supports creating constraints by batch by supplying one or more domain relations and relevant conditions.

Example:

// Bring foreach operator into scope.
with mathopt:Solver:Solve use foreach
 
// Add constraints through foreach.
def model:constraints:example = foreach[d in my_domain: { d * x[d] + 1  20 }]
Was this doc helpful?