Packages
fixpoint
0.3.5
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/propagators/propagator.ex
defmodule CPSolver.Propagator do
@type propagator_event :: :domain_change | :bound_change | :min_change | :max_change
@callback filter(args :: list()) :: map() | :stable | :failure
@callback variables(args :: list()) :: list()
@callback events() :: list()
alias CPSolver.Variable
alias CPSolver.Propagator.Variable, as: PropagatorVariable
defmacro __using__(_) do
quote do
@behaviour CPSolver.Propagator
def variables(args) do
args
end
## Events that trigger propagation
def events() do
CPSolver.Common.domain_events()
end
defoverridable variables: 1
defoverridable events: 0
end
end
def normalize(propagators, store) when is_list(propagators) do
propagators
|> Enum.map(fn p -> normalize(p, store) end)
|> Enum.uniq()
end
def normalize({mod, args} = _propagator, store) when is_list(args) do
{mod,
Enum.map(
args,
fn
%Variable{} = arg ->
arg
|> Map.put(:store, store)
const ->
const
end
)}
end
def normalize(propagator, store) when is_tuple(propagator) do
[mod | args] = Tuple.to_list(propagator)
normalize({mod, args}, store)
end
def filter(mod, args) do
PropagatorVariable.reset_variable_ops()
case mod.filter(args) do
:stable ->
:stable
_res ->
## If propagator doesn't explicitly return 'stable',
## we retrieve the map of variable operations created by PropagatorVariable wrapper
case PropagatorVariable.get_variable_ops() do
{:fail, var} ->
{:fail, var}
op_results when is_map(op_results) ->
process_op_changes(op_results)
end
end
end
## How domain events map to propagator events
## (see Propagator.events() callback).
def to_domain_events(:domain_change) do
[:domain_change, :min_change, :max_change, :fixed]
end
def to_domain_events(:bound_change) do
[:min_change, :max_change, :fixed]
end
def to_domain_events(:min_change) do
[:min_change, :fixed]
end
def to_domain_events(:max_change) do
[:max_change, :fixed]
end
def to_domain_events(:fixed) do
[:fixed]
end
@spec process_op_changes(%{reference() => atom()}) ::
:stable | {:changed, [{atom(), reference()}]}
defp process_op_changes(op_results) do
op_results
|> Enum.flat_map(fn {var, result} ->
(result == :no_change && []) || [{result, var}]
end)
|> then(fn changes -> (changes == [] && :stable) || {:changed, changes} end)
end
end