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 package org.sat4j.pb.core;
29
30 import org.sat4j.core.Vec;
31 import org.sat4j.minisat.constraints.cnf.Lits;
32 import org.sat4j.minisat.core.AssertingClauseGenerator;
33 import org.sat4j.minisat.core.Constr;
34 import org.sat4j.minisat.core.ILits;
35 import org.sat4j.minisat.core.IOrder;
36 import org.sat4j.minisat.core.LearningStrategy;
37 import org.sat4j.minisat.core.Pair;
38 import org.sat4j.minisat.core.RestartStrategy;
39 import org.sat4j.minisat.core.SearchParams;
40 import org.sat4j.minisat.restarts.MiniSATRestarts;
41 import org.sat4j.pb.constraints.pb.ConflictMap;
42 import org.sat4j.pb.constraints.pb.IConflict;
43 import org.sat4j.pb.constraints.pb.PBConstr;
44 import org.sat4j.specs.IVec;
45
46
47
48
49
50 public class PBSolverCP<L extends ILits> extends PBSolver<L> {
51
52 private static final long serialVersionUID = 1L;
53
54
55
56
57
58
59 public PBSolverCP(AssertingClauseGenerator acg, LearningStrategy<L,PBDataStructureFactory<L>> learner,
60 PBDataStructureFactory<L> dsf, IOrder<L> order) {
61 super(acg, learner, dsf, new SearchParams(1.5, 100), order,new MiniSATRestarts());
62 }
63
64 public PBSolverCP(AssertingClauseGenerator acg, LearningStrategy<L,PBDataStructureFactory<L>> learner, PBDataStructureFactory<L> dsf, SearchParams params, IOrder<L> order, RestartStrategy restarter) {
65 super(acg, learner, dsf, params, order, restarter);
66 }
67
68 public PBSolverCP(AssertingClauseGenerator acg, LearningStrategy<L,PBDataStructureFactory<L>> learner, PBDataStructureFactory<L> dsf, SearchParams params, IOrder<L> order) {
69 super(acg, learner, dsf, params, order,new MiniSATRestarts());
70 }
71
72
73 @Override
74 public void analyze(Constr myconfl, Pair results) {
75 int litImplied = trail.last();
76 int currentLevel = voc.getLevel(litImplied);
77 IConflict confl = chooseConflict((PBConstr)myconfl, currentLevel);
78 initExplanation();
79 buildExplanation(litImplied,myconfl);
80 assert confl.slackConflict().signum() < 0;
81 while (!confl.isAssertive(currentLevel)) {
82 PBConstr constraint = (PBConstr)voc.getReason(litImplied);
83 buildExplanation(litImplied,constraint);
84
85 confl.resolve(constraint, litImplied, this);
86 assert confl.slackConflict().signum() <= 0;
87
88 if (trail.size() == 1)
89 break;
90 undoOne();
91
92 if (decisionLevel() == 0)
93 break;
94 litImplied = trail.last();
95 if (voc.getLevel(litImplied) != currentLevel) {
96 trailLim.pop();
97 confl.updateSlack(voc.getLevel(litImplied));
98 }
99 assert voc.getLevel(litImplied) <= currentLevel;
100 currentLevel = voc.getLevel(litImplied);
101 assert confl.slackIsCorrect(currentLevel);
102 assert currentLevel == decisionLevel();
103 assert litImplied > 1;
104 }
105 assert confl.isAssertive(currentLevel) || trail.size() == 1 || decisionLevel() == 0;
106
107 assert currentLevel == decisionLevel();
108 undoOne();
109
110
111
112 if ((confl.size()==0) || ((decisionLevel() == 0 || trail.size() == 0) && confl.slackConflict().signum() < 0)){
113 results.reason = null;
114 results.backtrackLevel= -1;
115 return;
116 }
117
118
119 PBConstr resConstr = (PBConstr) dsfactory
120 .createUnregisteredPseudoBooleanConstraint(confl);
121
122 results.reason = resConstr;
123
124
125
126
127 if (decisionLevel() == 0 || trail.size() == 0)
128 results.backtrackLevel = -1;
129 else
130 results.backtrackLevel = confl.getBacktrackLevel(currentLevel);
131 }
132
133 @Override
134 protected void analyzeAtRootLevel(Constr myconfl) {
135
136 int litImplied = trail.last();
137 initExplanation();
138 buildExplanation(litImplied,myconfl);
139 while (!trail.isEmpty()) {
140 PBConstr constraint = (PBConstr)voc.getReason(litImplied);
141 if (constraint != null)
142 buildExplanation(litImplied,constraint);
143 trail.pop();
144 if (!trail.isEmpty())
145 litImplied = trail.last();
146 }
147 }
148
149 IConflict chooseConflict(PBConstr myconfl, int level) {
150 return ConflictMap.createConflict(myconfl, level);
151 }
152
153 @Override
154 public String toString(String prefix) {
155 return prefix + "Cutting planes based inference ("
156 + this.getClass().getName() + ")\n" + super.toString(prefix);
157 }
158
159 private IVec<String> conflictVariables = new Vec<String>();
160 private IVec<String> conflictConstraints = new Vec<String>();
161
162 void initExplanation(){
163 conflictVariables.clear();
164 conflictConstraints.clear();
165 }
166
167 void buildExplanation(int lit, Constr c){
168 if ((listOfVariables != null) && (listOfVariables.contains(lit>>1))){
169 conflictVariables.push(Lits.toString(lit));
170 conflictConstraints.push(c.toString());
171 }
172 }
173
174 @Override
175 public String getExplanation(){
176 if (!conflictVariables.isEmpty()){
177 assert conflictVariables.size() == conflictConstraints.size();
178 StringBuffer sb = new StringBuffer();
179 sb.append("Variables and constraints involved in unsatisfiability : \n");
180 for(int i = 0; i<conflictVariables.size();i++){
181 sb.append("Var : "+conflictVariables.get(i));
182 sb.append(" - Constr : "+conflictConstraints.get(i));
183 sb.append("\n");
184 }
185 return sb.toString();
186 }
187 return "";
188 }
189 }