From 16a9b534adec2c53b50f92a43c1623918b1c59c0 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 7 Mar 2024 22:10:42 +0100 Subject: refactor: move terms and DNF into logic subproject --- .../MismatchDescribingDnfEqualityChecker.java | 68 ++++++++++++++++++++++ .../tools/refinery/logic/tests/QueryMatchers.java | 46 +++++++++++++++ .../refinery/logic/tests/StructurallyEqualTo.java | 41 +++++++++++++ .../logic/tests/StructurallyEqualToRaw.java | 51 ++++++++++++++++ 4 files changed, 206 insertions(+) create mode 100644 subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/MismatchDescribingDnfEqualityChecker.java create mode 100644 subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/QueryMatchers.java create mode 100644 subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualTo.java create mode 100644 subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualToRaw.java (limited to 'subprojects/logic/src/testFixtures/java') diff --git a/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/MismatchDescribingDnfEqualityChecker.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/MismatchDescribingDnfEqualityChecker.java new file mode 100644 index 00000000..aa73baec --- /dev/null +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/MismatchDescribingDnfEqualityChecker.java @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.tests; + +import org.hamcrest.Description; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.equality.DeepDnfEqualityChecker; +import tools.refinery.logic.literal.Literal; + +import java.util.List; + +class MismatchDescribingDnfEqualityChecker extends DeepDnfEqualityChecker { + private final Description description; + private boolean raw; + private boolean needsDescription = true; + + MismatchDescribingDnfEqualityChecker(Description description) { + this.description = description; + } + + public boolean needsDescription() { + return needsDescription; + } + + @Override + public boolean dnfEqualRaw(List symbolicParameters, List> clauses, Dnf other) { + try { + raw = true; + boolean result = super.dnfEqualRaw(symbolicParameters, clauses, other); + if (!result && needsDescription) { + description.appendText("was ").appendText(other.toDefinitionString()); + } + return false; + } finally { + raw = false; + } + } + + @Override + protected boolean doCheckEqual(Pair pair) { + boolean result = super.doCheckEqual(pair); + if (!result && needsDescription) { + describeMismatch(pair); + // Only describe the first found (innermost) mismatch. + needsDescription = false; + } + return result; + } + + private void describeMismatch(Pair pair) { + var inProgress = getInProgress(); + int size = inProgress.size(); + if (size <= 1 && !raw) { + description.appendText("was ").appendText(pair.right().toDefinitionString()); + return; + } + var last = inProgress.get(size - 1); + description.appendText("expected ").appendText(last.left().toDefinitionString()); + for (int i = size - 2; i >= 0; i--) { + description.appendText(" called from ").appendText(inProgress.get(i).left().toString()); + } + description.appendText(" was not structurally equal to ").appendText(last.right().toDefinitionString()); + } +} diff --git a/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/QueryMatchers.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/QueryMatchers.java new file mode 100644 index 00000000..40332a8c --- /dev/null +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/QueryMatchers.java @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.tests; + +import org.hamcrest.Matcher; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.literal.Literal; + +import java.util.List; + +public final class QueryMatchers { + private QueryMatchers() { + throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); + } + + /** + * Compare two {@link Dnf} instances up to renaming of variables. + * + * @param expected The expected {@link Dnf} instance. + * @return A Hamcrest matcher for equality up to renaming of variables. + */ + public static Matcher structurallyEqualTo(Dnf expected) { + return new StructurallyEqualTo(expected); + } + + /** + * Compare a {@link Dnf} instance to another predicate in DNF form without constructing it. + *

+ * This matcher should be used instead of {@link #structurallyEqualTo(Dnf)} when the validation and + * pre-processing associated with the {@link Dnf} constructor, i.e., validation of parameter directions, + * topological sorting of literals, and the reduction of trivial predicates is not desired. In particular, this + * matcher can be used to test for exact order of literal after pre-processing. + * + * @param expectedSymbolicParameters The expected list of symbolic parameters. + * @param expectedLiterals The expected clauses. Each clause is represented by a list of literals. + * @return A Hamcrest matcher for equality up to renaming of variables. + */ + public static Matcher structurallyEqualTo(List expectedSymbolicParameters, + List> expectedLiterals) { + return new StructurallyEqualToRaw(expectedSymbolicParameters, expectedLiterals); + } +} diff --git a/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualTo.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualTo.java new file mode 100644 index 00000000..257e6850 --- /dev/null +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualTo.java @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.tests; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.equality.DeepDnfEqualityChecker; + +public class StructurallyEqualTo extends TypeSafeMatcher { + private final Dnf expected; + + public StructurallyEqualTo(Dnf expected) { + this.expected = expected; + } + + @Override + protected boolean matchesSafely(Dnf item) { + var checker = new DeepDnfEqualityChecker(); + return checker.dnfEqual(expected, item); + } + + @Override + protected void describeMismatchSafely(Dnf item, Description mismatchDescription) { + var describingChecker = new MismatchDescribingDnfEqualityChecker(mismatchDescription); + if (describingChecker.dnfEqual(expected, item)) { + throw new IllegalStateException("Mismatched Dnf was matching on repeated comparison"); + } + if (describingChecker.needsDescription()) { + super.describeMismatchSafely(item, mismatchDescription); + } + } + + @Override + public void describeTo(Description description) { + description.appendText("structurally equal to ").appendText(expected.toDefinitionString()); + } +} diff --git a/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualToRaw.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualToRaw.java new file mode 100644 index 00000000..944ab1ac --- /dev/null +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualToRaw.java @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.tests; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.equality.DeepDnfEqualityChecker; +import tools.refinery.logic.literal.Literal; + +import java.util.List; + +public class StructurallyEqualToRaw extends TypeSafeMatcher { + private final List expectedSymbolicParameters; + private final List> expectedClauses; + + public StructurallyEqualToRaw(List expectedSymbolicParameters, + List> expectedClauses) { + this.expectedSymbolicParameters = expectedSymbolicParameters; + this.expectedClauses = expectedClauses; + } + + @Override + protected boolean matchesSafely(Dnf item) { + var checker = new DeepDnfEqualityChecker(); + return checker.dnfEqualRaw(expectedSymbolicParameters, expectedClauses, item); + } + + @Override + protected void describeMismatchSafely(Dnf item, Description mismatchDescription) { + var describingChecker = new MismatchDescribingDnfEqualityChecker(mismatchDescription); + if (describingChecker.dnfEqualRaw(expectedSymbolicParameters, expectedClauses, item)) { + throw new IllegalStateException("Mismatched Dnf was matching on repeated comparison"); + } + if (describingChecker.needsDescription()) { + super.describeMismatchSafely(item, mismatchDescription); + } + } + + @Override + public void describeTo(Description description) { + description.appendText("structurally equal to ") + .appendValueList("(", ", ", ")", expectedSymbolicParameters) + .appendText(" <-> ") + .appendValueList("", ", ", ".", expectedClauses); + } +} -- cgit v1.2.3-70-g09d2