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.constraints;
29
30 import java.lang.reflect.Field;
31 import java.math.BigInteger;
32
33 import org.sat4j.core.Vec;
34 import org.sat4j.core.VecInt;
35 import org.sat4j.minisat.constraints.AbstractDataStructureFactory;
36 import org.sat4j.minisat.constraints.cnf.Clauses;
37 import org.sat4j.minisat.constraints.cnf.LearntBinaryClause;
38 import org.sat4j.minisat.constraints.cnf.LearntHTClause;
39 import org.sat4j.minisat.constraints.cnf.Lits;
40 import org.sat4j.minisat.constraints.cnf.OriginalBinaryClause;
41 import org.sat4j.minisat.constraints.cnf.OriginalHTClause;
42 import org.sat4j.minisat.constraints.cnf.UnitClause;
43 import org.sat4j.minisat.core.Constr;
44 import org.sat4j.minisat.core.ILits;
45 import org.sat4j.pb.constraints.pb.AtLeastPB;
46 import org.sat4j.pb.constraints.pb.IDataStructurePB;
47 import org.sat4j.pb.constraints.pb.Pseudos;
48 import org.sat4j.pb.core.PBDataStructureFactory;
49 import org.sat4j.specs.ContradictionException;
50 import org.sat4j.specs.IVec;
51 import org.sat4j.specs.IVecInt;
52
53
54
55
56
57 public abstract class AbstractPBDataStructureFactory extends
58 AbstractDataStructureFactory implements PBDataStructureFactory {
59
60 interface INormalizer {
61 PBContainer nice(IVecInt ps, IVec<BigInteger> bigCoefs,
62 boolean moreThan, BigInteger bigDeg, ILits voc)
63 throws ContradictionException;
64 }
65
66 public static final INormalizer FOR_COMPETITION = new INormalizer() {
67
68 private static final long serialVersionUID = 1L;
69
70 public PBContainer nice(IVecInt literals, IVec<BigInteger> coefs,
71 boolean moreThan, BigInteger degree, ILits voc)
72 throws ContradictionException {
73 if (literals.size() != coefs.size())
74 throw new IllegalArgumentException(
75 "Number of coeff and literals are different!!!");
76 IVecInt cliterals = new VecInt(literals.size());
77 literals.copyTo(cliterals);
78 IVec<BigInteger> ccoefs = new Vec<BigInteger>(literals.size());
79 coefs.copyTo(ccoefs);
80 for (int i = 0; i < cliterals.size();) {
81 if (ccoefs.get(i).equals(BigInteger.ZERO)) {
82 cliterals.delete(i);
83 ccoefs.delete(i);
84 } else {
85 i++;
86 }
87 }
88 int[] theLits = new int[cliterals.size()];
89 cliterals.copyTo(theLits);
90 BigInteger[] normCoefs = new BigInteger[ccoefs.size()];
91 ccoefs.copyTo(normCoefs);
92 BigInteger degRes = Pseudos.niceParametersForCompetition(theLits,
93 normCoefs, moreThan, degree);
94 return new PBContainer(theLits, normCoefs, degRes);
95
96 }
97
98 };
99
100 public static final INormalizer NO_COMPETITION = new INormalizer() {
101
102 private static final long serialVersionUID = 1L;
103
104 public PBContainer nice(IVecInt literals, IVec<BigInteger> coefs,
105 boolean moreThan, BigInteger degree, ILits voc)
106 throws ContradictionException {
107 IDataStructurePB res = Pseudos.niceParameters(literals, coefs,
108 moreThan, degree, voc);
109 int size = res.size();
110 int[] theLits = new int[size];
111 BigInteger[] theCoefs = new BigInteger[size];
112 res.buildConstraintFromMapPb(theLits, theCoefs);
113 BigInteger theDegree = res.getDegree();
114 return new PBContainer(theLits, theCoefs, theDegree);
115 }
116 };
117
118 private INormalizer norm = FOR_COMPETITION;
119
120 protected INormalizer getNormalizer() {
121 return norm;
122 }
123
124 public void setNormalizer(String simp) {
125 Field f;
126 try {
127 f = AbstractPBDataStructureFactory.class.getDeclaredField(simp);
128 norm = (INormalizer) f.get(this);
129 } catch (Exception e) {
130 e.printStackTrace();
131 norm = FOR_COMPETITION;
132 }
133 }
134
135 public void setNormalizer(INormalizer normalizer) {
136 norm = normalizer;
137 }
138
139
140
141
142 private static final long serialVersionUID = 1L;
143
144 public Constr createClause(IVecInt literals) throws ContradictionException {
145 IVecInt v = Clauses.sanityCheck(literals, getVocabulary(), solver);
146 if (v == null)
147 return null;
148 if (v.size() == 2) {
149 return OriginalBinaryClause.brandNewClause(solver, getVocabulary(),
150 v);
151 }
152 return OriginalHTClause.brandNewClause(solver, getVocabulary(), v);
153 }
154
155 public Constr createUnregisteredClause(IVecInt literals) {
156 if (literals.size() == 1) {
157 return new UnitClause(literals.last());
158 }
159 if (literals.size() == 2) {
160 return new LearntBinaryClause(literals, getVocabulary());
161 }
162 return new LearntHTClause(literals, getVocabulary());
163 }
164
165 @Override
166 public Constr createCardinalityConstraint(IVecInt literals, int degree)
167 throws ContradictionException {
168 return AtLeastPB.atLeastNew(solver, getVocabulary(), literals, degree);
169 }
170
171 public Constr createPseudoBooleanConstraint(IVecInt literals,
172 IVec<BigInteger> coefs, boolean moreThan, BigInteger degree)
173 throws ContradictionException {
174 PBContainer res = getNormalizer().nice(literals, coefs, moreThan,
175 degree, getVocabulary());
176 return constraintFactory(res.lits, res.coefs, res.degree);
177 }
178
179 public Constr createUnregisteredPseudoBooleanConstraint(
180 IDataStructurePB dspb) {
181 return learntConstraintFactory(dspb);
182 }
183
184 protected abstract Constr constraintFactory(int[] literals,
185 BigInteger[] coefs, BigInteger degree)
186 throws ContradictionException;
187
188 protected abstract Constr learntConstraintFactory(IDataStructurePB dspb);
189
190 @Override
191 protected ILits createLits() {
192 return new Lits();
193 }
194
195 }