defmodule CPSolver.Propagator do
@callback filter(args :: list()) :: map() | :stable | :failure
@callback variables(args :: list()) :: list()
@callback events() :: list()
alias CPSolver.Variable
defmacro __using__(_) do
quote do
@behaviour CPSolver.Propagator
def variables(args) do
args
end
## Events that trigger propagation
def events() do
CPSolver.Common.domain_changes()
end
defoverridable variables: 1
defoverridable events: 0
end
end
def normalize(propagators, store, store_impl) when is_list(propagators) do
propagators
|> Enum.map(fn p -> normalize(p, store, store_impl) end)
|> Enum.uniq()
end
def normalize({mod, args} = _propagator, store, store_impl) when is_list(args) do
{mod,
Enum.map(
args,
fn
%Variable{} = arg ->
arg
|> Map.put(:store, store)
|> Map.put(:store_impl, store_impl)
const ->
const
end
)}
end
def normalize(propagator, store, store_impl) when is_tuple(propagator) do
[mod | args] = Tuple.to_list(propagator)
normalize({mod, args}, store, store_impl)
end
def filter(mod, args) do
mod.filter(args)
end
end