Skip to content

None argument in Cumulative (demand) not allowed by safening #828

@ThomSerg

Description

@ThomSerg

Expression for the capacity of a cumulative constraint seems to trigger safening, which doesn't allow for the "None" argument in the constraint.

Minimal example:

import cpmpy as cp

def original_model():
    p = cp.boolvar(name='p')
    start_array_0 = cp.intvar(0, 10, name='start_array_0')
    start_array_1 = cp.intvar(0, 10, name='start_array_1')
    start_array_2 = cp.intvar(0, 10, name='start_array_2')

    constraints = [
        (p).implies((p > cp.Cumulative([start_array_0, start_array_1, start_array_2], [1, 4, 3], None, [4, 5, 7], 10))),
    ]
    return cp.Model(constraints)


def model():
    p = cp.boolvar(name='p')
    start_array_0 = cp.intvar(0, 10, name='start_array_0')
    start_array_1 = cp.intvar(0, 10, name='start_array_1')
    start_array_2 = cp.intvar(0, 10, name='start_array_2')
    _IV0 = cp.intvar(0, 0, name='_IV0')

    constraints = [
        (p).implies((p > cp.Cumulative([start_array_0, start_array_1, start_array_2], [1, 4, 3], None, [4, 5, 7], cp.sum([10, (-_IV0)])))),
    ]
    return cp.Model(constraints)


if __name__ == '__main__':
   model().solve()
   original_model().solve()
Traceback (most recent call last):
  File "/home/thomserg/Documents/programming/fuzz-tester/bug.py", line 29, in <module>
    model().solve()
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/model.py", line 194, in solve
    s = SolverLookup.get(solver, self)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/solvers/utils.py", line 148, in get
    return solver_cls(model, subsolver=subname, **init_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/solvers/ortools.py", line 140, in __init__
    super().__init__(name="ortools", cpm_model=cpm_model)
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/solvers/solver_interface.py", line 95, in __init__
    self += cpm_model.constraints
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/solvers/ortools.py", line 455, in add
    for con in self.transform(cpm_expr):
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/solvers/ortools.py", line 420, in transform
    cpm_cons = no_partial_functions(cpm_cons, safen_toplevel=frozenset({"div", "mod"})) # before decompose, assumes total decomposition for partial functions
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/transformations/safening.py", line 109, in no_partial_functions
    new_args = no_partial_functions(args, _toplevel, _nbc, safen_toplevel=safen_toplevel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/transformations/safening.py", line 109, in no_partial_functions
    new_args = no_partial_functions(args, _toplevel, _nbc, safen_toplevel=safen_toplevel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/transformations/safening.py", line 109, in no_partial_functions
    new_args = no_partial_functions(args, _toplevel, _nbc, safen_toplevel=safen_toplevel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomserg/Documents/programming/fuzz-tester/libraries/cpmpy/cpmpy/transformations/safening.py", line 99, in no_partial_functions
    assert isinstance(cpm_expr, Expression), f"each `cpm_expr` should be an Expression at this point, not {type(cpm_expr)} {lst_of_expr}"
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: each `cpm_expr` should be an Expression at this point, not <class 'NoneType'>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions