Current section

Files

Jump to
fixpoint test constraints or_test.exs
Raw

test/constraints/or_test.exs

defmodule CPSolverTest.Constraint.Or do
use ExUnit.Case, async: false
alias CPSolver.BooleanVariable
alias CPSolver.Model
alias CPSolver.Constraint.Or
import CPSolver.Variable.View.Factory
describe "Or constraint" do
test "`or` functionality" do
bool_vars = Enum.map(1..4, fn i -> BooleanVariable.new(name: "b#{i}") end)
or_constraint = Or.new(bool_vars)
model = Model.new(bool_vars, [or_constraint])
{:ok, result} = CPSolver.solve(model)
assert result.statistics.solution_count == 15
assert_or(result.solutions, length(bool_vars))
end
test "inconsistency (all-false)" do
bool_vars = List.duplicate(0, 4)
or_constraint = Or.new(bool_vars)
assert catch_throw({:fail, _} = Model.new(bool_vars, [or_constraint]))
end
test "with negation vars" do
x = BooleanVariable.new(name: "x")
not_y = negation(BooleanVariable.new(name: "y"))
vars = [x, not_y]
or_constraint = Or.new(vars)
model = Model.new(vars, [or_constraint])
{:ok, result} = CPSolver.solve(model)
assert [0, 0] in result.solutions
end
test "peformance" do
n = 1000
bool_vars = Enum.map(1..n, fn i -> BooleanVariable.new(name: "b#{i}") end)
or_constraint = Or.new(bool_vars)
model = Model.new(bool_vars, [or_constraint])
{:ok, res} =
CPSolver.solve(model,
stop_on: {:max_solutions, 1},
search: {:first_fail, :indomain_max},
space_threads: 1
)
assert res.statistics.solution_count >= 1
## Arbitrary elapsed time, the main point it shouldn't be too big
assert res.statistics.elapsed_time < 250_000
end
defp assert_or(solutions, array_len) do
assert Enum.all?(solutions, fn solution ->
arr = Enum.take(solution, array_len)
Enum.sum(arr) > 0
end)
end
end
end