Packages
fixpoint
0.5.12
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/variables/view.ex
defmodule CPSolver.Variable.View do
alias CPSolver.Variable
alias CPSolver.DefaultDomain, as: Domain
alias __MODULE__, as: View
defstruct [:view, :variable]
@type t :: %__MODULE__{
view: function(),
variable: Variable.t()
}
@doc """
Configures (ax + b) view on variable x.
`mapper_fun` maps view values back to the source variable;
returns nil if there is no mapping.
"""
@spec new(Variable.t(), neg_integer() | pos_integer(), integer()) :: View.t()
def new(variable, a, b) do
mapper_fun = fn
## Given value from variable domain, returns mapped value from view domain
value when is_integer(value) ->
a * value + b
## Given value from view domain, returns mapped value from variable domain,
## or nil, if no mapping exists.
{value, :reverse} when is_integer(value) ->
(rem(value - b, a) == 0 && div(value - b, a)) || nil
## (Used by removeAbove and removeBelow operations)
## Given value from view domain, computes the closest integer value
## implied by mapping function, and the operation to be applied.
{value, :above} when a > 0 ->
{floor((value - b) / a), :removeAbove}
{value, :above} when a < 0 ->
{ceil(value - b) / a, :removeBelow}
{value, :below} when a > 0 ->
{ceil((value - b) / a), :removeBelow}
{value, :below} when a < 0 ->
{floor((value - b) / a), :removeAbove}
## Used by min and max to decide if the operation has to be flipped
:flip? ->
a < 0
## Guard from exceptions when performing chained operations
:fail ->
:fail
end
%View{variable: variable, view: mapper_fun}
end
def domain(%{view: mapper_fun, variable: variable} = _view) do
Variable.domain(variable)
|> Domain.map(mapper_fun)
end
def size(%{variable: variable} = _view) do
Variable.size(variable)
end
def fixed?(%{variable: variable} = _view) do
Variable.fixed?(variable)
end
def min(%{view: mapper_fun, variable: variable} = _view) do
domain_value = (mapper_fun.(:flip?) && Variable.max(variable)) || Variable.min(variable)
mapper_fun.(domain_value)
end
def max(%{view: mapper_fun, variable: variable} = _view) do
domain_value = (mapper_fun.(:flip?) && Variable.min(variable)) || Variable.max(variable)
mapper_fun.(domain_value)
end
def contains?(%{view: mapper_fun, variable: variable} = _view, value) do
source_value = mapper_fun.({value, :reverse})
source_value && Variable.contains?(variable, source_value)
end
def remove(%{view: mapper_fun, variable: variable} = _view, value) do
source_value = mapper_fun.({value, :reverse})
(source_value && Variable.remove(variable, source_value)) || :no_change
end
def fix(%{view: mapper_fun, variable: variable} = _view, value) do
source_value = mapper_fun.({value, :reverse})
(source_value && Variable.fix(variable, source_value)) || :fail
end
def removeAbove(%{view: mapper_fun, variable: variable} = _view, value) do
{source_value, operation} = mapper_fun.({value, :above})
apply(Variable, operation, [variable, source_value])
end
def removeBelow(%{view: mapper_fun, variable: variable} = _view, value) do
{source_value, operation} = mapper_fun.({value, :below})
apply(Variable, operation, [variable, source_value])
end
end
defmodule CPSolver.Variable.View.Factory do
import CPSolver.Variable.View
alias CPSolver.Variable
def minus(%Variable{} = var) do
mul(var, -1)
end
def mul(%Variable{} = var, coefficient) do
linear(var, coefficient, 0)
end
def linear(%Variable{} = var, coefficient, offset)
when is_integer(coefficient) and
is_integer(offset) and
coefficient != 0 do
new(var, coefficient, offset)
end
end