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 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  *******************************************************************************/
28  package org.sat4j.minisat.constraints.card;
29  
30  import java.io.Serializable;
31  
32  import org.sat4j.minisat.constraints.cnf.Lits;
33  import org.sat4j.minisat.core.Constr;
34  import org.sat4j.minisat.core.ILits;
35  import org.sat4j.minisat.core.Undoable;
36  import org.sat4j.minisat.core.UnitPropagationListener;
37  import org.sat4j.specs.ContradictionException;
38  import org.sat4j.specs.IVecInt;
39  
40  /**
41   * Cardinality constraint.
42   *
43   * @author leberre 
44   */
45  public class AtLeast implements Constr, Undoable, Serializable {
46  
47      private static final long serialVersionUID = 1L;
48  
49      /** number of allowed falsified literal */
50      protected int maxUnsatisfied;
51  
52      /** current number of falsified literals */
53      private int counter;
54  
55      /**
56       * constraint literals
57       */
58      protected final int[] lits;
59  
60      protected final ILits voc;
61  
62      /**
63       * @param ps
64       *            a vector of literals
65       * @param degree
66       *            the minimal number of satisfied literals
67       */
68      protected AtLeast(ILits voc, IVecInt ps, int degree) {
69          maxUnsatisfied = ps.size() - degree;
70          this.voc = voc;
71          counter = 0;
72          lits = new int[ps.size()];
73          ps.moveTo(lits);
74          for (int q : lits) {
75              voc.attach(q ^ 1, this);
76          }
77      }
78  
79      public static AtLeast atLeastNew(UnitPropagationListener s, ILits voc,
80              IVecInt ps, int n) throws ContradictionException {
81          int degree = Cards.niceParameters(s, voc, ps, n);
82          if (degree == 0)
83              return null;
84          return new AtLeast(voc, ps, degree);
85      }
86  
87      /*
88       * (non-Javadoc)
89       * 
90       * @see Constr#remove(Solver)
91       */
92      public void remove() {
93          for (int q : lits) {
94              voc.attaches(q ^ 1).remove(this);
95          }
96      }
97  
98      /*
99       * (non-Javadoc)
100      * 
101      * @see Constr#propagate(Solver, Lit)
102      */
103     public boolean propagate(UnitPropagationListener s, int p) {
104         // remet la clause dans la liste des clauses regardees
105         voc.attach(p, this);
106 
107         if (counter == maxUnsatisfied)
108             return false;
109 
110         counter++;
111         voc.undos(p).push(this);
112 
113         // If no more can be false, enqueue the rest:
114         if (counter == maxUnsatisfied)
115             for (int q : lits) {
116                 if (voc.isUnassigned(q) && !s.enqueue(q, this)) {
117                     return false;
118                 }
119             }
120         return true;
121     }
122 
123     /*
124      * (non-Javadoc)
125      * 
126      * @see Constr#simplify(Solver)
127      */
128     public boolean simplify() {
129         return false;
130     }
131 
132     /*
133      * (non-Javadoc)
134      * 
135      * @see Constr#undo(Solver, Lit)
136      */
137     public void undo(int p) {
138         counter--;
139     }
140 
141     /*
142      * (non-Javadoc)
143      * 
144      * @see Constr#calcReason(Solver, Lit, Vec)
145      */
146     public void calcReason(int p, IVecInt outReason) {
147         int c = (p == ILits.UNDEFINED) ? -1 : 0;
148         for (int q : lits) {
149             if (voc.isFalsified(q)) {
150                 outReason.push(q ^ 1);
151                 if (++c == maxUnsatisfied)
152                     return;
153             }
154         }
155     }
156 
157     /*
158      * (non-Javadoc)
159      * 
160      * @see org.sat4j.minisat.datatype.Constr#learnt()
161      */
162     public boolean learnt() {
163         // Ces contraintes ne sont pas apprises pour le moment.
164         return false;
165     }
166 
167     /*
168      * (non-Javadoc)
169      * 
170      * @see org.sat4j.minisat.datatype.Constr#getActivity()
171      */
172     public double getActivity() {
173         // TODO Auto-generated method stub
174         return 0;
175     }
176 
177     /*
178      * (non-Javadoc)
179      * 
180      * @see org.sat4j.minisat.datatype.Constr#incActivity(double)
181      */
182     public void incActivity(double claInc) {
183         // TODO Auto-generated method stub
184 
185     }
186 
187     /*
188      * For learnt clauses only @author leberre
189      */
190     public boolean locked() {
191         // FIXME need to be adapted to AtLeast
192         // return lits[0].getReason() == this;
193         return true;
194     }
195 
196     public void setLearnt() {
197         throw new UnsupportedOperationException();
198     }
199 
200     public void register() {
201         throw new UnsupportedOperationException();
202     }
203 
204     public int size() {
205         return lits.length;
206     }
207 
208     public int get(int i) {
209         return lits[i];
210     }
211 
212     public void rescaleBy(double d) {
213         throw new UnsupportedOperationException();
214     }
215 
216     public void assertConstraint(UnitPropagationListener s) {
217         throw new UnsupportedOperationException();
218     }
219 
220     /**
221      * Cha?ne repr?sentant la contrainte
222      * 
223      * @return Cha?ne repr?sentant la contrainte
224      */
225     @Override
226     public String toString() {
227         StringBuffer stb = new StringBuffer();
228         stb.append("Card (" + lits.length + ") : ");
229         for (int i = 0; i < lits.length; i++) {
230             // if (voc.isUnassigned(lits[i])) {
231             stb.append(" + "); //$NON-NLS-1$
232             stb.append(Lits.toString(this.lits[i]));
233             stb.append("[");
234             stb.append(voc.valueToString(lits[i]));
235             stb.append("@");
236             stb.append(voc.getLevel(lits[i]));
237             stb.append("]");
238             stb.append(" ");
239             stb.append(" "); //$NON-NLS-1$
240         }
241         stb.append(">= "); //$NON-NLS-1$
242         stb.append(size() - maxUnsatisfied);
243 
244         return stb.toString();
245     }
246 
247 }