Skip to content

Commit

Permalink
fix doc
Browse files Browse the repository at this point in the history
  • Loading branch information
yangeorget committed Sep 30, 2024
1 parent 2dbb5f6 commit b35765f
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 48 deletions.
6 changes: 6 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
tls_verify = False

extensions = [
'sphinx.ext.linkcode',
'sphinx.ext.duration',
'sphinx.ext.doctest',
'sphinx.ext.autodoc',
Expand Down Expand Up @@ -44,3 +45,8 @@
# -- Options for EPUB output
epub_show_urls = 'footnote'

def linkcode_resolve(domain, info):
if domain != 'py' or not info['fullname']:
return None
filename = info['fullname'].replace('.', '/')
return f"https://github.com/yangeorget/nucs/tree/main/{filename}.py"
205 changes: 187 additions & 18 deletions docs/source/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,193 @@ Propagators

NUCS currently provides the following highly-optimized propagators.

==================================== ============================================== ========================
Name Definition Complexity
==================================== ============================================== ========================
:code:`affine_eq_propagator` :math:`\Sigma_i a_i \times x_i = a_{n-1}` :math:`n`
:code:`affine_geq_propagator` :math:`\Sigma_i a_i \times x_i \geq a_{n-1}` :math:`n`
:code:`affine_leq_propagator` :math:`\Sigma_i a_i \times x_i \leq a_{n-1}` :math:`n`
:code:`alldifferent_propagator` :math:`\forall i, j, x_i \neq x_j` :math:`n \times log(n)`
:code:`count_eq_propagator` :math:`\Sigma_i (x_i = a) = x_{n-1}` :math:`n`
:code:`element_lic_propagator` :math:`l_i = c` :math:`n`
:code:`element_liv_propagator` :math:`l_i = x` :math:`n`
:code:`exactly_eq_propagator` :math:`\Sigma_i (x_i = a_0) = a_1` :math:`n`
:code:`lexicographic_leq_propagator` :math:`x \leq_{lex} y` :math:`n`
:code:`max_eq_propagator` :math:`\max_i x_i = x_{n-1}` :math:`n`
:code:`max_leq_propagator` :math:`\max_i x_i \leq x_{n-1}` :math:`n`
:code:`min_eq_propagator` :math:`\min_i x_i = x_{n-1}` :math:`n`
:code:`min_geq_propagator` :math:`\min_i x_i \geq x_{n-1}` :math:`n`
:code:`relation_propagator` Relation defined in extension :math:`n`
==================================== ============================================== ========================

.. py:function:: nucs.propagators.affine_eq_propagator(domains, parameters)
This propagator implements the relation :math:`\Sigma_{i \in [0, n-1[} a_i \times x_i = a_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables, :math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, :math:`a` is an alias for parameters
:type parameters: NDArray


.. py:function:: nucs.propagators.affine_geq_propagator(domains, parameters)
This propagator implements the relation :math:`\Sigma_{i \in [0, n-1[} a_i \times x_i \geq a_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables, :math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, :math:`a` is an alias for parameters
:type parameters: NDArray


.. py:function:: nucs.propagators.affine_leq_propagator(domains, parameters)
This propagator implements the relation :math:`\Sigma_{i \in [0, n-1[} a_i \times x_i \leq a_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables, :math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, :math:`a` is an alias for parameters
:type parameters: NDArray


.. py:function:: nucs.propagators.alldifferent_propagator(domains, parameters)
This propagator implements the relation :math:`\forall i \neq j, x_i \neq x_j`.

It is adapted from "A fast and simple algorithm for bounds consistency of the alldifferent constraint".

It has the time complexity: :math:`O(n \times log(n))` where :math:`n` is the number of variables.

:param domains: the domains of the variables, :math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, it is unused
:type parameters: NDArray

.. py:function:: nucs.propagators.count_eq_propagator(domains, parameters)
This propagator implements the relation :math:`\Sigma_i (x_i = a) = x_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables, :math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, :math:`a` is the first parameter
:type parameters: NDArray


.. py:function:: nucs.propagators.element_lic_propagator(domains, parameters)
This propagator implements the relation :math:`l_i = c`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables,
:math:`l` is the list of the first :math:`n-1` domains,
:math:`i` is the last domain
:type domains: NDArray
:param parameters: the parameters of the propagator, :math:`c` is the first parameter
:type parameters: NDArray


.. py:function:: nucs.propagators.element_liv_propagator(domains, parameters)
This propagator implements the relation :math:`l_i = v`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables,
:math:`l` is the list of the first :math:`n-2` domains,
:math:`i` is the :math:`n-1` th domain,
:math:`v` is the last domain
:type domains: NDArray
:param parameters: the parameters of the propagator, it is unused
:type parameters: NDArray


.. py:function:: nucs.propagators.exactly_eq_propagator(domains, parameters)
This propagator implements the relation :math:`\Sigma_i (x_i = a) = c`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables, :math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator,
:math:`a` is the first parameter,
:math:`c` is the second parameter
:type parameters: NDArray


.. py:function:: nucs.propagators.lexicographic_leq_propagator(domains, parameters)
This propagator implements the relation :math:`x <_{leq} y`.

See https://www.diva-portal.org/smash/record.jsf?pid=diva2:1041533.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables,
:math:`x` is the list of the first :math:`n` domains,
:math:`y` is the list of the last :math:`n` domains
:type domains: NDArray
:param parameters: the parameters of the propagator, it is unused
:type parameters: NDArray


.. py:function:: nucs.propagators.max_eq_propagator(domains, parameters)
This propagator implements the relation :math:`\max_i x_i = x_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables,
:math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, it is unused
:type parameters: NDArray


.. py:function:: nucs.propagators.max_leq_propagator(domains, parameters)
This propagator implements the relation :math:`\max_i x_i \leq x_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables,
:math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, it is unused
:type parameters: NDArray


.. py:function:: nucs.propagators.min_eq_propagator(domains, parameters)
This propagator implements the relation :math:`\min_i x_i = x_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables,
:math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, it is unused
:type parameters: NDArray


.. py:function:: nucs.propagators.min_geq_propagator(domains, parameters)
This propagator implements the relation :math:`\min_i x_i \geq x_{n-1}`.

It has the time complexity: :math:`O(n)` where :math:`n` is the number of variables.

:param domains: the domains of the variables,
:math:`x` is an alias for domains
:type domains: NDArray
:param parameters: the parameters of the propagator, it is unused
:type parameters: NDArray


.. py:function:: nucs.propagators.relation_propagator(domains, parameters)
This propagator implements a relation over :math:`O(n)` variables defined by its allowed tuples.

It has the time complexity: :math:`O(p)` where :math:`p` is the number of parameters.

:param domains: the domains of the variables
:type domains: NDArray
:param parameters: the parameters of the propagator,
the allowed tuples correspond to:
:math:`(p_0, ..., p_{n-1}), (p_n, ..., p_{2n-1}), ...` where :math:`p` is an alias for parameters

:type parameters: NDArray


.. _heuristics:

Expand Down
4 changes: 2 additions & 2 deletions nucs/propagators/affine_eq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ def compute_domain_sum_max(domains: NDArray, parameters: NDArray) -> int:
def compute_domains_affine_eq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Sigma_i a_i * x_i = a_{n-1}.
:param domains: the domains of the variables, x = domains
:param parameters: the parameters of the propagator, a = parameters
:param domains: the domains of the variables, x is an alias for domains
:param parameters: the parameters of the propagator, a is an alias for parameters
"""
domain_sum_min = compute_domain_sum_min(domains, parameters)
domain_sum_max = compute_domain_sum_max(domains, parameters)
Expand Down
4 changes: 2 additions & 2 deletions nucs/propagators/affine_geq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def get_triggers_affine_geq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_affine_geq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Sigma_i a_i * x_i >= a_{n-1}.
:param domains: the domains of the variables, x = domains
:param parameters: the parameters of the propagator, a = parameters
:param domains: the domains of the variables, x is an alias for domains
:param parameters: the parameters of the propagator, a is an alias for parameters
"""
if compute_domain_sum_max(domains, parameters) <= 0:
return PROP_ENTAILMENT
Expand Down
4 changes: 2 additions & 2 deletions nucs/propagators/affine_leq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def get_triggers_affine_leq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_affine_leq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Sigma_i a_i * x_i <= a_{n-1}.
:param domains: the domains of the variables, x = domains
:param parameters: the parameters of the propagator, a = parameters
:param domains: the domains of the variables, x is an alias for domains
:param parameters: the parameters of the propagator, a is an alias for parameters
"""
if compute_domain_sum_min(domains, parameters) >= 0:
return PROP_ENTAILMENT
Expand Down
2 changes: 1 addition & 1 deletion nucs/propagators/alldifferent_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def compute_domains_alldifferent(domains: NDArray, parameters: NDArray) -> int:
"""
Enforces that x_i <> x_j when i<>j.
Adapted from "A fast and simple algorithm for bounds consistency of the alldifferent constraint".
:param domains: the domains of the variables, x=domains
:param domains: the domains of the variables, x is an alias for domains
:param parameters: unused here
"""
n = len(domains)
Expand Down
2 changes: 1 addition & 1 deletion nucs/propagators/count_eq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def get_triggers_count_eq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_count_eq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Sigma_i (x_i == a) = x_{n-1}.
:param domains: the domains of the variables, x = domains
:param domains: the domains of the variables, x is an alias for domains
:param parameters: the parameters of the propagator, a is the first parameter
"""
x = domains[:-1]
Expand Down
32 changes: 16 additions & 16 deletions nucs/propagators/element_liv_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,44 +23,44 @@ def get_triggers_element_liv(n: int, parameters: NDArray) -> NDArray:
@njit(cache=True)
def compute_domains_element_liv(domains: NDArray, parameters: NDArray) -> int:
"""
Enforces l_i = x.
Enforces l_i = v.
:param domains: the domains of the variables,
l is the list of the first n-2 domains,
i is the (n-1)th domain,
x is the last domain
:param parameters: the parameters of the propagator
v is the last domain
:param parameters: the parameters of the propagator, it is unused
"""
l = domains[:-2]
i = domains[-2]
i[MIN] = max(i[MIN], 0)
i[MAX] = min(i[MAX], len(l) - 1)
if i[MAX] < i[MIN]:
return PROP_INCONSISTENCY
x = domains[-1]
x_min = sys.maxsize
x_max = -sys.maxsize
v = domains[-1]
v_min = sys.maxsize
v_max = -sys.maxsize
i_min = i[MIN]
i_max = i[MAX]
for idx in range(i[MIN], i[MAX] + 1):
if x[MAX] < l[idx, MIN] or x[MIN] > l[idx, MAX]: # no intersection
if v[MAX] < l[idx, MIN] or v[MIN] > l[idx, MAX]: # no intersection
if idx == i_min:
i_min += 1
elif idx == i_max:
i_max -= 1
else: # intersection
if l[idx, MIN] < x_min:
x_min = l[idx, MIN]
if l[idx, MAX] > x_max:
x_max = l[idx, MAX]
if l[idx, MIN] < v_min:
v_min = l[idx, MIN]
if l[idx, MAX] > v_max:
v_max = l[idx, MAX]
if i_max < i_min:
return PROP_INCONSISTENCY
i[MIN] = i_min
i[MAX] = i_max
x[MIN] = max(x[MIN], x_min)
x[MAX] = min(x[MAX], x_max)
v[MIN] = max(v[MIN], v_min)
v[MAX] = min(v[MAX], v_max)
if i_min == i_max:
l[i_min, MIN] = max(l[i_min, MIN], x[MIN])
l[i_max, MAX] = min(l[i_max, MAX], x[MAX])
if x[MIN] == x[MAX]:
l[i_min, MIN] = max(l[i_min, MIN], v[MIN])
l[i_max, MAX] = min(l[i_max, MAX], v[MAX])
if v[MIN] == v[MAX]:
return PROP_ENTAILMENT
return PROP_CONSISTENCY
2 changes: 1 addition & 1 deletion nucs/propagators/exactly_eq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def get_triggers_exactly_eq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_exactly_eq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Sigma_i (x_i == a) = c.
:param domains: the domains of the variables, x=domains
:param domains: the domains of the variables, x is an alias for domains
:param parameters: the parameters of the propagator, a is the first parameter, c is the second parameter
"""
a = parameters[0]
Expand Down
2 changes: 1 addition & 1 deletion nucs/propagators/max_eq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def get_triggers_max_eq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_max_eq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Max_i x_i = x_{n-1}.
:param domains: the domains of the variables, x=domains
:param domains: the domains of the variables, x is an alias for domains
:param parameters: unused here
"""
x = domains[:-1]
Expand Down
2 changes: 1 addition & 1 deletion nucs/propagators/max_leq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def get_triggers_max_leq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_max_leq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Max_i x_i <= x_{n-1}.
:param domains: the domains of the variables, x=domains
:param domains: the domains of the variables, x is an alias for domains
:param parameters: unused here
"""
x = domains[:-1]
Expand Down
2 changes: 1 addition & 1 deletion nucs/propagators/min_eq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def get_triggers_min_eq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_min_eq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Min_i x_i = x_{n-1}.
:param domains: the domains of the variables, x=domains
:param domains: the domains of the variables, x is an alias for domains
:param parameters: unused here
"""
x = domains[:-1]
Expand Down
2 changes: 1 addition & 1 deletion nucs/propagators/min_geq_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def get_triggers_min_geq(n: int, parameters: NDArray) -> NDArray:
def compute_domains_min_geq(domains: NDArray, parameters: NDArray) -> int:
"""
Implements Min_i x_i >= x_{n-1}.
:param domains: the domains of the variables, x=domains
:param domains: the domains of the variables, x is an alias for domains
:param parameters: unused here
"""
x = domains[:-1]
Expand Down
3 changes: 2 additions & 1 deletion nucs/propagators/relation_propagator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ def get_triggers_relation(n: int, parameters: NDArray) -> NDArray:
@njit(cache=True)
def compute_domains_relation(domains: NDArray, parameters: NDArray) -> int:
"""
Implements a relation over n variables defined by its allowed tuples.
:param domains: the domains of the variables
:param parameters: the parameters of the propagator,
the allowed tuples correspond to:
(parameter_0, ..., parameter_n-1), (parameter_n, ..., parameter_2n-1), ...
(parameters_0, ..., parameters_n-1), (parameters_n, ..., parameters_2n-1), ...
"""
n = len(domains)
tuples = parameters.copy().reshape((-1, n))
Expand Down

0 comments on commit b35765f

Please sign in to comment.