Current section

Files

Jump to
fixpoint test propagators element2d_test.exs
Raw

test/propagators/element2d_test.exs

defmodule CPSolverTest.Propagator.Element2D do
use ExUnit.Case
describe "Propagator filtering" do
alias CPSolver.ConstraintStore
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Variable.Interface
alias CPSolver.Propagator
alias CPSolver.Propagator.Element2D
test "filtering" do
x = -2..40
y = -3..10
z = 2..40
t = [
[9, 8, 7, 5, 6],
[9, 1, 5, 2, 8],
[8, 3, 1, 4, 9],
[9, 1, 2, 8, 6]
]
variables = Enum.map([x, y, z], fn d -> Variable.new(d) end)
{:ok, [x_var, y_var, z_var] = _bound_vars, _store} = ConstraintStore.create_store(variables)
propagator = Element2D.new(t, x_var, y_var, z_var)
%{state: state1} = Propagator.filter(propagator)
assert Interface.min(x_var) == 0
assert Interface.max(x_var) == 3
assert Interface.min(y_var) == 0
assert Interface.max(y_var) == 4
assert Interface.min(z_var) == 2
assert Interface.max(z_var) == 9
Interface.removeAbove(z_var, 7)
%{state: state2} = Propagator.filter(Map.put(propagator, :state, state1))
assert Interface.min(y_var) == 1
Interface.remove(x_var, 0)
%{state: state3} = Propagator.filter(Map.put(propagator, :state, state2))
assert 6 == Interface.max(z_var)
assert 3 == Interface.max(x_var)
Interface.remove(y_var, 4)
%{state: state4} = Propagator.filter(Map.put(propagator, :state, state3))
assert 5 == Interface.max(z_var)
assert 2 == Interface.min(z_var)
%{state: state5} = Propagator.filter(Map.put(propagator, :state, state4))
Interface.remove(y_var, 2)
%{state: _state6} = Propagator.filter(Map.put(propagator, :state, state5))
assert 4 == Interface.max(z_var)
assert 2 == Interface.min(z_var)
end
test "inconsistency" do
x = 1..2
y = -10..1
z = -2..6
t = [
[3, 5],
[7, 8]
]
variables = Enum.map([x, y, z], fn d -> Variable.new(d) end)
{:ok, [x_var, y_var, z_var], _store} = ConstraintStore.create_store(variables)
## The propagator will fail.
## D(x) = 1..2 implies filtering to {1} (because T is 2x2, and it's a 0-based index)
## This leaves only the second row for the values of z, which is inconsistent with D(z).
propagator = Element2D.new(t, x_var, y_var, z_var)
assert :fail == Propagator.filter(propagator)
end
test "2 of 3 fixed" do
x = 3..3
y = 3..3
z = 2..40
t = [
[9, 8, 7, 5, 6],
[9, 1, 5, 2, 8],
[8, 3, 1, 4, 9],
[9, 1, 2, 8, 6]
]
variables = Enum.map([x, y, z], fn d -> Variable.new(d) end)
{:ok, [x_var, y_var, z_var] = _bound_vars, _store} = ConstraintStore.create_store(variables)
propagator = Element2D.new(t, x_var, y_var, z_var)
%{state: nil, active?: false} = Propagator.filter(propagator)
assert Interface.min(z_var) ==
Enum.at(t, Interface.min(x_var)) |> Enum.at(Interface.min(y_var))
assert Interface.fixed?(z_var)
end
end
end