Current section

Files

Jump to
fixpoint test cpsolver_test.exs
Raw

test/cpsolver_test.exs

defmodule CpSolverTest do
use ExUnit.Case
alias CPSolver.IntVariable
alias CPSolver.Constraint.NotEqual
test "Solves CSP with 2 variables and a single constraint" do
x = IntVariable.new([1, 2])
y = IntVariable.new([0, 1])
model = %{
variables: [x, y],
constraints: [{NotEqual, x, y}]
}
{:ok, solver} = CPSolver.solve(model)
Process.sleep(100)
assert CPSolver.statistics(solver).failure_count == 0
## Note: there are 2 "first fail" distributions:
## 1. Variable 'x' triggers distribution into 2 spaces - (x: 1, y: [0, 1]) and (x: 2, y: [0, 1])).
## 2. First space produces solution (x: 1, y: 0)
## 3. Second space triggers distribution into 2 spaces - (x: 2, y: 0) and (x: 2, y: 1)
## 4. These 2 spaces produce remaining solutions.
## 5. There have been 5 spaces - top one, and 4 as described above, which corresponds
## to 5 nodes.
assert CPSolver.statistics(solver).node_count == 5
assert CPSolver.statistics(solver).solution_count == 3
solver_state = :sys.get_state(solver)
solutions =
Enum.map(solver_state.solutions, fn solution ->
Enum.map(solution, fn {_ref, value} -> value end)
end)
|> Enum.sort_by(fn [x, y] -> x + y end)
assert solutions == [[1, 0], [2, 0], [2, 1]]
end
test "Stops on max_solutions reached" do
max_solutions = 1
{:ok, solver} = CPSolver.Examples.Queens.solve(5, stop_on: {:max_solutions, max_solutions})
Process.sleep(500)
assert CPSolver.statistics(solver).solution_count == max_solutions
end
end