Packages
fixpoint
0.3.6
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/propagators/not_equal_test.exs
defmodule CPSolverTest.Propagator.NotEqual do
use ExUnit.Case
describe "Propagator filtering" do
alias CPSolver.ConstraintStore
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Propagator.Variable, as: PropagatorVariable
alias CPSolver.Propagator.Thread, as: PropagatorThread
alias CPSolver.Propagator.NotEqual
test "filtering, unfixed domains" do
## Both vars are unfixed
x = 1..10
y = -5..5
variables = Enum.map([x, y], fn d -> Variable.new(d) end)
{:ok, bound_vars, _store} = ConstraintStore.create_store(variables)
assert :stable == NotEqual.filter(bound_vars)
assert PropagatorVariable.get_variable_ops() == %{}
[x_var, y_var] = bound_vars
## Fix one of vars
assert :fixed = Variable.fix(x_var, 5)
assert :domain_change == NotEqual.filter(bound_vars)
assert PropagatorVariable.get_variable_ops() == %{y_var.id => :domain_change}
## The filtering should have removed '5' from y_var
assert Variable.max(y_var) == 4
assert Variable.min(y_var) == -5
## Fix second var and filter again
assert :fixed == Variable.fix(y_var, 4)
assert :no_change == NotEqual.filter(bound_vars)
assert PropagatorVariable.get_variable_ops() == %{y_var.id => :no_change}
## Make sure filtering doesn't fail on further calls
refute Enum.any?(
[x_var, y_var],
fn var -> :fail == Variable.min(var) end
)
## Consequent filtering does not trigger domain change events
assert :no_change == NotEqual.filter(bound_vars)
end
test "inconsistency" do
x = 0..0
y = 0..0
[_x_var, y_var] = variables = Enum.map([x, y], fn d -> Variable.new(d) end)
{:ok, bound_vars, _store} = ConstraintStore.create_store(variables)
assert :fail == NotEqual.filter(bound_vars)
assert PropagatorVariable.get_variable_ops() == {:fail, y_var.id}
## One of variables (depending on filtering implementation) will fail
assert Enum.any?(
bound_vars,
fn var -> :fail == Variable.fixed?(var) end
)
end
test "offset" do
x = 5..5
y = -5..10
variables = Enum.map([x, y], fn d -> Variable.new(d) end)
{:ok, [x_var, y_var], _store} = ConstraintStore.create_store(variables)
assert Variable.contains?(y_var, 0)
# (x != y + 5)
offset = 5
NotEqual.filter(x_var, y_var, offset)
refute Variable.contains?(y_var, 0)
# (x != y - 5)
offset = -5
assert Variable.contains?(y_var, 10)
NotEqual.filter(x_var, y_var, offset)
refute Variable.contains?(y_var, 10)
end
test "propagates only when variables become fixed" do
## Both vars are unfixed
x = 1..2
y = 0..1
variables = Enum.map([x, y], fn d -> Variable.new(d) end)
{:ok, [x_var, y_var] = _bound_vars, store} =
ConstraintStore.create_store(variables, space: nil)
{:ok, _propagator_thread} =
PropagatorThread.create_thread(self(), {NotEqual, variables}, store: store)
Process.sleep(5)
assert 1 == Variable.min(x_var)
## Triggers the filtering; 'x' variable will have '1' removed
_domain_change = Variable.fix(y_var, 1)
Process.sleep(5)
assert 2 == Variable.min(x_var)
end
end
end