1 // Copyright 2010-2021 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 package com.google.ortools.sat;
15 
16 import com.google.ortools.sat.CpModelProto;
17 import com.google.ortools.sat.IntegerVariableProto;
18 import com.google.ortools.util.Domain;
19 
20 /** An integer variable. */
21 public final class IntVar implements Literal, LinearExpr {
IntVar(CpModelProto.Builder builder, Domain domain, String name)22   IntVar(CpModelProto.Builder builder, Domain domain, String name) {
23     this.modelBuilder = builder;
24     this.variableIndex = modelBuilder.getVariablesCount();
25     this.varBuilder = modelBuilder.addVariablesBuilder();
26     this.varBuilder.setName(name);
27     for (long b : domain.flattenedIntervals()) {
28       this.varBuilder.addDomain(b);
29     }
30     this.negation_ = null;
31   }
32 
IntVar(CpModelProto.Builder builder, int index)33   IntVar(CpModelProto.Builder builder, int index) {
34     this.modelBuilder = builder;
35     this.variableIndex = index;
36     this.varBuilder = modelBuilder.getVariablesBuilder(index);
37     this.negation_ = null;
38   }
39 
40   @Override
toString()41   public String toString() {
42     return varBuilder.toString();
43   }
44 
45   /** Returns the name of the variable given upon creation. */
getName()46   public String getName() {
47     return varBuilder.getName();
48   }
49 
50   /** Internal, returns the index of the variable in the underlying CpModelProto. */
51   @Override
getIndex()52   public int getIndex() {
53     return variableIndex;
54   }
55 
56   /** Returns the variable protobuf builder. */
getBuilder()57   public IntegerVariableProto.Builder getBuilder() {
58     return varBuilder;
59   }
60 
61   // LinearExpr interface.
62   @Override
numElements()63   public int numElements() {
64     return 1;
65   }
66 
67   @Override
getVariable(int index)68   public IntVar getVariable(int index) {
69     assert (index == 0);
70     return this;
71   }
72 
73   @Override
getCoefficient(int index)74   public long getCoefficient(int index) {
75     assert (index == 0);
76     return 1;
77   }
78 
79   @Override
getOffset()80   public long getOffset() {
81     return 0;
82   }
83 
84   /** Returns a short string describing the variable. */
85   @Override
getShortString()86   public String getShortString() {
87     if (varBuilder.getName().isEmpty()) {
88       if (varBuilder.getDomainCount() == 2 && varBuilder.getDomain(0) == varBuilder.getDomain(1)) {
89         return String.format("%d", varBuilder.getDomain(0));
90       } else {
91         return String.format("var_%d(%s)", getIndex(), displayBounds());
92       }
93     } else {
94       return String.format("%s(%s)", getName(), displayBounds());
95     }
96   }
97 
98   /** Returns the domain as a string without the enclosing []. */
displayBounds()99   public String displayBounds() {
100     String out = "";
101     for (int i = 0; i < varBuilder.getDomainCount(); i += 2) {
102       if (i != 0) {
103         out += ", ";
104       }
105       if (varBuilder.getDomain(i) == varBuilder.getDomain(i + 1)) {
106         out += String.format("%d", varBuilder.getDomain(i));
107       } else {
108         out += String.format("%d..%d", varBuilder.getDomain(i), varBuilder.getDomain(i + 1));
109       }
110     }
111     return out;
112   }
113 
114   /** Returns the negation of a boolean variable. */
115   @Override
not()116   public Literal not() {
117     if (negation_ == null) {
118       negation_ = new NotBooleanVariable(this);
119     }
120     return negation_;
121   }
122 
123   /** Returns the domain of the variable. */
getDomain()124   public Domain getDomain() {
125     return CpSatHelper.variableDomain(varBuilder.build());
126   }
127 
128   private final CpModelProto.Builder modelBuilder;
129   private final int variableIndex;
130   private final IntegerVariableProto.Builder varBuilder;
131   private NotBooleanVariable negation_ = null;
132 }
133