/* * Copyright (C) 2009-2012 University of Freiburg * * This file is part of SMTInterpol. * * SMTInterpol is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SMTInterpol is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SMTInterpol. If not, see <http://www.gnu.org/licenses/>. */ package de.uni_freiburg.informatik.ultimate.smtinterpol.smtlib2; import java.math.BigInteger; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import de.uni_freiburg.informatik.ultimate.logic.Logics; import de.uni_freiburg.informatik.ultimate.logic.ReasonUnknown; import de.uni_freiburg.informatik.ultimate.logic.SMTLIBException; import de.uni_freiburg.informatik.ultimate.logic.Script; import de.uni_freiburg.informatik.ultimate.logic.Script.LBool; import de.uni_freiburg.informatik.ultimate.logic.Sort; import de.uni_freiburg.informatik.ultimate.logic.Term; import de.uni_freiburg.informatik.ultimate.smtinterpol.Config; import de.uni_freiburg.informatik.ultimate.smtinterpol.DefaultLogger; /** * A basic test case for the API of SMTInterpol. * @author Juergen Christ */ @RunWith(JUnit4.class) public class APITest { private static class TerminationCounter implements TerminationRequest { private boolean mStop = false; @Override public boolean isTerminationRequested() { return mStop; } public void setStop(boolean stop) { mStop = stop; } } /** * Test what is possible without a logic... */ @Test public void testNoLogic() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); solver.setOption(":interactive-mode", true); try { solver.sort("Bool"); Assert.fail("Could retrieve sort Bool without logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.assertTerm(solver.term("true")); Assert.fail("Could assert true without logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.checkSat(); Assert.fail("Could check satisfiability without logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.push(1); Assert.fail("Could push without logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.pop(1); Assert.fail("Could pop without logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.assertTerm(solver.term("true")); Assert.fail("Could assert true without logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.getAssertions(); Assert.fail("Could get assertions without logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } } @Test public void testFaultyLogic() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); try { solver.setLogic("TestLogicThatDoesNotExist"); Assert.fail("Could set strange logic!"); } catch (final UnsupportedOperationException expected) { System.err.println(expected.getMessage()); } } @Test public void testPushPop() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); solver.setLogic(Logics.QF_LIA); try { solver.push(3);// NOCHECKSTYLE } catch (final SMTLIBException eUnexpected) { Assert.fail(eUnexpected.getMessage()); } try { solver.pop(2);// NOCHECKSTYLE } catch (final SMTLIBException eUnexpected) { Assert.fail(eUnexpected.getMessage()); } try { solver.pop(2);// NOCHECKSTYLE Assert.fail("Could pop 4 levels after pushing 3"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } } @Test public void testSetOptionLate() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); solver.setLogic(Logics.QF_LIA); try { solver.setOption(":interactive-mode", true); Assert.fail("Could activate interactive mode after setting logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.setOption(":produce-proofs", true); Assert.fail("Could activate proof production after setting logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.setOption(":produce-unsat-cores", true); Assert.fail("Could activate unsat core production after setting logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.setOption(":produce-assignments", true); Assert.fail("Could activate assignment production after setting logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.setOption(":interpolant-check-mode", true); Assert.fail("Could activate interpolant check mode after setting logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.setOption(":unsat-core-check-mode", true); Assert.fail("Could activate unsat core check mode after setting logic"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } } @Test public void testSetLogicTwice() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); solver.setLogic(Logics.QF_LIA); try { solver.setLogic(Logics.QF_LIA); Assert.fail("Could set logic a second time"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.declareFun("x", new Sort[0], solver.sort("Int")); solver.assertTerm(solver.term("=", solver.term("x"), solver.numeral(BigInteger.ZERO))); solver.checkSat(); } catch (final SMTLIBException eUnexpected) { Assert.fail(eUnexpected.getMessage()); } } @Test public void testTermAssertion() { final SMTInterpol solver1 = new SMTInterpol(new DefaultLogger()); final SMTInterpol solver2 = new SMTInterpol(new DefaultLogger()); solver1.setLogic(Logics.QF_LIA); solver2.setLogic(Logics.QF_LIA); solver1.declareFun("x", new Sort[0], solver1.sort("Int")); solver2.declareFun("x", new Sort[0], solver2.sort("Int")); try { solver1.assertTerm(solver2.term("=", solver2.term("x"), solver2.numeral(BigInteger.ZERO))); Assert.fail("Could assert term created by different solver"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver1.assertTerm(solver1.term("x")); Assert.fail("Could assert non-Boolean term"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } if (Config.STRONG_USAGE_CHECKS) { try { solver1.assertTerm(solver1.term("=", solver1.term("x"), solver1.variable("y", solver1.sort("Int")))); Assert.fail("Could assert open term"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } } else { System.out.println("Skipping closed formula test since strong usage checks are disabled");// NOCHECKSTYLE } } @Test public void testUndeclared() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); solver.setLogic(Logics.QF_LIA); try { solver.term("x"); Assert.fail("Could create undeclared term"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } try { solver.variable("x", solver.sort("NOTEXISTENT")); Assert.fail("Could create variable with unknown sort"); } catch (final SMTLIBException expected) { System.err.println(expected.getMessage()); } } @Test public void cancellationRequest() { final TerminationCounter tc = new TerminationCounter(); final SMTInterpol solver = new SMTInterpol(new DefaultLogger(), tc); solver.setLogic(Logics.CORE); final Sort bool = solver.sort("Bool"); solver.declareFun("P", new Sort[0], bool); solver.declareFun("Q", new Sort[0], bool); solver.declareFun("R", new Sort[0], bool); solver.push(1); solver.assertTerm(solver.term( "or", solver.term("P"), solver.term("Q"))); solver.assertTerm(solver.term( "or", solver.term("P"), solver.term("R"))); solver.assertTerm(solver.term( "or", solver.term("not", solver.term("P")), solver.term("not", solver.term("Q")))); solver.assertTerm(solver.term( "or", solver.term("not", solver.term("P")), solver.term("not", solver.term("R")))); solver.assertTerm(solver.term( "or", solver.term("not", solver.term("P")), solver.term("Q"), solver.term("R"))); LBool isSat = solver.checkSat(); Assert.assertSame(LBool.SAT, isSat); solver.pop(1); tc.setStop(true); solver.push(1); solver.assertTerm(solver.term( "or", solver.term("P"), solver.term("Q"))); solver.assertTerm(solver.term( "or", solver.term("P"), solver.term("R"))); solver.assertTerm(solver.term( "or", solver.term("not", solver.term("P")), solver.term("not", solver.term("Q")))); solver.assertTerm(solver.term( "or", solver.term("not", solver.term("P")), solver.term("not", solver.term("R")))); solver.assertTerm(solver.term( "or", solver.term("not", solver.term("P")), solver.term("Q"), solver.term("R"))); solver.assertTerm(solver.term( "or", solver.term("P"), solver.term("not", solver.term("Q")), solver.term("not", solver.term("R")))); isSat = solver.checkSat(); Assert.assertSame(LBool.UNKNOWN, isSat); ReasonUnknown ru = (ReasonUnknown) solver.getInfo(":reason-unknown"); Assert.assertSame(ReasonUnknown.CANCELLED, ru); // Check monotonicity of checker tc.setStop(false); isSat = solver.checkSat(); Assert.assertSame(LBool.UNKNOWN, isSat); ru = (ReasonUnknown) solver.getInfo(":reason-unknown"); Assert.assertSame(ReasonUnknown.CANCELLED, ru); solver.pop(1); isSat = solver.checkSat(); Assert.assertSame(LBool.SAT, isSat); } @Test public void testResetAssertions() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); solver.setLogic(Logics.QF_LIA); solver.declareFun("x", Script.EMPTY_SORT_ARRAY, solver.sort("Int")); solver.assertTerm(solver.term("false")); LBool res = solver.checkSat(); Assert.assertSame(res, LBool.UNSAT); try { solver.resetAssertions(); res = solver.checkSat(); Assert.assertSame(res, LBool.SAT); } catch (final SMTLIBException ese) { Assert.fail(ese.getMessage()); } catch (final UnsupportedOperationException eunsupp) { Assert.fail(eunsupp.getMessage()); } try { solver.declareFun("x", Script.EMPTY_SORT_ARRAY, solver.sort("Int")); } catch (final SMTLIBException ese) { Assert.fail(ese.getMessage()); } } @Test public void testGlobalSymbols() { final SMTInterpol solver = new SMTInterpol(new DefaultLogger()); try { solver.setOption(":global-declarations", Boolean.TRUE); } catch (final UnsupportedOperationException eunsupp) { Assert.fail("global-declarations not supported!!!"); } solver.setLogic(Logics.QF_LIA); solver.declareFun("x", Script.EMPTY_SORT_ARRAY, solver.sort("Int")); final Term x = solver.term("x"); try { solver.resetAssertions(); } catch (final SMTLIBException ese) { Assert.fail(ese.getMessage()); } catch (final UnsupportedOperationException eunsupp) { Assert.fail(eunsupp.getMessage()); } try { final Term x2 = solver.term("x"); Assert.assertSame(x, x2); } catch (final SMTLIBException ese) { Assert.fail(ese.getMessage()); } } }