How to specify conditional constraints in CP-SAT

Viewed 123

I would like to add constraints of the form

a - b > 0 if c + d == 4

The documentation talks about OnlyEnforceIf which I was hoping would allow

model.Add(a-b > 0).OnlyEnforceIf(c+d==4)

Unfortunately it seems OnlyEnforceIf can only take a single Boolean and not a condition such as c+d==4. If I am reading the documentation right it then goes on to suggest

model.Add(c+d==4).OnlyEnforceIf(b)
model.Add(c+d!=4).OnlyEnforceIf(b.Not())
model.Add(a-b > 0).OnlyEnforceIf(b)

I have two questions:

  1. Could someone explain the logic of this formulation please. If the first conditions should be read "if b then c+d == 4. if not b then c+d != 4. if b then a-b > 0" then the logic doesn't seem the right way round. I want the constraint to be that a-b>0 if c+d==4 so surely it would be "if c+d==4 then b" shouldn't?.
  2. I have a lot of these constraints I need to impose so it seems I will need to create a lot of new variables. I notice that in CPLEX for example you can specify if-then directly without creating a new variable. Am I missing something?
1 Answers
  1. Let's decompose (c+d == 4) <=> b
    1. b => (c+d == 4) is added with model.Add(c+d==4).OnlyEnforceIf(b)
    2. (c+d == 4) => b's contrapositive is not(b) => not(c+d == 4) and that is modeled with model.Add(c+d!=4).OnlyEnforceIf(b.Not())
  2. The ortools philosophy is that they do not want to create variables under the hood as CPLEX does. Reference
Related