Packages
fixpoint
0.3.1
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/space/space_test.exs
defmodule CPSolverTest.Space do
use ExUnit.Case
import ExUnit.CaptureLog
import CPSolver.Test.Helpers
describe "Computation space" do
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Space, as: Space
alias CPSolver.Propagator.NotEqual
alias CPSolver.Solution
setup do
Logger.configure(level: :debug)
on_exit(fn -> Logger.configure(level: :error) end)
end
test "create space" do
x_values = 1..10
y_values = -5..5
z_values = 0..2
values = [x_values, y_values, z_values]
[x, y, z] = variables = Enum.map(values, fn d -> Variable.new(d) end)
propagators = [{NotEqual, [x, y]}, {NotEqual, [y, z]}]
{:ok, space} = Space.create(variables, propagators)
# Process.sleep(1)
{state, %{variables: space_variables, propagator_threads: threads} = _data} =
Space.get_state_and_data(space)
assert state == :propagating
assert length(propagators) == map_size(threads)
assert length(variables) == length(space_variables)
thread_pids =
Enum.map(threads, fn {_id, thread} -> thread.thread end)
assert Enum.all?(thread_pids, fn pid -> is_pid(pid) end)
end
test "stable space" do
%{space: space} = create_stable_space()
Process.sleep(100)
refute Process.alive?(space)
solutions =
Enum.map(1..2, fn _ ->
receive do
{:solution, sol} -> sol
end
end)
node_creations =
Enum.reduce(1..1, 0, fn _, acc ->
receive do
{:nodes, nodes} -> length(nodes) + acc
end
end)
# For all solutions, constraints (x != y and y != z) are satisfied.
assert Enum.all?(solutions, fn variables ->
[x, y, z] = Enum.map(variables, fn {_id, value} -> value end)
x != y && y != z
end)
assert node_creations == 2
end
test "solved space" do
%{space: space} = create_solved_space()
Process.sleep(10)
{state, %{variables: space_variables} = _data} = Space.get_state_and_data(space)
assert state == :solved
## Check if all space variables are fixed
assert Enum.all?(space_variables, fn var -> Variable.fixed?(var) end)
end
test "failing space" do
x_values = 1..1
y_values = 1..2
z_values = 2..2
values = [x_values, y_values, z_values]
[x, y, z] = variables = Enum.map(values, fn d -> Variable.new(d) end)
propagators = [{NotEqual, [x, y]}, {NotEqual, [y, z]}]
{:ok, space} = Space.create(variables, propagators)
Process.sleep(10)
refute Process.alive?(space)
end
test "solution handler as function" do
target_pid = self()
## The solution will be send to the current process
solution_handler = fn solution ->
send(target_pid, Enum.sort_by(solution, fn {var, _value} -> var end))
end
## Create a space with the solution handler as a function
%{variables: space_variables} =
create_solved_space(solution_handler: solution_handler)
Process.sleep(10)
## Check the solution against the store
store_vars =
Enum.map(space_variables, fn v -> {v.id, Variable.min(v)} end)
|> Enum.sort_by(fn {var, _value} -> var end)
assert_receive ^store_vars, 10
end
test "solution handler as a module" do
solution_handler = Solution.default_handler()
## Create a space with the solution handler as a function
log =
capture_log([level: :debug], fn ->
_ = create_solved_space(solution_handler: solution_handler)
Process.sleep(10)
end)
assert log =~ "Solution found"
assert number_of_occurences(log, "<- 2") == 2
assert number_of_occurences(log, "<- 1") == 1
end
defp create_solved_space(space_opts \\ []) do
x_values = 1..2
y_values = 1..1
z_values = 1..2
values = [x_values, y_values, z_values]
[x, y, z] = variables = Enum.map(values, fn d -> Variable.new(d) end)
propagators = [{NotEqual, [x, y]}, {NotEqual, [y, z]}]
{:ok, space} =
Space.create(variables, propagators, Keyword.put(space_opts, :keep_alive, true))
{_, space_data} = :sys.get_state(space)
%{space: space, propagators: propagators, variables: space_data.variables}
end
defp create_stable_space(space_opts \\ []) do
x_values = 1..2
y_values = 1..2
z_values = 1..2
values = [x_values, y_values, z_values]
[x, y, z] = variables = Enum.map(values, fn d -> Variable.new(d) end)
propagators = [{NotEqual, [x, y]}, {NotEqual, [y, z]}]
{:ok, space} = Space.create(variables, propagators, space_opts)
{_, space_data} = :sys.get_state(space)
%{space: space, propagators: propagators, variables: space_data.variables, domains: values}
end
end
end