ortools.sat.python.cp_model_numbers

helpers methods for the cp_model module.

 1# Copyright 2010-2025 Google LLC
 2# Licensed under the Apache License, Version 2.0 (the "License");
 3# you may not use this file except in compliance with the License.
 4# You may obtain a copy of the License at
 5#
 6#     http://www.apache.org/licenses/LICENSE-2.0
 7#
 8# Unless required by applicable law or agreed to in writing, software
 9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14"""helpers methods for the cp_model module."""
15
16import numbers
17from typing import Any
18import numpy as np
19
20
21INT_MIN = -9223372036854775808  # hardcoded to be platform independent.
22INT_MAX = 9223372036854775807
23
24
25def is_boolean(x: Any) -> bool:
26    """Checks if the x is a boolean."""
27    if isinstance(x, bool):
28        return True
29    if isinstance(x, np.bool_):
30        return True
31    return False
32
33
34def assert_is_zero_or_one(x: Any) -> int:
35    """Asserts that x is 0 or 1 and returns it as an int."""
36    if not isinstance(x, numbers.Integral):
37        raise TypeError(f"Not a boolean: {x} of type {type(x)}")
38    x_as_int = int(x)
39    if x_as_int < 0 or x_as_int > 1:
40        raise TypeError(f"Not a boolean: {x}")
41    return x_as_int
42
43
44def to_capped_int64(v: int) -> int:
45    """Restrict v within [INT_MIN..INT_MAX] range."""
46    if v > INT_MAX:
47        return INT_MAX
48    if v < INT_MIN:
49        return INT_MIN
50    return v
51
52
53def capped_subtraction(x: int, y: int) -> int:
54    """Saturated arithmetics. Returns x - y truncated to the int64_t range."""
55    if y == 0:
56        return x
57    if x == y:
58        if x == INT_MAX or x == INT_MIN:
59            raise OverflowError("Integer NaN: subtracting INT_MAX or INT_MIN to itself")
60        return 0
61    if x == INT_MAX or x == INT_MIN:
62        return x
63    if y == INT_MAX:
64        return INT_MIN
65    if y == INT_MIN:
66        return INT_MAX
67    return to_capped_int64(x - y)
INT_MIN = -9223372036854775808
INT_MAX = 9223372036854775807
def is_boolean(x: Any) -> bool:
26def is_boolean(x: Any) -> bool:
27    """Checks if the x is a boolean."""
28    if isinstance(x, bool):
29        return True
30    if isinstance(x, np.bool_):
31        return True
32    return False

Checks if the x is a boolean.

def assert_is_zero_or_one(x: Any) -> int:
35def assert_is_zero_or_one(x: Any) -> int:
36    """Asserts that x is 0 or 1 and returns it as an int."""
37    if not isinstance(x, numbers.Integral):
38        raise TypeError(f"Not a boolean: {x} of type {type(x)}")
39    x_as_int = int(x)
40    if x_as_int < 0 or x_as_int > 1:
41        raise TypeError(f"Not a boolean: {x}")
42    return x_as_int

Asserts that x is 0 or 1 and returns it as an int.

def to_capped_int64(v: int) -> int:
45def to_capped_int64(v: int) -> int:
46    """Restrict v within [INT_MIN..INT_MAX] range."""
47    if v > INT_MAX:
48        return INT_MAX
49    if v < INT_MIN:
50        return INT_MIN
51    return v

Restrict v within [INT_MIN..INT_MAX] range.

def capped_subtraction(x: int, y: int) -> int:
54def capped_subtraction(x: int, y: int) -> int:
55    """Saturated arithmetics. Returns x - y truncated to the int64_t range."""
56    if y == 0:
57        return x
58    if x == y:
59        if x == INT_MAX or x == INT_MIN:
60            raise OverflowError("Integer NaN: subtracting INT_MAX or INT_MIN to itself")
61        return 0
62    if x == INT_MAX or x == INT_MIN:
63        return x
64    if y == INT_MAX:
65        return INT_MIN
66    if y == INT_MIN:
67        return INT_MAX
68    return to_capped_int64(x - y)

Saturated arithmetics. Returns x - y truncated to the int64_t range.