Current section

Files

Jump to
fixpoint test space space_propagation2_test._exs
Raw

test/space/space_propagation2_test._exs

defmodule CPSolverTest.SpacePropagation2 do
use ExUnit.Case
alias CPSolver.IntVariable, as: Variable
alias CPSolver.DefaultDomain, as: Domain
alias CPSolver.Propagator.NotEqual
alias CPSolver.Space.Propagation2, as: Propagation
alias CPSolver.Propagator
alias CPSolver.Propagator.ConstraintGraph
import CPSolver.Test.Helpers
test "Propagation on stable space" do
%{
propagators: propagators,
variables: [x, y, z] = variables,
constraint_graph: graph,
store: store
} = stable_setup()
{:stable, constraint_graph} = Propagation.run(graph, propagators, store: store)
assert Enum.all?([x, z], fn v -> Variable.fixed?(v) end)
#assert Graph.num_vertices(constraint_graph) == 3
assert [y] ==
Enum.filter(variables, fn var ->
Graph.has_vertex?(constraint_graph, {:variable, var.id})
end)
## In stable state, variables referenced in constraint graph 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
)
IO.inspect(constraint_graph, label: :graph)
IO.inspect(Enum.map(propagators_from_graph, fn p -> {p.id, p.name} end), label: :propagators)
IO.inspect(Enum.map(variables, fn v -> {v.name, Variable.domain(v) |> Domain.to_list()} end), label: :variables)
assert length(propagators_from_graph) == 2
propagator_vars_in_graph =
Enum.map(propagators_from_graph, fn %{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)
end
test "Propagation on solvable space" do
%{propagators: propagators, variables: variables, constraint_graph: graph, store: store} =
solved_setup()
refute Enum.all?(variables, fn var -> Variable.fixed?(var) end)
assert :solved == Propagation.run(propagators, graph, store)
assert Enum.all?(variables, fn var -> Variable.fixed?(var) end)
end
test "Propagation on failed space" do
%{propagators: propagators, constraint_graph: graph, store: store} = fail_setup()
assert :fail == Propagation.run(graph, propagators, store)
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, bound_vars, store} =
create_store(variables)
[x_var, y_var, z_var] = bound_vars
propagators =
Enum.map(
[{x_var, y_var, "x != y"}, {y_var, z_var, "y != z"}, {x_var, z_var, "x != z"}],
fn {v1, v2, name} -> Propagator.new(NotEqual, [v1, v2], name: name) end
)
graph = ConstraintGraph.create(propagators)
{updated_graph, _bound_propagators} = ConstraintGraph.update(graph, bound_vars)
%{
propagators: propagators,
variables: bound_vars,
constraint_graph: updated_graph,
store: store
}
end
end