Skip to content

Commit 4dfcf13

Browse files
committed
SolverFormulaIOTest: check declared function symbols, also for arrays.
1 parent 07c40f7 commit 4dfcf13

File tree

1 file changed

+71
-27
lines changed

1 file changed

+71
-27
lines changed

src/org/sosy_lab/java_smt/test/SolverFormulaIOTest.java

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414
import static com.google.common.truth.TruthJUnit.assume;
1515

1616
import com.google.common.base.Splitter;
17-
import com.google.common.collect.HashMultiset;
17+
import com.google.common.collect.HashMultimap;
18+
import com.google.common.collect.ImmutableSet;
1819
import com.google.common.collect.Iterables;
19-
import com.google.common.collect.Multiset;
20+
import com.google.common.collect.Multimap;
2021
import com.google.common.truth.TruthJUnit;
22+
import java.util.Collection;
2123
import java.util.function.Supplier;
24+
import java.util.regex.Pattern;
25+
import org.junit.AssumptionViolatedException;
2226
import org.junit.Test;
2327
import org.sosy_lab.java_smt.SolverContextFactory.Solvers;
2428
import org.sosy_lab.java_smt.api.BitvectorFormula;
@@ -105,6 +109,10 @@ public class SolverFormulaIOTest extends SolverBasedTest0.ParameterizedSolverBas
105109
+ "(assert (let (($x35 (and (xor q (= (+ a b) c)) (>= a b)))) (let (($x9 (= a b))) (and"
106110
+ " (and (or $x35 u) q) (and $x9 $x35)))))";
107111

