88
99package org .sosy_lab .java_smt .test ;
1010
11- import static com .google .common .truth .TruthJUnit .assume ;
1211import static org .sosy_lab .java_smt .test .ProverEnvironmentSubject .assertThat ;
1312
13+ import java .util .List ;
1414import java .util .concurrent .ExecutionException ;
1515import java .util .concurrent .ExecutorService ;
1616import java .util .concurrent .Executors ;
1717import java .util .concurrent .Future ;
18+ import java .util .concurrent .TimeUnit ;
1819import org .junit .Test ;
1920import org .sosy_lab .common .ShutdownManager ;
2021import org .sosy_lab .common .ShutdownNotifier ;
2122import org .sosy_lab .common .configuration .Configuration ;
2223import org .sosy_lab .common .configuration .InvalidConfigurationException ;
2324import org .sosy_lab .common .log .LogManager ;
2425import org .sosy_lab .java_smt .SolverContextFactory ;
25- import org .sosy_lab .java_smt .SolverContextFactory .Solvers ;
2626import org .sosy_lab .java_smt .api .BasicProverEnvironment ;
2727import org .sosy_lab .java_smt .api .BooleanFormula ;
2828import org .sosy_lab .java_smt .api .BooleanFormulaManager ;
2929import org .sosy_lab .java_smt .api .FormulaManager ;
3030import org .sosy_lab .java_smt .api .IntegerFormulaManager ;
31+ import org .sosy_lab .java_smt .api .InterpolatingProverEnvironment ;
3132import org .sosy_lab .java_smt .api .SolverContext ;
3233import org .sosy_lab .java_smt .api .SolverException ;
34+ import org .sosy_lab .java_smt .solvers .opensmt .Logics ;
3335
3436public class SolverThreadLocalTest extends SolverBasedTest0 .ParameterizedSolverBasedTest0 {
3537 @ Test
@@ -50,12 +52,6 @@ public void allLocalTest() throws InterruptedException, SolverException {
5052 public void nonlocalContext () throws ExecutionException , InterruptedException , SolverException {
5153 requireIntegers ();
5254
53- /* FIXME: Exception for CVC5 (related to #310?)
54- io.github.cvc5.CVC5ApiException:
55- Invalid call to 'cvc5::SortKind cvc5::Sort::getKind() const', expected non-null object
56- */
57- assume ().that (solverToUse ()).isNotEqualTo (Solvers .CVC5 );
58-
5955 ExecutorService executor = Executors .newSingleThreadExecutor ();
6056 Future <SolverContext > result =
6157 executor .submit (
@@ -77,16 +73,23 @@ public void nonlocalContext() throws ExecutionException, InterruptedException, S
7773 }
7874 });
7975
80- executor .shutdownNow ();
81-
8276 try (SolverContext newContext = result .get ()) {
8377 FormulaManager newMgr = newContext .getFormulaManager ();
8478
8579 BooleanFormulaManager newBmgr = newMgr .getBooleanFormulaManager ();
8680 IntegerFormulaManager newImgr = newMgr .getIntegerFormulaManager ();
8781
8882 HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator (newImgr , newBmgr );
89- BooleanFormula formula = gen .generate (8 ); // CVC5 throws an exception here
83+
84+ // FIXME: Exception for CVC5 (related to bug #310?)
85+ // io.github.cvc5.CVC5ApiException:
86+ // Invalid call to 'cvc5::SortKind cvc5::Sort::getKind() const', expected non-null object
87+ // at io.github.cvc5.Sort.getKind
88+ // (Native Method)
89+ // at io.github.cvc5.Sort.getKind
90+ // (Sort.java:93)
91+ // at ..
92+ BooleanFormula formula = gen .generate (8 );
9093
9194 try (BasicProverEnvironment <?> prover = newContext .newProverEnvironment ()) {
9295 prover .push (formula );
@@ -101,21 +104,25 @@ public void nonlocalFormulaTest()
101104 throws InterruptedException , SolverException , ExecutionException {
102105 requireIntegers ();
103106
104- /* FIXME: Exception for CVC5 (related to #310?)
105- Invalid call to 'cvc5::SortKind cvc5::Sort::getKind() const', expected non-null object
106- */
107- assume ().that (solverToUse ()).isNotEqualTo (Solvers .CVC5 );
108-
109107 ExecutorService executor = Executors .newSingleThreadExecutor ();
110108 Future <BooleanFormula > result =
111109 executor .submit (
112110 () -> {
113111 HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator (imgr , bmgr );
112+
113+ // FIXME: Exception for CVC5 (related to bug #310?)
114+ // io.github.cvc5.CVC5ApiException:
115+ // Invalid call to 'cvc5::SortKind cvc5::Sort::getKind() const', expected non-null
116+ // object
117+ // at io.github.cvc5.Sort.getKind
118+ // (Native Method)
119+ // at io.github.cvc5.Sort.getKind
120+ // (Sort.java:93)
121+ // at ..
114122 return gen .generate (8 );
115123 });
116124
117125 BooleanFormula formula = result .get ();
118- executor .shutdownNow ();
119126
120127 try (BasicProverEnvironment <?> prover = context .newProverEnvironment ()) {
121128 prover .push (formula );
@@ -128,12 +135,6 @@ public void nonlocalFormulaTest()
128135 public void nonlocalProverTest () throws InterruptedException , ExecutionException {
129136 requireIntegers ();
130137
131- /* FIXME: Exception for CVC5
132- io.github.cvc5.CVC5ApiException:
133- Given term is not associated with the node manager of this solver
134- */
135- assume ().that (solverToUse ()).isNotEqualTo (Solvers .CVC5 );
136-
137138 HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator (imgr , bmgr );
138139 BooleanFormula formula = gen .generate (8 );
139140
@@ -142,14 +143,148 @@ public void nonlocalProverTest() throws InterruptedException, ExecutionException
142143 executor .submit (
143144 () -> {
144145 try (BasicProverEnvironment <?> prover = context .newProverEnvironment ()) {
145- prover .push (formula ); // CVC5 throws an exception here
146+ // FIXME: Exception for CVC5
147+ // io.github.cvc5.CVC5ApiException:
148+ // Given term is not associated with the node manager of this solver
149+ // at io.github.cvc5.Solver.assertFormula
150+ // (Native Method)
151+ // at io.github.cvc5.Solver.assertFormula
152+ // (Solver.java:1455)
153+ // at org.sosy_lab.java_smt.solvers.cvc5.CVC5AbstractProver.addConstraintImpl
154+ // (CVC5AbstractProver.java:114)
155+ // at org.sosy_lab.java_smt.basicimpl.AbstractProver.addConstraint
156+ // (AbstractProver.java:108)
157+ // at ..
158+ prover .push (formula );
159+
146160 return prover .isUnsat ();
147161 }
148162 });
149163
150- Boolean isUnsat = result .get ();
151- executor .shutdownNow ();
164+ assert result .get ();
165+ }
166+
167+ @ Override
168+ protected Logics logicToUse () {
169+ return Logics .QF_LIA ;
170+ }
171+
172+ private void checkInterpolant (
173+ BooleanFormula formulaA , BooleanFormula formulaB , BooleanFormula itp )
174+ throws SolverException , InterruptedException {
175+ assertThatFormula (formulaA ).implies (itp );
176+ assertThatFormula (bmgr .and (itp , formulaB )).implies (bmgr .makeBoolean (false ));
177+ }
178+
179+ @ SuppressWarnings ({"unchecked" , "resource" })
180+ @ Test
181+ public <T > void localInterpolationTest () throws InterruptedException , SolverException {
182+ requireIntegers ();
183+ requireInterpolation ();
184+
185+ BooleanFormula f1 = imgr .lessThan (imgr .makeVariable ("A" ), imgr .makeVariable ("B" ));
186+ BooleanFormula f2 = imgr .lessThan (imgr .makeVariable ("B" ), imgr .makeVariable ("A" ));
187+
188+ try (InterpolatingProverEnvironment <T > prover =
189+ (InterpolatingProverEnvironment <T >) context .newProverEnvironmentWithInterpolation ()) {
190+ prover .push (f1 );
191+ T id2 = prover .push (f2 );
192+
193+ assertThat (prover ).isUnsatisfiable ();
194+
195+ BooleanFormula itp = prover .getInterpolant (List .of (id2 ));
196+ checkInterpolant (f2 , f1 , itp );
197+
198+ prover .pop ();
199+ prover .push (itp );
152200
153- assert isUnsat .equals (true );
201+ assertThat (prover ).isUnsatisfiable ();
202+ }
203+ }
204+
205+ @ SuppressWarnings ({"unchecked" , "resource" })
206+ @ Test
207+ public <T > void nonlocalInterpolationTest () throws InterruptedException , ExecutionException {
208+ requireIntegers ();
209+ requireInterpolation ();
210+
211+ ExecutorService executor = Executors .newFixedThreadPool (5 );
212+
213+ BooleanFormula f1 = imgr .lessThan (imgr .makeVariable ("A" ), imgr .makeVariable ("B" ));
214+ BooleanFormula f2 = imgr .lessThan (imgr .makeVariable ("B" ), imgr .makeVariable ("A" ));
215+
216+ try (InterpolatingProverEnvironment <T > prover =
217+ (InterpolatingProverEnvironment <T >) context .newProverEnvironmentWithInterpolation ()) {
218+ T id1 = prover .push (f1 );
219+
220+ Future <?> task1 = executor .submit (
221+ () -> {
222+ try {
223+ // FIXME: Exception for CVC5
224+ // java.lang.IllegalStateException:
225+ // You tried to use push() on an CVC5 assertion stack illegally.
226+ // at org.sosy_lab.java_smt.solvers.cvc5.CVC5AbstractProver.pushImpl
227+ // (CVC5AbstractProver.java:89)
228+ // at org.sosy_lab.java_smt.basicimpl.AbstractProver.push
229+ // (AbstractProver.java:88)
230+ // at ..
231+ prover .push (f2 );
232+
233+ // FIXME: Exception for MathSAT (bug #339)
234+ // java.lang.StackOverflowError
235+ // at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_solve
236+ // (Native Method)
237+ // at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_check_sat
238+ // (Mathsat5NativeApi.java:156)
239+ // at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5AbstractProver.isUnsat
240+ // (Mathsat5AbstractProver.java:106)
241+ // at org.sosy_lab.java_smt.test.ProverEnvironmentSubject.isUnsatisfiable
242+ // (ProverEnvironmentSubject.java:67)
243+ // at ..
244+ assertThat (prover ).isUnsatisfiable ();
245+
246+ } catch (SolverException | InterruptedException pE ) {
247+ throw new RuntimeException (pE );
248+ }
249+ });
250+
251+ assert task1 .get () == null ;
252+
253+ Future <BooleanFormula > itp =
254+ executor .submit (
255+ () -> {
256+ BooleanFormula interpol = prover .getInterpolant (List .of (id1 ));
257+ Future <?> task2 =
258+ executor .submit (
259+ () -> {
260+ try {
261+ checkInterpolant (f1 , f2 , interpol );
262+ } catch (SolverException | InterruptedException pE ) {
263+ throw new RuntimeException (pE );
264+ }
265+ });
266+ assert task2 .get () == null ;
267+ return interpol ;
268+ });
269+
270+ executor .awaitTermination (100 , TimeUnit .MILLISECONDS );
271+ prover .pop ();
272+
273+ Future <?> task3 = executor .submit (
274+ () -> {
275+ try {
276+ prover .pop ();
277+
278+ prover .push (itp .get ());
279+ prover .push (f2 );
280+
281+ assertThat (prover ).isUnsatisfiable ();
282+ } catch (SolverException | InterruptedException | ExecutionException pE ) {
283+ throw new RuntimeException (pE );
284+ }
285+ });
286+
287+ assert task3 .get () == null ;
288+ }
154289 }
155290}
0 commit comments