1414import static com .google .common .truth .TruthJUnit .assume ;
1515
1616import 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 ;
1819import com .google .common .collect .Iterables ;
19- import com .google .common .collect .Multiset ;
20+ import com .google .common .collect .Multimap ;
2021import com .google .common .truth .TruthJUnit ;
22+ import java .util .Collection ;
2123import java .util .function .Supplier ;
24+ import java .util .regex .Pattern ;
25+ import org .junit .AssumptionViolatedException ;
2226import org .junit .Test ;
2327import org .sosy_lab .java_smt .SolverContextFactory .Solvers ;
2428import 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