1 /******************************************
2 Copyright (c) 2016, Mate Soos
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 ***********************************************/
22 
23 #include "gtest/gtest.h"
24 
25 #include <fstream>
26 
27 #include "src/solver.h"
28 #include "src/xorfinder.h"
29 #include "src/solverconf.h"
30 #include "src/occsimplifier.h"
31 using namespace CMSat;
32 #include "test_helper.h"
33 #include "src/toplevelgaussabst.h"
34 #ifdef USE_M4RI
35 #include "src/toplevelgauss.h"
36 #endif
37 
38 struct xor_finder : public ::testing::Test {
xor_finderxor_finder39     xor_finder()
40     {
41         must_inter.store(false, std::memory_order_relaxed);
42         SolverConf conf;
43         s = new Solver(&conf, &must_inter);
44         s->new_vars(30);
45         occsimp = s->occsimplifier;
46     }
~xor_finderxor_finder47     ~xor_finder()
48     {
49         delete s;
50     }
51     Solver* s = NULL;
52     OccSimplifier* occsimp = NULL;
53     std::atomic<bool> must_inter;
54 };
55 
TEST_F(xor_finder,find_none)56 TEST_F(xor_finder, find_none)
57 {
58     s->add_clause_outer(str_to_cl("1, 2"));
59     s->add_clause_outer(str_to_cl("-1, -2"));
60 
61     occsimp->setup();
62     XorFinder finder(occsimp, s);
63     finder.grab_mem();
64     finder.find_xors();
65     EXPECT_EQ(finder.xors.size(), 0U);
66 }
67 
TEST_F(xor_finder,find_tri_1)68 TEST_F(xor_finder, find_tri_1)
69 {
70     s->add_clause_outer(str_to_cl("1, 2, 3"));
71     s->add_clause_outer(str_to_cl("-1, -2, 3"));
72     s->add_clause_outer(str_to_cl("-1, 2, -3"));
73     s->add_clause_outer(str_to_cl("1, -2, -3"));
74 
75     occsimp->setup();
76     XorFinder finder(occsimp, s);
77     finder.find_xors();
78     check_xors_contains(finder.xors, "1, 2, 3 = 1");
79 }
80 
TEST_F(xor_finder,find_tri_2)81 TEST_F(xor_finder, find_tri_2)
82 {
83     s->add_clause_outer(str_to_cl("-1, 2, 3"));
84     s->add_clause_outer(str_to_cl("1, -2, 3"));
85     s->add_clause_outer(str_to_cl("1, 2, -3"));
86     s->add_clause_outer(str_to_cl("-1, -2, -3"));
87 
88     occsimp->setup();
89     XorFinder finder(occsimp, s);
90     finder.find_xors();
91     check_xors_eq(finder.xors, "1, 2, 3 = 0");
92 }
93 
TEST_F(xor_finder,find_tri_3)94 TEST_F(xor_finder, find_tri_3)
95 {
96     s->add_clause_outer(str_to_cl("-1, 2, 3"));
97     s->add_clause_outer(str_to_cl("1, -2, 3"));
98     s->add_clause_outer(str_to_cl("1, 2, -3"));
99     s->add_clause_outer(str_to_cl("-1, -2, -3"));
100 
101     s->add_clause_outer(str_to_cl("1, 2, 3"));
102     s->add_clause_outer(str_to_cl("-1, -2, 3"));
103     s->add_clause_outer(str_to_cl("-1, 2, -3"));
104     s->add_clause_outer(str_to_cl("1, -2, -3"));
105 
106     occsimp->setup();
107     XorFinder finder(occsimp, s);
108     finder.find_xors();
109     check_xors_contains(finder.xors, "1, 2, 3 = 0");
110     check_xors_contains(finder.xors, "1, 2, 3 = 1");
111 }
112 
113 
TEST_F(xor_finder,find_4_1)114 TEST_F(xor_finder, find_4_1)
115 {
116     s->add_clause_outer(str_to_cl("-1, 2, 3, 4"));
117     s->add_clause_outer(str_to_cl("1, -2, 3, 4"));
118     s->add_clause_outer(str_to_cl("1, 2, -3, 4"));
119     s->add_clause_outer(str_to_cl("1, 2, 3, -4"));
120 
121     s->add_clause_outer(str_to_cl("1, -2, -3, -4"));
122     s->add_clause_outer(str_to_cl("-1, 2, -3, -4"));
123     s->add_clause_outer(str_to_cl("-1, -2, 3, -4"));
124     s->add_clause_outer(str_to_cl("-1, -2, -3, 4"));
125 
126     occsimp->setup();
127     XorFinder finder(occsimp, s);
128     finder.find_xors();
129     check_xors_eq(finder.xors, "1, 2, 3, 4 = 0;");
130 }
131 
TEST_F(xor_finder,find_4_4)132 TEST_F(xor_finder, find_4_4)
133 {
134     s->add_clause_outer(str_to_cl("-1, -2, 3, 4"));
135     s->add_clause_outer(str_to_cl("1, -2, -3, 4"));
136     s->add_clause_outer(str_to_cl("1, 2, -3, -4"));
137     s->add_clause_outer(str_to_cl("-1, 2,  -3, 4"));
138     s->add_clause_outer(str_to_cl("-1, 2,  3, -4"));
139     s->add_clause_outer(str_to_cl("1, -2,  3, -4"));
140     s->add_clause_outer(str_to_cl("-1, -2, -3, -4"));
141     s->add_clause_outer(str_to_cl("1, 2, 3, 4"));
142 
143     occsimp->setup();
144     XorFinder finder(occsimp, s);
145     finder.find_xors();
146     check_xors_eq(finder.xors, "1, 2, 3, 4 = 1");
147 }
148 
149 /*
150  * These tests only work if the matching is non-exact
151  * i.e. if size is not checked for equality
152  */
TEST_F(xor_finder,find_4_2)153 TEST_F(xor_finder, find_4_2)
154 {
155     s->add_clause_outer(str_to_cl("-1, 2, 3, 4"));
156     s->add_clause_outer(str_to_cl("1, -2, 3, 4"));
157     s->add_clause_outer(str_to_cl("1, 2, -3, 4"));
158     s->add_clause_outer(str_to_cl("1, 2, 3"));
159 
160     s->add_clause_outer(str_to_cl("1, -2, -3, -4"));
161     s->add_clause_outer(str_to_cl("-1, 2, -3, -4"));
162     s->add_clause_outer(str_to_cl("-1, -2, 3, -4"));
163     s->add_clause_outer(str_to_cl("-1, -2, -3, 4"));
164 
165     occsimp->setup();
166     XorFinder finder(occsimp, s);
167     finder.find_xors();
168     check_xors_eq(finder.xors, "1, 2, 3, 4 = 0;");
169 }
170 
TEST_F(xor_finder,find_4_3)171 TEST_F(xor_finder, find_4_3)
172 {
173     s->add_clause_outer(str_to_cl("-1, 2, 3, 4"));
174     s->add_clause_outer(str_to_cl("1, -2, 3, 4"));
175     s->add_clause_outer(str_to_cl("1, 2, -3, 4"));
176     s->add_clause_outer(str_to_cl("1, 2, 3"));
177 
178     s->add_clause_outer(str_to_cl("1, -2, -3, -4"));
179     s->add_clause_outer(str_to_cl("-1, 2, -3, -4"));
180     s->add_clause_outer(str_to_cl("-1, -2, 3, -4"));
181     s->add_clause_outer(str_to_cl("-1, -3, 4"));
182 
183     occsimp->setup();
184     XorFinder finder(occsimp, s);
185     finder.find_xors();
186     check_xors_eq(finder.xors, "1, 2, 3, 4 = 0;");
187 }
188 
189 /*
190 //Finder pruning is too strong and we don't find this one
191 TEST_F(xor_finder, find_5_2)
192 {
193     s->add_clause_outer(str_to_cl("-1, -2, 3, 4, 5"));
194     s->add_clause_outer(str_to_cl("-1, 2, -3"));
195     s->add_clause_outer(str_to_cl("-1, 2, 3"));
196 
197     s->add_clause_outer(str_to_cl("1, -2, -3, 4, 5"));
198     s->add_clause_outer(str_to_cl("1, -2, 3, -4, 5"));
199     s->add_clause_outer(str_to_cl("1, -2, 3, 4, -5"));
200 
201     s->add_clause_outer(str_to_cl("1, 2, -3, -4, 5"));
202     s->add_clause_outer(str_to_cl("1, 2, -3, 4, -5"));
203 
204     s->add_clause_outer(str_to_cl("1, 2, 3, -4, -5"));
205 
206     //
207 
208     s->add_clause_outer(str_to_cl("1, -2, -3, -4, -5"));
209     s->add_clause_outer(str_to_cl("-1, 2, -3, -4, -5"));
210     s->add_clause_outer(str_to_cl("-1, -2, 3, -4, -5"));
211     s->add_clause_outer(str_to_cl("-1, -2, -3, 4, -5"));
212     s->add_clause_outer(str_to_cl("-1, -2, -3, -4, 5"));
213 
214     s->add_clause_outer(str_to_cl("1, 2, 3, 4, 5"));
215 
216     occsimp->setup();
217     XorFinder finder(occsimp, s);
218     finder.find_xors();
219     check_xors_eq(finder.xors, "1, 2, 3, 4, 5 = 1;");
220 }*/
221 
TEST_F(xor_finder,find_4_5)222 TEST_F(xor_finder, find_4_5)
223 {
224     s->add_clause_outer(str_to_cl("-1, -2, 3, 4"));
225     s->add_clause_outer(str_to_cl("1, -2, -3, 4"));
226     s->add_clause_outer(str_to_cl("1, 2, -3, -4"));
227     s->add_clause_outer(str_to_cl("-1, 2,  -3, 4"));
228     s->add_clause_outer(str_to_cl("-1, 2,  3, -4"));
229     s->add_clause_outer(str_to_cl("1, -2,  3, -4"));
230     s->add_clause_outer(str_to_cl("-1, -2, -3, -4"));
231     s->add_clause_outer(str_to_cl("1, 2, 3"));
232 
233     s->add_clause_outer(str_to_cl("-1, 2, 3, 4"));
234     s->add_clause_outer(str_to_cl("1, -2, 3, 4"));
235     s->add_clause_outer(str_to_cl("1, 2, -3, 4"));
236     s->add_clause_outer(str_to_cl("1, 2, 3"));
237 
238     s->add_clause_outer(str_to_cl("1, -2, -3, -4"));
239     s->add_clause_outer(str_to_cl("-1, 2, -3, -4"));
240     s->add_clause_outer(str_to_cl("-1, -2, 3, -4"));
241     s->add_clause_outer(str_to_cl("-1, -3, 4"));
242 
243     occsimp->setup();
244     XorFinder finder(occsimp, s);
245     finder.find_xors();
246     check_xors_eq(finder.xors, "1, 2, 3, 4 = 1; 1, 2, 3, 4 = 0");
247 }
248 /***
249  * Specialty, non-matching XOR test end
250 */
251 
TEST_F(xor_finder,find_5_1)252 TEST_F(xor_finder, find_5_1)
253 {
254     s->add_clause_outer(str_to_cl("-1, -2, 3, 4, 5"));
255     s->add_clause_outer(str_to_cl("-1, 2, -3, 4, 5"));
256     s->add_clause_outer(str_to_cl("-1, 2, 3, -4, 5"));
257     s->add_clause_outer(str_to_cl("-1, 2, 3, 4, -5"));
258 
259     s->add_clause_outer(str_to_cl("1, -2, -3, 4, 5"));
260     s->add_clause_outer(str_to_cl("1, -2, 3, -4, 5"));
261     s->add_clause_outer(str_to_cl("1, -2, 3, 4, -5"));
262 
263     s->add_clause_outer(str_to_cl("1, 2, -3, -4, 5"));
264     s->add_clause_outer(str_to_cl("1, 2, -3, 4, -5"));
265 
266     s->add_clause_outer(str_to_cl("1, 2, 3, -4, -5"));
267 
268     //
269 
270     s->add_clause_outer(str_to_cl("1, -2, -3, -4, -5"));
271     s->add_clause_outer(str_to_cl("-1, 2, -3, -4, -5"));
272     s->add_clause_outer(str_to_cl("-1, -2, 3, -4, -5"));
273     s->add_clause_outer(str_to_cl("-1, -2, -3, 4, -5"));
274     s->add_clause_outer(str_to_cl("-1, -2, -3, -4, 5"));
275 
276     s->add_clause_outer(str_to_cl("1, 2, 3, 4, 5"));
277 
278     occsimp->setup();
279     XorFinder finder(occsimp, s);
280     finder.find_xors();
281     check_xors_eq(finder.xors, "1, 2, 3, 4, 5 = 1;");
282 }
283 
284 
285 //we don't find 6-long, too expensive
286 /*TEST_F(xor_finder, find_6_0)
287 {
288     s->add_clause_outer(str_to_cl("1, -7, -3, -4, -5, -9"));
289     s->add_clause_outer(str_to_cl("-1, 7, -3, -4, -5, -9"));
290     s->add_clause_outer(str_to_cl("-1, -7, 3, -4, -5, -9"));
291     s->add_clause_outer(str_to_cl("1, 7, 3, -4, -5, -9"));
292     s->add_clause_outer(str_to_cl("-1, -7, -3, 4, -5, -9"));
293     s->add_clause_outer(str_to_cl("1, 7, -3, 4, -5, -9"));
294     s->add_clause_outer(str_to_cl("1, -7, 3, 4, -5, -9"));
295     s->add_clause_outer(str_to_cl("-1, 7, 3, 4, -5, -9"));
296     s->add_clause_outer(str_to_cl("-1, -7, -3, -4, 5, -9"));
297     s->add_clause_outer(str_to_cl("1, 7, -3, -4, 5, -9"));
298     s->add_clause_outer(str_to_cl("1, -7, 3, -4, 5, -9"));
299     s->add_clause_outer(str_to_cl("-1, 7, 3, -4, 5, -9"));
300     s->add_clause_outer(str_to_cl("1, -7, -3, 4, 5, -9"));
301     s->add_clause_outer(str_to_cl("-1, 7, -3, 4, 5, -9"));
302     s->add_clause_outer(str_to_cl("-1, -7, 3, 4, 5, -9"));
303     s->add_clause_outer(str_to_cl("1, 7, 3, 4, 5, -9"));
304     s->add_clause_outer(str_to_cl("-1, -7, -3, -4, -5, 9"));
305     s->add_clause_outer(str_to_cl("1, 7, -3, -4, -5, 9"));
306     s->add_clause_outer(str_to_cl("1, -7, 3, -4, -5, 9"));
307     s->add_clause_outer(str_to_cl("-1, 7, 3, -4, -5, 9"));
308     s->add_clause_outer(str_to_cl("1, -7, -3, 4, -5, 9"));
309     s->add_clause_outer(str_to_cl("-1, 7, -3, 4, -5, 9"));
310     s->add_clause_outer(str_to_cl("-1, -7, 3, 4, -5, 9"));
311     s->add_clause_outer(str_to_cl("1, 7, 3, 4, -5, 9"));
312     s->add_clause_outer(str_to_cl("1, -7, -3, -4, 5, 9"));
313     s->add_clause_outer(str_to_cl("-1, 7, -3, -4, 5, 9"));
314     s->add_clause_outer(str_to_cl("-1, -7, 3, -4, 5, 9"));
315     s->add_clause_outer(str_to_cl("1, 7, 3, -4, 5, 9"));
316     s->add_clause_outer(str_to_cl("-1, -7, -3, 4, 5, 9"));
317     s->add_clause_outer(str_to_cl("1, 7, -3, 4, 5, 9"));
318     s->add_clause_outer(str_to_cl("1, -7, 3, 4, 5, 9"));
319     s->add_clause_outer(str_to_cl("-1, 7, 3, 4, 5, 9"));
320 
321     occsimp->setup();
322     XorFinder finder(occsimp, s);
323     finder.find_xors();
324     check_xors_eq(finder.xors, "1, 7, 3, 4, 5, 9 = 0;");
325 }
326 
327 TEST_F(xor_finder, find_6_1)
328 {
329     s->add_clause_outer(str_to_cl("-6, -7, -3, -4, -5, -9"));
330     s->add_clause_outer(str_to_cl("6, 7, -3, -4, -5, -9"));
331     s->add_clause_outer(str_to_cl("6, -7, 3, -4, -5, -9"));
332     s->add_clause_outer(str_to_cl("-6, 7, 3, -4, -5, -9"));
333     s->add_clause_outer(str_to_cl("6, -7, -3, 4, -5, -9"));
334     s->add_clause_outer(str_to_cl("-6, 7, -3, 4, -5, -9"));
335     s->add_clause_outer(str_to_cl("-6, -7, 3, 4, -5, -9"));
336     s->add_clause_outer(str_to_cl("6, 7, 3, 4, -5, -9"));
337     s->add_clause_outer(str_to_cl("6, -7, -3, -4, 5, -9"));
338     s->add_clause_outer(str_to_cl("-6, 7, -3, -4, 5, -9"));
339     s->add_clause_outer(str_to_cl("-6, -7, 3, -4, 5, -9"));
340     s->add_clause_outer(str_to_cl("6, 7, 3, -4, 5, -9"));
341     s->add_clause_outer(str_to_cl("-6, -7, -3, 4, 5, -9"));
342     s->add_clause_outer(str_to_cl("6, 7, -3, 4, 5, -9"));
343     s->add_clause_outer(str_to_cl("6, -7, 3, 4, 5, -9"));
344     s->add_clause_outer(str_to_cl("-6, 7, 3, 4, 5, -9"));
345     s->add_clause_outer(str_to_cl("6, -7, -3, -4, -5, 9"));
346     s->add_clause_outer(str_to_cl("-6, 7, -3, -4, -5, 9"));
347     s->add_clause_outer(str_to_cl("-6, -7, 3, -4, -5, 9"));
348     s->add_clause_outer(str_to_cl("6, 7, 3, -4, -5, 9"));
349     s->add_clause_outer(str_to_cl("-6, -7, -3, 4, -5, 9"));
350     s->add_clause_outer(str_to_cl("6, 7, -3, 4, -5, 9"));
351     s->add_clause_outer(str_to_cl("6, -7, 3, 4, -5, 9"));
352     s->add_clause_outer(str_to_cl("-6, 7, 3, 4, -5, 9"));
353     s->add_clause_outer(str_to_cl("-6, -7, -3, -4, 5, 9"));
354     s->add_clause_outer(str_to_cl("6, 7, -3, -4, 5, 9"));
355     s->add_clause_outer(str_to_cl("6, -7, 3, -4, 5, 9"));
356     s->add_clause_outer(str_to_cl("-6, 7, 3, -4, 5, 9"));
357     s->add_clause_outer(str_to_cl("6, -7, -3, 4, 5, 9"));
358     s->add_clause_outer(str_to_cl("-6, 7, -3, 4, 5, 9"));
359     s->add_clause_outer(str_to_cl("-6, -7, 3, 4, 5, 9"));
360     s->add_clause_outer(str_to_cl("6, 7, 3, 4, 5, 9"));
361 
362     occsimp->setup();
363     XorFinder finder(occsimp, s);
364     finder.find_xors();
365     check_xors_eq(finder.xors, "6, 7, 3, 4, 5, 9 = 1;");
366 }*/
367 
368 struct xor_finder2 : public ::testing::Test {
xor_finder2xor_finder2369     xor_finder2()
370     {
371         must_inter.store(false, std::memory_order_relaxed);
372         SolverConf conf;
373         s = new Solver(&conf, &must_inter);
374         s->new_vars(30);
375         occsimp = s->occsimplifier;
376         finder = new XorFinder(occsimp, s);
377         finder->grab_mem();
378         #ifdef USE_M4RI
379         topLevelGauss = new TopLevelGauss(s);
380         #endif
381     }
~xor_finder2xor_finder2382     ~xor_finder2()
383     {
384         delete s;
385         delete finder;
386         #ifdef USE_M4RI
387         delete topLevelGauss;
388         #endif
389     }
390     Solver* s = NULL;
391     OccSimplifier* occsimp = NULL;
392     std::atomic<bool> must_inter;
393     XorFinder* finder;
394     #ifdef USE_M4RI
395     TopLevelGaussAbst *topLevelGauss;
396     #endif
397 };
398 
399 
TEST_F(xor_finder2,clean_v1)400 TEST_F(xor_finder2, clean_v1)
401 {
402     finder->xors = str_to_xors("1, 2, 3 = 0;");
403     finder->xors = finder->remove_xors_without_connecting_vars(finder->xors);
404     EXPECT_EQ(finder->xors.size(), 0u);
405 }
406 
TEST_F(xor_finder2,clean_v2)407 TEST_F(xor_finder2, clean_v2)
408 {
409     finder->xors = str_to_xors("1, 2, 3 = 0; 1, 4, 5, 6 = 0");
410     finder->xors = finder->remove_xors_without_connecting_vars(finder->xors);
411     EXPECT_EQ(finder->xors.size(), 2u);
412 }
413 
TEST_F(xor_finder2,clean_v3)414 TEST_F(xor_finder2, clean_v3)
415 {
416     finder->xors = str_to_xors("1, 2, 3 = 0; 1, 4, 5, 6 = 0; 10, 11, 12, 13 = 1");
417     finder->xors = finder->remove_xors_without_connecting_vars(finder->xors);
418     EXPECT_EQ(finder->xors.size(), 2u);
419 }
420 
TEST_F(xor_finder2,clean_v4)421 TEST_F(xor_finder2, clean_v4)
422 {
423     finder->xors = str_to_xors("1, 2, 3 = 0; 1, 4, 5, 6 = 0; 10, 11, 12, 13 = 1; 10, 15, 16, 17 = 0");
424     finder->xors = finder->remove_xors_without_connecting_vars(finder->xors);
425     EXPECT_EQ(finder->xors.size(), 4u);
426 }
427 
TEST_F(xor_finder2,xor_1)428 TEST_F(xor_finder2, xor_1)
429 {
430     finder->xors = str_to_xors("1, 2, 3 = 1; 1, 4, 5, 6 = 0;");
431     finder->xor_together_xors(finder->xors);
432     check_xors_eq(finder->xors, "2, 3, 4, 5, 6 = 1 c 1;");
433 }
434 
TEST_F(xor_finder2,xor_2)435 TEST_F(xor_finder2, xor_2)
436 {
437     finder->xors = str_to_xors("1, 2, 3 = 0; 1, 4, 5, 6 = 0;");
438     finder->xor_together_xors(finder->xors);
439     check_xors_eq(finder->xors, "2, 3, 4, 5, 6 = 0 c 1;");
440 }
441 
TEST_F(xor_finder2,xor_3)442 TEST_F(xor_finder2, xor_3)
443 {
444     finder->xors = str_to_xors("1, 2, 3 = 0; 10, 4, 5, 6 = 0;");
445     finder->xor_together_xors(finder->xors);
446     check_xors_eq(finder->xors, "1, 2, 3 = 0; 10, 4, 5, 6 = 0;");
447 }
448 
TEST_F(xor_finder2,xor_4)449 TEST_F(xor_finder2, xor_4)
450 {
451     finder->xors = str_to_xors("1, 2, 3 = 0; 1, 4, 5, 6 = 0;"
452         "1, 9, 10, 11 = 0;");
453     finder->xor_together_xors(finder->xors);
454     EXPECT_EQ(finder->xors.size(), 3u);
455 }
456 
TEST_F(xor_finder2,xor_5)457 TEST_F(xor_finder2, xor_5)
458 {
459     finder->xors = str_to_xors(
460         "2, 3, 1 = 0;"
461         "1, 5, 6, 4 = 0;"
462         "4, 10, 11 = 0;");
463     finder->xor_together_xors(finder->xors);
464     EXPECT_EQ(finder->xors.size(), 1u);
465     check_xors_contains(finder->xors, "2, 3, 5, 6, 10, 11 = 0 c 1, 4");
466 }
467 
TEST_F(xor_finder2,xor_6)468 TEST_F(xor_finder2, xor_6)
469 {
470     finder->xors = str_to_xors(
471         "1, 2 = 0;"
472         "1, 4 = 0;"
473         "6, 7 = 0;"
474         "6, 10 = 1");
475     finder->xor_together_xors(finder->xors);
476     EXPECT_EQ(finder->xors.size(), 2u);
477     check_xors_eq(finder->xors, "2, 4 = 0 c 1; 7, 10 = 1 c 6");
478 }
479 
TEST_F(xor_finder2,xor_7)480 TEST_F(xor_finder2, xor_7)
481 {
482     finder->xors = str_to_xors(
483         "1, 2 = 0 c 10;"
484         "1, 4 = 0 c 11;"
485         "6, 7 = 0;"
486         "6, 9 = 1 c 18");
487     finder->xor_together_xors(finder->xors);
488     EXPECT_EQ(finder->xors.size(), 2u);
489     check_xors_eq(finder->xors,
490         "2, 4 = 0 c 10, 11, 1;"
491         "7, 9 = 1 c 6, 18");
492 }
493 
TEST_F(xor_finder2,xor_8)494 TEST_F(xor_finder2, xor_8)
495 {
496     finder->xors = str_to_xors(
497         "1, 2 = 0 c 10;"
498         "1, 4, 7 = 0 c 11;"
499         "7, 8, 9 = 0 c 12;");
500     finder->xor_together_xors(finder->xors);
501     EXPECT_EQ(finder->xors.size(), 1u);
502     check_xors_eq(finder->xors,
503         "2, 4, 8, 9 = 0 c 10, 11, 12, 1, 7;");
504 }
505 
506 
TEST_F(xor_finder2,dont_xor_together_when_clash_more_than_one)507 TEST_F(xor_finder2, dont_xor_together_when_clash_more_than_one)
508 {
509     finder->xors = str_to_xors(
510         "1, 2, 3, 4 = 0;"
511         "1, 2, 5, 6 = 0;");
512     finder->xor_together_xors(finder->xors);
513     EXPECT_EQ(finder->xors.size(), 2u);
514     check_xors_eq(finder->xors,
515       "1, 2, 3, 4 = 0;"
516       "1, 2, 5, 6 = 0;");
517 }
518 
TEST_F(xor_finder2,clash_1)519 TEST_F(xor_finder2, clash_1)
520 {
521     finder->xors = str_to_xors("1, 2, 3, 4 = 0; 1, 2, 5, 6= 0;");
522     finder->xor_together_xors(finder->xors);
523     EXPECT_EQ(finder->xors.size(), 2u);
524     check_xors_eq(finder->xors, "1, 2, 3, 4 = 0; 1, 2, 5, 6= 0;");
525 }
526 
TEST_F(xor_finder2,dont_remove_xors)527 TEST_F(xor_finder2, dont_remove_xors)
528 {
529     finder->xors = str_to_xors("1, 2 = 0; 1, 2= 0;");
530     finder->xor_together_xors(finder->xors);
531     EXPECT_EQ(finder->xors.size(), 1U);
532 }
533 
TEST_F(xor_finder2,dont_remove_xors2)534 TEST_F(xor_finder2, dont_remove_xors2)
535 {
536     finder->xors = str_to_xors("1, 2, 3 = 0; 1, 2, 3= 0;");
537     finder->xor_together_xors(finder->xors);
538     EXPECT_EQ(finder->xors.size(), 1U);
539 }
540 
TEST_F(xor_finder2,xor_pure_unit_unsat)541 TEST_F(xor_finder2, xor_pure_unit_unsat)
542 {
543     finder->xors = str_to_xors("1 = 0; 1 = 1;");
544     finder->xor_together_xors(finder->xors);
545     bool ret = finder->add_new_truths_from_xors(finder->xors);
546     EXPECT_FALSE(ret);
547 }
548 
TEST_F(xor_finder2,xor_add_truths)549 TEST_F(xor_finder2, xor_add_truths)
550 {
551     finder->xors = str_to_xors("1, 2 = 0; 1 = 1; 2 = 0");
552     bool ret = finder->xor_together_xors(finder->xors);
553     EXPECT_TRUE(ret);
554     EXPECT_EQ(finder->xors.size(), 1U);
555 
556     ret = finder->add_new_truths_from_xors(finder->xors);
557     EXPECT_FALSE(ret);
558 }
559 
TEST_F(xor_finder2,xor_unit)560 TEST_F(xor_finder2, xor_unit)
561 {
562     finder->xors = str_to_xors("1 = 0; 1, 2, 3 = 1; 3 = 1");
563     finder->xor_together_xors(finder->xors);
564     bool ret = finder->add_new_truths_from_xors(finder->xors);
565     EXPECT_TRUE(ret);
566     EXPECT_EQ(finder->xors.size(), 0u);
567 }
568 
569 #ifdef USE_M4RI
TEST_F(xor_finder2,xor_unit2_2)570 TEST_F(xor_finder2, xor_unit2_2)
571 {
572     s->add_clause_outer(str_to_cl("-4"));
573     finder->xors = str_to_xors("1, 2, 3 = 0; 1, 2, 3, 4 = 1;");
574     vector<Lit> out_changed_occur;
575     bool ret = topLevelGauss->toplevelgauss(finder->xors, &out_changed_occur);
576     EXPECT_FALSE(ret);
577 }
578 #endif
579 
TEST_F(xor_finder2,xor_binx)580 TEST_F(xor_finder2, xor_binx)
581 {
582     finder->xors = str_to_xors("1, 2, 5 = 0; 1, 3 = 0; 2 = 0");
583     bool ret = finder->xor_together_xors(finder->xors);
584     if (ret) {
585         ret &= finder->add_new_truths_from_xors(finder->xors);
586     }
587     EXPECT_TRUE(ret);
588     EXPECT_EQ(finder->xors.size(), 0u);
589     check_red_cls_eq(s, "5, -3; -5, 3");
590 }
591 
TEST_F(xor_finder2,xor_binx_inv_not_found)592 TEST_F(xor_finder2, xor_binx_inv_not_found)
593 {
594     finder->xors = str_to_xors("3, 1 = 1; 1, 3 = 0;");
595     bool ret = finder->xor_together_xors(finder->xors);
596     if (ret) {
597         ret &= finder->add_new_truths_from_xors(finder->xors);
598     }
599     EXPECT_TRUE(ret);
600 }
601 
TEST_F(xor_finder2,xor_recur_bug)602 TEST_F(xor_finder2, xor_recur_bug)
603 {
604     finder->xors = str_to_xors("3, 7, 9 = 0; 1, 3, 4, 5 = 1;");
605     bool ret = finder->xor_together_xors(finder->xors);
606     EXPECT_TRUE(ret);
607     check_xors_eq(finder->xors, "7, 9, 1, 4, 5 = 1 c 3;");
608 }
609 
610 
main(int argc,char ** argv)611 int main(int argc, char **argv) {
612   ::testing::InitGoogleTest(&argc, argv);
613   return RUN_ALL_TESTS();
614 }
615