View Javadoc

1   /*******************************************************************************
2   * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre
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 pseudo boolean algorithms described in:
20  * A fast pseudo-Boolean constraint solver Chai, D.; Kuehlmann, A.
21  * Computer-Aided Design of Integrated Circuits and Systems, IEEE Transactions on
22  * Volume 24, Issue 3, March 2005 Page(s): 305 - 317
23  * 
24  * and 
25  * Heidi E. Dixon, 2004. Automating Pseudo-Boolean Inference within a DPLL 
26  * Framework. Ph.D. Dissertation, University of Oregon.
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   * @author parrain To change the template for this generated type comment go to
48   *         Window - Preferences - Java - Code Generation - Code and Comments
49   */
50  public class PBSolverCP<L extends ILits> extends PBSolver<L> {
51  
52      private static final long serialVersionUID = 1L;
53      
54      /**
55       * @param acg
56       * @param learner
57       * @param dsf
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              // result of the resolution is in the conflict (confl)
85              confl.resolve(constraint, litImplied, this);
86              assert confl.slackConflict().signum() <= 0;
87              // implication trail is reduced
88              if (trail.size() == 1)
89                  break;
90              undoOne();
91              //assert decisionLevel() >= 0;
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         // necessary informations to build a PB-constraint
111         // are kept from the conflict
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         // assertive PB-constraint is build and referenced
119         PBConstr resConstr = (PBConstr) dsfactory
120               .createUnregisteredPseudoBooleanConstraint(confl);
121         
122         results.reason = resConstr;
123         
124         // the conflict give the highest decision level for the backtrack 
125         // (which is less than current level) 
126     	// assert confl.isAssertive(currentLevel);
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         // first literal implied in the conflict
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 }