When we would like to combine AddMaxEquality and OnlyEnforceIf in the model formulation, we consistently get cp_model.MODEL_INVALID.
Are these two not compatible with each other yet? If not, is there any work around?
from ortools.sat.python import cp_model
model = cp_model.CpModel()
x = model.NewBoolVar('x')
y = model.NewBoolVar('y')
z = model.NewBoolVar('z')
model.AddMaxEquality(z, [0, y]).OnlyEnforceIf(x)
model.Minimize(1)
solver = cp_model.CpSolver()
status = solver.Solve(model=model)
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
print(f'x {solver.Value(x)}, y {solver.Value(y)}, z {solver.Value(z)}')
elif status == cp_model.INFEASIBLE:
print("Infeasible")
elif status == cp_model.MODEL_INVALID:
print("Model invalid")
else:
print(status)
>Solution :
It is not compatible. As stated in the documentation: https://google.github.io/or-tools/python/ortools/sat/python/cp_model.html#Constraint.OnlyEnforceIf
It is supported by BoolOr, BoolAnd and linear constraints.
The way to support enforced min/max/prod/… is to duplicate the target variable, use the target variable in the min/max/prod/… constraint, then add an enforced equality between that target and its copy.