/** * Author: Bettina Koenighofer <bettina.koenighofer@iaik.tugraz.at> */ package at.iaik.suraq.test; import java.util.HashSet; import java.util.Set; import org.junit.Assert; import org.junit.Test; import at.iaik.suraq.exceptions.ParseError; import at.iaik.suraq.parser.ProofParser; import at.iaik.suraq.parser.SExpParser; import at.iaik.suraq.resProof.ResProof; import at.iaik.suraq.sexp.SExpression; import at.iaik.suraq.sexp.SExpressionConstants; import at.iaik.suraq.smtlib.TransformedZ3Proof; import at.iaik.suraq.smtlib.Z3Proof; import at.iaik.suraq.smtlib.formula.ArrayVariable; import at.iaik.suraq.smtlib.formula.DomainVariable; import at.iaik.suraq.smtlib.formula.PropositionalVariable; import at.iaik.suraq.smtlib.formula.UninterpretedFunction; import at.iaik.suraq.util.Util; /** * @author Bettina Koenighofer <bettina.koenighofer@iaik.tugraz.at> * */ public class TransformedZ3ProofTest { /** * Tests the transformation of unit-resolution into multiple (simple) * resolutions. */ @Test public void testUnitResolutionTransformationSimple() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); propsitionalVars.add(PropositionalVariable.create("a")); propsitionalVars.add(PropositionalVariable.create("b")); String proof = "(|unit-resolution| (asserted (or a b)) (asserted (not a)) b)"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( asserted ( or b ))"; Assert.assertEquals(SExpression.fromString(expectedOutput), SExpression.fromString(output)); } /** * Tests the transformation of unit-resolution into multiple (simple) * resolutions. */ @Test public void testUnitResolutionTransformation() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); propsitionalVars.add(PropositionalVariable.create("a", -1)); propsitionalVars.add(PropositionalVariable.create("b", 1)); propsitionalVars.add(PropositionalVariable.create("c", 1)); String proof = "(|unit-resolution| (asserted (or a b c)) (asserted (not a)) (asserted (not b)) c)"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( asserted ( or c ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } /** * Tests the transformation of lemma into resolutions. */ @Test public void testLemmaTransformation() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); propsitionalVars.add(PropositionalVariable.create("a", 1)); propsitionalVars.add(PropositionalVariable.create("b", 2)); propsitionalVars.add(PropositionalVariable.create("c")); String resolution1 = "(|unit-resolution| (asserted (or (not a) c)) (hypothesis a) c )"; String resolution2 = "(|unit-resolution| (asserted (or b (not c))) (hypothesis (not b)) (not c) )"; String resolution3 = "(|unit-resolution| " + resolution1 + resolution2 + " false)"; String proof = "(lemma " + resolution3 + "(or (not a) b))"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( unit-resolution{c} ( asserted ( or c ( not a ) ) ) ( asserted ( or ( not c ) b ) ) ( or b ( not a ) ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } /** * Tests the transformation of unit-resolution into multiple (simple) * resolutions. */ @Test public void testTransitivity() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); propsitionalVars.add(PropositionalVariable.create("a", 1)); propsitionalVars.add(PropositionalVariable.create("b", 2)); propsitionalVars.add(PropositionalVariable.create("x", -1)); propsitionalVars.add(PropositionalVariable.create("y", -1)); String symmetry = "(symm (asserted (= a y)) (= y a))"; String trans1 = "(trans (asserted (= a x)) (asserted (= x b)) (= a b))"; String trans2 = "(trans " + symmetry + trans1 + "(= y b))"; String proof = "(|unit-resolution| " + trans2 + "(asserted (not (= y b))) false)"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( unit-resolution{( = y b)} ( unit-resolution{( = x b)} ( asserted ( or ( = x b ) ) ) ( unit-resolution{( = y x)} ( unit-resolution{( = a x)} ( asserted ( or ( = a x ) ) ) ( unit-resolution{( = y a)} ( asserted ( or ( = y a ) ) ) ( asserted ( or ( not ( = y a ) ) ( not ( = a x ) ) ( = y x ) ) ) ( or ( not ( = a x ) ) ( = y x ) ) ) ( or ( = y x ) ) ) ( asserted ( or ( not ( = y x ) ) ( not ( = x b ) ) ( = y b ) ) ) ( or ( not ( = x b ) ) ( = y b ) ) ) ( or ( = y b ) ) ) ( asserted ( or ( not ( = y b ) ) ) ) ( or false ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } @Test public void testLemma() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); domainVars.add(DomainVariable.create("a", 1)); domainVars.add(DomainVariable.create("b", 2)); domainVars.add(DomainVariable.create("c", 3)); domainVars.add(DomainVariable.create("d", 3)); domainVars.add(DomainVariable.create("e", -1)); domainVars.add(DomainVariable.create("f", -1)); domainVars.add(DomainVariable.create("x", -1)); domainVars.add(DomainVariable.create("y", -1)); String unitResolution1 = "(|unit-resolution| (hypothesis (not (= x b))) (asserted (or (= b x) (not (= e f)))) (not (= e f)))"; String unitResolution2 = "(|unit-resolution| (asserted (or (= c d) (= e f)))" + unitResolution1 + "(= c d))"; String unitResolution3 = "(|unit-resolution| " + unitResolution2 + " (asserted (not (= c d))) false)"; String proof = "(lemma " + unitResolution3 + "(= x b))"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( unit-resolution{( = c d)} ( unit-resolution{( = e f)} ( asserted ( or ( = c d ) ( = e f ) ) ) ( asserted ( or ( not ( = e f ) ) ( = x b ) ) ) ( or ( = c d ) ( = x b ) ) ) ( asserted ( or ( not ( = c d ) ) ) ) ( or ( = x b ) ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } @Test public void testLemmaAndTransitivity() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); propsitionalVars.add(PropositionalVariable.create("a", 1)); propsitionalVars.add(PropositionalVariable.create("b", 2)); propsitionalVars.add(PropositionalVariable.create("c", 3)); propsitionalVars.add(PropositionalVariable.create("d", 3)); propsitionalVars.add(PropositionalVariable.create("e", -1)); propsitionalVars.add(PropositionalVariable.create("f", -1)); propsitionalVars.add(PropositionalVariable.create("x", -1)); propsitionalVars.add(PropositionalVariable.create("y", -1)); String unitResolution1 = "(|unit-resolution| (hypothesis (not (= x b))) (asserted (or (= b x) (not (= e f)))) (not (= e f)))"; String unitResolution2 = "(|unit-resolution| (asserted (or (= c d) (= e f)))" + unitResolution1 + "(= c d))"; String unitResolution3 = "(|unit-resolution| " + unitResolution2 + " (asserted (not (= c d))) false)"; String lemmaProof = "(lemma " + unitResolution3 + "(= x b))"; String symmetry = "(symm (asserted (= a y)) (= y a))"; String trans1 = "(trans (asserted (= a x)) " + lemmaProof + " (= a b))"; String trans2 = "(trans " + symmetry + trans1 + "(= y b))"; String proof = "(|unit-resolution| " + trans2 + "(asserted (not (= y b))) false)"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( unit-resolution{( = y b)} ( unit-resolution{( = x b)} ( unit-resolution{( = c d)} ( unit-resolution{( = e f)} ( asserted ( or ( = c d ) ( = e f ) ) ) ( asserted ( or ( not ( = e f ) ) ( = x b ) ) ) ( or ( = c d ) ( = x b ) ) ) ( asserted ( or ( not ( = c d ) ) ) ) ( or ( = x b ) ) ) ( unit-resolution{( = y x)} ( unit-resolution{( = a x)} ( asserted ( or ( = a x ) ) ) ( unit-resolution{( = y a)} ( asserted ( or ( = y a ) ) ) ( asserted ( or ( not ( = y a ) ) ( not ( = a x ) ) ( = y x ) ) ) ( or ( not ( = a x ) ) ( = y x ) ) ) ( or ( = y x ) ) ) ( asserted ( or ( not ( = y x ) ) ( not ( = x b ) ) ( = y b ) ) ) ( or ( not ( = x b ) ) ( = y b ) ) ) ( or ( = y b ) ) ) ( asserted ( or ( not ( = y b ) ) ) ) ( or false ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } @Test public void test1ToLocalProof() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); domainVars.add(DomainVariable.create("a", 1)); domainVars.add(DomainVariable.create("b", 2)); domainVars.add(DomainVariable.create("x", -1)); domainVars.add(DomainVariable.create("y", -1)); uninterpretedFunctions.add(UninterpretedFunction.create("f", 1, SExpressionConstants.VALUE_TYPE)); String trans1 = "(trans (asserted (= a x)) (asserted (= x b)) (= a b))"; String monotonicity1 = "(monotonicity " + trans1 + "(= (f a) (f b)))"; String symmetrie = "(symm " + monotonicity1 + "(= (f b) (f a)))"; String trans2 = "(trans " + symmetrie + "(asserted (= (f a) y)) (= (f b) y))"; String proof = "(|unit-resolution| " + trans2 + "(symm (asserted (not (= y (f b)))) (not (= (f b) y)))" + "false)"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( unit-resolution{( = ( f b ) y)} ( unit-resolution{( = ( f x ) y)} ( unit-resolution{( = ( f a ) y)} ( asserted ( or ( = ( f a ) y ) ) ) ( unit-resolution{( = ( f a ) ( f x ))} ( unit-resolution{( = a x)} ( asserted ( or ( = a x ) ) ) ( asserted ( or ( not ( = a x ) ) ( = ( f a ) ( f x ) ) ) ) ( or ( = ( f a ) ( f x ) ) ) ) ( asserted ( or ( not ( = ( f x ) ( f a ) ) ) ( not ( = ( f a ) y ) ) ( = ( f x ) y ) ) ) ( or ( not ( = ( f a ) y ) ) ( = ( f x ) y ) ) ) ( or ( = ( f x ) y ) ) ) ( unit-resolution{( = ( f x ) ( f b ))} ( unit-resolution{( = x b)} ( asserted ( or ( = x b ) ) ) ( asserted ( or ( not ( = x b ) ) ( = ( f x ) ( f b ) ) ) ) ( or ( = ( f x ) ( f b ) ) ) ) ( asserted ( or ( not ( = ( f b ) ( f x ) ) ) ( not ( = ( f x ) y ) ) ( = ( f b ) y ) ) ) ( or ( not ( = ( f x ) y ) ) ( = ( f b ) y ) ) ) ( or ( = ( f b ) y ) ) ) ( asserted ( or ( not ( = ( f b ) y ) ) ) ) ( or false ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } @Test public void test2ToLocalProof() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); domainVars.add(DomainVariable.create("a", 1)); domainVars.add(DomainVariable.create("b", 1)); domainVars.add(DomainVariable.create("c", 2)); domainVars.add(DomainVariable.create("d", 2)); domainVars.add(DomainVariable.create("x", -1)); domainVars.add(DomainVariable.create("y", -1)); domainVars.add(DomainVariable.create("z", -1)); domainVars.add(DomainVariable.create("u", -1)); domainVars.add(DomainVariable.create("v", -1)); domainVars.add(DomainVariable.create("w", -1)); uninterpretedFunctions.add(UninterpretedFunction.create("f", 2, SExpressionConstants.VALUE_TYPE)); String trans1 = "(trans (asserted (= a x)) (asserted (= x c)) (= a c))"; String trans2 = "(trans (asserted (= b y)) (asserted (= y d)) (= b d))"; String mono1 = "(monotonicity " + trans1 + trans2 + " (= (f a b) (f c d)))"; String trans3 = "(trans (asserted (= u (f a b))) " + mono1 + " (= u (f c d)))"; String sym1 = "(symm " + trans3 + " (= (f c d) u))"; String trans4 = "(trans " + sym1 + " (asserted (= u v)) (= (f c d) v))"; String sym2 = "(symm " + trans4 + " (= v (f c d)))"; String proof = "(|unit-resolution| " + sym2 + " (asserted (not (= v (f c d)))) false)"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); String expectedOutput = "( unit-resolution{( = v ( f c d ))} ( unit-resolution{( = ( f x y ) ( f c d ))} ( unit-resolution{( = y d)} ( asserted ( or ( = y d ) ) ) ( unit-resolution{( = x c)} ( asserted ( or ( = x c ) ) ) ( asserted ( or ( not ( = x c ) ) ( not ( = y d ) ) ( = ( f x y ) ( f c d ) ) ) ) ( or ( not ( = y d ) ) ( = ( f x y ) ( f c d ) ) ) ) ( or ( = ( f x y ) ( f c d ) ) ) ) ( unit-resolution{( = ( f x y ) v)} ( unit-resolution{( = u v)} ( asserted ( or ( = u v ) ) ) ( unit-resolution{( = u ( f x y ))} ( unit-resolution{( = ( f a b ) ( f x y ))} ( unit-resolution{( = b y)} ( asserted ( or ( = b y ) ) ) ( unit-resolution{( = a x)} ( asserted ( or ( = a x ) ) ) ( asserted ( or ( not ( = a x ) ) ( not ( = b y ) ) ( = ( f a b ) ( f x y ) ) ) ) ( or ( not ( = b y ) ) ( = ( f a b ) ( f x y ) ) ) ) ( or ( = ( f a b ) ( f x y ) ) ) ) ( unit-resolution{( = u ( f a b ))} ( asserted ( or ( = u ( f a b ) ) ) ) ( asserted ( or ( not ( = u ( f a b ) ) ) ( not ( = ( f a b ) ( f x y ) ) ) ( = u ( f x y ) ) ) ) ( or ( not ( = ( f a b ) ( f x y ) ) ) ( = u ( f x y ) ) ) ) ( or ( = u ( f x y ) ) ) ) ( asserted ( or ( not ( = ( f x y ) u ) ) ( not ( = u v ) ) ( = ( f x y ) v ) ) ) ( or ( not ( = u v ) ) ( = ( f x y ) v ) ) ) ( or ( = ( f x y ) v ) ) ) ( asserted ( or ( not ( = v ( f x y ) ) ) ( not ( = ( f x y ) ( f c d ) ) ) ( = v ( f c d ) ) ) ) ( or ( not ( = ( f x y ) ( f c d ) ) ) ( = v ( f c d ) ) ) ) ( or ( = v ( f c d ) ) ) ) ( asserted ( or ( not ( = v ( f c d ) ) ) ) ) ( or false ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } @Test public void testDAGProofWithHypotheses() { Set<DomainVariable> domainVars = new HashSet<DomainVariable>(); Set<PropositionalVariable> propsitionalVars = new HashSet<PropositionalVariable>(); Set<UninterpretedFunction> uninterpretedFunctions = new HashSet<UninterpretedFunction>(); Set<ArrayVariable> arrayVars = new HashSet<ArrayVariable>(); propsitionalVars.add(PropositionalVariable.create("a", -1)); propsitionalVars.add(PropositionalVariable.create("b", -1)); propsitionalVars.add(PropositionalVariable.create("c", 1)); propsitionalVars.add(PropositionalVariable.create("d", 2)); propsitionalVars.add(PropositionalVariable.create("e", 2)); String unitResolutionE = "(|unit-resolution| (hypothesis e) (asserted (or (not b) (not d) (not e))) (or (not b) (not d)))"; String unitResolutionD = "(|unit-resolution| (hypothesis d) " + unitResolutionE + " (or (not b)))"; String unitResolutionC = "(|unit-resolution| (hypothesis (not c)) (asserted (or (not a) b c)) (or (not a) b))"; String unitResolutionB1 = "(|unit-resolution| (asserted (or a b )) @x1 (or a))"; String unitResolutionB2 = "(|unit-resolution| @x1 " + unitResolutionC + "(not a))"; String unitResolutionA = "(|unit-resolution| " + unitResolutionB1 + " " + unitResolutionB2 + "false)"; String letExpression = "(let ((@x1 " + unitResolutionD + "))" + unitResolutionA + ")"; String proof = "(lemma " + letExpression + "(or c (not d) (not e)))"; String output = parseAndTransform(proof, domainVars, propsitionalVars, uninterpretedFunctions, arrayVars); System.out.println(output); String expectedOutput = "( unit-resolution{a} ( unit-resolution{b} ( asserted ( or a b ) ) ( asserted ( or ( not b ) ( not d ) ( not e ) ) ) ( or a ( not d ) ( not e ) ) ) ( unit-resolution{b} ( asserted ( or ( not b ) ( not d ) ( not e ) ) ) ( asserted ( or ( not a ) b c ) ) ( or ( not a ) c ( not d ) ( not e ) ) ) ( or c ( not d ) ( not e ) ))"; Assert.assertEquals(SExpression.fromString(expectedOutput).toString(), SExpression.fromString(output).toString()); } /** * Helper function to parse and transform a given proof. * * @param proof * proof string to be parsed * @param domainVars * set of <code>DomainVariable</code> contained in the proof * @param propsitionalVars * set of <code>PropsitionalVariable</code> contained in the * proof * @param uninterpretedFunctions * set of <code>UninterpretedFunction</code> contained in the * proof * @param arrayVars * set of <code>ArrayVariable</code> contained in the proof */ @SuppressWarnings("deprecation") private String parseAndTransform(String proof, Set<DomainVariable> domainVars, Set<PropositionalVariable> propsitionalVars, Set<UninterpretedFunction> uninterpretedFunctions, Set<ArrayVariable> arrayVars) { // expression parsing of proof SExpParser sExpProofParser = null; sExpProofParser = new SExpParser(proof); try { sExpProofParser.parse(); assert (sExpProofParser.wasParsingSuccessfull()); } catch (ParseError exc) { exc.printStackTrace(); throw new RuntimeException("SExpression Parse Error in Testcase: " + exc); } // parsing proof ProofParser proofParser = new ProofParser( sExpProofParser.getRootExpr(), domainVars, propsitionalVars, arrayVars, uninterpretedFunctions); try { proofParser.parse(); assert (proofParser.wasParsingSuccessfull()); } catch (ParseError exc) { exc.printStackTrace(); throw new RuntimeException("Proof Parse Error in Testcase: " + exc); } Z3Proof rootProof = proofParser.getRootProof(); Assert.assertEquals(rootProof.allNodes().size(), rootProof.size()); @SuppressWarnings("unused") String proofString = rootProof.prettyPrint(); Assert.assertTrue(rootProof.checkZ3ProofNodeRecursive()); rootProof.localLemmasToAssertions(); Assert.assertTrue(rootProof.checkZ3ProofNodeRecursive()); rootProof.removeLocalSubProofs(); Assert.assertTrue(rootProof.checkZ3ProofNodeRecursive()); TransformedZ3Proof transformedZ3Proof = TransformedZ3Proof .convertToTransformedZ3Proof(rootProof); Assert.assertTrue(transformedZ3Proof.checkZ3ProofNodeRecursive()); transformedZ3Proof.toLocalProof(); Assert.assertTrue(transformedZ3Proof.isLocal()); Assert.assertTrue(transformedZ3Proof.checkZ3ProofNodeRecursive()); transformedZ3Proof.toResolutionProof(); Assert.assertTrue(transformedZ3Proof.checkZ3ProofNodeRecursive()); @SuppressWarnings("unused") String test = transformedZ3Proof.prettyPrint(); Assert.assertEquals(transformedZ3Proof.allNodes().size(), transformedZ3Proof.size()); // START: ASHUTOSH code ResProof resolutionProof = Util .createResolutionProof(transformedZ3Proof); resolutionProof.checkProof(false); resolutionProof.rmDoubleLits(); resolutionProof.checkProof(false); resolutionProof.deLocalizeProof(); resolutionProof.checkProof(false); // END: ASHUTOSH code // Transform back into Z3Proof format @SuppressWarnings("unused") TransformedZ3Proof recoveredProof = new TransformedZ3Proof( resolutionProof.getRoot(), Util.getLiteralMap(), null); // System.out.println(recoveredProof); // System.out.println(recoveredProof.prettyPrint()); return transformedZ3Proof.toString().replaceAll("\n", "") .replaceAll("\\s{2,}", " "); } }