View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004, 2012 Artois University and CNRS
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    *  http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   *
19   * Based on the original MiniSat specification from:
20   *
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   *
27   * Contributors:
28   *   CRIL - initial API and implementation
29   *******************************************************************************/
30  package org.sat4j.pb.constraints;
31  
32  import static org.junit.Assert.assertEquals;
33  import static org.junit.Assert.assertFalse;
34  import static org.junit.Assert.assertTrue;
35  
36  import java.math.BigInteger;
37  import java.util.Collection;
38  
39  import org.junit.Test;
40  import org.sat4j.core.Vec;
41  import org.sat4j.core.VecInt;
42  import org.sat4j.pb.SolverFactory;
43  import org.sat4j.pb.tools.XplainPB;
44  import org.sat4j.specs.ContradictionException;
45  import org.sat4j.specs.IConstr;
46  import org.sat4j.specs.IVec;
47  import org.sat4j.specs.IVecInt;
48  import org.sat4j.specs.TimeoutException;
49  
50  public class TestQuickExplainPB {
51  
52      @Test
53      public void testGlobalInconsistency() throws ContradictionException,
54              TimeoutException {
55          XplainPB solver = new XplainPB(SolverFactory.newDefault());
56          solver.newVar(2);
57          IVec<BigInteger> coeffs = new Vec<BigInteger>();
58          coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
59          IVecInt clause = new VecInt();
60          clause.push(1).push(2);
61          solver.addPseudoBoolean(clause, coeffs, true, BigInteger.ONE);
62          clause.clear();
63          coeffs.clear();
64          clause.push(1).push(-2);
65          coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
66          solver.addPseudoBoolean(clause, coeffs, true, BigInteger.ONE);
67          clause.clear();
68          coeffs.clear();
69          clause.push(-1).push(2);
70          coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
71          solver.addPseudoBoolean(clause, coeffs, true, BigInteger.ONE);
72          clause.clear();
73          coeffs.clear();
74          clause.push(-1).push(-2);
75          coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
76          solver.addPseudoBoolean(clause, coeffs, true, BigInteger.ONE);
77          clause.clear();
78          coeffs.clear();
79          assertFalse(solver.isSatisfiable());
80          Collection<IConstr> explanation = solver.explain();
81          assertEquals(4, explanation.size());
82      }
83  
84      @Test
85      public void testGlobalInconsistencyPB() throws ContradictionException,
86              TimeoutException {
87          XplainPB solver = new XplainPB(SolverFactory.newDefault());
88          solver.newVar(4);
89          IVec<BigInteger> coeffs = new Vec<BigInteger>();
90          coeffs.push(BigInteger.valueOf(3)).push(BigInteger.valueOf(2))
91                  .push(BigInteger.ONE);
92          IVecInt clause = new VecInt();
93          clause.push(1).push(2).push(3);
94          IConstr c1 = solver.addPseudoBoolean(clause, coeffs, true,
95                  BigInteger.valueOf(4));
96          clause.clear();
97          coeffs.clear();
98          clause.push(-1).push(3).push(4);
99          coeffs.push(BigInteger.valueOf(3)).push(BigInteger.ONE)
100                 .push(BigInteger.ONE);
101         IConstr c2 = solver.addPseudoBoolean(clause, coeffs, true,
102                 BigInteger.valueOf(4));
103         clause.clear();
104         coeffs.clear();
105         assertFalse(solver.isSatisfiable());
106         Collection<IConstr> explanation = solver.explain();
107         assertEquals(2, explanation.size());
108         System.out.println(explanation);
109         assertTrue(explanation.contains(c1));
110         assertTrue(explanation.contains(c2));
111     }
112 
113     @Test
114     public void testAlmostGlobalInconsistency() throws ContradictionException,
115             TimeoutException {
116         XplainPB solver = new XplainPB(SolverFactory.newDefault());
117         solver.newVar(3);
118         IVec<BigInteger> coeffs = new Vec<BigInteger>();
119         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
120         IVecInt clause = new VecInt();
121         clause.push(1).push(2);
122         IConstr c1 = solver.addPseudoBoolean(clause, coeffs, true,
123                 BigInteger.ONE);
124         clause.clear();
125         coeffs.clear();
126         clause.push(1).push(-2);
127         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
128         IConstr c2 = solver.addPseudoBoolean(clause, coeffs, true,
129                 BigInteger.ONE);
130         clause.clear();
131         coeffs.clear();
132         clause.push(-1).push(2);
133         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
134         IConstr c3 = solver.addPseudoBoolean(clause, coeffs, true,
135                 BigInteger.ONE);
136         clause.clear();
137         coeffs.clear();
138         clause.push(-1).push(-2);
139         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
140         IConstr c4 = solver.addPseudoBoolean(clause, coeffs, true,
141                 BigInteger.ONE);
142         clause.clear();
143         coeffs.clear();
144         clause.push(1).push(3);
145         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
146         solver.addPseudoBoolean(clause, coeffs, true, BigInteger.ONE);
147         clause.clear();
148         coeffs.clear();
149         assertFalse(solver.isSatisfiable());
150         Collection<IConstr> explanation = solver.explain();
151         assertEquals(4, explanation.size());
152         assertTrue(explanation.contains(c1));
153         assertTrue(explanation.contains(c2));
154         assertTrue(explanation.contains(c3));
155         assertTrue(explanation.contains(c4));
156     }
157 
158     @Test
159     public void testAlmostGlobalInconsistencyII()
160             throws ContradictionException, TimeoutException {
161         XplainPB solver = new XplainPB(SolverFactory.newDefault());
162         solver.newVar(3);
163         IVec<BigInteger> coeffs = new Vec<BigInteger>();
164         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
165         IVecInt clause = new VecInt();
166         clause.push(1).push(2);
167         IConstr c1 = solver.addPseudoBoolean(clause, coeffs, true,
168                 BigInteger.ONE);
169         clause.clear();
170         coeffs.clear();
171         clause.push(1).push(-2);
172         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
173         IConstr c2 = solver.addPseudoBoolean(clause, coeffs, true,
174                 BigInteger.ONE);
175         clause.clear();
176         coeffs.clear();
177         clause.push(1).push(3);
178         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
179         solver.addPseudoBoolean(clause, coeffs, true, BigInteger.ONE);
180         clause.clear();
181         coeffs.clear();
182         clause.push(-1).push(2);
183         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
184         IConstr c4 = solver.addPseudoBoolean(clause, coeffs, true,
185                 BigInteger.ONE);
186         clause.clear();
187         coeffs.clear();
188         clause.push(-1).push(-2);
189         coeffs.push(BigInteger.ONE).push(BigInteger.ONE);
190         IConstr c5 = solver.addPseudoBoolean(clause, coeffs, true,
191                 BigInteger.ONE);
192         clause.clear();
193         coeffs.clear();
194         assertFalse(solver.isSatisfiable());
195         Collection<IConstr> explanation = solver.explain();
196         assertEquals(4, explanation.size());
197         assertTrue(explanation.contains(c1));
198         assertTrue(explanation.contains(c2));
199         assertTrue(explanation.contains(c4));
200         assertTrue(explanation.contains(c5));
201     }
202 
203     @Test
204     public void testAlmostGlobalInconsistencyPB()
205             throws ContradictionException, TimeoutException {
206         XplainPB solver = new XplainPB(SolverFactory.newDefault());
207         solver.newVar(4);
208         IVec<BigInteger> coeffs = new Vec<BigInteger>();
209         coeffs.push(BigInteger.valueOf(3)).push(BigInteger.valueOf(2))
210                 .push(BigInteger.ONE);
211         IVecInt clause = new VecInt();
212         clause.push(1).push(2).push(3);
213         IConstr c1 = solver.addPseudoBoolean(clause, coeffs, true,
214                 BigInteger.valueOf(4));
215         clause.clear();
216         coeffs.clear();
217         clause.push(2).push(-3).push(4);
218         coeffs.push(BigInteger.ONE).push(BigInteger.ONE).push(BigInteger.ONE);
219         solver.addPseudoBoolean(clause, coeffs, true, BigInteger.valueOf(2));
220         clause.clear();
221         coeffs.clear();
222         clause.push(-1).push(3).push(4);
223         coeffs.push(BigInteger.valueOf(3)).push(BigInteger.ONE)
224                 .push(BigInteger.ONE);
225         IConstr c3 = solver.addPseudoBoolean(clause, coeffs, true,
226                 BigInteger.valueOf(4));
227         clause.clear();
228         coeffs.clear();
229         assertFalse(solver.isSatisfiable());
230         Collection<IConstr> explanation = solver.explain();
231         assertEquals(2, explanation.size());
232         assertTrue(explanation.contains(c1));
233         assertTrue(explanation.contains(c3));
234     }
235 
236     @Test
237     public void testEclipsePatchEncoding() throws ContradictionException,
238             TimeoutException {
239         XplainPB solver = new XplainPB(SolverFactory.newDefault());
240         solver.newVar(12);
241         IVecInt clause = new VecInt();
242         clause.push(-1).push(-2).push(3);
243         solver.addClause(clause);
244         clause.clear();
245         clause.push(-2).push(1).push(5);
246         solver.addClause(clause);
247         clause.clear();
248         clause.push(-7).push(-2).push(8);
249         solver.addClause(clause);
250         clause.clear();
251         clause.push(-2).push(7).push(5);
252         solver.addClause(clause);
253         clause.clear();
254         clause.push(3).push(5).push(8);
255         solver.addAtMost(clause, 1);
256         clause.clear();
257         clause.push(-12).push(1);
258         solver.addClause(clause);
259         clause.clear();
260         clause.push(-12).push(2);
261         IConstr patch = solver.addClause(clause);
262         clause.clear();
263         clause.push(-12).push(7);
264         solver.addClause(clause);
265         IVecInt assump = new VecInt();
266         assump.push(12);
267         assertFalse(solver.isSatisfiable(assump));
268         Collection<IConstr> explanation = solver.explain();
269         assertEquals(6, explanation.size());
270         assertTrue(explanation.contains(patch));
271     }
272 
273     @Test
274     public void testUpdatedEclipsePatchEncoding()
275             throws ContradictionException, TimeoutException {
276         XplainPB solver = new XplainPB(SolverFactory.newDefault());
277         solver.newVar(12);
278         IVecInt clause = new VecInt();
279         clause.push(-1).push(-2).push(3);
280         solver.addClause(clause);
281         clause.clear();
282         clause.push(-7).push(-2).push(8);
283         solver.addClause(clause);
284         clause.clear();
285         clause.push(-2).push(7).push(5).push(1);
286         solver.addClause(clause);
287         clause.clear();
288         clause.push(3).push(5).push(8);
289         solver.addAtMost(clause, 1);
290         clause.clear();
291         clause.push(-12).push(1);
292         solver.addClause(clause);
293         clause.clear();
294         clause.push(-12).push(2);
295         solver.addClause(clause);
296         clause.clear();
297         clause.push(-12).push(7);
298         IConstr patch = solver.addClause(clause);
299         IVecInt assump = new VecInt();
300         assump.push(12);
301         assertFalse(solver.isSatisfiable(assump));
302         Collection<IConstr> explanation = solver.explain();
303         assertEquals(6, explanation.size());
304         assertTrue(explanation.contains(patch));
305     }
306 }