1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.sat4j.minisat.constraints.cnf;
31
32 import static org.sat4j.core.LiteralsUtils.neg;
33
34 import java.io.Serializable;
35
36 import org.sat4j.minisat.core.Constr;
37 import org.sat4j.minisat.core.ILits;
38 import org.sat4j.minisat.core.Propagatable;
39 import org.sat4j.specs.IVecInt;
40 import org.sat4j.specs.UnitPropagationListener;
41
42
43
44
45
46
47
48 public abstract class BinaryClause implements Propagatable, Constr,
49 Serializable {
50
51 private static final long serialVersionUID = 1L;
52
53 protected double activity;
54
55 private final ILits voc;
56
57 protected int head;
58
59 protected int tail;
60
61
62
63
64
65
66
67
68
69 public BinaryClause(IVecInt ps, ILits voc) {
70 assert ps.size() == 2;
71 this.head = ps.get(0);
72 this.tail = ps.get(1);
73 this.voc = voc;
74 this.activity = 0;
75 }
76
77
78
79
80
81
82 public void calcReason(int p, IVecInt outReason) {
83 if (this.voc.isFalsified(this.head)) {
84 outReason.push(neg(this.head));
85 }
86 if (this.voc.isFalsified(this.tail)) {
87 outReason.push(neg(this.tail));
88 }
89 }
90
91
92
93
94
95
96 public void remove(UnitPropagationListener upl) {
97 this.voc.watches(neg(this.head)).remove(this);
98 this.voc.watches(neg(this.tail)).remove(this);
99 }
100
101
102
103
104
105
106 public boolean simplify() {
107 if (this.voc.isSatisfied(this.head) || this.voc.isSatisfied(this.tail)) {
108 return true;
109 }
110 return false;
111 }
112
113 public boolean propagate(UnitPropagationListener s, int p) {
114 this.voc.watch(p, this);
115 if (this.head == neg(p)) {
116 return s.enqueue(this.tail, this);
117 }
118 assert this.tail == neg(p);
119 return s.enqueue(this.head, this);
120 }
121
122
123
124
125 public boolean locked() {
126 return this.voc.getReason(this.head) == this
127 || this.voc.getReason(this.tail) == this;
128 }
129
130
131
132
133 public double getActivity() {
134 return this.activity;
135 }
136
137 @Override
138 public String toString() {
139 StringBuffer stb = new StringBuffer();
140 stb.append(Lits.toString(this.head));
141 stb.append("[");
142 stb.append(this.voc.valueToString(this.head));
143 stb.append("]");
144 stb.append(" ");
145 stb.append(Lits.toString(this.tail));
146 stb.append("[");
147 stb.append(this.voc.valueToString(this.tail));
148 stb.append("]");
149 return stb.toString();
150 }
151
152
153
154
155
156
157
158
159
160 public int get(int i) {
161 if (i == 0) {
162 return this.head;
163 }
164 assert i == 1;
165 return this.tail;
166 }
167
168
169
170
171 public void rescaleBy(double d) {
172 this.activity *= d;
173 }
174
175 public int size() {
176 return 2;
177 }
178
179 public void assertConstraint(UnitPropagationListener s) {
180
181 boolean ret = s.enqueue(this.head, this);
182 assert ret;
183 }
184
185 public void assertConstraintIfNeeded(UnitPropagationListener s) {
186 if (voc.isFalsified(this.tail)) {
187 boolean ret = s.enqueue(this.head, this);
188 assert ret;
189 }
190 }
191
192 public ILits getVocabulary() {
193 return this.voc;
194 }
195
196 public int[] getLits() {
197 int[] tmp = new int[2];
198 tmp[0] = this.head;
199 tmp[1] = this.tail;
200 return tmp;
201 }
202
203 @Override
204 public boolean equals(Object obj) {
205 if (obj == null) {
206 return false;
207 }
208 try {
209 BinaryClause wcl = (BinaryClause) obj;
210 if (wcl.head != this.head || wcl.tail != this.tail) {
211 return false;
212 }
213 return true;
214 } catch (ClassCastException e) {
215 return false;
216 }
217 }
218
219 @Override
220 public int hashCode() {
221 long sum = this.head + this.tail;
222 return (int) sum / 2;
223 }
224
225 public void register() {
226 this.voc.watch(neg(this.head), this);
227 this.voc.watch(neg(this.tail), this);
228 }
229
230 public boolean canBePropagatedMultipleTimes() {
231 return false;
232 }
233
234 public Constr toConstraint() {
235 return this;
236 }
237
238 public void calcReasonOnTheFly(int p, IVecInt trail, IVecInt outReason) {
239 calcReason(p, outReason);
240 }
241 }