Packages
fixpoint
0.8.41
0.22.2
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/propagator_test.exs
defmodule CPSolverTest.Propagator do
use ExUnit.Case
describe "Propagator general" do
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Variable.Interface
alias CPSolver.Propagator.{NotEqual, LessOrEqual}
alias CPSolver.ConstraintStore
alias CPSolver.Propagator
import CPSolver.Test.Helpers
import CPSolver.Variable.View.Factory
test ":fixed? flag for propagator variables" do
x = Variable.new(1..2)
y = Variable.new(1..1)
propagator = LessOrEqual.new([x, y])
[p_x, p_y] = propagator.args
refute p_x.fixed?
assert p_y.fixed?
end
test "filtering with variables bound to a store" do
%{bound_variables: bound_variables, store: store} =
setup_store([1..1, 1..2])
[x_bound, y_bound] = bound_variables
refute Variable.fixed?(y_bound)
assert Variable.fixed?(x_bound)
propagator = NotEqual.new(bound_variables)
assert %{changes: %{y_bound.id => :fixed}, active?: false, state: nil} ==
Propagator.filter(propagator)
assert ConstraintStore.get(store, y_bound, :fixed?)
end
test "Using views" do
x = 1..10
y = 0..10
variables = Enum.map([x, y], fn d -> Variable.new(d) end)
{:ok, bound_vars, _store} =
create_store(variables)
[x_var, y_var] = bound_vars
## Make 'minus' view
minus_y_view = minus(y_var)
## Inconsistency: no solution to x <= -y
##
## The propagator will fail on one of the variables
assert :fail = Propagator.filter(LessOrEqual.new(x_var, minus_y_view))
end
test "dry run (reduction)" do
# `dry_run` option tests the result of the propagator filtering,
# but does not change space variables
%{bound_variables: bound_variables} =
setup_store([1..1, 1..2])
[x_bound, y_bound] = bound_variables
assert Variable.fixed?(x_bound)
refute Variable.fixed?(y_bound)
propagator = NotEqual.new(bound_variables)
## Dry-run first
{_p_copy, dry_run_result} = Propagator.dry_run(propagator)
assert dry_run_result == %{changes: %{y_bound.id => :fixed}, active?: false, state: nil}
# Store variables didn't change
assert Variable.fixed?(x_bound)
refute Variable.fixed?(y_bound)
## Real run now
real_run_result = Propagator.filter(propagator)
## The results of dry run vs. real run
assert dry_run_result == real_run_result
## Variables are fixed, as expected
assert Variable.fixed?(x_bound)
assert Variable.fixed?(y_bound)
end
test "dry run (inconsistency, view)" do
x = 1..10
y = 0..10
variables = Enum.map([x, y], fn d -> Variable.new(d) end)
{:ok, bound_vars, _store} =
create_store(variables)
[x_var, y_var] = bound_vars
minus_y_view = minus(y_var)
{_p_copy, res} = Propagator.dry_run(LessOrEqual.new(x_var, minus_y_view))
## Should fail, because `minus` view turns `y` domain to -10..0
assert res == :fail
## ...but the domains of variables stay intact
assert 10 == Interface.size(x_var) && (11 = Interface.size(y_var))
## Now, filter for real
assert :fail == Propagator.filter(LessOrEqual.new(x_var, minus_y_view))
## At least one variable is now in :fail state
assert catch_throw(10 == Interface.size(x_var) && (11 = Interface.size(y_var))) == :fail
end
defp setup_store(domains) do
variables = Enum.map(domains, fn d -> Variable.new(d) end)
{:ok, bound_variables, store} = create_store(variables)
%{variables: variables, bound_variables: bound_variables, store: store}
end
end
end