Current section

Files

Jump to
fixpoint test space space_propagation_test.exs
Raw

test/space/space_propagation_test.exs

defmodule CPSolverTest.SpacePropagation do
use ExUnit.Case
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Propagator.NotEqual
alias CPSolver.ConstraintStore
alias CPSolver.Space.Propagation
alias CPSolver.Propagator.ConstraintGraph
test "Propagation on stable space" do
%{propagators: propagators, variables: [_x, y, _z] = variables} = stable_setup()
{:stable, constraint_graph, stable_propagators} = Propagation.run(propagators, variables)
assert Graph.num_vertices(constraint_graph) == 3
assert map_size(stable_propagators) == 2
assert [y] ==
Enum.filter(variables, fn var ->
Graph.has_vertex?(constraint_graph, {:variable, var.id})
end)
## Variables in constraint graph in stable state are unfixed
refute Variable.fixed?(y)
propagators_from_graph =
Enum.flat_map(
Graph.vertices(constraint_graph),
fn
{:propagator, id} -> [ConstraintGraph.get_propagator(constraint_graph, id)]
_ -> []
end
)
assert length(propagators_from_graph) == 2
propagator_vars_in_graph =
Enum.map(propagators_from_graph, fn {_id, %{mod: NotEqual, args: vars}} = _v ->
Enum.map(vars, fn v -> v.name end)
end)
## Both propagators in constraint graph have "y" variable
assert Enum.all?(propagator_vars_in_graph, fn vars -> "y" in vars end)
## Stable propagators are the same as the ones in constraint graph
assert Enum.sort_by(propagators_from_graph, fn {id, _propagator} -> id end) ==
Enum.sort_by(stable_propagators, fn {id, _propagator} -> id end)
end
test "Propagation on solvable space" do
%{propagators: propagators, variables: variables} = solved_setup()
refute Enum.all?(variables, fn var -> Variable.fixed?(var) end)
assert :solved == Propagation.run(propagators, variables)
assert Enum.all?(variables, fn var -> Variable.fixed?(var) end)
end
test "Propagation on failed space" do
%{propagators: propagators, variables: variables} = fail_setup()
assert :fail == Propagation.run(propagators, variables)
end
defp stable_setup() do
x = 1..1
y = -5..5
z = 0..1
space_setup(x, y, z)
end
defp solved_setup() do
x = 1..1
y = 0..2
z = 0..1
space_setup(x, y, z)
end
defp fail_setup() do
x = 1..1
y = 0..1
z = 0..1
space_setup(x, y, z)
end
defp space_setup(x, y, z) do
variables =
Enum.map([{x, "x"}, {y, "y"}, {z, "z"}], fn {d, name} -> Variable.new(d, name: name) end)
{:ok, [x_var, y_var, z_var] = bound_vars, _store} =
ConstraintStore.create_store(variables)
propagators =
Enum.map(
[{x_var, y_var}, {y_var, z_var}, {x_var, z_var}],
fn {v1, v2} -> NotEqual.new([v1, v2]) end
)
%{propagators: propagators, variables: bound_vars}
end
end