Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/docs_improvement' into docs-sear…
Browse files Browse the repository at this point in the history
…ch_info

# Conflicts:
#	cpmpy/model.py
#	cpmpy/solvers/minizinc.py
#	docs/conf.py
#	docs/index.rst
#	docs/modeling.md
  • Loading branch information
Wout4 committed Jul 18, 2024
2 parents d393a4f + 4da121b commit 437831f
Show file tree
Hide file tree
Showing 77 changed files with 3,934 additions and 580 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ jobs:
pip install z3-solver
pip install exact
pip install pysdd
pip install pychoco
sudo snap install minizinc --classic
pip install minizinc
- name: Test with pytest
run: |
python -m pytest tests/
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,9 @@ cython_debug/
bugs/

# Intellij
.idea/
.idea/

# VeriPB proof log files (from Glasgow Constraint solver)
*.veripb
*.opb
*.pbp
4 changes: 2 additions & 2 deletions cpmpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
- `solvers`: CPMpy classes that translate a model into approriate calls of a solver's API
- `transformations`: common methods for transforming expressions into other expressions, used by `solvers` modules to simplify/rewrite expressions
"""
# Tias Guns, 2019-2023
# Tias Guns, 2019-2024

__version__ = "0.9.18"
__version__ = "0.9.21"


from .expressions import *
Expand Down
6 changes: 6 additions & 0 deletions cpmpy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class MinizincNameException(CPMpyException):
class MinizincBoundsException(CPMpyException):
pass

class ChocoTypeException(CPMpyException):
pass

class ChocoBoundsException(CPMpyException):
pass

class NotSupportedError(CPMpyException):
pass

Expand Down
7 changes: 5 additions & 2 deletions cpmpy/expressions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
# others need to be imported by the developer explicitely
from .variables import boolvar, intvar, cpm_array
from .variables import BoolVar, IntVar, cparray # Old, to be deprecated
from .globalconstraints import AllDifferent, AllDifferentExcept0, AllEqual, Circuit, Inverse, Table, Xor, Cumulative, IfThenElse, GlobalCardinalityCount, DirectConstraint, InDomain
from .globalconstraints import AllDifferent, AllDifferentExcept0, AllDifferentExceptN, AllEqual, AllEqualExceptN, Circuit, Inverse, Table, Xor, Cumulative, \
IfThenElse, GlobalCardinalityCount, DirectConstraint, InDomain, Increasing, Decreasing, IncreasingStrict, DecreasingStrict, \
LexLess, LexLessEq, LexChainLess, LexChainLessEq, Precedence, NoOverlap, \
NegativeTable
from .globalconstraints import alldifferent, allequal, circuit # Old, to be deprecated
from .globalfunctions import Maximum, Minimum, Abs, Element, Count
from .globalfunctions import Maximum, Minimum, Abs, Element, Count, NValue, NValueExcept, Among
from .core import BoolVal
from .python_builtins import all, any, max, min, sum
38 changes: 22 additions & 16 deletions cpmpy/expressions/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Here is a list of standard python operators and what object (with what expr.name) it creates:
Comparisons:
**Comparisons**:
- x == y Comparison("==", x, y)
- x != y Comparison("!=", x, y)
Expand All @@ -20,9 +20,9 @@
- x > y Comparison(">", x, y)
- x >= y Comparison(">=", x, y)
Mathematical operators:
**Mathematical operators**:
- -x Operator("-", [x])
- x Operator("-", [x])
- x + y Operator("sum", [x,y])
- sum([x,y,z]) Operator("sum", [x,y,z])
- sum([c0*x, c1*y, c2*z]) Operator("wsum", [[c0,c1,c2],[x,y,z]])
Expand All @@ -32,7 +32,7 @@
- x % y Operator("mod", [x,y])
- x ** y Operator("pow", [x,y])
Logical operators:
**Logical operators**:
- x & y Operator("and", [x,y])
- x | y Operator("or", [x,y])
Expand All @@ -47,14 +47,16 @@
Apart from operator overloading, expressions implement two important functions:
- `is_bool()` which returns whether the __return type__ of the expression is Boolean.
If it does, the expression can be used as top-level constraint
or in logical operators.
- `is_bool()`
which returns whether the return type of the expression is Boolean.
If it does, the expression can be used as top-level constraint
or in logical operators.
- `value()` computes the value of this expression, by calling .value() on its
subexpressions and doing the appropriate computation
this is used to conveniently print variable values, objective values
and any other expression value (e.g. during debugging).
- `value()`
computes the value of this expression, by calling .value() on its
subexpressions and doing the appropriate computation
this is used to conveniently print variable values, objective values
and any other expression value (e.g. during debugging).
===============
List of classes
Expand All @@ -72,7 +74,7 @@
import numpy as np


from .utils import is_num, is_any_list, flatlist, argval, get_bounds, is_boolexpr, is_true_cst, is_false_cst
from .utils import is_num, is_any_list, flatlist, argval, get_bounds, is_boolexpr, is_true_cst, is_false_cst, argvals
from ..exceptions import IncompleteFunctionError, TypeError


Expand Down Expand Up @@ -144,6 +146,7 @@ def is_bool(self):
def value(self):
return None # default


def get_bounds(self):
if self.is_bool():
return 0, 1 #default for boolean expressions
Expand Down Expand Up @@ -400,7 +403,8 @@ def __repr__(self):
# return the value of the expression
# optional, default: None
def value(self):
arg_vals = [argval(a) for a in self.args]
arg_vals = argvals(self.args)

if any(a is None for a in arg_vals): return None
if self.name == "==": return arg_vals[0] == arg_vals[1]
elif self.name == "!=": return arg_vals[0] != arg_vals[1]
Expand Down Expand Up @@ -526,11 +530,12 @@ def wrap_bracket(arg):
return "{}({})".format(self.name, self.args)

def value(self):

if self.name == "wsum":
# wsum: arg0 is list of constants, no .value() use as is
arg_vals = [self.args[0], [argval(arg) for arg in self.args[1]]]
arg_vals = [self.args[0], argvals(self.args[1])]
else:
arg_vals = [argval(arg) for arg in self.args]
arg_vals = argvals(self.args)


if any(a is None for a in arg_vals): return None
Expand All @@ -546,7 +551,8 @@ def value(self):
try:
return arg_vals[0] // arg_vals[1]
except ZeroDivisionError:
raise IncompleteFunctionError(f"Division by zero during value computation for expression {self}")
raise IncompleteFunctionError(f"Division by zero during value computation for expression {self}"
+ "\n Use argval(expr) to get the value of expr with relational semantics.")

# boolean
elif self.name == "and": return all(arg_vals)
Expand Down
Loading

0 comments on commit 437831f

Please sign in to comment.