Packages
fixpoint
0.8.32
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
alias CPSolver.DefaultDomain, as: Domain
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(args) do
filter(args, nil)
end
@impl true
def filter([x, y], state, changes) do
(state && filter_impl(x, y, changes)) || initial_reduction(x, y)
{:state, %{}}
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
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(x) |> Domain.to_list(), fn val -> abs(val) != value && remove(x, val) end)
end
end