Packages
fixpoint
0.15.2
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
lib/solver/constraints/propagators/abs.ex
defmodule CPSolver.Propagator.Absolute do
use CPSolver.Propagator
def new(x, y) do
new([x, y])
end
@impl true
def variables(args) do
args
|> Propagator.default_variables_impl()
|> Enum.map(fn var -> set_propagate_on(var, :bound_change) end)
end
@impl true
def filter([x, y] = args, state, changes) do
((state && map_size(changes) > 0) || initial_reduction(x, y)) && filter_impl(x, y, changes)
cond do
failed?(args) ->
throw(:fail)
entailed?(args) ->
:passive
true ->
{:state, %{active: true}}
end
end
@impl true
def failed?([x, y], _state \\ nil) do
max_y = max(y)
max(y) < 0 ||
(
{abs_min_x, abs_max_x} =
Enum.min_max_by(domain_values(x), fn val -> abs(val) end)
|> then(fn {min_val, max_val} -> {abs(min_val), abs(max_val)} end)
min_y = max(0, min(y))
abs_min_x > max_y || abs_max_x < min_y
)
end
@impl true
def entailed?([x, y], _state \\ nil) do
## x and y have to be fixed...
## y = |x|
fixed?(x) && fixed?(y) && abs(min(x)) == min(y)
end
def filter_impl(x, y, changes) do
## x and y have 0 and 1 indices in the list of args
x_idx = 0
y_idx = 1
Enum.each(
changes,
fn
{idx, _change} when idx == x_idx ->
abs_min_x = abs(min(x))
abs_max_x = abs(max(x))
abs_x_lb = min(abs_min_x, abs_max_x)
abs_x_ub = max(abs_min_x, abs_max_x)
removeBelow(y, min(min(y), abs_x_lb))
removeAbove(y, max(max(y), abs_x_ub))
{idx, _change} when idx == y_idx ->
y_min = min(y)
y_max = max(y)
cond do
min(x) >= 0 ->
removeBelow(x, y_min)
removeAbove(x, y_max)
max(x) <= 0 ->
:ok
removeBelow(x, -y_max)
removeAbove(x, -y_min)
true ->
removeAbove(x, y_max)
removeBelow(x, -y_max)
end
{_idx, _change} ->
:ignore
end
)
fixed?(x) && fix(y, abs(min(x)))
fixed?(y) && fix_abs(x, min(y))
end
defp initial_reduction(x, y) do
## y is non-negative
removeBelow(y, 0)
filter_impl(x, y, %{0 => :domain_change, 1 => :domain_change})
end
defp fix_abs(x, value) do
Enum.each(domain_values(x), fn val -> abs(val) != value && remove(x, val) end)
end
end
defmodule CPSolver.Propagator.AbsoluteNotEqual do
use CPSolver.Propagator
alias CPSolver.Propagator.Absolute
def new(x, y) do
new([x, y])
end
@impl true
defdelegate variables(args), to: Absolute
@impl true
def filter([x, y], _state, _changes) do
filter_impl(x, y)
end
def filter_impl(x, c) when is_integer(c) do
remove(x, c)
remove(x, -c)
:passive
end
def filter_impl(x, y) do
cond do
fixed?(x) ->
remove(y, abs(min(x)))
:passive
fixed?(y) ->
y_val = min(y)
remove(x, y_val)
remove(x, -y_val)
:passive
true ->
{:state, %{active: true}}
end
end
@impl true
def failed?(args, state) do
Absolute.entailed?(args, state)
end
@impl true
def entailed?(args, state) do
Absolute.failed?(args, state)
end
end