112+
private static final Collection<String> ABDE = ImmutableSet.of("a", "b", "d", "e");
113+
private static final Collection<String> AQBCU = ImmutableSet.of("a", "q", "b", "c", "u");
114+
private static final Collection<String> QBCU = ImmutableSet.of("q", "b", "c", "u");
115+
108116
@Test
109117
public void logicsParseTest() throws SolverException, InterruptedException {
110118
requireParser();
@@ -278,83 +286,83 @@ public void funcsDumpTest() {
278286
@Test
279287
public void parseMathSatTestParseFirst1() throws SolverException, InterruptedException {
280288
requireParser();
281-
compareParseWithOrgParseFirst(MATHSAT_DUMP1, this::genBoolExpr);
289+
compareParseWithOrgParseFirst(MATHSAT_DUMP1, this::genBoolExpr, ABDE);
282290
}
283291

284292
@Test
285293
public void parseMathSatTestExprFirst1() throws SolverException, InterruptedException {
286294
requireParser();
287-
compareParseWithOrgExprFirst(MATHSAT_DUMP1, this::genBoolExpr);
295+
compareParseWithOrgExprFirst(MATHSAT_DUMP1, this::genBoolExpr, ABDE);
288296
}
289297

290298
@Test
291299
public void parseSmtinterpolTestParseFirst1() throws SolverException, InterruptedException {
292300
requireParser();
293-
compareParseWithOrgParseFirst(SMTINTERPOL_DUMP1, this::genBoolExpr);
301+
compareParseWithOrgParseFirst(SMTINTERPOL_DUMP1, this::genBoolExpr, ABDE);
294302
}
295303

296304
@Test
297305
public void parseSmtinterpolTestExprFirst1() throws SolverException, InterruptedException {
298306
requireParser();
299-
compareParseWithOrgExprFirst(SMTINTERPOL_DUMP1, this::genBoolExpr);
307+
compareParseWithOrgExprFirst(SMTINTERPOL_DUMP1, this::genBoolExpr, ABDE);
300308
}
301309

302310
@Test
303311
public void parseZ3TestParseFirst1() throws SolverException, InterruptedException {
304312
requireParser();
305-
compareParseWithOrgParseFirst(Z3_DUMP1, this::genBoolExpr);
313+
compareParseWithOrgParseFirst(Z3_DUMP1, this::genBoolExpr, ABDE);
306314
}
307315

308316
@Test
309317
public void parseZ3TestExprFirst1() throws SolverException, InterruptedException {
310318
requireParser();
311-
compareParseWithOrgExprFirst(Z3_DUMP1, this::genBoolExpr);
319+
compareParseWithOrgExprFirst(Z3_DUMP1, this::genBoolExpr, ABDE);
312320
}
313321

314322
@Test
315323
public void parseMathSatTestParseFirst2() throws SolverException, InterruptedException {
316324
requireParser();
317325
requireIntegers();
318-
compareParseWithOrgParseFirst(MATHSAT_DUMP2, this::redundancyExprGen);
326+
compareParseWithOrgParseFirst(MATHSAT_DUMP2, this::redundancyExprGen, AQBCU);
319327
}
320328

321329
@Test
322330
public void parseMathSatTestExprFirst2() throws SolverException, InterruptedException {
323331
requireParser();
324-
compareParseWithOrgExprFirst(MATHSAT_DUMP2, this::redundancyExprGen);
332+
compareParseWithOrgExprFirst(MATHSAT_DUMP2, this::redundancyExprGen, AQBCU);
325333
}
326334

327335
@Test
328336
public void parseSmtinterpolSatTestParseFirst2() throws SolverException, InterruptedException {
329337
requireParser();
330338
requireIntegers();
331-
compareParseWithOrgParseFirst(SMTINTERPOL_DUMP2, this::redundancyExprGen);
339+
compareParseWithOrgParseFirst(SMTINTERPOL_DUMP2, this::redundancyExprGen, QBCU);
332340
}
333341

334342
@Test
335343
public void parseSmtinterpolSatTestExprFirst2() throws SolverException, InterruptedException {
336344
requireParser();
337-
compareParseWithOrgExprFirst(SMTINTERPOL_DUMP2, this::redundancyExprGen);
345+
compareParseWithOrgExprFirst(SMTINTERPOL_DUMP2, this::redundancyExprGen, QBCU);
338346
}
339347

340348
@Test
341349
public void parseZ3SatTestParseFirst2() throws SolverException, InterruptedException {
342350
requireParser();
343351
requireIntegers();
344-
compareParseWithOrgParseFirst(Z3_DUMP2, this::redundancyExprGen);
352+
compareParseWithOrgParseFirst(Z3_DUMP2, this::redundancyExprGen, AQBCU);
345353
}
346354

347355
@Test
348356
public void parseZ3SatTestExprFirst2() throws SolverException, InterruptedException {
349357
requireParser();
350-
compareParseWithOrgExprFirst(Z3_DUMP2, this::redundancyExprGen);
358+
compareParseWithOrgExprFirst(Z3_DUMP2, this::redundancyExprGen, AQBCU);
351359
}
352360

353361
@Test
354362
public void parseMathSatTestExprFirst3() throws SolverException, InterruptedException {
355363
requireParser();
356364
requireIntegers();
357-
compareParseWithOrgExprFirst(MATHSAT_DUMP3, this::functionExprGen);
365+
compareParseWithOrgExprFirst(MATHSAT_DUMP3, this::functionExprGen, ImmutableSet.of("fun_b"));
358366
}
359367

360368
@Test
@@ -399,7 +407,7 @@ public void funDeclareTest() {
399407
String formDump = mgr.dumpFormula(imgr.equal(calc, int1)).toString();
400408

401409
// check if dumped formula fits our specification
402-
checkThatFunOnlyDeclaredOnce(formDump);
410+
checkThatFunOnlyDeclaredOnce(formDump, ImmutableSet.of("fun_a", "fun_b"));
403411
checkThatAssertIsInLastLine(formDump);
404412
checkThatDumpIsParseable(formDump);
405413
}
@@ -419,17 +427,41 @@ public void funDeclareTest2() {
419427
String formDump = mgr.dumpFormula(imgr.equal(calc, int1)).toString();
420428

421429
// check if dumped formula fits our specification
422-
checkThatFunOnlyDeclaredOnce(formDump);
430+
checkThatFunOnlyDeclaredOnce(formDump, ImmutableSet.of("fun_a"));
431+
checkThatAssertIsInLastLine(formDump);
432+
checkThatDumpIsParseable(formDump);
433+
}
434+
435+
@Test
436+
public void funDeclareWithArrayTest() {
437+
requireIntegers();
438+
requireArrays();
439+
440+
IntegerFormula idx = imgr.makeVariable("idx");
441+
IntegerFormula int1 = imgr.makeNumber(1);
442+
IntegerFormula int2 = imgr.makeNumber(2);
443+
444+
// assert (((select (store arr idx 2) 1) 2)
445+
var arr = amgr.makeArray("arr", FormulaType.IntegerType, FormulaType.IntegerType);
446+
var store = amgr.store(arr, idx, int2);
447+
var select = amgr.select(store, int1);
448+
var query = imgr.equal(int2, select);
449+
450+
String formDump = mgr.dumpFormula(query).toString();
451+
452+
// check if dumped formula fits our specification
453+
checkThatFunOnlyDeclaredOnce(formDump, ImmutableSet.of("idx", "arr"));
423454
checkThatAssertIsInLastLine(formDump);
424455
checkThatDumpIsParseable(formDump);
425456
}
426457

427-
private void compareParseWithOrgExprFirst(String textToParse, Supplier<BooleanFormula> fun)
458+
private void compareParseWithOrgExprFirst(
459+
String textToParse, Supplier<BooleanFormula> fun, Collection<String> expectedDeclarations)
428460
throws SolverException, InterruptedException {
429461
// Boolector will fail this anyway since bools are bitvecs for btor
430462
TruthJUnit.assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR);
431463
// check if input is correct
432-
checkThatFunOnlyDeclaredOnce(textToParse);
464+
checkThatFunOnlyDeclaredOnce(textToParse, expectedDeclarations);
433465
checkThatAssertIsInLastLine(textToParse);
434466

435467
// actual test
@@ -438,12 +470,13 @@ private void compareParseWithOrgExprFirst(String textToParse, Supplier<BooleanFo
438470
assertThatFormula(parsedForm).isEquivalentTo(expr);
439471
}
440472

441-
private void compareParseWithOrgParseFirst(String textToParse, Supplier<BooleanFormula> fun)
473+
private void compareParseWithOrgParseFirst(
474+
String textToParse, Supplier<BooleanFormula> fun, Collection<String> expectedDeclarations)
442475
throws SolverException, InterruptedException {
443476
// Boolector will fail this anyway since bools are bitvecs for btor
444477
TruthJUnit.assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR);
445478
// check if input is correct
446-
checkThatFunOnlyDeclaredOnce(textToParse);
479+
checkThatFunOnlyDeclaredOnce(textToParse, expectedDeclarations);
447480
checkThatAssertIsInLastLine(textToParse);
448481

449482
// actual test
@@ -452,19 +485,25 @@ private void compareParseWithOrgParseFirst(String textToParse, Supplier<BooleanF
452485
assertThatFormula(parsedForm).isEquivalentTo(expr);
453486
}
454487

455-
private void checkThatFunOnlyDeclaredOnce(String formDump) {
488+
private void checkThatFunOnlyDeclaredOnce(
489+
String formDump, Collection<String> expectedDeclarations) {
456490
// Boolector will fail this anyway since bools are bitvecs for btor
457491
TruthJUnit.assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR);
458-
Multiset<String> funDeclares = HashMultiset.create();
492+
Multimap<String, String> funDeclares = HashMultimap.create();
459493

494+
final Pattern declareFunRegex = Pattern.compile("\\(declare-fun\\s+(?<name>\\S+)\\s*");
460495
for (String line : Splitter.on('\n').split(formDump)) {
461496
if (line.startsWith("(declare-fun ")) {
462-
funDeclares.add(line.replaceAll("\\s+", ""));
497+
var matcher = declareFunRegex.matcher(line);
498+
var name = matcher.find() ? matcher.group(1) : line.replaceAll("\\s+", "");
499+
funDeclares.put(name, line.replaceAll("\\s+", ""));
463500
}
464501
}
465502

503+
assertThat(funDeclares.keySet()).containsExactlyElementsIn(expectedDeclarations);
504+
466505
// remove non-duplicates
467-
funDeclares.entrySet().removeIf(pStringEntry -> pStringEntry.getCount() <= 1);
506+
funDeclares.keySet().removeIf(pStringEntry -> funDeclares.get(pStringEntry).size() <= 1);
468507
assertWithMessage("duplicate function declarations").that(funDeclares).isEmpty();
469508
}
470509

@@ -487,8 +526,13 @@ private void checkThatAssertIsInLastLine(String dump) {
487526

488527
@SuppressWarnings("CheckReturnValue")
489528
private void checkThatDumpIsParseable(String dump) {
490-
requireParser();
491-
mgr.parse(dump);
529+
try {
530+
requireParser();
531+
mgr.parse(dump);
532+
} catch (AssumptionViolatedException ave) {
533+
// ignore, i.e., do not report test-case as skipped.
534+
}
535+
;
492536
}
493537

494538
private BooleanFormula genBoolExpr() {

0 commit comments

Comments
 (0)