Packages
fixpoint
0.2.1
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/store/store.ex
defmodule CPSolver.ConstraintStore do
@moduledoc """
Constraint store is a key-value store, where `key` is a variable id,
and `value` is a implementation-dependent structure that allows to
update and keep track of variables' domains.
"""
#################
alias CPSolver.Common
alias CPSolver.Variable
@type get_operation :: Common.domain_get_operation() | nil
@type update_operation :: Common.domain_update_operation()
def default_store() do
CPSolver.Store.Registry
end
### Callbacks
## Tell basic constraints (a.k.a, domains) to a constraint store
@callback create(variables :: Enum.t(), opts :: Keyword.t()) ::
{:ok, Enum.t(), any()} | {:error, any()}
## Get variable details
@callback get(store :: any(), variable :: Variable.t(), get_operation(), [any()]) ::
{:ok, any()} | {:error, any()}
@callback update(store :: any(), variable :: Variable.t(), update_operation(), [any()]) ::
any()
@callback update_domain(store :: any(), variable :: Variable.t(), update_operation(), [any()]) ::
any()
@callback dispose(store :: any(), variables :: [Variable.t()]) :: :ok | :not_found
@callback domain(store :: any(), variable :: Variable.t()) :: {:ok, any()} | {:error, any()}
@callback on_fail(variable :: Variable.t()) :: any()
@callback on_no_change(variable :: Variable.t()) :: any()
@callback on_change(
variable :: Variable.t(),
change :: :fixed | :min_change | :max_change | :domain_change
) :: any()
@callback get_variables(store :: any()) :: [any()]
### API
defmacro __using__(_) do
quote do
@behaviour CPSolver.ConstraintStore
@domain_changes CPSolver.Common.domain_changes()
require Logger
def update(store, variable, operation, args) do
update_domain(store, variable, operation, args)
|> tap(fn
:fail -> on_fail(variable)
:no_change -> on_no_change(variable)
change when change in @domain_changes -> on_change(variable, change)
end)
end
def on_change(var, domain_change) do
publish(var, domain_change)
|> tap(fn _ ->
Logger.debug("Domain change (#{domain_change}) for #{inspect(var.id)}")
maybe_unsubscribe_all(domain_change, var)
end)
end
def on_fail(var) do
Logger.debug("Failure for variable #{inspect(var.id)}")
## TODO: notify space (and maybe don't notify propagators)
publish(var, :fail)
end
def on_no_change(_var) do
:ok
end
defp publish(variable, event) do
Variable.publish(variable, {event, variable.id})
end
defp maybe_unsubscribe_all(:fixed, var) do
Enum.each(Variable.subscribers(var), fn pid -> Variable.unsubscribe(pid, var) end)
end
defp maybe_unsubscribe_all(_, _var) do
:ok
end
defoverridable update: 4
defoverridable on_change: 2
defoverridable on_fail: 1
defoverridable on_no_change: 1
end
end
end