Current section

Files

Jump to
fixpoint test objective objective_test.exs
Raw

test/objective/objective_test.exs

defmodule CpSolverTest.Objective do
use ExUnit.Case
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Objective
alias CPSolver.Propagator
alias CPSolver.ConstraintStore
alias CPSolver.Variable.Interface
describe "Objective API" do
test "low-level operations" do
handle = Objective.init_bound_handle()
Objective.update_bound(handle, 100)
assert 100 == Objective.get_bound(handle)
## Updates the bound with the lower value
Objective.update_bound(handle, 10)
assert 10 == Objective.get_bound(handle)
## Doesn't update the bound with the higher value
Objective.update_bound(handle, 100)
assert 10 == Objective.get_bound(handle)
end
test "concurrent updates to the bound result in setting the lowest bound value" do
handle = Objective.init_bound_handle()
refute 1 == Objective.get_bound(handle)
num_updates = 1000
bounds = Enum.shuffle(1..num_updates)
results =
Task.async_stream(bounds, fn b ->
Objective.update_bound(handle, b)
end)
|> Enum.to_list()
assert num_updates == length(results)
assert 1 == Objective.get_bound(handle)
end
test "Propagation and tightening" do
{:ok, [objective_variable] = _bound_vars, store} =
ConstraintStore.create_store([Variable.new(1..10)])
min_objective =
%{propagator: min_propagator, bound_handle: min_handle} =
Objective.minimize(objective_variable)
assert :stable == Propagator.filter(min_propagator, store: store)
## Tighten the bound (this will set the bound to objective_variable.max() - 1)
Objective.tighten(min_objective)
assert Objective.get_bound(min_handle) == 9
## Propagation will result in :max_change, :fixed, or :fail for the objective variable, if the global bound changes
assert {:changed, %{Interface.id(objective_variable) => :max_change}} ==
Propagator.filter(min_propagator)
## Propagation doesn't change a global bound
assert Objective.get_bound(min_handle) == 9
Objective.update_bound(min_handle, Interface.min(objective_variable))
assert {:changed, %{Interface.id(objective_variable) => :fixed}} ==
Propagator.filter(min_propagator)
## Tightening bound when the objective variable is fixed
Objective.tighten(min_objective)
assert {:fail, Interface.id(objective_variable)} == Propagator.filter(min_propagator)
end
end
end