ortools.sat.python.cp_model_helper
helpers methods for the cp_model module.
1# Copyright 2010-2024 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, Union 18import numpy as np 19 20 21INT_MIN = -9223372036854775808 # hardcoded to be platform independent. 22INT_MAX = 9223372036854775807 23INT32_MIN = -2147483648 24INT32_MAX = 2147483647 25 26 27def is_boolean(x: Any) -> bool: 28 """Checks if the x is a boolean.""" 29 if isinstance(x, bool): 30 return True 31 if isinstance(x, np.bool_): 32 return True 33 return False 34 35 36def is_zero(x: Any) -> bool: 37 """Checks if the x is 0 or 0.0.""" 38 if isinstance(x, numbers.Integral): 39 return int(x) == 0 40 if isinstance(x, numbers.Real): 41 return float(x) == 0.0 42 return False 43 44 45def is_one(x: Any) -> bool: 46 """Checks if x is 1 or 1.0.""" 47 if isinstance(x, numbers.Integral): 48 return int(x) == 1 49 if isinstance(x, numbers.Real): 50 return float(x) == 1.0 51 return False 52 53 54def is_minus_one(x: Any) -> bool: 55 """Checks if x is -1 or -1.0 .""" 56 if isinstance(x, numbers.Integral): 57 return int(x) == -1 58 if isinstance(x, numbers.Real): 59 return float(x) == -1.0 60 return False 61 62 63def assert_is_int64(x: Any) -> int: 64 """Asserts that x is integer and x is in [min_int_64, max_int_64] and returns it casted to an int.""" 65 if not isinstance(x, numbers.Integral): 66 raise TypeError(f"Not an integer: {x} of type {type(x)}") 67 x_as_int = int(x) 68 if x_as_int < INT_MIN or x_as_int > INT_MAX: 69 raise OverflowError(f"Does not fit in an int64_t: {x}") 70 return x_as_int 71 72 73def assert_is_int32(x: Any) -> int: 74 """Asserts that x is integer and x is in [min_int_32, max_int_32] and returns it casted to an int.""" 75 if not isinstance(x, numbers.Integral): 76 raise TypeError(f"Not an integer: {x} of type {type(x)}") 77 x_as_int = int(x) 78 if x_as_int < INT32_MIN or x_as_int > INT32_MAX: 79 raise OverflowError(f"Does not fit in an int32_t: {x}") 80 return x_as_int 81 82 83def assert_is_zero_or_one(x: Any) -> int: 84 """Asserts that x is 0 or 1 and returns it as an int.""" 85 if not isinstance(x, numbers.Integral): 86 raise TypeError(f"Not a boolean: {x} of type {type(x)}") 87 x_as_int = int(x) 88 if x_as_int < 0 or x_as_int > 1: 89 raise TypeError(f"Not a boolean: {x}") 90 return x_as_int 91 92 93def assert_is_a_number(x: Any) -> Union[int, float]: 94 """Asserts that x is a number and returns it casted to an int or a float.""" 95 if isinstance(x, numbers.Integral): 96 return int(x) 97 if isinstance(x, numbers.Real): 98 return float(x) 99 raise TypeError(f"Not a number: {x} of type {type(x)}") 100 101 102def to_capped_int64(v: int) -> int: 103 """Restrict v within [INT_MIN..INT_MAX] range.""" 104 if v > INT_MAX: 105 return INT_MAX 106 if v < INT_MIN: 107 return INT_MIN 108 return v 109 110 111def capped_subtraction(x: int, y: int) -> int: 112 """Saturated arithmetics. Returns x - y truncated to the int64_t range.""" 113 assert_is_int64(x) 114 assert_is_int64(y) 115 if y == 0: 116 return x 117 if x == y: 118 if x == INT_MAX or x == INT_MIN: 119 raise OverflowError("Integer NaN: subtracting INT_MAX or INT_MIN to itself") 120 return 0 121 if x == INT_MAX or x == INT_MIN: 122 return x 123 if y == INT_MAX: 124 return INT_MIN 125 if y == INT_MIN: 126 return INT_MAX 127 return to_capped_int64(x - y)
INT_MIN =
-9223372036854775808
INT_MAX =
9223372036854775807
INT32_MIN =
-2147483648
INT32_MAX =
2147483647
def
is_boolean(x: Any) -> bool:
28def is_boolean(x: Any) -> bool: 29 """Checks if the x is a boolean.""" 30 if isinstance(x, bool): 31 return True 32 if isinstance(x, np.bool_): 33 return True 34 return False
Checks if the x is a boolean.
def
is_zero(x: Any) -> bool:
37def is_zero(x: Any) -> bool: 38 """Checks if the x is 0 or 0.0.""" 39 if isinstance(x, numbers.Integral): 40 return int(x) == 0 41 if isinstance(x, numbers.Real): 42 return float(x) == 0.0 43 return False
Checks if the x is 0 or 0.0.
def
is_one(x: Any) -> bool:
46def is_one(x: Any) -> bool: 47 """Checks if x is 1 or 1.0.""" 48 if isinstance(x, numbers.Integral): 49 return int(x) == 1 50 if isinstance(x, numbers.Real): 51 return float(x) == 1.0 52 return False
Checks if x is 1 or 1.0.
def
is_minus_one(x: Any) -> bool:
55def is_minus_one(x: Any) -> bool: 56 """Checks if x is -1 or -1.0 .""" 57 if isinstance(x, numbers.Integral): 58 return int(x) == -1 59 if isinstance(x, numbers.Real): 60 return float(x) == -1.0 61 return False
Checks if x is -1 or -1.0 .
def
assert_is_int64(x: Any) -> int:
64def assert_is_int64(x: Any) -> int: 65 """Asserts that x is integer and x is in [min_int_64, max_int_64] and returns it casted to an int.""" 66 if not isinstance(x, numbers.Integral): 67 raise TypeError(f"Not an integer: {x} of type {type(x)}") 68 x_as_int = int(x) 69 if x_as_int < INT_MIN or x_as_int > INT_MAX: 70 raise OverflowError(f"Does not fit in an int64_t: {x}") 71 return x_as_int
Asserts that x is integer and x is in [min_int_64, max_int_64] and returns it casted to an int.
def
assert_is_int32(x: Any) -> int:
74def assert_is_int32(x: Any) -> int: 75 """Asserts that x is integer and x is in [min_int_32, max_int_32] and returns it casted to an int.""" 76 if not isinstance(x, numbers.Integral): 77 raise TypeError(f"Not an integer: {x} of type {type(x)}") 78 x_as_int = int(x) 79 if x_as_int < INT32_MIN or x_as_int > INT32_MAX: 80 raise OverflowError(f"Does not fit in an int32_t: {x}") 81 return x_as_int
Asserts that x is integer and x is in [min_int_32, max_int_32] and returns it casted to an int.
def
assert_is_zero_or_one(x: Any) -> int:
84def assert_is_zero_or_one(x: Any) -> int: 85 """Asserts that x is 0 or 1 and returns it as an int.""" 86 if not isinstance(x, numbers.Integral): 87 raise TypeError(f"Not a boolean: {x} of type {type(x)}") 88 x_as_int = int(x) 89 if x_as_int < 0 or x_as_int > 1: 90 raise TypeError(f"Not a boolean: {x}") 91 return x_as_int
Asserts that x is 0 or 1 and returns it as an int.
def
assert_is_a_number(x: Any) -> Union[int, float]:
94def assert_is_a_number(x: Any) -> Union[int, float]: 95 """Asserts that x is a number and returns it casted to an int or a float.""" 96 if isinstance(x, numbers.Integral): 97 return int(x) 98 if isinstance(x, numbers.Real): 99 return float(x) 100 raise TypeError(f"Not a number: {x} of type {type(x)}")
Asserts that x is a number and returns it casted to an int or a float.
def
to_capped_int64(v: int) -> int:
103def to_capped_int64(v: int) -> int: 104 """Restrict v within [INT_MIN..INT_MAX] range.""" 105 if v > INT_MAX: 106 return INT_MAX 107 if v < INT_MIN: 108 return INT_MIN 109 return v
Restrict v within [INT_MIN..INT_MAX] range.
def
capped_subtraction(x: int, y: int) -> int:
112def capped_subtraction(x: int, y: int) -> int: 113 """Saturated arithmetics. Returns x - y truncated to the int64_t range.""" 114 assert_is_int64(x) 115 assert_is_int64(y) 116 if y == 0: 117 return x 118 if x == y: 119 if x == INT_MAX or x == INT_MIN: 120 raise OverflowError("Integer NaN: subtracting INT_MAX or INT_MIN to itself") 121 return 0 122 if x == INT_MAX or x == INT_MIN: 123 return x 124 if y == INT_MAX: 125 return INT_MIN 126 if y == INT_MIN: 127 return INT_MAX 128 return to_capped_int64(x - y)
Saturated arithmetics. Returns x - y truncated to the int64_t range.