Packages
fixpoint
0.3.3
0.22.1
0.21.5
0.21.4
0.21.3
0.21.2
0.21.1
0.21.0
0.20.6
0.20.5
0.20.4
0.20.3
0.20.2
0.20.1
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.18.2
0.18.1
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.13.5
0.13.4
0.13.2
0.13.1
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.2
0.12.1
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.46
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.28
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.1.3
0.1.2
0.1.1
0.1.0
Constraint Programming Solver
Current section
Files
Jump to
Current section
Files
test/store/store_test.exs
defmodule CPSolverTest.Store do
use ExUnit.Case
describe "Store" do
alias CPSolver.ConstraintStore
alias CPSolver.IntVariable, as: Variable
test "create variables in the space" do
v1_values = 1..10
v2_values = -5..5
values = [v1_values, v2_values]
variables = Enum.map(values, fn d -> Variable.new(d) end)
{:ok, bound_vars, _store, _store_impl} = ConstraintStore.create_store(variables)
## Bound vars have space and ids assigned
assert Enum.all?(bound_vars, fn var -> var end)
end
test "Store variables" do
v1_values = 1..10
v2_values = -5..5
v3_values = [0, 3, 6, 9, -1]
values = [v1_values, v2_values, v3_values]
variables = Enum.map(values, fn d -> Variable.new(d) end)
{:ok, bound_vars, store, store_impl} = ConstraintStore.create_store(variables)
store_var_ids = store_impl.get_variables(store)
assert length(bound_vars) == store_var_ids |> length
## Make sure that the sets of bound vars and store vars coincide.
assert Enum.all?(
Enum.zip(Enum.sort(store_var_ids), Enum.sort_by(bound_vars, fn v -> v.id end)),
fn {store_var, bound_var} ->
store_var == bound_var.id
end
)
end
test "GET operations" do
v1_values = 1..10
v2_values = -5..5
v3_values = 1..1
values = [v1_values, v2_values, v3_values]
variables = Enum.map(values, fn d -> Variable.new(d) end)
{:ok, bound_vars, store, store_impl} = ConstraintStore.create_store(variables)
# Min
assert Enum.all?(Enum.zip(bound_vars, values), fn {var, vals} ->
store_impl.get(store, var, :min) == Enum.min(vals)
end)
# Max
assert Enum.all?(Enum.zip(bound_vars, values), fn {var, vals} ->
store_impl.get(store, var, :max) == Enum.max(vals)
end)
# Size
assert Enum.all?(Enum.zip(bound_vars, values), fn {var, vals} ->
store_impl.get(store, var, :size) == Range.size(vals)
end)
# Fixed?
assert Enum.all?(Enum.zip(bound_vars, values), fn {var, vals} ->
store_impl.get(store, var, :fixed?) == (Range.size(vals) == 1)
end)
# Contains?
assert Enum.all?(Enum.zip(bound_vars, values), fn {var, vals} ->
Enum.all?(vals, fn val -> store_impl.get(store, var, :contains?, [val]) end)
end)
end
test "UPDATE operations" do
v1_values = 1..10
v2_values = -5..5
v3_values = 1..2
values = [v1_values, v2_values, v3_values]
variables = Enum.map(values, fn d -> Variable.new(d) end)
{:ok, bound_vars, store, store_impl} = ConstraintStore.create_store(variables)
[v1, v2, v3] = bound_vars
# remove
refute Enum.any?(bound_vars, fn var ->
assert store_impl.update(store, var, :remove, [1]) in [:domain_change, :fixed]
store_impl.get(store, var, :contains?, [1])
end)
assert store_impl.get(store, v3, :fixed?)
assert store_impl.get(store, v3, :min) == 2
# Remove on fixed var
assert :fail == store_impl.update(store, v3, :remove, [2])
assert :fail == store_impl.get(store, v3, :contains?, [1])
assert :fail == store_impl.update(store, v3, :remove, [2])
assert :fail == store_impl.get(store, v3, :size)
# removeAbove
:max_change = store_impl.update(store, v1, :removeAbove, [5])
assert store_impl.get(store, v1, :max) == 5
assert store_impl.get(store, v1, :min) == 2
# removeBelow
:min_change = store_impl.update(store, v2, :removeBelow, [0])
assert store_impl.get(store, v2, :max) == 5
assert store_impl.get(store, v2, :min) == 0
# fix variable with value outside the domain
assert store_impl.update(store, v1, :fix, [0]) == :no_change
assert store_impl.get(store, v1, :max) == 5
:fixed = store_impl.update(store, v2, :fix, [0])
assert store_impl.get(store, v2, :max) == 0
end
test "Store subscriptions" do
v1_values = -5..5
v2_values = 1..10
v3_values = 1..2
values = [v1_values, v2_values, v3_values]
variables = Enum.map(values, fn d -> Variable.new(d) end)
{:ok, [v1, v2, _v3] = bound_vars, store, store_impl} =
ConstraintStore.create_store(variables)
## No notifications, if no subscriptions
assert :max_change == store_impl.update(store, v2, :removeAbove, [5])
refute_received _, 10
## Subscribe to :min_change for all variables
store_impl.subscribe(
store,
Enum.map(bound_vars, fn v -> %{variable: v.id, pid: self(), events: [:min_change]} end)
)
assert :min_change == store_impl.update(store, v1, :removeBelow, [0])
id = v1.id
assert_received {:min_change, ^id}, 10
end
test "Dispose of store variables for Local" do
v1_values = -5..5
v2_values = 1..10
v3_values = 1..2
values = [v1_values, v2_values, v3_values]
variables = Enum.map(values, fn d -> Variable.new(d) end)
{:ok, _bound_vars, store, store_impl} =
ConstraintStore.create_store(variables, CPSolver.Store.Local)
store_impl.dispose(store, :ignore)
Process.sleep(10)
refute Process.alive?(store)
end
end
end