Current section

Files

Jump to
fixpoint test propagators circuit_test.exs
Raw

test/propagators/circuit_test.exs

defmodule CPSolverTest.Propagator.Circuit do
use ExUnit.Case
alias CPSolver.ConstraintStore
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Variable.Interface
alias CPSolver.DefaultDomain, as: Domain
alias CPSolver.Propagator
alias CPSolver.Propagator.Circuit
describe "Propagator filtering" do
test "fixed variables: valid circuit" do
valid_circuit = [2, 3, 4, 0, 5, 1]
result = filter(valid_circuit)
refute result.active?
end
test "fails on invalid circuit" do
invalid_circuits =
[
[1, 2, 3, 4, 5, 2],
[1, 2, 0, 4, 5, 3]
]
Enum.all?(invalid_circuits, fn circuit ->
:fail ==
try do
filter(circuit)
catch
x -> x
end
end)
end
test "domains are cut accordingly on initialization" do
n = 10
domains = Enum.map(0..(n - 1), fn _idx -> -n..n end)
propagator = make_propagator(domains)
Propagator.filter(propagator)
## args of a propagator are bounded variables
assert_initial_reduction(propagator)
end
test "filtering" do
domains = [0..2, 0..2, 0..2]
propagator = make_propagator(domains)
[x0, x1, x2] = propagator.args
res1 = Propagator.filter(propagator)
assert_initial_reduction(propagator)
## Make x1 to be successor of x0
Interface.fix(x0, 1)
propagator1 = propagator |> Map.put(:state, res1.state)
_res2 = Propagator.filter(propagator1)
## x0 is now a successor of x2
assert Interface.fixed?(x2)
assert Interface.min(x2) == 0
## x1 is also fixed
assert Interface.fixed?(x1)
end
end
defp filter(domains) do
domains
|> make_propagator()
|> Propagator.filter()
end
defp make_propagator(domains) do
variables =
Enum.map(Enum.with_index(domains), fn {d, idx} -> Variable.new(d, name: "x#{idx}") end)
{:ok, x_vars, _store} = ConstraintStore.create_store(variables)
Circuit.new(x_vars)
end
defp assert_initial_reduction(propagator) do
n = length(propagator.args)
assert Enum.all?(
Enum.with_index(propagator.args),
fn {var, idx} ->
domain = Interface.domain(var) |> Domain.to_list()
MapSet.new(domain) == MapSet.new(0..(n - 1)) |> MapSet.delete(idx)
end
)
end
end