Exhort.SAT.Builder (Exhort v0.1.0)

Provide for the building of a model for eventual solving.

All functions except build/0 are pure Elixir.

Create a new builder with new/0. Build a model with build/0.

build/0 interacts with the underlying native implementation, returning a Exhort.SAT.Model struct.

Link to this section Summary

Functions

Add an item or list of items to the builder.

Build the model. Once the model is built it may be solved.

Apply the constraint to the given list.

Define a boolean variable in the model.

Create a named constant. value should be a constant integer.

Define an integer variable in the model.

Define an interval variable in the model.

Add a constraint on the variable named by literal to the list of items in list.

Specify an objective to maximize expression.

Specify an objective to minimize literal.

Start a new builder.

Link to this section Types

@type t() :: %Exhort.SAT.Builder{
  constraints: term(),
  decision_strategy: term(),
  objectives: term(),
  res: term(),
  vars: term()
}

Link to this section Functions

Link to this function

add(builder, list)

Add an item or list of items to the builder.

@spec build(t()) :: Exhort.SAT.Model.t()

Build the model. Once the model is built it may be solved.

This function interacts with the underlying native model.

Link to this macro

constrain(builder, expr, opts \\ [])

(macro)

See Exhort.SAT.Constraint.

Define a bounded constraint.

The expression must include a boundary like ==, <=, >, etc.

x < y

The components of the expressoin may be simple mathematical expressions, including the use of + and *:

x * y = z

The sum/1 function may be used to sum over a series of terms:

sum(x + y) == z

The variables in the expression are defined in the model and do not by default reference the variables in Elixir scope. The pin operator, ^ may be used to reference a scoped Elixir variable.

For example, where x is a model variable (e.g., def_int_var(x, {0, 3})) and y is an Elixir variable (e.g., y = 2):

x < ^y

A for comprehension may be used to generate list values:

sum(for {x, y} <- ^list, do: x * y) == z

As a larger example:

y = 20
z = [{0, 1}, {2, 3}, {4, 5}]

Builder.new()
|> Builder.def_int_var(x, {0, 3})
|> Builder.constrain(sum(for {a, b} <- ^z, do: ^a * ^b) < y)
|> Builder.build()
...
Link to this function

constrain_list(builder, constraint, list, opts \\ [])

@spec constrain_list(
  t(),
  Exhort.SAT.Constraint.constraint(),
  list(),
  opts :: Keyword.t()
) :: t()

Apply the constraint to the given list.

See Exhort.SAT.Constraint for the list of constraints.

Link to this function

decision_strategy(builder, vars, variable_selection_strategy, domain_reduction_strategy)

@spec decision_strategy(
  t(),
  list(),
  variable_selection_strategy ::
    :choose_first
    | :choose_lowest_min
    | :choose_highest_max
    | :choose_min_domain_size
    | :choose_max_domain_size,
  domain_reduction_strategy ::
    :select_min_value
    | :select_max_value
    | :select_lower_half
    | :select_upper_half
    | :select_median_value
) :: t()

Specifiy a decision strategy on a list of variables.

Link to this function

def_bool_var(builder, name)

Define a boolean variable in the model.

Link to this function

def_constant(builder, name, value)

Create a named constant. value should be a constant integer.

Link to this function

def_int_var(builder, name, domain)

Define an integer variable in the model.

  • name is the variable name
  • domain is the uppper and lower bounds of the integer as a tuple, {lower_bound, upper_bound}
Link to this function

def_interval_var(builder, name, start, size, stop, opts \\ [])

Define an interval variable in the model.

See https://developers.google.com/optimization/reference/python/sat/python/cp_model#intervalvar

  • name is the variable name
  • start is the start of the interval
  • size is the size of the interval
  • stop is the end of the interval
  • opts may specify if: bool_var, where bool_var being a previously defined boolean variable
Link to this function

max_equality(builder, literal, list)

@spec max_equality(
  t(),
  literal :: atom() | String.t() | Exhort.SAT.IntVar.t(),
  list()
) :: t()

Add a constraint on the variable named by literal to the list of items in list.

Link to this macro

maximize(builder, expression)

(macro)

Specify an objective to maximize expression.

Link to this macro

minimize(builder, expression)

(macro)

Specify an objective to minimize literal.

@spec new() :: t()

Start a new builder.