From 23f1a5657749baa638618ac26c885f7a68628dfb Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 2 Feb 2022 15:12:47 +0100 Subject: [PATCH 01/59] refactoring: reduce dependencies of unit tests, separate unit- and integration tests --- .../kr/alpha/AnswerSetToXlsxWriterTest.java | 1 + .../java/at/ac/tuwien/kr/alpha/MainTest.java | 1 + .../alpha/app/ComponentGraphWriterTest.java | 1 + .../alpha/app/DependencyGraphWriterTest.java | 1 + .../AnswerSetToWorkbookMapperTest.java | 1 + .../externals/AspStandardLibrary.java | 2 +- .../BinaryPredicateInterpretation.java | 2 +- .../BindingMethodPredicateInterpretation.java | 2 +- .../alpha/commons}/externals/Externals.java | 9 +- .../IntPredicateInterpretation.java | 2 +- .../LongPredicateInterpretation.java | 2 +- .../MethodPredicateInterpretation.java | 2 +- .../NonBindingPredicateInterpretation.java | 2 +- .../PredicateInterpretationImpl.java | 14 + .../SuppliedPredicateInterpretation.java | 2 +- .../UnaryPredicateInterpretation.java | 2 +- .../commons/atoms/BasicAtomImplTest.java | 67 +++ .../commons/atoms/ExternalAtomImplTest.java | 104 ++++ .../externals/AspStandardLibraryTest.java | 2 +- ...LiteralBindingNonBindingVariablesTest.java | 92 ++-- .../util}/SimpleAnswerSetFormatterTest.java | 3 +- .../kr/alpha/core/common/AtomStore.java | 4 + .../alpha/core/parser/ProgramParserImpl.java | 2 +- .../tuwien/kr/alpha/core/rules/BasicRule.java | 4 + .../kr/alpha/core/rules/InternalRule.java | 5 + .../ac/tuwien/kr/alpha/core/rules/Rules.java | 28 ++ .../ac/tuwien/kr/alpha/core/solver/Atoms.java | 9 - .../kr/alpha/core/solver/ChoiceManager.java | 2 +- .../kr/alpha/core/solver/TrailAssignment.java | 3 +- .../heuristics/AlphaRandomSignHeuristic.java | 9 +- .../tuwien/kr/alpha/core/atoms/AtomsTest.java | 148 ------ .../kr/alpha/core/common/ProgramTest.java | 40 +- .../tuwien/kr/alpha/core/common/RuleTest.java | 70 ++- .../depgraph/DependencyGraphImplTest.java | 276 ----------- .../depgraph/StratificationAlgorithmTest.java | 241 --------- ...java => GrounderMockWithBasicProgram.java} | 6 +- ...under.java => GrounderMockWithChoice.java} | 6 +- .../core/grounder/NaiveGrounderTest.java | 460 ------------------ .../core/grounder/NoGoodGeneratorTest.java | 93 ---- .../core/grounder/RuleGroundingInfoTest.java | 199 ++++++++ .../core/grounder/RuleGroundingOrderTest.java | 167 ------- .../alpha/core/grounder/SubstitutionTest.java | 23 +- .../alpha/core/grounder/UnificationTest.java | 111 ----- .../kr/alpha/core/grounder/UnifierTest.java | 84 ---- .../structure/AnalyzeUnjustifiedTest.java | 215 -------- .../kr/alpha/core/parser/ParserTest.java | 35 +- .../ProgramTransformationTest.java | 5 +- .../StratifiedEvaluationRegressionTest.java | 1 + .../StratifiedEvaluationTest.java | 3 +- .../AggregateRewritingRuleAnalysisTest.java | 207 -------- .../aggregates/AggregateRewritingTest.java | 1 + .../kr/alpha/core/solver/AggregatesTest.java | 1 + .../kr/alpha/core/solver/AntecedentTest.java | 32 -- .../core/solver/ArithmeticTermsTest.java | 1 + .../alpha/core/solver/AtomCounterTests.java | 1 + .../alpha/core/solver/ChoiceManagerTests.java | 25 +- .../kr/alpha/core/solver/HanoiTowerTest.java | 1 + .../core/solver/NaiveNoGoodStoreTest.java | 13 +- .../solver/NoGoodStoreAlphaRoamingTest.java | 13 +- .../core/solver/OmigaBenchmarksTest.java | 1 + .../solver/PartSubpartConfigurationTest.java | 1 + .../kr/alpha/core/solver/PigeonHoleTest.java | 1 + .../kr/alpha/core/solver/RacksTest.java | 1 + .../core/solver/SolverStatisticsTests.java | 7 +- .../kr/alpha/core/solver/SolverTests.java | 9 +- .../core/solver/TestableChoiceManager.java | 50 -- .../solver/ThreeColouringRandomGraphTest.java | 1 + .../solver/ThreeColouringTestWithRandom.java | 1 + .../core/solver/ThreeColouringWheelTest.java | 1 + .../core/solver/TrailAssignmentTest.java | 35 +- .../AlphaHeuristicTestAssumptions.java | 56 ++- .../GroundConflictNoGoodLearnerTest.java | 3 +- .../kr/alpha/core/test/util/TestUtils.java | 42 +- .../impl}/AggregateLiteralSplittingTest.java | 5 +- .../AggregateOperatorNormalizationTest.java | 10 +- .../impl}/AggregateRewritingContextTest.java | 4 +- .../kr/alpha/api/impl/AlphaImplTest.java | 7 +- .../impl}/ArithmeticTermsRewritingTest.java | 6 +- .../impl/FixedInterpretationLiteralsTest.java | 5 +- .../tuwien/kr/alpha/api/impl}/RuleParser.java | 2 +- .../kr/alpha/api/impl}/RuleToStringTest.java | 2 +- 81 files changed, 767 insertions(+), 2341 deletions(-) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/externals/AspStandardLibrary.java (99%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/BinaryPredicateInterpretation.java (96%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/BindingMethodPredicateInterpretation.java (98%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/externals/Externals.java (90%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/IntPredicateInterpretation.java (96%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/LongPredicateInterpretation.java (96%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/MethodPredicateInterpretation.java (97%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/NonBindingPredicateInterpretation.java (97%) create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/SuppliedPredicateInterpretation.java (97%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals}/UnaryPredicateInterpretation.java (96%) create mode 100644 alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImplTest.java create mode 100644 alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/ExternalAtomImplTest.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core => alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons}/externals/AspStandardLibraryTest.java (98%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms => alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals}/LiteralBindingNonBindingVariablesTest.java (61%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common => alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/util}/SimpleAnswerSetFormatterTest.java (85%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Atoms.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms/AtomsTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphImplTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithmTest.java rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/{DummyGrounder.java => GrounderMockWithBasicProgram.java} (96%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/{ChoiceGrounder.java => GrounderMockWithChoice.java} (97%) delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnificationTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustifiedTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AntecedentTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TestableChoiceManager.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl}/AggregateLiteralSplittingTest.java (95%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl}/AggregateOperatorNormalizationTest.java (95%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl}/AggregateRewritingContextTest.java (96%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl}/ArithmeticTermsRewritingTest.java (93%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl}/RuleParser.java (93%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl}/RuleToStringTest.java (98%) diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java index f1bf9e441..c3887321f 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java @@ -19,6 +19,7 @@ import at.ac.tuwien.kr.alpha.app.mappers.AnswerSetToWorkbookMapperTest; import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; +// TODO this is an integration test public class AnswerSetToXlsxWriterTest { @Test diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java index a6b26f307..97fec5bee 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java @@ -39,6 +39,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +// TODO this is an end-to-end test public class MainTest { private static final String INPUT = "p(a). " + System.lineSeparator() + " b :- p(X)." + System.lineSeparator(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java index fff165831..39273cf20 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java @@ -11,6 +11,7 @@ import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; +// TODO This is a functional test and should not be run with standard unit tests public class ComponentGraphWriterTest { private static final String LS = System.lineSeparator(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java index b487e8479..942da90a5 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java @@ -11,6 +11,7 @@ import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; +// TODO This is a functional test and should not be run with standard unit tests public class DependencyGraphWriterTest { private static final String LS = System.lineSeparator(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java index a2433d692..b528cd500 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java @@ -22,6 +22,7 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; +// TODO This is a functional test and should not be run with standard unit tests public class AnswerSetToWorkbookMapperTest { private AnswerSetToWorkbookMapper mapper = new AnswerSetToWorkbookMapper(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java similarity index 99% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java index 30aad5eed..14142ed62 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java @@ -23,7 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.externals; +package at.ac.tuwien.kr.alpha.commons.externals; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BinaryPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BinaryPredicateInterpretation.java index d0f62b756..22150b49f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BinaryPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BindingMethodPredicateInterpretation.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BindingMethodPredicateInterpretation.java index a73aae4b2..a12c6f44d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BindingMethodPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.StringUtils; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java index a4e02806a..386c8c983 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java @@ -23,7 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.externals; +package at.ac.tuwien.kr.alpha.commons.externals; import java.lang.reflect.Method; import java.util.ArrayList; @@ -44,13 +44,6 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BinaryPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BindingMethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.IntPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.LongPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.MethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.SuppliedPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.UnaryPredicateInterpretation; public final class Externals { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/IntPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/IntPredicateInterpretation.java index dd8acc05e..36d0a06bc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/IntPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/LongPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/LongPredicateInterpretation.java index e5ef94663..e7978f3c8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/LongPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/MethodPredicateInterpretation.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/MethodPredicateInterpretation.java index ff7dc78f6..c4aaacbdc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/MethodPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import org.apache.commons.lang3.ClassUtils; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/NonBindingPredicateInterpretation.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/NonBindingPredicateInterpretation.java index 53ad2350b..7a065aa7c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/NonBindingPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java new file mode 100644 index 000000000..8e52bfacb --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java @@ -0,0 +1,14 @@ +package at.ac.tuwien.kr.alpha.commons.externals; + +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +// TODO this looks like a duplicate +public interface PredicateInterpretationImpl extends PredicateInterpretation { + @Override + Set>> evaluate(List terms); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/SuppliedPredicateInterpretation.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/SuppliedPredicateInterpretation.java index a29adffbf..1efa81425 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/SuppliedPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.BindingPredicateInterpretation; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/UnaryPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/UnaryPredicateInterpretation.java index 5e90b4712..10611bcdc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/UnaryPredicateInterpretation.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.commons.externals; import java.util.List; diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImplTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImplTest.java new file mode 100644 index 000000000..275aa413e --- /dev/null +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImplTest.java @@ -0,0 +1,67 @@ +package at.ac.tuwien.kr.alpha.commons.atoms; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; + +/** + * Test for basic functionality of various implementations of {@link Atom}. + * + * Copyright (c) 2019-2021, the Alpha Team. + */ +public class BasicAtomImplTest { + + @Test + public void testIsBasicAtomGround() { + BasicAtomImpl a = new BasicAtomImpl(Predicates.getPredicate("bla", 2), Terms.newSymbolicConstant("blubb"), + Terms.newFunctionTerm("foo", Terms.newSymbolicConstant("bar"))); + assertTrue(a.isGround()); + BasicAtomImpl a1 = new BasicAtomImpl(Predicates.getPredicate("foo", 4), Terms.newConstant(1), Terms.newConstant(2), Terms.newConstant(3), + Terms.newConstant("bar")); + assertTrue(a1.isGround()); + BasicAtomImpl a2 = new BasicAtomImpl(Predicates.getPredicate("foo", 1), Terms.newVariable("BAR")); + assertFalse(a2.isGround()); + BasicAtomImpl a3 = new BasicAtomImpl(Predicates.getPredicate("foo", 3), Terms.newSymbolicConstant("b"), Terms.newSymbolicConstant("a"), + Terms.newFunctionTerm("r", Terms.newConstant("bla"), Terms.newVariable("BLUBB"))); + assertFalse(a3.isGround()); + } + + @Test + public void testAreBasicAtomsEqual() { + BasicAtomImpl a1 = new BasicAtomImpl(Predicates.getPredicate("bla", 2), Terms.newSymbolicConstant("blubb"), + Terms.newFunctionTerm("foo", Terms.newSymbolicConstant("bar"))); + BasicAtomImpl a2 = new BasicAtomImpl(Predicates.getPredicate("bla", 2), Terms.newSymbolicConstant("blubb"), + Terms.newFunctionTerm("foo", Terms.newSymbolicConstant("bar"))); + assertEquals(a1, a2); + + BasicAtomImpl a3 = new BasicAtomImpl(Predicates.getPredicate("foo", 4), Terms.newConstant(1), Terms.newConstant(2), Terms.newConstant(3), + Terms.newConstant("bar")); + BasicAtomImpl a4 = new BasicAtomImpl(Predicates.getPredicate("foo", 4), Terms.newConstant(1), Terms.newConstant(2), Terms.newConstant(3), + Terms.newConstant("bar")); + assertEquals(a3, a4); + + BasicAtomImpl a5 = new BasicAtomImpl(Predicates.getPredicate("foo", 1), Terms.newVariable("BAR")); + BasicAtomImpl a6 = new BasicAtomImpl(Predicates.getPredicate("foo", 1), Terms.newVariable("BAR")); + assertEquals(a5, a6); + + BasicAtomImpl a7 = new BasicAtomImpl(Predicates.getPredicate("foo", 3), Terms.newSymbolicConstant("b"), Terms.newSymbolicConstant("a"), + Terms.newFunctionTerm("r", Terms.newConstant("bla"), Terms.newVariable("BLUBB"))); + BasicAtomImpl a8 = new BasicAtomImpl(Predicates.getPredicate("foo", 3), Terms.newSymbolicConstant("b"), Terms.newSymbolicConstant("a"), + Terms.newFunctionTerm("r", Terms.newConstant("bla"), Terms.newVariable("BLUBB"))); + assertEquals(a7, a8); + + assertFalse(a1.equals(a3)); + assertFalse(a3.equals(a1)); + assertFalse(a1.equals(a5)); + assertFalse(a5.equals(a1)); + assertFalse(a1.equals(a7)); + assertFalse(a7.equals(a1)); + } + +} diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/ExternalAtomImplTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/ExternalAtomImplTest.java new file mode 100644 index 000000000..d762709b5 --- /dev/null +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/ExternalAtomImplTest.java @@ -0,0 +1,104 @@ +package at.ac.tuwien.kr.alpha.commons.atoms; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.externals.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; + +public class ExternalAtomImplTest { + + private Map externals; + + public ExternalAtomImplTest() throws NoSuchMethodException, SecurityException { + externals = new HashMap<>(); + externals.put("isFoo", Externals.processPredicateMethod(ExternalAtomImplTest.class.getMethod("isFoo", int.class))); + externals.put("extWithOutput", Externals.processPredicateMethod(ExternalAtomImplTest.class.getMethod("extWithOutput", int.class))); + } + + @Predicate + public static final boolean isFoo(int bar) { + return 0xF00 == bar; + } + + @Predicate + public static final Set>> extWithOutput(int in) { + Set>> retVal = new HashSet<>(); + List> lst = new ArrayList<>(); + lst.add(Terms.newConstant(in)); + retVal.add(lst); + return retVal; + } + + @Test + public void testIsExternalAtomGround() { + List ext1Input = new ArrayList<>(); + ext1Input.add(Terms.newConstant(1)); + // ext1 := &isFoo[1] + ExternalAtom ext1 = Atoms.newExternalAtom(Predicates.getPredicate("isFoo", 1), externals.get("isFoo"), ext1Input, Collections.emptyList()); + assertTrue(ext1.isGround()); + + // ext2 := &isFoo[bar(1)] + List ext2Input = new ArrayList<>(); + ext2Input.add(Terms.newFunctionTerm("bar", Terms.newConstant(1))); + ExternalAtom ext2 = Atoms.newExternalAtom(Predicates.getPredicate("isFoo", 1), externals.get("isFoo"), ext2Input, Collections.emptyList()); + assertTrue(ext2.isGround()); + + // ext3 := &isFoo[BLA] + List ext3Input = new ArrayList<>(); + ext3Input.add(Terms.newVariable("BLA")); + ExternalAtom ext3 = Atoms.newExternalAtom(Predicates.getPredicate("isFoo", 1), externals.get("isFoo"), ext3Input, Collections.emptyList()); + assertFalse(ext3.isGround()); + } + + @Test + @SuppressWarnings("unlikely-arg-type") + public void testAreExternalAtomsEqual() { + // ext1 := &isFoo[1] + List ext1Input = new ArrayList<>(); + ext1Input.add(Terms.newConstant(1)); + ExternalAtom ext1 = Atoms.newExternalAtom(Predicates.getPredicate("isFoo", 1), externals.get("isFoo"), ext1Input, Collections.emptyList()); + // ext2 := &isFoo[1] + List ext2Input = new ArrayList<>(); + ext2Input.add(Terms.newConstant(1)); + ExternalAtom ext2 = Atoms.newExternalAtom(Predicates.getPredicate("isFoo", 1), externals.get("isFoo"), ext2Input, Collections.emptyList()); + + assertEquals(ext1, ext2); + assertEquals(ext2, ext1); + + assertFalse(ext1.equals(null)); + assertFalse(ext1.equals("bla")); + assertTrue(ext1.hashCode() == ext2.hashCode()); + } + + @Test + public void testExternalHasOutput() { + // ext := &extWithOutput[1](OUT) + List input = new ArrayList<>(); + List output = new ArrayList<>(); + input.add(Terms.newConstant(1)); + output.add(Terms.newVariable("OUT")); + ExternalAtom ext = Atoms.newExternalAtom(Predicates.getPredicate("extWithOutput", 2), externals.get("extWithOutput"), input, output); + + assertFalse(ext.isGround()); + assertTrue(ext.hasOutput()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibraryTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibraryTest.java similarity index 98% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibraryTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibraryTest.java index 2e2e954ce..75efaa200 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibraryTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibraryTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.externals; +package at.ac.tuwien.kr.alpha.commons.externals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms/LiteralBindingNonBindingVariablesTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/LiteralBindingNonBindingVariablesTest.java similarity index 61% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms/LiteralBindingNonBindingVariablesTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/LiteralBindingNonBindingVariablesTest.java index 5b0370e9e..e60887fed 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms/LiteralBindingNonBindingVariablesTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/LiteralBindingNonBindingVariablesTest.java @@ -23,30 +23,29 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.atoms; +package at.ac.tuwien.kr.alpha.commons.literals; import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.IntPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.commons.externals.IntPredicateInterpretation; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; /** * Tests the behaviour of {@link Literal#getBindingVariables()} and {@link Literal#getNonBindingVariables()} @@ -55,12 +54,10 @@ */ public class LiteralBindingNonBindingVariablesTest { - private final Map externals = new HashMap<>(); - private final ProgramParser parser = new ProgramParserImpl(); - @Test public void testPositiveBasicLiteral() { - Literal literal = parser.parse("p(X,Y) :- q(X,Y).").getRules().get(0).getBody().stream().findFirst().get(); + // literal := q(X, Y) + Literal literal = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("X"), Terms.newVariable("Y")), true); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables(), "X", "Y"); expectVariables(literal.getNonBindingVariables()); @@ -68,7 +65,8 @@ public void testPositiveBasicLiteral() { @Test public void testNegativeBasicLiteral() { - Literal literal = parser.parse("p(X,Y) :- q(X,Y), not r(X,Y).").getRules().get(0).getNegativeBody().stream().findFirst().get(); + // literal := not r(X, Y) + Literal literal = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("r", 2), Terms.newVariable("X"), Terms.newVariable("Y")), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); @@ -76,8 +74,8 @@ public void testNegativeBasicLiteral() { @Test public void testPositiveComparisonLiteral_EQ_LeftAssigning() { - Rule rule = parser.parse("p(X) :- q(X,Y), Y = 5.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperators.EQ.toPredicate()).findFirst().get(); + // literal := Y = 5 + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.EQ), true); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); @@ -85,8 +83,8 @@ public void testPositiveComparisonLiteral_EQ_LeftAssigning() { @Test public void testNegativeComparisonLiteral_EQ_LeftAssigning() { - Rule rule = parser.parse("p(X) :- q(X,Y), not Y = 5.").getRules().get(0); - Literal literal = rule.getNegativeBody().stream().findFirst().get(); + // literal := not Y = 5 + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.EQ), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); @@ -94,8 +92,8 @@ public void testNegativeComparisonLiteral_EQ_LeftAssigning() { @Test public void testPositiveComparisonLiteral_EQ_RightAssigning() { - Rule rule = parser.parse("p(X) :- q(X,Y), 5 = Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperators.EQ.toPredicate()).findFirst().get(); + // literal := 5 = Y + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.EQ), true); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); @@ -103,25 +101,17 @@ public void testPositiveComparisonLiteral_EQ_RightAssigning() { @Test public void testNegativeComparisonLiteral_EQ_RightAssigning() { - Literal literal = parser.parse("p(X) :- q(X,Y), not 5 = Y.").getRules().get(0).getNegativeBody().stream().findFirst().get(); + // literal := 5 = Y + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.EQ), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); } - @Test - @Disabled("Literals of this kind are compiled away by VariableEqualityRemoval") - public void testPositiveComparisonLiteral_EQ_Bidirectional() { - Rule rule = parser.parse("p(X) :- q(X,Y), X = Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperators.EQ.toPredicate()).findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "X", "Y"); - } - @Test public void testNegativeComparisonLiteral_EQ_Bidirectional() { - Literal literal = parser.parse("p(X) :- q(X,Y), not X = Y.").getRules().get(0).getNegativeBody().stream().findFirst().get(); + // literal := not X = Y + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("X"), Terms.newVariable("Y"), ComparisonOperators.EQ), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); @@ -129,8 +119,8 @@ public void testNegativeComparisonLiteral_EQ_Bidirectional() { @Test public void testPositiveComparisonLiteral_NEQ_LeftAssigning() { - Rule rule = parser.parse("p(X) :- q(X,Y), Y != 5.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperators.NE.toPredicate()).findFirst().get(); + // literal := Y != 5 + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.NE), true); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); @@ -138,7 +128,8 @@ public void testPositiveComparisonLiteral_NEQ_LeftAssigning() { @Test public void testNegativeComparisonLiteral_NEQ_LeftAssigning() { - Literal literal = parser.parse("p(X) :- q(X,Y), not Y != 5.").getRules().get(0).getNegativeBody().stream().findFirst().get(); + // literal := not Y != 5 + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.NE), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); @@ -146,8 +137,8 @@ public void testNegativeComparisonLiteral_NEQ_LeftAssigning() { @Test public void testPositiveComparisonLiteral_NEQ_RightAssigning() { - Rule rule = parser.parse("p(X) :- q(X,Y), 5 != Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperators.NE.toPredicate()).findFirst().get(); + // literal := 5 != Y + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.NE), true); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); @@ -155,7 +146,8 @@ public void testPositiveComparisonLiteral_NEQ_RightAssigning() { @Test public void testNegativeComparisonLiteral_NEQ_RightAssigning() { - Literal literal = parser.parse("p(X) :- q(X,Y), not 5 != Y.").getRules().get(0).getNegativeBody().stream().findFirst().get(); + // literal := not 5 != Y + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.NE), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); @@ -163,8 +155,8 @@ public void testNegativeComparisonLiteral_NEQ_RightAssigning() { @Test public void testPositiveComparisonLiteral_NEQ_Bidirectional() { - Rule rule = parser.parse("p(X) :- q(X,Y), X != Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperators.NE.toPredicate()).findFirst().get(); + // literal := X != Y + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("X"), Terms.newVariable("Y"), ComparisonOperators.NE), true); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); @@ -173,7 +165,8 @@ public void testPositiveComparisonLiteral_NEQ_Bidirectional() { @Test @Disabled("Literals of this kind are compiled away by VariableEqualityRemoval") public void testNegativeComparisonLiteral_NEQ_Bidirectional() { - Literal literal = parser.parse("p(X) :- q(X,Y), not X != Y.").getRules().get(0).getNegativeBody().stream().findFirst().get(); + // literal := not X != Y + Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("X"), Terms.newVariable("Y"), ComparisonOperators.NE), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables(), "X", "Y"); expectVariables(literal.getNonBindingVariables()); @@ -181,9 +174,12 @@ public void testNegativeComparisonLiteral_NEQ_Bidirectional() { @Test public void testPositiveExternalLiteral() { - externals.put("ext", new IntPredicateInterpretation(i -> i > 0)); - Rule rule = parser.parse("p(X) :- q(Y), &ext[Y](X).", externals).getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate().getName().equals("ext")).findFirst().get(); + // literal := &ext[Y](X) + List extInput = new ArrayList<>(); + List extOutput = new ArrayList<>(); + extInput.add(Terms.newVariable("Y")); + extOutput.add(Terms.newVariable("X")); + Literal literal = Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("ext", 2), new IntPredicateInterpretation(i -> i > 0), extInput, extOutput), true); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables(), "X"); expectVariables(literal.getNonBindingVariables(), "Y"); @@ -191,8 +187,12 @@ public void testPositiveExternalLiteral() { @Test public void testNegativeExternalLiteral() { - externals.put("ext", new IntPredicateInterpretation(i -> i > 0)); - Literal literal = parser.parse("p(X) :- q(Y), not &ext[Y](X).", externals).getRules().get(0).getNegativeBody().stream().findFirst().get(); + // literal := not &ext[Y](X) + List extInput = new ArrayList<>(); + List extOutput = new ArrayList<>(); + extInput.add(Terms.newVariable("Y")); + extOutput.add(Terms.newVariable("X")); + Literal literal = Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("ext", 2), new IntPredicateInterpretation(i -> i > 0), extInput, extOutput), false); assertEquals(true, literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatterTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/util/SimpleAnswerSetFormatterTest.java similarity index 85% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatterTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/util/SimpleAnswerSetFormatterTest.java index 0b14388ad..b187bc242 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatterTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/util/SimpleAnswerSetFormatterTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.common; +package at.ac.tuwien.kr.alpha.commons.util; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -7,7 +7,6 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.util.AnswerSetFormatter; import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; -import at.ac.tuwien.kr.alpha.commons.util.SimpleAnswerSetFormatter; public class SimpleAnswerSetFormatterTest { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStore.java index e55c6fcfb..eeaa2f024 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStore.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStore.java @@ -116,4 +116,8 @@ default String noGoodToString(T noGood) { } AtomCounter getAtomCounter(); + + static boolean isAtom(int atom) { + return atom >= 0; + } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java index 2b7d82905..a0a71d8a5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java @@ -19,9 +19,9 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.externals.Externals; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; public class ProgramParserImpl implements ProgramParser { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java index 1a2cab45e..1c218769a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java @@ -27,6 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.rules; +import java.util.Arrays; import java.util.List; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -45,4 +46,7 @@ public BasicRule(Head head, List body) { super(head, body); } + public BasicRule(Head head, Literal... body) { + this(head, Arrays.asList(body)); + } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java index 9a72fca12..3283ac64f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java @@ -28,6 +28,7 @@ package at.ac.tuwien.kr.alpha.core.rules; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import com.google.common.annotations.VisibleForTesting; @@ -59,6 +60,10 @@ public class InternalRule extends NormalRuleImpl implements CompiledRule { private final RuleGroundingInfoImpl groundingOrders; + public InternalRule(NormalHead head, Literal... body) { + this(head, Arrays.asList(body)); + } + public InternalRule(NormalHead head, List body) { super(head, body); if (body.isEmpty()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java new file mode 100644 index 000000000..7666ba84a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java @@ -0,0 +1,28 @@ +package at.ac.tuwien.kr.alpha.core.rules; + +import java.util.ArrayList; +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; + +public final class Rules { + + private Rules() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static Rule newRule(BasicAtom headAtom, Literal... body) { + NormalHead head = Heads.newNormalHead(headAtom); + List bodyLiterals = new ArrayList<>(); + for (Literal lit : body) { + bodyLiterals.add(lit); + } + return new BasicRule(head, bodyLiterals); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Atoms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Atoms.java deleted file mode 100644 index 9ba91dbfa..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Atoms.java +++ /dev/null @@ -1,9 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.solver; - -public final class Atoms { - - public static boolean isAtom(int atom) { - return atom >= 0; - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManager.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManager.java index 8d8edcbb3..8e800b953 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManager.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManager.java @@ -205,7 +205,7 @@ public Choice backtrack() { return choice; } - void addChoiceInformation(Pair, Map> choiceAtoms, Map> headsToBodies) { + public void addChoiceInformation(Pair, Map> choiceAtoms, Map> headsToBodies) { choicePointInfluenceManager.addInformation(choiceAtoms); addHeadsToBodies(headsToBodies); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java index 9194925d8..929b904f3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java @@ -32,7 +32,6 @@ import static at.ac.tuwien.kr.alpha.core.atoms.Literals.atomOf; import static at.ac.tuwien.kr.alpha.core.atoms.Literals.atomToLiteral; import static at.ac.tuwien.kr.alpha.core.atoms.Literals.isPositive; -import static at.ac.tuwien.kr.alpha.core.solver.Atoms.isAtom; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.FALSE; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; @@ -335,7 +334,7 @@ private boolean assignmentsConsistent(ThriceTruth oldTruth, ThriceTruth value) { } private ConflictCause assignWithTrail(int atom, ThriceTruth value, Antecedent impliedBy) { - if (!isAtom(atom)) { + if (!AtomStore.isAtom(atom)) { throw new IllegalArgumentException("not an atom"); } if (value == null) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaRandomSignHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaRandomSignHeuristic.java index 4e2cbc238..e2b539dc4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaRandomSignHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaRandomSignHeuristic.java @@ -25,15 +25,14 @@ */ package at.ac.tuwien.kr.alpha.core.solver.heuristics; +import java.util.Random; + import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; -import static at.ac.tuwien.kr.alpha.core.solver.Atoms.isAtom; - -import java.util.Random; - public class AlphaRandomSignHeuristic extends DependencyDrivenHeuristic { public AlphaRandomSignHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { @@ -51,7 +50,7 @@ protected void incrementSignCounter(Integer literal) { @Override public boolean chooseSign(int atom) { - if (!isAtom(atom)) { + if (!AtomStore.isAtom(atom)) { throw new IllegalArgumentException("Atom must be a positive integer."); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms/AtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms/AtomsTest.java deleted file mode 100644 index 602bb960f..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/atoms/AtomsTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.atoms; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.externals.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.externals.Externals; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; - -/** - * Test for basic functionality of various implementations of {@link Atom}. - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public class AtomsTest { - - private final ProgramParser parser; - private Map externals; - - public AtomsTest() throws NoSuchMethodException, SecurityException { - externals = new HashMap<>(); - externals.put("isFoo", Externals.processPredicateMethod(AtomsTest.class.getMethod("isFoo", int.class))); - externals.put("extWithOutput", Externals.processPredicateMethod(AtomsTest.class.getMethod("extWithOutput", int.class))); - parser = new ProgramParserImpl(); - } - - @Predicate - public static final boolean isFoo(int bar) { - return 0xF00 == bar; - } - - @Predicate - public static final Set>> extWithOutput(int in) { - Set>> retVal = new HashSet<>(); - List> lst = new ArrayList<>(); - lst.add(Terms.newConstant(in)); - retVal.add(lst); - return retVal; - } - - @Test - public void testIsBasicAtomGround() { - ASPCore2Program p = parser.parse("bla(blubb, foo(bar))."); - Atom a = p.getFacts().get(0); - assertBasicAtomGround(a, true); - ASPCore2Program p1 = parser.parse("foo(1, 2, 3, \"bar\")."); - Atom a1 = p1.getFacts().get(0); - assertBasicAtomGround(a1, true); - ASPCore2Program p2 = parser.parse("foo(BAR)."); - Atom a2 = p2.getFacts().get(0); - assertBasicAtomGround(a2, false); - ASPCore2Program p3 = parser.parse("foo(b, a, r(\"bla\", BLUBB))."); - Atom a3 = p3.getFacts().get(0); - assertBasicAtomGround(a3, false); - } - - @Test - public void testAreBasicAtomsEqual() { - ASPCore2Program p1 = parser.parse("bla(blubb, foo(bar)). bla(blubb, foo(bar))."); - Atom a1 = p1.getFacts().get(0); - Atom a2 = p1.getFacts().get(1); - assertEquals(a1, a2); - ASPCore2Program p2 = parser.parse("foo(1, 2, 3, \"bar\"). foo(1, 2, 3, \"bar\")."); - Atom a3 = p2.getFacts().get(0); - Atom a4 = p2.getFacts().get(1); - assertEquals(a3, a4); - ASPCore2Program p3 = parser.parse("foo(BAR). foo(BAR)."); - Atom a5 = p3.getFacts().get(0); - Atom a6 = p3.getFacts().get(1); - assertEquals(a5, a6); - ASPCore2Program p4 = parser.parse("foo(b, a, r(\"bla\", BLUBB)). foo(b, a, r(\"bla\", BLUBB))."); - Atom a7 = p4.getFacts().get(0); - Atom a8 = p4.getFacts().get(1); - assertEquals(a7, a8); - - assertFalse(a1.equals(a3)); - assertFalse(a3.equals(a1)); - assertFalse(a1.equals(a5)); - assertFalse(a5.equals(a1)); - assertFalse(a1.equals(a7)); - assertFalse(a7.equals(a1)); - } - - @Test - public void testIsExternalAtomGround() { - ASPCore2Program p1 = parser.parse("a :- &isFoo[1].", externals); - Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext1, true); - ASPCore2Program p2 = parser.parse("a :- &isFoo[bar(1)].", externals); - Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext2, true); - ASPCore2Program p3 = parser.parse("a :- &isFoo[BLA].", externals); - Atom ext3 = p3.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext3, false); - } - - @Test - @SuppressWarnings("unlikely-arg-type") - public void testAreExternalAtomsEqual() { - ASPCore2Program p1 = parser.parse("a :- &isFoo[1].", externals); - Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - ASPCore2Program p2 = parser.parse("a :- &isFoo[1].", externals); - Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertEquals(ext1, ext2); - assertEquals(ext2, ext1); - - assertFalse(ext1.equals(null)); - assertFalse(ext1.equals("bla")); - assertTrue(ext1.hashCode() == ext2.hashCode()); - } - - @Test - public void testExternalHasOutput() { - ASPCore2Program p = parser.parse("a:- &extWithOutput[1](OUT).", externals); - Atom ext = p.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext, false); - assertTrue(((ExternalAtom) ext).hasOutput()); - } - - private void assertBasicAtomGround(Atom a, boolean expectedGround) { - assertTrue(a instanceof BasicAtom); - assertEquals(expectedGround, a.isGround()); - } - - private void assertExternalAtomGround(Atom a, boolean expectedGround) { - assertTrue(a instanceof ExternalAtom); - assertEquals(expectedGround, a.isGround()); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java index 9ced45803..0bd692dda 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java @@ -27,23 +27,43 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.ArrayList; +import java.util.List; + import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.Rules; public class ProgramTest { - + @Test public void testToString() { - ASPCore2Program parsedProgram = new ProgramParserImpl().parse( - "p(a)." + System.lineSeparator() + - "q(X) :- p(X)." + System.lineSeparator() + - "p(b)."); + ASPCore2Program program; + // rule := q(X) :- p(X). + List body = new ArrayList<>(); + body.add(Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newVariable("X")), true)); + Rule rule = Rules.newRule( + Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newVariable("X")), + Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newVariable("X")).toLiteral()); + List facts = new ArrayList<>(); + facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a"))); + facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("b"))); + // program := p(a). p(b). q(X) :- p(X). + program = InputProgram.builder().addFacts(facts).addRule(rule).build(); assertEquals( "p(a)." + System.lineSeparator() + - "p(b)." + System.lineSeparator() + - "q(X) :- p(X)." + System.lineSeparator(), - parsedProgram.toString()); + "p(b)." + System.lineSeparator() + + "q(X) :- p(X)." + System.lineSeparator(), + program.toString()); } -} \ No newline at end of file +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java index 0c637cb1a..9359bb09c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java @@ -1,46 +1,76 @@ package at.ac.tuwien.kr.alpha.core.common; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; +import at.ac.tuwien.kr.alpha.core.rules.Rules; /** - * Copyright (c) 2018, the Alpha Team. + * Copyright (c) 2018 - 2021, the Alpha Team. */ public class RuleTest { - private final ProgramParserImpl parser = new ProgramParserImpl(); - @Test public void renameVariables() { - String originalRule = "p(X,Y) :- a, f(Z) = 1, q(X,g(Y),Z), dom(A)."; - Rule rule = parser.parse(originalRule).getRules().get(0); - CompiledRule normalRule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(rule)); - CompiledRule renamedRule = normalRule.renameVariables("_13"); - Rule expectedRenamedRule = parser.parse("p(X_13, Y_13) :- a, f(Z_13) = 1, q(X_13, g(Y_13), Z_13), dom(A_13).").getRules().get(0); - CompiledRule expectedRenamedNormalRule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(expectedRenamedRule)); - assertEquals(expectedRenamedNormalRule.toString(), renamedRule.toString()); + // rule := p(X,Y) :- a, f(Z) = 1, q(X,g(Y),Z), dom(A). + BasicAtom headAtom = Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")); + BasicAtom bodyAtom1 = Atoms.newBasicAtom(Predicates.getPredicate("a", 0)); + ComparisonAtom bodyAtom2 = Atoms.newComparisonAtom(Terms.newFunctionTerm("f", Terms.newVariable("Z")), Terms.newConstant(1), ComparisonOperators.EQ); + BasicAtom bodyAtom3 = Atoms.newBasicAtom(Predicates.getPredicate("q", 3), + Terms.newVariable("X"), Terms.newFunctionTerm("g", Terms.newVariable("Y")), Terms.newVariable("Z")); + BasicAtom bodyAtom4 = Atoms.newBasicAtom(Predicates.getPredicate("dom", 1), Terms.newVariable("A")); + CompiledRule rule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule( + Rules.newRule(headAtom, bodyAtom1.toLiteral(), bodyAtom2.toLiteral(), bodyAtom3.toLiteral(), bodyAtom4.toLiteral()))); + + // ruleWithRenamedVars := p(X_13, Y_13) :- a, f(Z_13) = 1, q(X_13, g(Y_13), Z_13), dom(A_13). + BasicAtom headAtomRenamed = Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X_13"), Terms.newVariable("Y_13")); + BasicAtom bodyAtom1Renamed = Atoms.newBasicAtom(Predicates.getPredicate("a", 0)); + ComparisonAtom bodyAtom2Renamed = Atoms.newComparisonAtom(Terms.newFunctionTerm("f", Terms.newVariable("Z_13")), Terms.newConstant(1), + ComparisonOperators.EQ); + BasicAtom bodyAtom3Renamed = Atoms.newBasicAtom(Predicates.getPredicate("q", 3), + Terms.newVariable("X_13"), Terms.newFunctionTerm("g", Terms.newVariable("Y_13")), Terms.newVariable("Z_13")); + BasicAtom bodyAtom4Renamed = Atoms.newBasicAtom(Predicates.getPredicate("dom", 1), Terms.newVariable("A_13")); + CompiledRule ruleWithRenamedVars = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule( + Rules.newRule(headAtomRenamed, bodyAtom1Renamed.toLiteral(), bodyAtom2Renamed.toLiteral(), bodyAtom3Renamed.toLiteral(), + bodyAtom4Renamed.toLiteral()))); + + assertEquals(ruleWithRenamedVars, rule.renameVariables("_13")); } @Test public void testRulesEqual() { - ASPCore2Program p1 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); - Rule r1 = p1.getRules().get(0); - ASPCore2Program p2 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); - Rule r2 = p2.getRules().get(0); - ASPCore2Program p3 = parser.parse("p(X, Y) :- bla(X), blub(X), foo(X, X), not bar(X)."); - Rule r3 = p3.getRules().get(0); + // r1 := p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X). + Rule r1 = Rules.newRule(Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")), + Atoms.newBasicAtom(Predicates.getPredicate("bla", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("blub", 1), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("foo", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("bar", 1), Terms.newVariable("X")).toLiteral(false)); + // r2 := p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X). + Rule r2 = Rules.newRule(Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")), + Atoms.newBasicAtom(Predicates.getPredicate("bla", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("blub", 1), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("foo", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("bar", 1), Terms.newVariable("X")).toLiteral(false)); + // r3 := p(X, Y) :- bla(X), blub(X), foo(X, X), not bar(X). + Rule r3 = Rules.newRule(Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")), + Atoms.newBasicAtom(Predicates.getPredicate("bla", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("blub", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("foo", 2), Terms.newVariable("X"), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("bar", 1), Terms.newVariable("X")).toLiteral(false)); assertTrue(r1.equals(r2)); assertTrue(r2.equals(r1)); assertTrue(r1.hashCode() == r2.hashCode()); @@ -52,4 +82,4 @@ public void testRulesEqual() { assertTrue(r2.hashCode() != r3.hashCode()); } -} \ No newline at end of file +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphImplTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphImplTest.java deleted file mode 100644 index 65e4f32ae..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphImplTest.java +++ /dev/null @@ -1,276 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.depgraph; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; -import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph.Node; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.test.util.DependencyGraphUtils; - -public class DependencyGraphImplTest { - - private ProgramParser parser = new ProgramParserImpl(); - private NormalizeProgramTransformation normalizeTransform = new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - - // Currently not used anywhere, but keep as it might come in handy - @SuppressWarnings("unused") - private static String generateRandomProgram(int numRules, int numPredicates, int maxRuleBodyLiterals) { - String[] predicates = new String[numPredicates]; - for (int i = 0; i < predicates.length; i++) { - predicates[i] = "p" + Integer.toString(i + 1); - } - - StringBuilder prgBuilder = new StringBuilder(); - String tmpAtom; - int tmpBodyLiterals; - for (int i = 0; i < numRules; i++) { - tmpBodyLiterals = 1 + ((int) (Math.random() * maxRuleBodyLiterals)); - tmpAtom = predicates[(int) (Math.random() * predicates.length)]; - prgBuilder.append(tmpAtom).append(" :- "); - for (int j = 0; j < tmpBodyLiterals; j++) { - tmpAtom = predicates[(int) (Math.random() * predicates.length)]; - prgBuilder.append(tmpAtom); - if (j < (tmpBodyLiterals - 1)) { - prgBuilder.append(", "); - } - } - prgBuilder.append("."); - prgBuilder.append("\n"); - } - return prgBuilder.toString(); - } - - @Test - public void edgesEqualTest() { - Predicate testPredicate = Predicates.getPredicate("test", 2, false, false); - EdgeImpl e1 = new EdgeImpl(new NodeImpl(testPredicate), true); - EdgeImpl e2 = new EdgeImpl(new NodeImpl(testPredicate), true); - assertEquals(e1, e2); - } - - @Test - public void reachabilityCheckSimpleTest() { - ASPCore2Program prog = parser.parse("b :- a."); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - - Node a = dg.getNodeForPredicate(Predicates.getPredicate("a", 0)); - Node b = dg.getNodeForPredicate(Predicates.getPredicate("b", 0)); - - NodeImpl nonExistent = new NodeImpl(Predicates.getPredicate("notHere", 0)); - - assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); - assertFalse(DependencyGraphUtils.isReachableFrom(a, b, dg)); - assertFalse(DependencyGraphUtils.isReachableFrom(nonExistent, a, dg)); - assertFalse(DependencyGraphUtils.isReachableFrom(nonExistent, b, dg)); - } - - @Test - public void reachabilityCheckWithHopsTest() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a.").append("\n"); - bld.append("c :- b.").append("\n"); - bld.append("d :- c.").append("\n"); - - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - Node a = dg.getNodeForPredicate(Predicates.getPredicate("a", 0)); - Node b = dg.getNodeForPredicate(Predicates.getPredicate("b", 0)); - Node c = dg.getNodeForPredicate(Predicates.getPredicate("c", 0)); - Node d = dg.getNodeForPredicate(Predicates.getPredicate("d", 0)); - - assertTrue(DependencyGraphUtils.isReachableFrom(d, a, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(c, a, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); - - assertTrue(DependencyGraphUtils.isReachableFrom(d, b, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(c, b, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(b, b, dg)); - - assertTrue(DependencyGraphUtils.isReachableFrom(d, c, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(c, c, dg)); - - assertFalse(DependencyGraphUtils.isReachableFrom(a, d, dg)); - assertFalse(DependencyGraphUtils.isReachableFrom(a, c, dg)); - assertFalse(DependencyGraphUtils.isReachableFrom(a, b, dg)); - } - - @Test - public void reachabilityWithCyclesTest() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a, f1.").append("\n"); - bld.append("c :- b.").append("\n"); - bld.append("d :- c.").append("\n"); - bld.append("a :- d.").append("\n"); - bld.append("x :- d, f1."); - - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - Node a = dg.getNodeForPredicate(Predicates.getPredicate("a", 0)); - Node b = dg.getNodeForPredicate(Predicates.getPredicate("b", 0)); - Node c = dg.getNodeForPredicate(Predicates.getPredicate("c", 0)); - Node d = dg.getNodeForPredicate(Predicates.getPredicate("d", 0)); - Node f1 = dg.getNodeForPredicate(Predicates.getPredicate("f1", 0)); - Node x = dg.getNodeForPredicate(Predicates.getPredicate("x", 0)); - Node notInGraph = new NodeImpl(Predicates.getPredicate("notInGraph", 0)); - - assertTrue(DependencyGraphUtils.isReachableFrom(d, a, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(c, a, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); - - assertTrue(DependencyGraphUtils.isReachableFrom(d, b, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(c, b, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(b, b, dg)); - - assertTrue(DependencyGraphUtils.isReachableFrom(d, c, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(c, c, dg)); - - assertTrue(DependencyGraphUtils.isReachableFrom(a, d, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(a, c, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(a, b, dg)); - - assertTrue(DependencyGraphUtils.isReachableFrom(x, f1, dg)); - assertTrue(DependencyGraphUtils.isReachableFrom(c, f1, dg)); - - assertFalse(DependencyGraphUtils.isReachableFrom(notInGraph, a, dg)); - } - - @Test - public void stronglyConnectedComponentsSimpleTest() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a.").append("\n"); - bld.append("a :- b.").append("\n"); - - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - Node a = dg.getNodeForPredicate(Predicates.getPredicate("a", 0)); - Node b = dg.getNodeForPredicate(Predicates.getPredicate("b", 0)); - - List componentA = new ArrayList<>(); - componentA.add(a); - assertTrue(DependencyGraphUtils.areStronglyConnected(componentA, dg)); - assertFalse(DependencyGraphUtils.isStronglyConnectedComponent(componentA, dg)); - - - List componentB = new ArrayList<>(); - componentB.add(b); - assertTrue(DependencyGraphUtils.areStronglyConnected(componentB, dg)); - assertFalse(DependencyGraphUtils.isStronglyConnectedComponent(componentB, dg)); - - List componentAll = new ArrayList<>(); - componentAll.add(a); - componentAll.add(b); - assertTrue(DependencyGraphUtils.areStronglyConnected(componentAll, dg)); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(componentAll, dg)); - } - - @Test - public void stronglyConnectedComponentsMultipleComponentsTest() { - String inputProgram = "f0.\n" + - "f1.\n" + - "f2.\n" + - "f3.\n" + - "a :- f0, f1, not b.\n" + - "b :- f0, f1, not a.\n" + - "c :- f2, f3, not d.\n" + - "d :- f2, f3, not c.\n" + - "x :- a, c, y.\n" + - "y :- b, d, x.\n" + - "z :- x, y, z."; - - ASPCore2Program prog = parser.parse(inputProgram); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - - Node f0 = dg.getNodeForPredicate(Predicates.getPredicate("f0", 0)); - Node f1 = dg.getNodeForPredicate(Predicates.getPredicate("f1", 0)); - Node f2 = dg.getNodeForPredicate(Predicates.getPredicate("f2", 0)); - Node f3 = dg.getNodeForPredicate(Predicates.getPredicate("f3", 0)); - Node a = dg.getNodeForPredicate(Predicates.getPredicate("a", 0)); - Node b = dg.getNodeForPredicate(Predicates.getPredicate("b", 0)); - Node c = dg.getNodeForPredicate(Predicates.getPredicate("c", 0)); - Node d = dg.getNodeForPredicate(Predicates.getPredicate("d", 0)); - Node x = dg.getNodeForPredicate(Predicates.getPredicate("x", 0)); - Node y = dg.getNodeForPredicate(Predicates.getPredicate("y", 0)); - Node z = dg.getNodeForPredicate(Predicates.getPredicate("z", 0)); - - StronglyConnectedComponentsAlgorithm.SccResult sccResult = StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg); - Map nodesByComponent = sccResult.nodesByComponentId; - List> stronglyConnectedComponents = sccResult.stronglyConnectedComponents; - assertEquals(8, stronglyConnectedComponents.size()); - - for (int i = 0; i < stronglyConnectedComponents.size(); i++) { - List stronglyConnectedComponent = stronglyConnectedComponents.get(i); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(stronglyConnectedComponent, dg)); - for (Node node : stronglyConnectedComponent) { - assertEquals(Integer.valueOf(i), nodesByComponent.get(node)); - } - } - - List c1 = new ArrayList<>(); - c1.add(a); - c1.add(b); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c1, dg)); - assertEquals(nodesByComponent.get(a), nodesByComponent.get(b)); - - List c2 = new ArrayList<>(); - c2.add(c); - c2.add(d); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c2, dg)); - assertEquals(nodesByComponent.get(c), nodesByComponent.get(d)); - - List c3 = new ArrayList<>(); - c3.add(x); - c3.add(y); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c3, dg)); - assertEquals(nodesByComponent.get(x), nodesByComponent.get(y)); - - List c4 = new ArrayList<>(); - c4.add(z); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c4, dg)); - - List c5 = new ArrayList<>(); - c5.add(f0); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c5, dg)); - - List c6 = new ArrayList<>(); - c6.add(f1); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c6, dg)); - - List c7 = new ArrayList<>(); - c7.add(f2); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c7, dg)); - - List c8 = new ArrayList<>(); - c8.add(f3); - assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c8, dg)); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithmTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithmTest.java deleted file mode 100644 index c50acaf9b..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithmTest.java +++ /dev/null @@ -1,241 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.depgraph; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; -import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph.SCComponent; -import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; -import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph.Node; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; - -public class StratificationAlgorithmTest { - - private ProgramParser parser = new ProgramParserImpl(); - private NormalizeProgramTransformation normalizeTransform = new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - - private boolean predicateIsBeforePredicateInOrder(Predicate predBefore, Predicate predAfter, List order) { - boolean foundPredBefore = false; - for (SCComponent component : order) { - for (Node node : component.getNodes()) { - if (node.getPredicate() == predBefore) { - foundPredBefore = true; - } - if (node.getPredicate() == predAfter) { - // Found second predicate, return true if we already found the first predicate. - return foundPredBefore; - } - } - } - return false; - } - - @Test - public void stratifyOneRuleTest() { - ASPCore2Program prog = parser.parse("a :- b."); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraphImpl.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicates.getPredicate("a", 0); - Predicate b = Predicates.getPredicate("b", 0); - - assertEquals(2, strata.size()); - assertTrue(predicateIsBeforePredicateInOrder(b, a, strata)); - } - - @Test - public void stratifyTwoRulesTest() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a.").append("\n"); - bld.append("c :- b.").append("\n"); - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraphImpl.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicates.getPredicate("a", 0); - Predicate b = Predicates.getPredicate("b", 0); - Predicate c = Predicates.getPredicate("c", 0); - - assertEquals(3, strata.size()); - assertTrue(predicateIsBeforePredicateInOrder(a, b, strata)); - assertTrue(predicateIsBeforePredicateInOrder(b, c, strata)); - assertTrue(predicateIsBeforePredicateInOrder(a, c, strata)); - } - - @Test - public void stratifyWithNegativeDependencyTest() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a.").append("\n"); - bld.append("c :- b.").append("\n"); - bld.append("d :- not c.").append("\n"); - bld.append("e :- d.").append("\n"); - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraphImpl.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicates.getPredicate("a", 0); - Predicate b = Predicates.getPredicate("b", 0); - Predicate c = Predicates.getPredicate("c", 0); - Predicate d = Predicates.getPredicate("d", 0); - Predicate e = Predicates.getPredicate("e", 0); - - assertEquals(5, strata.size()); - assertTrue(predicateIsBeforePredicateInOrder(a, b, strata)); - assertTrue(predicateIsBeforePredicateInOrder(b, c, strata)); - assertTrue(predicateIsBeforePredicateInOrder(c, d, strata)); - assertTrue(predicateIsBeforePredicateInOrder(d, e, strata)); - } - - @Test - public void stratifyWithPositiveCycleTest() { - StringBuilder bld = new StringBuilder(); - bld.append("ancestor_of(X, Y) :- parent_of(X, Y)."); - bld.append("ancestor_of(X, Z) :- parent_of(X, Y), ancestor_of(Y, Z)."); - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraphImpl.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate ancestorOf = Predicates.getPredicate("ancestor_of", 2); - Predicate parentOf = Predicates.getPredicate("parent_of", 2); - - assertEquals(2, strata.size()); - assertTrue(predicateIsBeforePredicateInOrder(parentOf, ancestorOf, strata)); - } - - @Test - public void stratifyLargeGraphTest() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a."); - bld.append("c :- b."); - bld.append("d :- c."); - bld.append("e :- d."); - bld.append("f :- not e."); - bld.append("g :- d, j, not f."); - bld.append("h :- not c."); - bld.append("i :- h, not j."); - bld.append("j :- h, not i."); - bld.append("k :- g, not l."); - bld.append("l :- g, not k."); - bld.append("m :- not k, not l."); - bld.append("n :- m, not i, not j."); - bld.append("p :- not m, not n."); - - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraphImpl.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicates.getPredicate("a", 0); - Predicate b = Predicates.getPredicate("b", 0); - Predicate c = Predicates.getPredicate("c", 0); - Predicate d = Predicates.getPredicate("d", 0); - Predicate e = Predicates.getPredicate("e", 0); - Predicate f = Predicates.getPredicate("f", 0); - Predicate h = Predicates.getPredicate("h", 0); - - assertTrue(predicateIsBeforePredicateInOrder(a, h, strata)); - assertTrue(predicateIsBeforePredicateInOrder(b, h, strata)); - assertTrue(predicateIsBeforePredicateInOrder(c, h, strata)); - - assertTrue(predicateIsBeforePredicateInOrder(a, f, strata)); - assertTrue(predicateIsBeforePredicateInOrder(b, f, strata)); - assertTrue(predicateIsBeforePredicateInOrder(c, f, strata)); - assertTrue(predicateIsBeforePredicateInOrder(d, f, strata)); - assertTrue(predicateIsBeforePredicateInOrder(e, f, strata)); - } - - @Test - public void stratifyAvoidDuplicatesTest() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a."); - bld.append("c :- b."); - bld.append("d :- c."); - bld.append("e :- d."); - bld.append("f :- not e."); - bld.append("g :- d, j, not f."); - bld.append("h :- not c."); - bld.append("i :- h, not j."); - bld.append("j :- h, not i."); - bld.append("k :- g, not l."); - bld.append("l :- g, not k."); - bld.append("m :- not k, not l."); - bld.append("n :- m, not i, not j."); - bld.append("p :- not m, not n."); - - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraphImpl.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicates.getPredicate("a", 0); - Predicate b = Predicates.getPredicate("b", 0); - Predicate c = Predicates.getPredicate("c", 0); - Predicate d = Predicates.getPredicate("d", 0); - Predicate e = Predicates.getPredicate("e", 0); - Predicate f = Predicates.getPredicate("f", 0); - Predicate h = Predicates.getPredicate("h", 0); - - assertEquals(7, strata.size()); - assertTrue(predicateIsBeforePredicateInOrder(a, b, strata)); - assertTrue(predicateIsBeforePredicateInOrder(b, c, strata)); - assertTrue(predicateIsBeforePredicateInOrder(c, h, strata)); - assertTrue(predicateIsBeforePredicateInOrder(c, d, strata)); - assertTrue(predicateIsBeforePredicateInOrder(d, e, strata)); - assertTrue(predicateIsBeforePredicateInOrder(e, f, strata)); - assertTrue(predicateIsBeforePredicateInOrder(d, f, strata)); - } - - @Test - public void avoidDuplicatesTest1() { - StringBuilder bld = new StringBuilder(); - bld.append("b :- a."); - bld.append("c :- b."); - bld.append("c :- a."); - - ASPCore2Program prog = parser.parse(bld.toString()); - NormalProgram normalProg = normalizeTransform.apply(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraphImpl.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicates.getPredicate("a", 0); - Predicate b = Predicates.getPredicate("b", 0); - Predicate c = Predicates.getPredicate("c", 0); - - assertTrue(predicateIsBeforePredicateInOrder(a, b, strata)); - assertTrue(predicateIsBeforePredicateInOrder(b, c, strata)); - assertTrue(predicateIsBeforePredicateInOrder(a, c, strata)); - - assertEquals(3, strata.size()); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/DummyGrounder.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java similarity index 96% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/DummyGrounder.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java index 669e6037f..7950b90dd 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/DummyGrounder.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java @@ -71,7 +71,7 @@ * * Copyright (c) 2016, the Alpha Team. */ -public class DummyGrounder implements Grounder { +public class GrounderMockWithBasicProgram implements Grounder { public static final Set EXPECTED = new HashSet<>(singletonList(new AnswerSetBuilder() .predicate("a") .predicate("b") @@ -98,11 +98,11 @@ public class DummyGrounder implements Grounder { private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(ruleABC)), new BasicSubstitution()); private Set returnedNogoods = new HashSet<>(); - public DummyGrounder(AtomStore atomStore) { + public GrounderMockWithBasicProgram(AtomStore atomStore) { this(atomStore, p -> true); } - public DummyGrounder(AtomStore atomStore, java.util.function.Predicate filter) { + public GrounderMockWithBasicProgram(AtomStore atomStore, java.util.function.Predicate filter) { this.atomStore = atomStore; this.filter = filter; Arrays.asList(atomAA, atomBB, rule1, atomCC).forEach(atomStore::putIfAbsent); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceGrounder.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceGrounder.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java index 66374d312..bda74f709 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceGrounder.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java @@ -70,7 +70,7 @@ /** * Represents a small ASP program with choices {@code { aa :- not bb. bb :- not aa. }}. */ -public class ChoiceGrounder implements Grounder { +public class GrounderMockWithChoice implements Grounder { public static final Set EXPECTED = new HashSet<>(asList( new AnswerSetBuilder() .predicate("aa") @@ -129,11 +129,11 @@ public class ChoiceGrounder implements Grounder { private final java.util.function.Predicate filter; - public ChoiceGrounder(AtomStore atomStore) { + public GrounderMockWithChoice(AtomStore atomStore) { this(atomStore, p -> true); } - public ChoiceGrounder(AtomStore atomStore, java.util.function.Predicate filter) { + public GrounderMockWithChoice(AtomStore atomStore, java.util.function.Predicate filter) { this.atomStore = atomStore; this.filter = filter; Arrays.asList(atomAA, atomBB, rule1, rule2, atomEnBR1, atomEnBR2, atomDisBR1, atomDisBR2).forEach(atomStore::putIfAbsent); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java deleted file mode 100644 index 4321d27da..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2018-2020 Siemens AG - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package at.ac.tuwien.kr.alpha.core.grounder; - -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.atom; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; -import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.atoms.Literals; -import at.ac.tuwien.kr.alpha.core.common.Assignment; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.common.NoGood; -import at.ac.tuwien.kr.alpha.core.grounder.instantiation.BindingResult; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; -import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; - -/** - * Tests {@link NaiveGrounder} - * - * Some test cases use atoms of the something/1 predicate to trick the grounder - * into believing that other atoms might become true. This is fragile because future implementations - * of preprocessing techniques might render this trick useless. - * If unit tests in this class begin to fail due to such improvements to preprocessing, this issue must be addressed. - */ -public class NaiveGrounderTest { - private static final ProgramParser PROGRAM_PARSER = new ProgramParserImpl(); - private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); - private static final NormalizeProgramTransformation NORMALIZE_TRANSFORM = new NormalizeProgramTransformation( - SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - - final Literal litP1X = PROGRAM_PART_PARSER.parseLiteral("p1(X)"); - final Literal litP2X = PROGRAM_PART_PARSER.parseLiteral("p2(X)"); - final Literal litQ2Y = PROGRAM_PART_PARSER.parseLiteral("q2(Y)"); - final Literal litQ1Y = PROGRAM_PART_PARSER.parseLiteral("q1(Y)"); - final Literal litAX = PROGRAM_PART_PARSER.parseLiteral("a(X)"); - final Literal litA1 = PROGRAM_PART_PARSER.parseLiteral("a(1)"); - - @BeforeEach - public void resetRuleIdGenerator() { - InternalRule.resetIdGenerator(); - } - - /** - * Asserts that a ground rule whose positive body is not satisfied by the empty assignment - * is grounded immediately. - */ - @Test - public void groundRuleAlreadyGround() { - ASPCore2Program program = PROGRAM_PARSER.parse("a :- not b. " - + "b :- not a. " - + "c :- b."); - NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); - CompiledProgram prog = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normal)); - - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, true); - Map noGoods = grounder.getNoGoods(new TrailAssignment(atomStore)); - int litCNeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("c")), false); - int litB = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("b"))); - assertExistsNoGoodContaining(noGoods.values(), litCNeg); - assertExistsNoGoodContaining(noGoods.values(), litB); - } - - /** - * Asserts that a ground rule whose positive non-unary body is not satisfied by the empty assignment - * is grounded immediately. - */ - @Test - public void groundRuleWithLongerBodyAlreadyGround() { - ASPCore2Program program = PROGRAM_PARSER.parse("a :- not b. " - + "b :- not a. " - + "c :- b. " - + "d :- b, c. "); - NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); - InternalProgram prog = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normal)); - - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, true); - Map noGoods = grounder.getNoGoods(new TrailAssignment(atomStore)); - int litANeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("a")), false); - int litBNeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("b")), false); - int litCNeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("c")), false); - int litDNeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("d")), false); - assertExistsNoGoodContaining(noGoods.values(), litANeg); - assertExistsNoGoodContaining(noGoods.values(), litBNeg); - assertExistsNoGoodContaining(noGoods.values(), litCNeg); - assertExistsNoGoodContaining(noGoods.values(), litDNeg); - } - - /** - * Asserts that a ground constraint whose positive body is not satisfied by the empty assignment - * is grounded immediately. - */ - @Test - public void groundConstraintAlreadyGround() { - ASPCore2Program program = PROGRAM_PARSER.parse("a :- not b. " - + "b :- not a. " - + ":- b."); - NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); - InternalProgram prog = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normal)); - - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, true); - Map noGoods = grounder.getNoGoods(new TrailAssignment(atomStore)); - int litB = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("b"))); - assertTrue(noGoods.containsValue(NoGood.fromConstraint(Collections.singletonList(litB), Collections.emptyList()))); - } - - @Test - public void avoidDeadEndsWithPermissiveGrounderHeuristicForP1() { - RuleGroundingOrderImpl groundingOrderP1 = new RuleGroundingOrderImpl(litP1X, - Arrays.asList(litP2X, litQ2Y, litQ1Y), -1, false); - testDeadEnd("p1", groundingOrderP1, true); - } - - @Test - public void avoidDeadEndsWithPermissiveGrounderHeuristicForQ1() { - RuleGroundingOrderImpl groundingOrderQ1 = new RuleGroundingOrderImpl(litQ1Y, - Arrays.asList(litQ2Y, litP2X, litP1X), -1, false); - testDeadEnd("q1", groundingOrderQ1, true); - } - - @Test - public void noDeadEndWithPermissiveGrounderHeuristicForP1() { - RuleGroundingOrderImpl groundingOrderP1 = new RuleGroundingOrderImpl(litP1X, - Arrays.asList(litP2X, litQ1Y, litQ2Y), -1, false); - testDeadEnd("p1", groundingOrderP1, true); - } - - @Test - public void noDeadEndWithPermissiveGrounderHeuristicForQ1() { - RuleGroundingOrderImpl groundingOrderQ1 = new RuleGroundingOrderImpl(litQ1Y, - Arrays.asList(litQ2Y, litP1X, litP2X), -1, false); - testDeadEnd("q1", groundingOrderQ1, true); - } - - /** - * Tests the method {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)} on a - * predefined program: - * - * p1(1). q1(1).
- * x :- p1(X), p2(X), q1(Y), q2(Y).
- * p2(X) :- something(X).
- * q2(X) :- something(X).
- *
- * Given one grounding order {@code groundingOrder} for the first rule in this program which starts with - * the literal whose predicate name is {@code predicateNameOfStartingLiteral} and a substitution substituting - * the variable in this literal by 1 it is attempted to ground the rule. - * It is then asserted that ground instantiations are produced if and only if {@code expectNoGoods} is true. - * - * @param predicateNameOfStartingLiteral the predicate name of the starting literal, either "p1" or "q1". - * @param groundingOrder a grounding order for the first rule in the predefined program that starts with the literal - * whose predicate name is {@code predicateNameOfStartingLiteral}. - * @param expectNoGoods {@code true} iff ground instantiations are expected to be produced under the conditions - * described above. - */ - private void testDeadEnd(String predicateNameOfStartingLiteral, RuleGroundingOrderImpl groundingOrder, boolean expectNoGoods) { - String aspStr = "p1(1). q1(1). " - + "x :- p1(X), p2(X), q1(Y), q2(Y). " - + "p2(X) :- something(X). " - + "q2(X) :- something(X). "; - CompiledProgram program = InternalProgram.fromNormalProgram( - NORMALIZE_TRANSFORM.apply( - PROGRAM_PARSER.parse(aspStr))); - - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", program, atomStore, p -> true, - GrounderHeuristicsConfiguration.permissive(), true); - - CompiledRule nonGroundRule = grounder.getNonGroundRule(0); - String strLiteral = "p1".equals(predicateNameOfStartingLiteral) ? "p1(X)" : "p1(Y)"; - final Literal startingLiteral = PROGRAM_PART_PARSER.parseLiteral(strLiteral); - ((RuleGroundingInfoImpl) nonGroundRule.getGroundingInfo()).groundingOrders.put(startingLiteral, groundingOrder); - - grounder.bootstrap(); - TrailAssignment currentAssignment = new TrailAssignment(atomStore); - final Substitution subst1 = BasicSubstitution.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(1)), - BasicSubstitution.EMPTY_SUBSTITUTION); - final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, groundingOrder, subst1, currentAssignment); - - assertEquals(expectNoGoods, bindingResult.size() > 0); - } - - @Test - public void testGroundingOfRuleSwitchedOffByFalsePositiveBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X). " - + "b(X) :- something(X). "); - testIfGrounderGroundsRule(program, 0, litAX, 1, ThriceTruth.FALSE, false); - } - - @Test - public void testGroundingOfRuleNotSwitchedOffByTruePositiveBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X). " - + "b(X) :- something(X). "); - testIfGrounderGroundsRule(program, 0, litAX, 1, ThriceTruth.TRUE, true); - } - - @Test - @Disabled("Currently, rule grounding is not switched off by a true negative body atom") - public void testGroundingOfRuleSwitchedOffByTrueNegativeBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), not b(X). " - + "b(X) :- something(X). "); - testIfGrounderGroundsRule(program, 0, litAX, 1, ThriceTruth.TRUE, false); - } - - @Test - public void testGroundingOfRuleNotSwitchedOffByFalseNegativeBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), not b(X). " - + "b(X) :- something(X). "); - - testIfGrounderGroundsRule(program, 0, litAX, 1, ThriceTruth.FALSE, true); - } - - /** - * Tests if {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)} - * produces ground instantiations for the rule with ID {@code ruleID} in {@code program} when {@code startingLiteral} - * unified with the numeric instance {@code startingInstance} is used as starting literal and {@code b(1)} is assigned - * {@code bTruth}. - * It is asserted that ground instantiations are produced if and only if {@code expectNoGoods} is true. - */ - private void testIfGrounderGroundsRule(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, ThriceTruth bTruth, - boolean expectNoGoods) { - CompiledProgram internalPrg = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(program)); - AtomStore atomStore = new AtomStoreImpl(); - TrailAssignment currentAssignment = new TrailAssignment(atomStore); - NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", internalPrg, atomStore, p -> true, - GrounderHeuristicsConfiguration.permissive(), true); - - int b = atomStore.putIfAbsent(atom("b", 1)); - currentAssignment.growForMaxAtomId(); - currentAssignment.assign(b, bTruth); - - grounder.bootstrap(); - final CompiledRule nonGroundRule = grounder.getNonGroundRule(ruleID); - final Substitution substStartingLiteral = BasicSubstitution.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(startingInstance)), - BasicSubstitution.EMPTY_SUBSTITUTION); - final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingInfo().orderStartingFrom(startingLiteral), - substStartingLiteral, currentAssignment); - assertEquals(expectNoGoods, bindingResult.size() > 0); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_0_reject() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X). " - + "b(X) :- something(X)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 0, false, Arrays.asList(1)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_accept() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X). " - + "b(X) :- something(X)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 1, true, Arrays.asList(1)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_reject() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X), b(X+1). " - + "b(X) :- something(X)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 1, false, Arrays.asList(2)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_2_accept() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X), b(X+1). " - + "b(X) :- something(X)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 2, true, Arrays.asList(2)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_accept_two_substitutions() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X,Y). " - + "b(X,Y) :- something(X,Y)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 1, new ThriceTruth[] {ThriceTruth.TRUE, ThriceTruth.TRUE }, 2, true, - Arrays.asList(0, 0)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_accept_accept_two_substitutions_with_different_remaining_tolerances() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(1), b(X,Y). " - + "b(X,Y) :- something(X,Y)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litA1, 1, 1, new ThriceTruth[] {null, null }, 2, true, Arrays.asList(1, 1)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_2_reject() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " - + "c(X) :- a(X), b(X), b(X+1), b(X+2). " - + "b(X) :- something(X)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 2, false, Arrays.asList(3)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_2_accept_multiple_facts_of_same_variable() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). b(1). " - + "c(X) :- a(X), b(X), b(X+1), b(X+2). " - + "b(X) :- something(X)."); - testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 2, true, Arrays.asList(2)); - } - - private void testPermissiveGrounderHeuristicTolerance(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, - boolean expectNoGoods, List expectedNumbersOfUnassignedPositiveBodyAtoms) { - testPermissiveGrounderHeuristicTolerance(program, ruleID, startingLiteral, startingInstance, tolerance, new ThriceTruth[] {}, 1, expectNoGoods, - expectedNumbersOfUnassignedPositiveBodyAtoms); - } - - /** - * Tests if {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)} - * produces ground instantiations for the rule with ID {@code ruleID} in {@code program} when {@code startingLiteral} - * unified with the numeric instance {@code startingInstance} is used as starting literal and the following - * additional conditions are established: - *
    - *
  • The atoms {@code b([startingInstance], 1), ..., b([startingInstance], n)} are added to the grounder's - * working memory without changing the assignment, where {@code arityOfB-1} occurences of {@code startingInstance} - * are used instead of {@code [startingInstance]} and {@code n} is the length of the {@code truthsOfB} array. - * For example, if the length of {@code truthsOfB} is 2 and {@code arityOfB} is also 2, these atoms are - * {@code b(1,1), b(1,2)}. - *
  • - *
  • The same atoms are assigned the truth values in the {@code truthsOfB} array.
  • - *
- * It is asserted that ground instantiations are produced if and only if {@code expectNoGoods} is true. - * If ground instantiations are produced, it is also asserted that the numbers of unassigned positive body atoms - * determined by {@code getGroundInstantiations} match those given in {@code expectedNumbersOfUnassignedPositiveBodyAtoms}. - */ - private void testPermissiveGrounderHeuristicTolerance(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, - ThriceTruth[] truthsOfB, int arityOfB, boolean expectNoGoods, List expectedNumbersOfUnassignedPositiveBodyAtoms) { - CompiledProgram internalPrg = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(program)); - AtomStore atomStore = new AtomStoreImpl(); - TrailAssignment currentAssignment = new TrailAssignment(atomStore); - GrounderHeuristicsConfiguration heuristicConfiguration = GrounderHeuristicsConfiguration.getInstance(tolerance, tolerance); - NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", internalPrg, atomStore, p -> true, heuristicConfiguration, true); - - int[] bAtomIDs = new int[truthsOfB.length]; - for (int i = 0; i < truthsOfB.length; i++) { - int[] bTerms = new int[arityOfB]; - for (int n = 0; n < arityOfB; n++) { - bTerms[n] = (n == arityOfB - 1) ? i + 1 : startingInstance; - } - bAtomIDs[i] = atomStore.putIfAbsent(atom("b", bTerms)); - } - addAtomsToWorkingMemoryWithoutChangingTheAssignment(atomStore, grounder, bAtomIDs); - assign(currentAssignment, bAtomIDs, truthsOfB); - - grounder.bootstrap(); - final CompiledRule nonGroundRule = grounder.getNonGroundRule(ruleID); - final Substitution substStartingLiteral = BasicSubstitution.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(startingInstance)), - BasicSubstitution.EMPTY_SUBSTITUTION); - final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingInfo().orderStartingFrom(startingLiteral), - substStartingLiteral, currentAssignment); - assertEquals(expectNoGoods, bindingResult.size() > 0); - if (bindingResult.size() > 0) { - assertEquals(expectedNumbersOfUnassignedPositiveBodyAtoms, bindingResult.getNumbersOfUnassignedPositiveBodyAtoms()); - } else { - assertTrue(bindingResult.getNumbersOfUnassignedPositiveBodyAtoms().isEmpty()); - } - } - - /** - * Assigns {@code truthValues} to atoms {@code atomIDs} in {@code currentAssignment}. - */ - private void assign(TrailAssignment currentAssignment, int[] atomIDs, ThriceTruth[] truthValues) { - currentAssignment.growForMaxAtomId(); - for (int i = 0; i < truthValues.length; i++) { - int atomID = atomIDs[i]; - if (truthValues[i] != null) { - currentAssignment.assign(atomID, truthValues[i]); - } - } - } - - /** - * Adds atoms {@code atomIDs} to {@code grounder}'s working memory without changing the assignment. - * This is achieved by creating a temporary assignment on {@code atomStore} in which those atoms are assigned true - * and using this temporary assignment to update the grounder's working memory. - */ - private void addAtomsToWorkingMemoryWithoutChangingTheAssignment(AtomStore atomStore, NaiveGrounder grounder, int[] atomIDs) { - TrailAssignment temporaryAssignment = new TrailAssignment(atomStore); - temporaryAssignment.growForMaxAtomId(); - for (int b : atomIDs) { - temporaryAssignment.assign(b, ThriceTruth.TRUE); - } - grounder.updateAssignment(temporaryAssignment.getNewPositiveAssignmentsIterator()); - } - - private void assertExistsNoGoodContaining(Collection noGoods, int literal) { - for (NoGood noGood : noGoods) { - for (int literalInNoGood : noGood) { - if (literalInNoGood == literal) { - return; - } - } - } - fail("No NoGood exists that contains literal " + literal); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java deleted file mode 100644 index e5d44ded9..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2018 Siemens AG - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package at.ac.tuwien.kr.alpha.core.grounder; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.atoms.Literals; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; - -/** - * Tests {@link NoGoodGenerator} - */ -public class NoGoodGeneratorTest { - - private static final ProgramParser PARSER = new ProgramParserImpl(); - private static final NormalizeProgramTransformation NORMALIZE_TRANSFORM = new NormalizeProgramTransformation( - SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - - private static final ConstantTerm A = Terms.newSymbolicConstant("a"); - private static final ConstantTerm B = Terms.newSymbolicConstant("b"); - - private static final VariableTerm X = Terms.newVariable("X"); - private static final VariableTerm Y = Terms.newVariable("Y"); - - /** - * Calls {@link NoGoodGenerator#collectNegLiterals(InternalRule, Substitution)}, which puts the atom occurring - * negatively in a rule into the atom store. It is then checked whether the atom in the atom store is positive. - */ - @Test - public void collectNeg_ContainsOnlyPositiveLiterals() { - ASPCore2Program input = PARSER.parse("p(a,b). " - + "q(a,b) :- not nq(a,b). " - + "nq(a,b) :- not q(a,b)."); - NormalProgram normal = NORMALIZE_TRANSFORM.apply(input); - CompiledProgram program = InternalProgram.fromNormalProgram(normal); - - CompiledRule rule = program.getRules().get(1); - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", program, atomStore, true); - NoGoodGenerator noGoodGenerator = ((NaiveGrounder) grounder).noGoodGenerator; - Substitution substitution = new BasicSubstitution(); - substitution.put(X, A); - substitution.put(Y, B); - List collectedNeg = noGoodGenerator.collectNegLiterals(rule, substitution); - assertEquals(1, collectedNeg.size()); - String negAtomString = atomStore.atomToString(Literals.atomOf(collectedNeg.get(0))); - assertEquals("q(a, b)", negAtomString); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoTest.java new file mode 100644 index 000000000..4f95d0f2c --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoTest.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2017-2020, the Alpha Team. + * All rights reserved. + * + * Additional changes made by Siemens. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package at.ac.tuwien.kr.alpha.core.grounder; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; + +import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.terms.ArithmeticOperator; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; + +/** + * Copyright (c) 2017-2021, the Alpha Team. + */ +public class RuleGroundingInfoTest { + + @Test + public void groundingOrder() { + // r1 := h(X,C) :- p(X,Y), q(A,B), r(Y,A), s(C). + CompiledRule r1 = new InternalRule( + Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 2), Terms.newVariable("X"), Terms.newVariable("C"))), + Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("A"), Terms.newVariable("B")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("r", 2), Terms.newVariable("Y"), Terms.newVariable("A")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("s", 1), Terms.newVariable("C")).toLiteral()); + RuleGroundingInfo rgo1 = new RuleGroundingInfoImpl(r1); + rgo1.computeGroundingOrders(); + assertEquals(4, rgo1.getStartingLiterals().size()); + + // r2 := j(A,A,X,Y) :- r1(A,A), r1(X,Y), r1(A,X), r1(A,Y). + CompiledRule r2 = new InternalRule( + Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("j", 4), Terms.newVariable("A"), Terms.newVariable("A"), Terms.newVariable("X"), + Terms.newVariable("Y"))), + Atoms.newBasicAtom(Predicates.getPredicate("r1", 2), Terms.newVariable("A"), Terms.newVariable("A")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("r1", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("r1", 2), Terms.newVariable("A"), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("r1", 2), Terms.newVariable("A"), Terms.newVariable("Y")).toLiteral()); + RuleGroundingInfo rgo2 = new RuleGroundingInfoImpl(r2); + rgo2.computeGroundingOrders(); + assertEquals(4, rgo2.getStartingLiterals().size()); + + // r3 := p(a) :- b = a. + CompiledRule r3 = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a"))), + Atoms.newComparisonAtom(Terms.newSymbolicConstant("b"), Terms.newSymbolicConstant("a"), ComparisonOperators.EQ).toLiteral()); + RuleGroundingInfo rgo3 = new RuleGroundingInfoImpl(r3); + rgo3.computeGroundingOrders(); + assertTrue(rgo3.hasFixedInstantiation()); + } + + /** + * Tests that an exception is thrown when trying to compute grounding orders for a rule that is not safe due to cyclic dependencies between + * body variables. + */ + @Test + public void groundingOrderUnsafe() { + assertThrows(RuntimeException.class, () -> { + // rule := h(X, Z) :- Y = X + 1, X = Z + 1, Z = Y - 2. + CompiledRule rule = new InternalRule( + Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 2), Terms.newVariable("X"), Terms.newVariable("Z"))), + Atoms.newComparisonAtom( + Terms.newVariable("Y"), + Terms.newArithmeticTerm(Terms.newVariable("Y"), ArithmeticOperator.PLUS, Terms.newConstant(1)), + ComparisonOperators.EQ).toLiteral(), + Atoms.newComparisonAtom( + Terms.newVariable("X"), + Terms.newArithmeticTerm(Terms.newVariable("Z"), ArithmeticOperator.PLUS, Terms.newConstant(1)), + ComparisonOperators.EQ).toLiteral(), + Atoms.newComparisonAtom( + Terms.newVariable("Z"), + Terms.newArithmeticTerm(Terms.newVariable("Y"), ArithmeticOperator.MINUS, Terms.newConstant(2)), + ComparisonOperators.EQ).toLiteral()); + computeGroundingOrdersForRule(rule); + }); + } + + @Test + public void testPositionFromWhichAllVarsAreBound_ground() { + // rule := a :- b, not c. + CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 0))), + Atoms.newBasicAtom(Predicates.getPredicate("b", 0)).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("c", 0)).toLiteral(false)); + RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(rule); + assertEquals(0, rgo0.getFixedGroundingOrder().getPositionFromWhichAllVarsAreBound()); + } + + @Test + public void testPositionFromWhichAllVarsAreBound_simpleNonGround() { + // rule := a(X) :- b(X), not c(X). + CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newVariable("X")).toLiteral(false)); + RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(rule); + assertEquals(1, rgo0.getStartingLiterals().size()); + for (Literal startingLiteral : rgo0.getStartingLiterals()) { + assertEquals(0, rgo0.orderStartingFrom(startingLiteral).getPositionFromWhichAllVarsAreBound()); + } + } + + @Test + public void testPositionFromWhichAllVarsAreBound_longerSimpleNonGround() { + // rule := a(X) :- b(X), c(X), d(X), not e(X). + CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("e", 1), Terms.newVariable("X")).toLiteral(false)); + RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(rule); + assertEquals(3, rgo0.getStartingLiterals().size()); + for (Literal startingLiteral : rgo0.getStartingLiterals()) { + assertEquals(0, rgo0.orderStartingFrom(startingLiteral).getPositionFromWhichAllVarsAreBound()); + } + } + + @Test + public void testToString_longerSimpleNonGround() { + // rule := a(X) :- b(X), c(X), d(X), not e(X). + CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("e", 1), Terms.newVariable("X")).toLiteral(false)); + RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(rule); + assertEquals(3, rgo0.getStartingLiterals().size()); + for (Literal startingLiteral : rgo0.getStartingLiterals()) { + switch (startingLiteral.getPredicate().getName()) { + case "b": + assertEquals("b(X) : | c(X), d(X), not e(X)", rgo0.orderStartingFrom(startingLiteral).toString()); + break; + case "c": + assertEquals("c(X) : | b(X), d(X), not e(X)", rgo0.orderStartingFrom(startingLiteral).toString()); + break; + case "d": + assertEquals("d(X) : | b(X), c(X), not e(X)", rgo0.orderStartingFrom(startingLiteral).toString()); + break; + default: + fail("Unexpected starting literal: " + startingLiteral); + } + } + } + + @Test + public void testPositionFromWhichAllVarsAreBound_joinedNonGround() { + // rule := a(X) :- b(X), c(X, Y), d(X, Z), not e(X). + CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("c", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("d", 2), Terms.newVariable("X"), Terms.newVariable("Z")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("e", 1), Terms.newVariable("X")).toLiteral(false)); + RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(rule); + final Literal litBX = Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(); + final Literal litCXY = Atoms.newBasicAtom(Predicates.getPredicate("c", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(); + final Literal litDXZ = Atoms.newBasicAtom(Predicates.getPredicate("d", 2), Terms.newVariable("X"), Terms.newVariable("Z")).toLiteral(); + assertTrue(2 <= rgo0.orderStartingFrom(litBX).getPositionFromWhichAllVarsAreBound()); + assertTrue(1 <= rgo0.orderStartingFrom(litCXY).getPositionFromWhichAllVarsAreBound()); + assertTrue(1 <= rgo0.orderStartingFrom(litDXZ).getPositionFromWhichAllVarsAreBound()); + } + + private RuleGroundingInfo computeGroundingOrdersForRule(CompiledRule rule) { + RuleGroundingInfo rgo = new RuleGroundingInfoImpl(rule); + rgo.computeGroundingOrders(); + return rgo; + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderTest.java deleted file mode 100644 index b8964e9b6..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2017-2020, the Alpha Team. - * All rights reserved. - * - * Additional changes made by Siemens. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package at.ac.tuwien.kr.alpha.core.grounder; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import java.util.function.Function; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; - -/** - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class RuleGroundingOrderTest { - - private static final ProgramParser PARSER = new ProgramParserImpl(); - private static final NormalizeProgramTransformation NORMALIZE_TRANSFORM = new NormalizeProgramTransformation( - SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - private static final Function PARSE_AND_PREPROCESS = (str) -> { - return InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(PARSER.parse(str))); - }; - - private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); - - @Test - public void groundingOrder() { - String aspStr = "h(X,C) :- p(X,Y), q(A,B), r(Y,A), s(C)." + - "j(A,B,X,Y) :- r1(A,B), r1(X,Y), r1(A,X), r1(B,Y), A = B." + - "p(a) :- b = a."; - CompiledProgram prog = PARSE_AND_PREPROCESS.apply(aspStr); - CompiledRule rule0 = prog.getRules().get(0); - RuleGroundingInfo rgo0 = new RuleGroundingInfoImpl(rule0); - rgo0.computeGroundingOrders(); - assertEquals(4, rgo0.getStartingLiterals().size()); - - CompiledRule rule1 = prog.getRules().get(1); - RuleGroundingInfo rgo1 = new RuleGroundingInfoImpl(rule1); - rgo1.computeGroundingOrders(); - assertEquals(4, rgo1.getStartingLiterals().size()); - - CompiledRule rule2 = prog.getRules().get(2); - RuleGroundingInfo rgo2 = new RuleGroundingInfoImpl(rule2); - rgo2.computeGroundingOrders(); - assertTrue(rgo2.hasFixedInstantiation()); - } - - @Test - public void groundingOrderUnsafe() { - assertThrows(RuntimeException.class, () -> { - String aspStr = "h(X,C) :- X = Y, Y = C .. 3, C = X."; - CompiledProgram prog = PARSE_AND_PREPROCESS.apply(aspStr); - computeGroundingOrdersForRule(prog, 0); - }); - } - - @Test - public void testPositionFromWhichAllVarsAreBound_ground() { - String aspStr = "a :- b, not c."; - CompiledProgram internalPrg = PARSE_AND_PREPROCESS.apply(aspStr); - RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(internalPrg, 0); - assertEquals(0, rgo0.getFixedGroundingOrder().getPositionFromWhichAllVarsAreBound()); - } - - @Test - public void testPositionFromWhichAllVarsAreBound_simpleNonGround() { - String aspStr = "a(X) :- b(X), not c(X)."; - CompiledProgram internalPrg = PARSE_AND_PREPROCESS.apply(aspStr); - RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(internalPrg, 0); - assertEquals(1, rgo0.getStartingLiterals().size()); - for (Literal startingLiteral : rgo0.getStartingLiterals()) { - assertEquals(0, rgo0.orderStartingFrom(startingLiteral).getPositionFromWhichAllVarsAreBound()); - } - } - - @Test - public void testPositionFromWhichAllVarsAreBound_longerSimpleNonGround() { - String aspStr = "a(X) :- b(X), c(X), d(X), not e(X)."; - CompiledProgram internalPrg = PARSE_AND_PREPROCESS.apply(aspStr); - RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(internalPrg, 0); - assertEquals(3, rgo0.getStartingLiterals().size()); - for (Literal startingLiteral : rgo0.getStartingLiterals()) { - assertEquals(0, rgo0.orderStartingFrom(startingLiteral).getPositionFromWhichAllVarsAreBound()); - } - } - - @Test - public void testToString_longerSimpleNonGround() { - String aspStr = "a(X) :- b(X), c(X), d(X), not e(X)."; - CompiledProgram internalPrg = PARSE_AND_PREPROCESS.apply(aspStr); - RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(internalPrg, 0); - assertEquals(3, rgo0.getStartingLiterals().size()); - for (Literal startingLiteral : rgo0.getStartingLiterals()) { - switch (startingLiteral.getPredicate().getName()) { - case "b": - assertEquals("b(X) : | c(X), d(X), not e(X)", rgo0.orderStartingFrom(startingLiteral).toString()); - break; - case "c": - assertEquals("c(X) : | b(X), d(X), not e(X)", rgo0.orderStartingFrom(startingLiteral).toString()); - break; - case "d": - assertEquals("d(X) : | b(X), c(X), not e(X)", rgo0.orderStartingFrom(startingLiteral).toString()); - break; - default: - fail("Unexpected starting literal: " + startingLiteral); - } - } - } - - @Test - public void testPositionFromWhichAllVarsAreBound_joinedNonGround() { - String aspStr = "a(X) :- b(X), c(X,Y), d(X,Z), not e(X)."; - CompiledProgram internalPrg = PARSE_AND_PREPROCESS.apply(aspStr); - RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(internalPrg, 0); - final Literal litBX = PROGRAM_PART_PARSER.parseLiteral("b(X)"); - final Literal litCXY = PROGRAM_PART_PARSER.parseLiteral("c(X,Y)"); - final Literal litDXZ = PROGRAM_PART_PARSER.parseLiteral("d(X,Z)"); - assertTrue(2 <= rgo0.orderStartingFrom(litBX).getPositionFromWhichAllVarsAreBound()); - assertTrue(1 <= rgo0.orderStartingFrom(litCXY).getPositionFromWhichAllVarsAreBound()); - assertTrue(1 <= rgo0.orderStartingFrom(litDXZ).getPositionFromWhichAllVarsAreBound()); - } - - private RuleGroundingInfo computeGroundingOrdersForRule(CompiledProgram program, int ruleIndex) { - CompiledRule rule = program.getRules().get(ruleIndex); - RuleGroundingInfo rgo = new RuleGroundingInfoImpl(rule); - rgo.computeGroundingOrders(); - return rgo; - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java index 2fc8f87a2..24c2aceea 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java @@ -35,11 +35,8 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -47,19 +44,17 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; import at.ac.tuwien.kr.alpha.core.test.util.SubstitutionTestUtil; import at.ac.tuwien.kr.alpha.core.util.Substitutions; public class SubstitutionTest { - private static final ProgramParser PARSER = new ProgramParserImpl(); private static final ConstantTerm A = Terms.newSymbolicConstant("a"); private static final ConstantTerm B = Terms.newSymbolicConstant("b"); @@ -113,11 +108,13 @@ public void substituteNegativeBasicAtom() { @Test public void groundAndPrintRule() { - Rule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); - CompiledRule nonGroundRule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(rule)); + // rule := x :- p(X,Y), not q(X,Y). + CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("x", 0))), + Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(false)); Substitution substitution1 = BasicSubstitution.specializeSubstitution(PX, PA, BasicSubstitution.EMPTY_SUBSTITUTION); Substitution substitution2 = BasicSubstitution.specializeSubstitution(PY, PB, substitution1); - String printedString = SubstitutionTestUtil.groundAndPrintRule(nonGroundRule, substitution2); + String printedString = SubstitutionTestUtil.groundAndPrintRule(rule, substitution2); assertEquals("x :- p(a, b), not q(a, b).", printedString); } @@ -168,11 +165,13 @@ private void groundLiteralToString(boolean negated) { @Test public void substitutionFromString() { - Rule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); - CompiledRule nonGroundRule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(rule)); + // rule := x :- p(X,Y), not q(X,Y). + CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("x", 0))), + Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(false)); Substitution substitution1 = BasicSubstitution.specializeSubstitution(PX, PA, BasicSubstitution.EMPTY_SUBSTITUTION); Substitution substitution = BasicSubstitution.specializeSubstitution(PY, PB, substitution1); - RuleAtom ruleAtom = new RuleAtom(nonGroundRule, substitution); + RuleAtom ruleAtom = new RuleAtom(rule, substitution); String substitutionString = (String) ((ConstantTerm) ruleAtom.getTerms().get(1)).getObject(); Substitution fromString = Substitutions.fromString(substitutionString); assertEquals(substitution, fromString); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnificationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnificationTest.java deleted file mode 100644 index 7492fc3d7..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnificationTest.java +++ /dev/null @@ -1,111 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.grounder; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; -import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; - -/** - * Copyright (c) 2021, the Alpha Team. - */ -public class UnificationTest { - - private ProgramPartParser partsParser = new ProgramPartParser(); - - @Test - public void simpleGroundUnification() { - Atom pX = partsParser.parseLiteral("p(X)").getAtom(); - Atom pa = partsParser.parseLiteral("p(abc)").getAtom(); - Unifier unifier = Unification.unifyAtoms(pa, pX); - assertNotNull(unifier); - assertEquals(1, unifier.getMappedVariables().size()); - assertEquals("abc", unifier.eval(Terms.newVariable("X")).toString()); - } - - @Test - public void unificationBothSides() { - Atom left = partsParser.parseLiteral("p(X, 1)").getAtom(); - Atom right = partsParser.parseLiteral("p(d, Y)").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNotNull(unifier); - assertEquals(2, unifier.getMappedVariables().size()); - assertEquals("d", unifier.eval(Terms.newVariable("X")).toString()); - assertEquals("1", unifier.eval(Terms.newVariable("Y")).toString()); - } - - @Test - public void unificationNonGround() { - Atom left = partsParser.parseLiteral("p(X, 13)").getAtom(); - Atom right = partsParser.parseLiteral("p(Z, Y)").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNotNull(unifier); - assertEquals(3, unifier.getMappedVariables().size()); - assertEquals("13", unifier.eval(Terms.newVariable("Y")).toString()); - // Check that the unifier sets X=Z by either mapping X -> Z or Z -> X. - if (unifier.eval(Terms.newVariable("X")) != null) { - // X is mapped, it must map to Z now. - assertEquals("Z", unifier.eval(Terms.newVariable("X")).toString()); - } else { - // X is not mapped, so Z must map to X. - assertEquals("X", unifier.eval(Terms.newVariable("Z")).toString()); - } - } - - @Test - public void unificationWithFunctionTerms() { - Atom left = partsParser.parseLiteral("a(b, f(X, 13), g(Z), d)").getAtom(); - Atom right = partsParser.parseLiteral("a(b, A, g(e), d)").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNotNull(unifier); - assertEquals(3, unifier.getMappedVariables().size()); - assertEquals(left.substitute(unifier).toString(), right.substitute(unifier).toString()); - } - - @Test - public void unificationWithArithmeticTerms() { - Atom left = partsParser.parseLiteral("a(X - (3 * Y))").getAtom(); - Atom right = partsParser.parseLiteral("a(15 - Z)").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNotNull(unifier); - assertEquals(3, unifier.getMappedVariables().size()); - assertEquals(left.substitute(unifier).toString(), right.substitute(unifier).toString()); - } - - @Test - public void nonunificationWithArithmeticTerms() { - Atom left = partsParser.parseLiteral("a(X + 4)").getAtom(); - Atom right = partsParser.parseLiteral("a(Y - 4)").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNull(unifier); - } - - @Test - public void nonunificationWithArithmeticTermsNested() { - Atom left = partsParser.parseLiteral("a(X + 7)").getAtom(); - Atom right = partsParser.parseLiteral("a(Y + (Z - 2))").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNull(unifier); - } - - @Test - public void nonunificationSimple() { - Atom left = partsParser.parseLiteral("a(b,X)").getAtom(); - Atom right = partsParser.parseLiteral("a(c,Y)").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNull(unifier); - } - - @Test - public void nonunificationNested() { - Atom left = partsParser.parseLiteral("a(f(X,a))").getAtom(); - Atom right = partsParser.parseLiteral("a(f(a,b))").getAtom(); - Unifier unifier = Unification.unifyAtoms(left, right); - assertNull(unifier); - } -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java deleted file mode 100644 index d0a0aaf62..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2018, 2020, the Alpha Team. - * All rights reserved. - * - * Additional changes made by Siemens. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package at.ac.tuwien.kr.alpha.core.grounder; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; - -public class UnifierTest extends SubstitutionTest { - - @Test - public void extendUnifier() { - VariableTerm varX = Terms.newVariable("X"); - VariableTerm varY = Terms.newVariable("Y"); - Unifier sub1 = new Unifier(); - sub1.put(varX, varY); - Unifier sub2 = new Unifier(); - sub2.put(varY, Terms.newConstant("a")); - - sub1.extendWith(sub2); - BasicAtom atom1 = parseAtom("p(X)"); - - Atom atomSubstituted = atom1.substitute(sub1); - assertEquals(Terms.newConstant("a"), atomSubstituted.getTerms().get(0)); - } - - @Test - public void mergeUnifierIntoLeft() { - VariableTerm varX = Terms.newVariable("X"); - VariableTerm varY = Terms.newVariable("Y"); - VariableTerm varZ = Terms.newVariable("Z"); - Term constA = Terms.newConstant("a"); - Unifier left = new Unifier(); - left.put(varX, varY); - left.put(varZ, varY); - Unifier right = new Unifier(); - right.put(varX, constA); - Unifier merged = Unifier.mergeIntoLeft(left, right); - assertEquals(constA, merged.eval(varY)); - assertEquals(constA, merged.eval(varZ)); - } - - private BasicAtom parseAtom(String atom) { - ProgramParser programParser = new ProgramParserImpl(); - ASPCore2Program program = programParser.parse(atom + "."); - return (BasicAtom) program.getFacts().get(0); - } -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustifiedTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustifiedTest.java deleted file mode 100644 index 87097ecad..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustifiedTest.java +++ /dev/null @@ -1,215 +0,0 @@ -/** - * Copyright (c) 2018-2019, the Alpha Team. - * All rights reserved. - * - * Additional changes made by Siemens. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package at.ac.tuwien.kr.alpha.core.grounder.structure; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; -import java.util.function.Function; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; - -/** - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class AnalyzeUnjustifiedTest { - - private final ProgramParser parser = new ProgramParserImpl(); - private final NormalizeProgramTransformation normalize = new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - private final Function parseAndPreprocess = (str) -> { - return InternalProgram.fromNormalProgram(normalize.apply(parser.parse(str))); - }; - - @Test - public void justifySimpleRules() { - String program = "p(X) :- q(X)." + - "q(X) :- p(X)." + - "q(5) :- r." + - "r :- not nr." + - "nr :- not r." + - ":- not p(5)."; - CompiledProgram internalProgram = parseAndPreprocess.apply(program); - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); - grounder.getNoGoods(null); - TrailAssignment assignment = new TrailAssignment(atomStore); - int rId = atomStore.get(Atoms.newBasicAtom(Predicates.getPredicate("r", 0))); - int nrId = atomStore.get(Atoms.newBasicAtom(Predicates.getPredicate("nr", 0))); - assignment.growForMaxAtomId(); - assignment.assign(rId, ThriceTruth.FALSE); - assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Collections.singletonList(Terms.newConstant(5))); - assignment.assign(atomStore.get(p5), ThriceTruth.MBT); - Set reasons = grounder.justifyAtom(atomStore.get(p5), assignment); - assertFalse(reasons.isEmpty()); - } - - @Test - public void justifyLargerRules() { - String program = "p(X) :- q(X,Y), r(Y), not s(X,Y)." + - "{ q(1,X)} :- dom(X)." + - "dom(1..3)." + - "{r(X)} :- p(X)." + - "{r(2)}." + - "{s(1,2)}." + - ":- not p(1)."; - CompiledProgram internalProgram = parseAndPreprocess.apply(program); - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); - grounder.getNoGoods(null); - TrailAssignment assignment = new TrailAssignment(atomStore); - Atom p1 = parser.parse("p(1).").getFacts().get(0); - Atom r2 = parser.parse("r(2).").getFacts().get(0); - Atom s12 = parser.parse("s(1,2).").getFacts().get(0); - Atom q11 = parser.parse("q(1,1).").getFacts().get(0); - Atom q12 = parser.parse("q(1,2).").getFacts().get(0); - Atom q13 = parser.parse("q(1,3).").getFacts().get(0); - int p1Id = atomStore.get(p1); - int r2Id = atomStore.get(r2); - int s12Id = atomStore.get(s12); - int q11Id = atomStore.get(q11); - int q12Id = atomStore.get(q12); - int q13Id = atomStore.get(q13); - assignment.growForMaxAtomId(); - assignment.assign(p1Id, ThriceTruth.MBT); - assignment.assign(r2Id, ThriceTruth.TRUE); - assignment.assign(s12Id, ThriceTruth.TRUE); - assignment.assign(q11Id, ThriceTruth.TRUE); - assignment.assign(q12Id, ThriceTruth.TRUE); - assignment.assign(q13Id, ThriceTruth.FALSE); - - Set reasons = grounder.justifyAtom(p1Id, assignment); - assertFalse(reasons.isEmpty()); - } - - @Test - public void justifyMultipleReasons() { - String program = "n(a). n(b). n(c). n(d). n(e)." + - "s(a,b). s(b,c). s(c,d). s(d,e)." + - "{ q(X) } :- n(X)." + - "p(X) :- q(X)." + - "p(X) :- p(Y), s(Y,X)." + - ":- not p(c)."; - CompiledProgram internalProgram = parseAndPreprocess.apply(program); - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); - grounder.getNoGoods(null); - TrailAssignment assignment = new TrailAssignment(atomStore); - Atom qa = parser.parse("q(a).").getFacts().get(0); - Atom qb = parser.parse("q(b).").getFacts().get(0); - Atom qc = parser.parse("q(c).").getFacts().get(0); - Atom qd = parser.parse("q(d).").getFacts().get(0); - Atom qe = parser.parse("q(e).").getFacts().get(0); - int qaId = atomStore.get(qa); - int qbId = atomStore.get(qb); - int qcId = atomStore.get(qc); - int qdId = atomStore.get(qd); - int qeId = atomStore.get(qe); - - assignment.growForMaxAtomId(); - assignment.assign(qaId, ThriceTruth.FALSE); - assignment.assign(qbId, ThriceTruth.FALSE); - assignment.assign(qcId, ThriceTruth.FALSE); - assignment.assign(qdId, ThriceTruth.FALSE); - assignment.assign(qeId, ThriceTruth.FALSE); - - Predicate nq = Predicates.getPredicate("_nq", 2, true); - Atom nqa = Atoms.newBasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("a"))); - Atom nqb = Atoms.newBasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("b"))); - Atom nqc = Atoms.newBasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("c"))); - Atom nqd = Atoms.newBasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("d"))); - Atom nqe = Atoms.newBasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("e"))); - int nqaId = atomStore.get(nqa); - int nqbId = atomStore.get(nqb); - int nqcId = atomStore.get(nqc); - int nqdId = atomStore.get(nqd); - int nqeId = atomStore.get(nqe); - - assignment.growForMaxAtomId(); - assignment.assign(nqaId, ThriceTruth.TRUE); - assignment.assign(nqbId, ThriceTruth.TRUE); - assignment.assign(nqcId, ThriceTruth.TRUE); - assignment.assign(nqdId, ThriceTruth.TRUE); - assignment.assign(nqeId, ThriceTruth.TRUE); - - Atom pc = parser.parse("p(c).").getFacts().get(0); - Set reasons = grounder.justifyAtom(atomStore.get(pc), assignment); - assertFalse(reasons.isEmpty()); - } - - @Test - public void justifyNegatedFactsRemovedFromReasons() { - String program = "forbidden(2,9). forbidden(1,9)." + - "p(X) :- q(X)." + - "q(X) :- p(X)." + - "q(5) :- r." + - "r :- not nr, not forbidden(2,9), not forbidden(1,9)." + - "nr :- not r." + - ":- not p(5)."; - CompiledProgram internalProgram = parseAndPreprocess.apply(program); - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); - grounder.getNoGoods(null); - TrailAssignment assignment = new TrailAssignment(atomStore); - int rId = atomStore.get(Atoms.newBasicAtom(Predicates.getPredicate("r", 0))); - int nrId = atomStore.get(Atoms.newBasicAtom(Predicates.getPredicate("nr", 0))); - assignment.growForMaxAtomId(); - assignment.assign(rId, ThriceTruth.FALSE); - assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Collections.singletonList(Terms.newConstant(5))); - assignment.assign(atomStore.get(p5), ThriceTruth.MBT); - Set reasons = grounder.justifyAtom(atomStore.get(p5), assignment); - assertFalse(reasons.isEmpty()); - for (Literal literal : reasons) { - // Check that facts are not present in justification. - assertNotEquals(literal.getPredicate(), Predicates.getPredicate("forbidden", 2)); - } - } -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index d63009bbb..24e3494ee 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -27,6 +27,23 @@ */ package at.ac.tuwien.kr.alpha.core.parser; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.channels.ReadableByteChannel; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.junit.jupiter.api.Test; + import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; @@ -43,22 +60,6 @@ import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.nio.channels.ReadableByteChannel; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; /** * Copyright (c) 2016, the Alpha Team. @@ -125,7 +126,7 @@ public void parseInterval() { ASPCore2Program parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); IntervalTerm factInterval = (IntervalTerm) parsedProgram.getFacts().get(0).getTerms().get(0); assertTrue(factInterval.equals(IntervalTerm.getInstance(Terms.newConstant(2), Terms.newConstant(5)))); - IntervalTerm bodyInterval = (IntervalTerm) parsedProgram.getRules().get(0).getBody().stream().findFirst().get().getTerms().get(1); + IntervalTerm bodyInterval = (IntervalTerm) ((Literal) parsedProgram.getRules().get(0).getBody().stream().findFirst().get()).getTerms().get(1); assertTrue(bodyInterval.equals(IntervalTerm.getInstance(Terms.newConstant(3), Terms.newVariable("X")))); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index f11692dcf..cbc92ed2c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -15,10 +15,11 @@ import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; +// TODO This is a functional test and should not be run with standard unit tests public class ProgramTransformationTest { private static final Logger LOGGER = LoggerFactory.getLogger(ProgramTransformationTest.class); @@ -87,4 +88,4 @@ public static boolean sayTrue(int val) { return true; } -} \ No newline at end of file +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java index b2450e02f..3c492d095 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java @@ -34,6 +34,7 @@ import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; +// TODO This is a functional test and should not be run with standard unit tests public class StratifiedEvaluationRegressionTest { private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluationRegressionTest.class); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java index 939bded78..ac7c30ec4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java @@ -50,11 +50,11 @@ import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.externals.Externals; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -65,6 +65,7 @@ import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; +// TODO This is a functional test and should not be run with standard unit tests public class StratifiedEvaluationTest { private final ProgramParser parser = new ProgramParserImpl(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java deleted file mode 100644 index a37c217d3..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java +++ /dev/null @@ -1,207 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; -import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; -import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; -import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.terms.ArithmeticOperator; -import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; -import at.ac.tuwien.kr.alpha.commons.literals.Literals; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.test.util.RuleParser; - -public class AggregateRewritingRuleAnalysisTest { - - //@formatter:off - private static final String BINDING_AGGREGATE_NO_GLOBALS = - "p(X) :- X = #max{N : q(N)}, X < 10, p(X, Y)."; - private static final String NONBINDING_AGGREGATE_NO_GLOBALS_1 = - "p(X) :- X < #max{N : q(N)}, X < 10, p(X, Y)."; - private static final String NONBINDING_AGGREGATE_NO_GLOBALS_2 = - "p(X) :- X < #max{N : q(N)}, X < 10, X = 3 + Y, Y = Z + 4, r(S, Z)."; - private static final String BINDING_AGGREGATES_NO_GLOBALS_INCLUDED = - "p :- not p(X), 3 < #max { Y : q(Y) }, X = #count { Y : q(Y) }."; - private static final String BINDING_AGGREGATE_WITH_GLOBALS_1 = - "graph_vertex_degree(G, V, D) :-" - + " graph(G)," - + " graph_vertex(G, V)," - + " D = #count{ VN : graph_edge(G, e(V, VN)); VN : graph_edge(G, e(VN, V)) }."; - private static final String BINDING_AGGREGATE_WITH_GLOBALS_2 = - "graph_max_degree_vertices(G, DMAX, N) :-" - + " graph(G)," - + " DMAX = #max{ DV : graph_vertex_degree(G, V, DV)}," - + " N = #count{ V : graph_vertex_degree(G, V, DMAX)}."; - //@formatter:on - - private static final AggregateRewritingRuleAnalysis analyze(String rule) { - return AggregateRewritingRuleAnalysis.analyzeRuleDependencies(RuleParser.parse(rule)); - } - - @Test - public void bindingAggregateNoGlobals() { - AggregateRewritingRuleAnalysis analysis = analyze(BINDING_AGGREGATE_NO_GLOBALS); - assertEquals(1, analysis.globalVariablesPerAggregate.size()); - assertEquals(1, analysis.dependenciesPerAggregate.size()); - - AggregateLiteral aggregate = new ArrayList<>(analysis.globalVariablesPerAggregate.keySet()).get(0); - assertTrue(analysis.globalVariablesPerAggregate.get(aggregate).isEmpty()); - assertEquals(0, analysis.dependenciesPerAggregate.get(aggregate).size()); - } - - @Test - public void nonBindingAggregateNoGlobals1() { - AggregateRewritingRuleAnalysis analysis = analyze(NONBINDING_AGGREGATE_NO_GLOBALS_1); - assertEquals(1, analysis.globalVariablesPerAggregate.size()); - assertEquals(1, analysis.dependenciesPerAggregate.size()); - - AggregateLiteral aggregate = new ArrayList<>(analysis.globalVariablesPerAggregate.keySet()).get(0); - assertTrue(analysis.globalVariablesPerAggregate.get(aggregate).isEmpty()); - assertFalse(analysis.dependenciesPerAggregate.get(aggregate).isEmpty()); - - Set dependencies = analysis.dependenciesPerAggregate.get(aggregate); - assertEquals(1, dependencies.size()); - - Literal pXY = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")), true); - assertTrue(dependencies.contains(pXY)); - } - - @Test - public void nonBindingAggregateNoGlobals2() { - AggregateRewritingRuleAnalysis analysis = analyze(NONBINDING_AGGREGATE_NO_GLOBALS_2); - assertEquals(1, analysis.globalVariablesPerAggregate.size()); - assertEquals(1, analysis.dependenciesPerAggregate.size()); - - AggregateLiteral aggregate = new ArrayList<>(analysis.globalVariablesPerAggregate.keySet()).get(0); - assertTrue(analysis.globalVariablesPerAggregate.get(aggregate).isEmpty()); - assertFalse(analysis.dependenciesPerAggregate.get(aggregate).isEmpty()); - - Set dependencies = analysis.dependenciesPerAggregate.get(aggregate); - assertEquals(3, dependencies.size()); - - Literal threePlusY = Literals.fromAtom( - Atoms.newComparisonAtom(Terms.newVariable("X"), - Terms.newArithmeticTerm(Terms.newConstant(3), ArithmeticOperator.PLUS, Terms.newVariable("Y")), - ComparisonOperators.EQ), - true); - assertTrue(dependencies.contains(threePlusY)); - - Literal zPlusFour = Literals.fromAtom( - Atoms.newComparisonAtom(Terms.newVariable("Y"), - Terms.newArithmeticTerm(Terms.newVariable("Z"), ArithmeticOperator.PLUS, Terms.newConstant(4)), - ComparisonOperators.EQ), - true); - assertTrue(dependencies.contains(zPlusFour)); - - Literal rSZ = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("r", 2), Terms.newVariable("S"), Terms.newVariable("Z")), true); - assertTrue(dependencies.contains(rSZ)); - } - - @Test - public void bindingAggregateWithGlobals1() { - AggregateRewritingRuleAnalysis analysis = analyze(BINDING_AGGREGATE_WITH_GLOBALS_1); - assertEquals(1, analysis.globalVariablesPerAggregate.size()); - assertEquals(1, analysis.dependenciesPerAggregate.size()); - - AggregateLiteral aggregate = new ArrayList<>(analysis.globalVariablesPerAggregate.keySet()).get(0); - assertFalse(analysis.globalVariablesPerAggregate.get(aggregate).isEmpty()); - assertFalse(analysis.dependenciesPerAggregate.get(aggregate).isEmpty()); - - Set globalVars = analysis.globalVariablesPerAggregate.get(aggregate); - assertTrue(globalVars.contains(Terms.newVariable("G"))); - assertTrue(globalVars.contains(Terms.newVariable("V"))); - - Set dependencies = analysis.dependenciesPerAggregate.get(aggregate); - assertEquals(2, dependencies.size()); - - Literal graph = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("graph", 1), Terms.newVariable("G")), true); - assertTrue(dependencies.contains(graph)); - - Literal graphVertex = Literals.fromAtom( - Atoms.newBasicAtom(Predicates.getPredicate("graph_vertex", 2), Terms.newVariable("G"), Terms.newVariable("V")), true); - assertTrue(dependencies.contains(graphVertex)); - } - - @Test - public void bindingAggregateWithGlobals2() { - AggregateRewritingRuleAnalysis analysis = analyze(BINDING_AGGREGATE_WITH_GLOBALS_2); - assertEquals(2, analysis.globalVariablesPerAggregate.size()); - assertEquals(2, analysis.dependenciesPerAggregate.size()); - - // Verify correct analysis of max aggregate - List vertexDegreeTerms = Collections.singletonList(Terms.newVariable("DV")); - Literal vertexDegreeLiteral = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("graph_vertex_degree", 3), Terms.newVariable("G"), - Terms.newVariable("V"), Terms.newVariable("DV")), true); - List vertexDegreeLiterals = Collections.singletonList(vertexDegreeLiteral); - AggregateElement vertexDegree = Atoms.newAggregateElement(vertexDegreeTerms, vertexDegreeLiterals); - AggregateLiteral maxAggregate = Literals.fromAtom( - Atoms.newAggregateAtom(ComparisonOperators.EQ, Terms.newVariable("DMAX"), AggregateFunctionSymbol.MAX, - Collections.singletonList(vertexDegree)), - true); - assertTrue(analysis.globalVariablesPerAggregate.containsKey(maxAggregate)); - - Set maxAggrGlobalVars = analysis.globalVariablesPerAggregate.get(maxAggregate); - assertEquals(1, maxAggrGlobalVars.size()); - assertTrue(maxAggrGlobalVars.contains(Terms.newVariable("G"))); - - assertTrue(analysis.dependenciesPerAggregate.containsKey(maxAggregate)); - Set maxAggrDependencies = analysis.dependenciesPerAggregate.get(maxAggregate); - assertEquals(1, maxAggrDependencies.size()); - Literal graph = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("graph", 1), Terms.newVariable("G")), true); - assertTrue(maxAggrDependencies.contains(graph)); - - // Verify correct analysis of count aggregate - List maxVertexDegreeTerms = Collections.singletonList(Terms.newVariable("V")); - Literal maxVertexDegreeLiteral = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("graph_vertex_degree", 3), Terms.newVariable("G"), - Terms.newVariable("V"), Terms.newVariable("DMAX")), true); - List maxVertexDegreeLiterals = Collections.singletonList(maxVertexDegreeLiteral); - AggregateElement maxVertexDegree = Atoms.newAggregateElement(maxVertexDegreeTerms, maxVertexDegreeLiterals); - AggregateLiteral countAggregate = Literals.fromAtom( - Atoms.newAggregateAtom(ComparisonOperators.EQ, Terms.newVariable("N"), AggregateFunctionSymbol.COUNT, - Collections.singletonList(maxVertexDegree)), - true); - assertTrue(analysis.globalVariablesPerAggregate.containsKey(countAggregate)); - Set cntAggrGlobalVars = analysis.globalVariablesPerAggregate.get(countAggregate); - assertEquals(2, cntAggrGlobalVars.size()); - assertTrue(cntAggrGlobalVars.contains(Terms.newVariable("G"))); - assertTrue(cntAggrGlobalVars.contains(Terms.newVariable("DMAX"))); - - assertTrue(analysis.dependenciesPerAggregate.containsKey(countAggregate)); - Set cntAggrDependencies = analysis.dependenciesPerAggregate.get(countAggregate); - assertEquals(2, cntAggrDependencies.size()); - assertTrue(cntAggrDependencies.contains(graph)); - assertTrue(cntAggrDependencies.contains(maxAggregate)); - } - - @Test - public void bindingAggregateGlobalsNotIncluded() { - AggregateRewritingRuleAnalysis analysis = analyze(BINDING_AGGREGATES_NO_GLOBALS_INCLUDED); - assertEquals(2, analysis.globalVariablesPerAggregate.size()); - assertEquals(2, analysis.dependenciesPerAggregate.size()); - - // Check that the #max aggregate does not include "not p(X)" as its dependency. - for (Map.Entry> aggregateDependencies : analysis.dependenciesPerAggregate.entrySet()) { - if (aggregateDependencies.getKey().getAtom().getAggregateFunction() == AggregateFunctionSymbol.MAX) { - for (Literal dependency : aggregateDependencies.getValue()) { - assertFalse(dependency.isNegated()); - } - } - } - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java index d514d90bd..e7dc1543f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java @@ -29,6 +29,7 @@ import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; +// TODO This is a functional test and should not be run with standard unit tests public class AggregateRewritingTest { private static final ProgramParser PARSER = new ProgramParserImpl(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java index 62542ba2d..d81c3e435 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java @@ -34,6 +34,7 @@ /** * Tests if correct answer sets for programs containing aggregates are computed. */ +// TODO This is a functional test and should not be run with standard unit tests public class AggregatesTest { private static final String LS = System.lineSeparator(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AntecedentTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AntecedentTest.java deleted file mode 100644 index a2cb52826..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AntecedentTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.solver; - -import java.util.HashSet; - -public class AntecedentTest { - - /** - * Tests whether two Antecedent objects have the same reason literals (irrespective of their order). - * Note that both Antecedents are assumed to contain no duplicate literals. - * @param l left Antecedent. - * @param r right Antecedent - * @return true iff both Antecedents contain the same literals. - */ - public static boolean antecedentsEquals(Antecedent l, Antecedent r) { - if (l == r) { - return true; - } - if (l != null && r != null && l.getReasonLiterals().length == r.getReasonLiterals().length) { - HashSet lSet = new HashSet<>(); - for (int literal : l.getReasonLiterals()) { - lSet.add(literal); - } - for (int literal : r.getReasonLiterals()) { - if (!lSet.contains(literal)) { - return false; - } - } - return true; - } - return false; - } -} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java index b232ba659..4d2aab5af 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java @@ -8,6 +8,7 @@ * * Copyright (c) 2020, the Alpha Team. */ +// TODO This is a functional test and should not be run with standard unit tests public class ArithmeticTermsTest { @RegressionTest diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java index 7e2adb491..f43a858e8 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java @@ -52,6 +52,7 @@ import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +// TODO should this be part of an AtomStoreTest?? public class AtomCounterTests { private AtomStore atomStore; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java index 0df75abb2..692e6840a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java @@ -29,22 +29,23 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Collection; +import java.util.Collections; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.common.NoGood; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; public class ChoiceManagerTests { private Grounder grounder; @@ -53,11 +54,19 @@ public class ChoiceManagerTests { @BeforeEach public void setUp() { - String testProgram = "h :- b1, b2, not b3, not b4."; - ASPCore2Program parsedProgram = new ProgramParserImpl().parse(testProgram); - CompiledProgram internalProgram = InternalProgram.fromNormalProgram(new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG).apply(parsedProgram)); + /* + * program := + * h :- b1, b2, not b3, not b4. + */ + CompiledProgram program = new InternalProgram(Collections.singletonList( + new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 0))), + Atoms.newBasicAtom(Predicates.getPredicate("b1", 0)).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("b2", 0)).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("b3", 0)).toLiteral(false), + Atoms.newBasicAtom(Predicates.getPredicate("b4", 0)).toLiteral(false)) + ), Collections.emptyList()); atomStore = new AtomStoreImpl(); - grounder = new NaiveGrounder(internalProgram, atomStore, true); + grounder = new NaiveGrounder(program, atomStore, true); WritableAssignment assignment = new TrailAssignment(atomStore); NoGoodStore store = new NoGoodStoreAlphaRoaming(assignment); choiceManager = new ChoiceManager(assignment, store); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java index 9083e3e6c..18afe56dc 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java @@ -53,6 +53,7 @@ * Tests {@link AbstractSolver} using some hanoi tower test cases (see https://en.wikipedia.org/wiki/Tower_of_Hanoi). * */ +// TODO This is a functional test and should not be run with standard unit tests public class HanoiTowerTest { @SuppressWarnings("unused") diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStoreTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStoreTest.java index b7f29a6ef..135cda060 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStoreTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStoreTest.java @@ -3,7 +3,6 @@ import static at.ac.tuwien.kr.alpha.core.common.NoGood.fact; import static at.ac.tuwien.kr.alpha.core.common.NoGood.headFirst; import static at.ac.tuwien.kr.alpha.core.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.core.solver.AntecedentTest.antecedentsEquals; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.FALSE; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; @@ -350,7 +349,7 @@ public void conflictingFact() { assignment.assign(1, FALSE); ConflictCause conflictCause = store.add(1, noGood); assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -360,7 +359,7 @@ public void conflictingBinary() { assignment.assign(1, TRUE); assignment.assign(2, TRUE); ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -371,7 +370,7 @@ public void conflictingNary() { assignment.assign(2, TRUE); assignment.assign(3, TRUE); ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -384,7 +383,7 @@ public void propagateViolatedConstraint() { ConflictCause conflictCause = store.propagate(); assertNotNull(conflictCause); assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -407,7 +406,7 @@ public void propagateViolatedConstraintHeadless() { ConflictCause conflictCause = store.propagate(); assertNotNull(conflictCause); assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -420,7 +419,7 @@ public void propagateViolatedConstraintHeadlessMbt() { ConflictCause conflictCause = store.propagate(); assertNotNull(conflictCause); assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoamingTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoamingTest.java index 7c86b69bf..3cca5a1af 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoamingTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoamingTest.java @@ -3,7 +3,6 @@ import static at.ac.tuwien.kr.alpha.core.common.NoGood.fact; import static at.ac.tuwien.kr.alpha.core.common.NoGood.headFirst; import static at.ac.tuwien.kr.alpha.core.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.core.solver.AntecedentTest.antecedentsEquals; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.FALSE; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; @@ -348,7 +347,7 @@ public void conflictingFact() { assignment.assign(1, FALSE); ConflictCause conflictCause = store.add(1, noGood); assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -357,7 +356,7 @@ public void conflictingBinary() { assignment.assign(1, TRUE); assignment.assign(2, TRUE); ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -367,7 +366,7 @@ public void conflictingNary() { assignment.assign(2, TRUE); assignment.assign(3, TRUE); ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -380,7 +379,7 @@ public void propagateViolatedConstraint() { ConflictCause conflictCause = store.propagate(); assertNotNull(conflictCause); assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -402,7 +401,7 @@ public void propagateViolatedConstraintHeadless() { ConflictCause conflictCause = store.propagate(); assertFalse(store.didPropagate()); assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test @@ -415,7 +414,7 @@ public void propagateViolatedConstraintHeadlessMbt() { ConflictCause conflictCause = store.propagate(); assertFalse(store.didPropagate()); assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + assertTrue(TestUtils.antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); } @Test diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java index 4962ddc4c..2d5713e14 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java @@ -42,6 +42,7 @@ * Tests {@link AbstractSolver} using Omiga benchmark problems. * */ +// TODO This is a functional test and should not be run with standard unit tests public class OmigaBenchmarksTest { @SuppressWarnings("unused") diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java index f39a9434a..670195ea1 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java @@ -40,6 +40,7 @@ * Tests {@link AbstractSolver} using some configuration test cases in which subparts are assigned to parts. * */ +// TODO This is a functional test and should not be run with standard unit tests public class PartSubpartConfigurationTest { private static final int DEBUG_TIMEOUT_FACTOR = 5; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java index d444d5a7e..318452c64 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java @@ -42,6 +42,7 @@ /** * Tests {@link AbstractSolver} using some pigeon-hole test cases (see https://en.wikipedia.org/wiki/Pigeonhole_principle). */ +// TODO This is a functional test and should not be run with standard unit tests public class PigeonHoleTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java index 1ea2b88ca..4c9150ca0 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java @@ -44,6 +44,7 @@ * Tests {@link AbstractSolver} using a racks configuration problem. * */ +// TODO This is a functional test and should not be run with standard unit tests @Disabled("disabled to save resources during CI") public class RacksTest { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java index 1afed713b..c091c53e9 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java @@ -38,8 +38,9 @@ import at.ac.tuwien.kr.alpha.api.StatisticsReportingSolver; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.DummyGrounder; +import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithBasicProgram; +// TODO This is a functional test and should not be run with standard unit tests public class SolverStatisticsTests { private AtomStore atomStore; @@ -65,14 +66,14 @@ public void checkStatsStringOneChoice(RegressionTestConfig cfg) { @RegressionTest public void checkNoGoodCounterStatsByTypeUsingDummyGrounder(RegressionTestConfig cfg) { - Solver solver = buildSolverForRegressionTest(atomStore, new DummyGrounder(atomStore), cfg); + Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); assumeTrue(solver instanceof StatisticsReportingSolver); collectAnswerSetsAndCheckNoGoodCounterStatsByType(solver, 4, 0, 0, 0); } @RegressionTest public void checkNoGoodCounterStatsByCardinalityUsingDummyGrounder(RegressionTestConfig cfg) { - Solver solver = buildSolverForRegressionTest(atomStore, new DummyGrounder(atomStore), cfg); + Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); assumeTrue(solver instanceof StatisticsReportingSolver); collectAnswerSetsAndCheckNoGoodCounterStatsByCardinality(solver, 2, 1, 1); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java index 911a2dd32..d7cf1ad99 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java @@ -53,12 +53,13 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.ChoiceGrounder; -import at.ac.tuwien.kr.alpha.core.grounder.DummyGrounder; +import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithChoice; +import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithBasicProgram; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.test.util.AnswerSetsParser; +// // TODO This is a functional test and should not be run with standard unit tests public class SolverTests { private static class Thingy implements Comparable { @@ -807,13 +808,13 @@ public void smallCardinalityAggregate(RegressionTestConfig cfg) { @RegressionTest public void dummyGrounder(RegressionTestConfig cfg) { AtomStore atomStore = new AtomStoreImpl(); - assertEquals(DummyGrounder.EXPECTED, buildSolverForRegressionTest(atomStore, new DummyGrounder(atomStore), cfg).collectSet()); + assertEquals(GrounderMockWithBasicProgram.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg).collectSet()); } @RegressionTest public void choiceGrounder(RegressionTestConfig cfg) { AtomStore atomStore = new AtomStoreImpl(); - assertEquals(ChoiceGrounder.EXPECTED, buildSolverForRegressionTest(atomStore, new ChoiceGrounder(atomStore), cfg).collectSet()); + assertEquals(GrounderMockWithChoice.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithChoice(atomStore), cfg).collectSet()); } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TestableChoiceManager.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TestableChoiceManager.java deleted file mode 100644 index 50eaa2443..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TestableChoiceManager.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2017-2018 Siemens AG - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package at.ac.tuwien.kr.alpha.core.solver; - -import org.apache.commons.lang3.tuple.Pair; - -import java.util.Map; -import java.util.Set; - -/** - * This class is only here to make {@link ChoiceManager#addChoiceInformation(Pair)} public so that unit tests can access it. - * - * Copyright (c) 2017 Siemens AG - * - */ -public class TestableChoiceManager extends ChoiceManager { - - public TestableChoiceManager(WritableAssignment assignment, NoGoodStore store) { - super(assignment, store); - } - - @Override - public void addChoiceInformation(Pair, Map> choiceAtoms, Map> headsToBodies) { - super.addChoiceInformation(choiceAtoms, headsToBodies); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java index 2108b65db..424ce245d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java @@ -45,6 +45,7 @@ import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +// TODO This is a functional test and should not be run with standard unit tests public class ThreeColouringRandomGraphTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java index d53a0b82d..821499ce4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java @@ -55,6 +55,7 @@ * In Theory and Practice of Logic Programming, pp. 1-45. DOI: * 10.1017/S1471068416000569 */ +// TODO This is a functional test and should not be run with standard unit tests public class ThreeColouringTestWithRandom { private static final long DEBUG_TIMEOUT_FACTOR = 5; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java index 48603e2e8..989f241f3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java @@ -53,6 +53,7 @@ * In Theory and Practice of Logic Programming, pp. 1-45. * DOI: 10.1017/S1471068416000569 */ +// TODO This is a functional test and should not be run with standard unit tests public class ThreeColouringWheelTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java index 72100a72b..82c0c0b06 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java @@ -27,18 +27,6 @@ */ package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.core.common.Assignment; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.common.IntIterator; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; - import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.FALSE; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; @@ -48,6 +36,19 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.core.common.IntIterator; +import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; + /** * Copyright (c) 2018-2020, the Alpha Team. */ @@ -180,8 +181,8 @@ public void newAssignmentsIteratorAndBacktracking() { newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(1, newAssignmentsIterator.next()); - assertEquals(2, newAssignmentsIterator.next()); + assertEquals(1, (int)newAssignmentsIterator.next()); + assertEquals(2, (int)newAssignmentsIterator.next()); assertFalse(newAssignmentsIterator.hasNext()); @@ -190,7 +191,7 @@ public void newAssignmentsIteratorAndBacktracking() { assignment.assign(3, FALSE); newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(3, newAssignmentsIterator.next()); + assertEquals(3, (int)newAssignmentsIterator.next()); assertFalse(newAssignmentsIterator.hasNext()); } @@ -204,8 +205,8 @@ public void newAssignmentsIteratorLowerDecisionLevelAndBacktracking() { assignment.backtrack(); newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(1, newAssignmentsIterator.next()); - assertEquals(3, newAssignmentsIterator.next()); + assertEquals(1, (int)newAssignmentsIterator.next()); + assertEquals(3, (int)newAssignmentsIterator.next()); assertFalse(newAssignmentsIterator.hasNext()); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java index b5c7516e0..6102ee79f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java @@ -29,27 +29,30 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Arrays; import java.util.Collection; -import java.util.function.Function; +import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.common.NoGood; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.core.solver.NaiveNoGoodStore; -import at.ac.tuwien.kr.alpha.core.solver.TestableChoiceManager; import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; @@ -63,30 +66,39 @@ */ public class AlphaHeuristicTestAssumptions { - private final ProgramParser parser = new ProgramParserImpl(); - private final NormalizeProgramTransformation normalizer = new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - private final Function parseAndPreprocess = (str) -> { - return InternalProgram.fromNormalProgram(normalizer.apply(parser.parse(str))); - }; - private Grounder grounder; private WritableAssignment assignment; - private TestableChoiceManager choiceManager; + private ChoiceManager choiceManager; private AtomStore atomStore; @BeforeEach public void setUp() { - String testProgram = "" - + "b1." - + "b2." - + "{b3}." - + "{b4}." - + "h :- b1, b2, not b3, not b4."; - CompiledProgram internalProgram = parseAndPreprocess.apply(testProgram); + /* program := + * b1. b2. + * b3 :- not nb3. + * nb3 :- not b3. + * b4 :- not nb4. + * nb4 :- not b4. + * h :- b1, b2, not b3, not b4. + */ + List facts = Arrays.asList(Atoms.newBasicAtom(Predicates.getPredicate("b1", 0)), Atoms.newBasicAtom(Predicates.getPredicate("b2", 0))); + List rules = Arrays.asList( + new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("b3", 0))), Atoms.newBasicAtom(Predicates.getPredicate("nb3", 0)).toLiteral(false)), + new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("nb3", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b3", 0)).toLiteral(false)), + new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("b4", 0))), Atoms.newBasicAtom(Predicates.getPredicate("nb4", 0)).toLiteral(false)), + new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("nb4", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b4", 0)).toLiteral(false)), + new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 0))), + Atoms.newBasicAtom(Predicates.getPredicate("b1", 0)).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("b2", 0)).toLiteral(), + Atoms.newBasicAtom(Predicates.getPredicate("b3", 0)).toLiteral(false), + Atoms.newBasicAtom(Predicates.getPredicate("b4", 0)).toLiteral(false)) + ); + CompiledProgram program = new InternalProgram(rules, facts); + atomStore = new AtomStoreImpl(); - grounder = new NaiveGrounder(internalProgram, atomStore, true); + grounder = new NaiveGrounder(program, atomStore, true); assignment = new TrailAssignment(atomStore); - choiceManager = new TestableChoiceManager(assignment, new NaiveNoGoodStore(assignment)); + choiceManager = new ChoiceManager(assignment, new NaiveNoGoodStore(assignment)); } @Test diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearnerTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearnerTest.java index b7ea7ef40..229f78755 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearnerTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearnerTest.java @@ -1,7 +1,6 @@ package at.ac.tuwien.kr.alpha.core.solver.learning; import static at.ac.tuwien.kr.alpha.core.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.core.solver.AntecedentTest.antecedentsEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -71,7 +70,7 @@ public void smallConflictNonTrivial1UIP() { assertNotNull(conflictCause); Antecedent violatedNoGood = conflictCause.getAntecedent(); assertNotNull(violatedNoGood); - assertTrue(antecedentsEquals(violatedNoGood, n5.asAntecedent()) || antecedentsEquals(violatedNoGood, n7.asAntecedent())); + assertTrue(TestUtils.antecedentsEquals(violatedNoGood, n5.asAntecedent()) || TestUtils.antecedentsEquals(violatedNoGood, n7.asAntecedent())); GroundConflictNoGoodLearner.ConflictAnalysisResult analysisResult = learner.analyzeConflictingNoGood(conflictCause.getAntecedent()); NoGood learnedNoGood = analysisResult.learnedNoGood; assertEquals(new NoGood(fromOldLiterals(1, -8)), learnedNoGood); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/TestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/TestUtils.java index 75cbc20df..d8d100065 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/TestUtils.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/TestUtils.java @@ -9,13 +9,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.StringJoiner; import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.function.Executable; @@ -43,6 +43,7 @@ import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; +import at.ac.tuwien.kr.alpha.core.solver.Antecedent; import at.ac.tuwien.kr.alpha.core.solver.RegressionTestConfig; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; @@ -55,25 +56,30 @@ public static void fillAtomStore(AtomStore atomStore, int numberOfAtomsToFill) { } } - public static Atom atom(String predicateName, String... termStrings) { - Term[] terms = new Term[termStrings.length]; - for (int i = 0; i < termStrings.length; i++) { - String termString = termStrings[i]; - if (StringUtils.isAllUpperCase(termString.substring(0, 1))) { - terms[i] = Terms.newVariable(termString); - } else { - terms[i] = Terms.newConstant(termString); - } + /** + * Tests whether two Antecedent objects have the same reason literals (irrespective of their order). + * Note that both Antecedents are assumed to contain no duplicate literals. + * @param l left Antecedent. + * @param r right Antecedent + * @return true iff both Antecedents contain the same literals. + */ + public static boolean antecedentsEquals(Antecedent l, Antecedent r) { + if (l == r) { + return true; } - return Atoms.newBasicAtom(Predicates.getPredicate(predicateName, terms.length), terms); - } - - public static Atom atom(String predicateName, int... termInts) { - Term[] terms = new Term[termInts.length]; - for (int i = 0; i < termInts.length; i++) { - terms[i] = Terms.newConstant(termInts[i]); + if (l != null && r != null && l.getReasonLiterals().length == r.getReasonLiterals().length) { + HashSet lSet = new HashSet<>(); + for (int literal : l.getReasonLiterals()) { + lSet.add(literal); + } + for (int literal : r.getReasonLiterals()) { + if (!lSet.contains(literal)) { + return false; + } + } + return true; } - return Atoms.newBasicAtom(Predicates.getPredicate(predicateName, terms.length), terms); + return false; } public static void printNoGoods(AtomStore atomStore, Collection noGoods) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplittingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java similarity index 95% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplittingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java index 4670282dd..f674121de 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplittingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; +package at.ac.tuwien.kr.alpha.api.impl; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -9,8 +9,9 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.test.util.RuleParser; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateLiteralSplitting; +// TODO This is a functional test and should not be run with standard unit tests public class AggregateLiteralSplittingTest { //@formatter:off diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalizationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java similarity index 95% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalizationTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java index 0461e9eea..5813bd930 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalizationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; +package at.ac.tuwien.kr.alpha.api.impl; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -17,8 +17,9 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.test.util.RuleParser; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateOperatorNormalization; +// TODO This is a functional test and should not be run with standard unit tests public class AggregateOperatorNormalizationTest { //@formatter:off @@ -38,6 +39,7 @@ public class AggregateOperatorNormalizationTest { "bla :- dom(X), not X > #count{N : thing(N)}."; public static final String OPERATOR_NORMALIZATION_GE_NEG_ASP = "bla :- dom(X), not X >= #count{N : thing(N)}."; + /** * Operator normalization must also make sure that literals with only a right-hand term * are normalized to left-hand term only (and then operator-normalized if necessary) @@ -175,9 +177,7 @@ private static void assertAggregateBoundIncremented(Rule sourceRule, Rule< ArithmeticTerm incrementTerm = (ArithmeticTerm) comparisonRightHandTerm; assertEquals(ArithmeticOperator.PLUS, incrementTerm.getOperator()); assertEquals(Terms.newConstant(1), incrementTerm.getRightOperand()); - Term sourceBound = sourceAggregate.getAtom().getLowerBoundTerm() != null ? sourceAggregate.getAtom().getLowerBoundTerm() - : sourceAggregate.getAtom().getUpperBoundTerm(); - assertEquals(sourceBound, incrementTerm.getLeftOperand()); + assertEquals(sourceAggregate.getAtom().getLowerBoundTerm(), incrementTerm.getLeftOperand()); } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java similarity index 96% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingContextTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java index b5603a9cf..92b41c9d8 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; +package at.ac.tuwien.kr.alpha.api.impl; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -19,8 +19,10 @@ import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; +// TODO This is a functional test and should not be run with standard unit tests public class AggregateRewritingContextTest { //@formatter:off diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 176862d40..9eba7a24f 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -68,18 +68,19 @@ import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.externals.AspStandardLibrary; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.MethodPredicateInterpretation; import at.ac.tuwien.kr.alpha.commons.literals.Literals; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.MethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; -import at.ac.tuwien.kr.alpha.core.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +// TODO This is a functional test and should not be run with standard unit tests public class AlphaImplTest { private static final Logger LOGGER = LoggerFactory.getLogger(AspStandardLibrary.class); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java similarity index 93% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewritingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java index 17ade9d66..8bc8d06b3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation; +package at.ac.tuwien.kr.alpha.api.impl; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -21,14 +21,16 @@ import at.ac.tuwien.kr.alpha.api.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermsRewriting; /** * Copyright (c) 2021, the Alpha Team. */ +// TODO This is a functional test and should not be run with standard unit tests public class ArithmeticTermsRewritingTest { private final Map externalsOfThisClass = Externals.scan(ArithmeticTermsRewritingTest.class); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java index 6d236e447..ef0a1a625 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java @@ -22,10 +22,11 @@ import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.externals.AspStandardLibrary; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +// // TODO This is a functional test and should not be run with standard unit tests public class FixedInterpretationLiteralsTest { @at.ac.tuwien.kr.alpha.api.externals.Predicate diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/RuleParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java similarity index 93% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/RuleParser.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java index 38da4d36d..0033015e6 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/RuleParser.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.test.util; +package at.ac.tuwien.kr.alpha.api.impl; import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java similarity index 98% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java index 38f8db22a..9cf689a0b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java @@ -23,7 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.grounder; +package at.ac.tuwien.kr.alpha.api.impl; import static org.junit.jupiter.api.Assertions.assertEquals; From 298118d99f8e54535ca3567f38482e7a880a4b1f Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 2 Feb 2022 15:30:19 +0100 Subject: [PATCH 02/59] refactoring: fix compiler warnings from redundant casts --- .../at/ac/tuwien/kr/alpha/core/parser/ParserTest.java | 2 +- .../kr/alpha/core/solver/TrailAssignmentTest.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 24e3494ee..33cdef134 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -126,7 +126,7 @@ public void parseInterval() { ASPCore2Program parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); IntervalTerm factInterval = (IntervalTerm) parsedProgram.getFacts().get(0).getTerms().get(0); assertTrue(factInterval.equals(IntervalTerm.getInstance(Terms.newConstant(2), Terms.newConstant(5)))); - IntervalTerm bodyInterval = (IntervalTerm) ((Literal) parsedProgram.getRules().get(0).getBody().stream().findFirst().get()).getTerms().get(1); + IntervalTerm bodyInterval = (IntervalTerm) parsedProgram.getRules().get(0).getBody().stream().findFirst().get().getTerms().get(1); assertTrue(bodyInterval.equals(IntervalTerm.getInstance(Terms.newConstant(3), Terms.newVariable("X")))); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java index 82c0c0b06..1c9265d3d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java @@ -181,8 +181,8 @@ public void newAssignmentsIteratorAndBacktracking() { newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(1, (int)newAssignmentsIterator.next()); - assertEquals(2, (int)newAssignmentsIterator.next()); + assertEquals(1, newAssignmentsIterator.next()); + assertEquals(2, newAssignmentsIterator.next()); assertFalse(newAssignmentsIterator.hasNext()); @@ -191,7 +191,7 @@ public void newAssignmentsIteratorAndBacktracking() { assignment.assign(3, FALSE); newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(3, (int)newAssignmentsIterator.next()); + assertEquals(3, newAssignmentsIterator.next()); assertFalse(newAssignmentsIterator.hasNext()); } @@ -205,8 +205,8 @@ public void newAssignmentsIteratorLowerDecisionLevelAndBacktracking() { assignment.backtrack(); newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(1, (int)newAssignmentsIterator.next()); - assertEquals(3, (int)newAssignmentsIterator.next()); + assertEquals(1, newAssignmentsIterator.next()); + assertEquals(3, newAssignmentsIterator.next()); assertFalse(newAssignmentsIterator.hasNext()); } From 758d731b61c368fbfcd3a13c09bf26ed42fed87a Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 7 Feb 2022 17:30:36 +0100 Subject: [PATCH 03/59] decouple core module from config structures, create Alpha instances using a factory --- .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 24 +- .../kr/alpha/api/ComparisonOperator.java | 4 +- .../kr/alpha/api/DebugSolvingContext.java | 8 +- .../kr/alpha/api/config/SystemConfig.java | 27 -- .../alpha/api/programs/ASPCore2Program.java | 13 - .../kr/alpha/api/programs/InputProgram.java | 9 + .../kr/alpha/api/programs/ProgramParser.java | 22 +- alpha-cli-app/build.gradle.kts | 1 + .../main/java/at/ac/tuwien/kr/alpha/Main.java | 8 +- .../alpha/app/config/CommandLineParser.java | 14 - .../java/at/ac/tuwien/kr/alpha/MainTest.java | 8 +- .../alpha/app/ComponentGraphWriterTest.java | 4 +- .../alpha/app/DependencyGraphWriterTest.java | 4 +- .../AnswerSetToWorkbookMapperTest.java | 4 +- .../alpha/core/grounder/GrounderFactory.java | 28 +- .../kr/alpha/core/grounder/NaiveGrounder.java | 4 + .../alpha/core/parser/ParseTreeVisitor.java | 9 +- .../alpha/core/parser/ProgramParserImpl.java | 24 +- ...nputProgram.java => InputProgramImpl.java} | 20 +- .../core/programs/NormalProgramImpl.java | 4 +- .../kr/alpha/core/programs/Programs.java | 4 +- .../transformation/ChoiceHeadToNormal.java | 10 +- .../transformation/EnumerationRewriting.java | 10 +- .../NormalizeProgramTransformation.java | 19 +- .../transformation/PredicateInternalizer.java | 8 +- .../transformation/StratifiedEvaluation.java | 22 +- .../VariableEqualityRemoval.java | 10 +- .../AggregateOperatorNormalization.java | 2 +- .../aggregates/AggregateRewriting.java | 25 +- .../encoders/AbstractAggregateEncoder.java | 16 +- .../encoders/AggregateEncoderFactory.java | 44 +++ .../aggregates/encoders/CountEncoder.java | 15 +- .../aggregates/encoders/MinMaxEncoder.java | 8 +- .../StringtemplateBasedAggregateEncoder.java | 16 +- .../aggregates/encoders/SumEncoder.java | 15 +- .../kr/alpha/core/rules/AbstractRule.java | 5 + .../kr/alpha/core/rules/NormalRuleImpl.java | 5 + .../kr/alpha/core/solver/DefaultSolver.java | 11 +- .../kr/alpha/core/solver/SolverConfig.java | 53 ++++ .../kr/alpha/core/solver/SolverFactory.java | 45 ++- .../kr/alpha/core/common/ProgramTest.java | 8 +- .../kr/alpha/core/parser/ParserTest.java | 22 +- .../ProgramTransformationTest.java | 6 +- .../StratifiedEvaluationRegressionTest.java | 263 ---------------- .../core/solver/ArithmeticTermsTest.java | 56 ---- .../core/solver/RegressionTestConfig.java | 125 -------- .../kr/alpha/core/test/util/TestUtils.java | 83 +---- .../tuwien/kr/alpha/test/AlphaAssertions.java | 75 +++++ .../kr/alpha/test}/AnswerSetsParser.java | 2 +- .../benchmarks/omiga/omiga-testcases.tar.gz | Bin .../omiga/omiga-testcases/3col/3col-10-18.txt | 0 .../omiga/omiga-testcases/3col/3col-20-38.txt | 0 .../cutedge/cutedge-100-30.txt | 0 .../cutedge/cutedge-100-50.txt | 0 .../omiga-testcases/locstrat/locstrat-200.txt | 0 .../omiga-testcases/locstrat/locstrat-400.txt | 0 .../omiga/omiga-testcases/reach/reach-1.txt | 0 .../omiga/omiga-testcases/reach/reach-4.txt | 0 .../benchmarks/siemens/racks/racks.lp | 0 alpha-solver/build.gradle.kts | 2 + .../kr/alpha/api/impl/AlphaFactory.java | 77 +++++ .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 113 ++++--- .../kr/alpha}/AggregateRewritingTest.java | 57 ++-- .../kr/alpha}/StratifiedEvaluationTest.java | 131 ++++---- .../impl/AggregateRewritingContextTest.java | 4 +- .../kr/alpha/api/impl/AlphaImplTest.java | 129 ++++---- .../kr/alpha/api/impl/AnswerSetsParser.java | 45 --- .../impl/FixedInterpretationLiteralsTest.java | 2 +- .../tuwien/kr/alpha/api/impl/RuleParser.java | 4 +- .../kr/alpha/api/impl/RuleToStringTest.java | 4 +- .../AggregateRegressionTest.java | 4 +- .../regressiontests}/AggregatesTest.java | 101 +++--- .../regressiontests/ArithmeticTermsTest.java | 58 ++++ .../regressiontests}/HanoiTowerTest.java | 39 ++- .../HeadBodyTransformationTests.java | 105 +++---- .../regressiontests}/OmigaBenchmarksTest.java | 60 ++-- .../PartSubpartConfigurationTest.java | 26 +- .../regressiontests}/PigeonHoleTest.java | 37 +-- .../kr/alpha/regressiontests}/RacksTest.java | 11 +- .../regressiontests}/RegressionTest.java | 6 +- .../RegressionTestConfigProvider.java | 77 +++-- .../regressiontests/RegressionTestUtils.java | 83 +++++ .../SolverStatisticsTests.java | 37 ++- .../alpha/regressiontests}/SolverTests.java | 160 +++++----- .../StratifiedEvaluationRegressionTest.java | 293 ++++++++++++++++++ .../ThreeColouringRandomGraphTest.java | 31 +- .../ThreeColouringTestWithRandom.java | 53 ++-- .../ThreeColouringWheelTest.java | 29 +- .../partial-eval/pup_topological_order.asp | 0 .../recursive_w_negated_condition.asp | 0 .../alpha.java-common-conventions.gradle.kts | 3 + 91 files changed, 1564 insertions(+), 1439 deletions(-) delete mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/{InputProgram.java => InputProgramImpl.java} (82%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverConfig.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTestConfig.java create mode 100644 alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java rename alpha-core/src/{test/java/at/ac/tuwien/kr/alpha/core/test/util => testFixtures/java/at/ac/tuwien/kr/alpha/test}/AnswerSetsParser.java (97%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases.tar.gz (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/reach/reach-1.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/omiga/omiga-testcases/reach/reach-4.txt (100%) rename {alpha-core => alpha-solver}/benchmarks/siemens/racks/racks.lp (100%) create mode 100644 alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha}/AggregateRewritingTest.java (81%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha}/StratifiedEvaluationTest.java (59%) delete mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AnswerSetsParser.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/AggregateRegressionTest.java (72%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/AggregatesTest.java (76%) create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/HanoiTowerTest.java (78%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/HeadBodyTransformationTests.java (65%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/OmigaBenchmarksTest.java (52%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/PartSubpartConfigurationTest.java (86%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/PigeonHoleTest.java (84%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/RacksTest.java (86%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/RegressionTest.java (73%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/RegressionTestConfigProvider.java (57%) create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestUtils.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/SolverStatisticsTests.java (79%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/SolverTests.java (78%) create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/ThreeColouringRandomGraphTest.java (85%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/ThreeColouringTestWithRandom.java (85%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver => alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests}/ThreeColouringWheelTest.java (86%) rename {alpha-core => alpha-solver}/src/test/resources/partial-eval/pup_topological_order.asp (100%) rename {alpha-core => alpha-solver}/src/test/resources/partial-eval/recursive_w_negated_condition.asp (100%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java index d1b37b00c..60dd0a236 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.config.InputConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; @@ -27,7 +27,7 @@ public interface Alpha { * @return an {@link ASPCore2Program} representing the parsed ASP code from all sources referenced in the given {@link InputConfig} * @throws IOException in case one or more program sources (e.g. files) cannot be read, or parsing fails */ - ASPCore2Program readProgram(InputConfig cfg) throws IOException; + InputProgram readProgram(InputConfig cfg) throws IOException; /** * Reads and parses an {@link ASPCore2Program} from a list of {@link String}s representing paths. @@ -38,12 +38,12 @@ public interface Alpha { * @return an {@link ASPCore2Program} representing the parsed ASP code from all given path strings * @throws IOException in case one or more program sources cannot be read, or parsing fails */ - ASPCore2Program readProgramFiles(boolean literate, Map externals, List paths) throws IOException; + InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException; /** * see {@link Alpha#readProgramFiles(boolean, Map, List)} */ - ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; + InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; /** * Parses a given String into an {@link ASPCore2Program}, using a map of custom {@link PredicateInterpretation}s to resolve external atoms @@ -53,19 +53,19 @@ public interface Alpha { * @param externals a map of custom {@link PredicateInterpretation}s against which external atoms in the given code are resolved * @return an {@link ASPCore2Program} representing the parsed ASP code */ - ASPCore2Program readProgramString(String aspString, Map externals); + InputProgram readProgramString(String aspString, Map externals); /** * Convenience method to parse ASP strings not containing any user-defined external atoms, see {@link Alpha#readProgramString(String, Map)}. */ - ASPCore2Program readProgramString(String aspString); + InputProgram readProgramString(String aspString); /** * Prepares a {@link DebugSolvingContext} for the given {@link ASPCore2Program} to debug program preprocessing. * * @return a {@link DebugSolvingContext} holding debug information for the given program */ - DebugSolvingContext prepareDebugSolve(final ASPCore2Program program); + DebugSolvingContext prepareDebugSolve(final InputProgram program); /** * Prepares a {@link DebugSolvingContext} for the given {@link NormalProgram} to debug program preprocessing. @@ -80,7 +80,7 @@ public interface Alpha { * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link DebugSolvingContext} holding debug information for the given program */ - DebugSolvingContext prepareDebugSolve(final ASPCore2Program program, java.util.function.Predicate filter); + DebugSolvingContext prepareDebugSolve(final InputProgram program, java.util.function.Predicate filter); /** * Prepares a {@link DebugSolvingContext} for the given {@link NormalProgram} to debug program preprocessing. @@ -95,7 +95,7 @@ public interface Alpha { * @param program an input program * @return a {@link Stream} of {@link AnswerSet}s of the given program */ - Stream solve(ASPCore2Program program); + Stream solve(InputProgram program); /** * Solves the given {@link ASPCore2Program}. @@ -103,7 +103,7 @@ public interface Alpha { * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Stream} of {@link AnswerSet}s of the given program */ - Stream solve(ASPCore2Program program, java.util.function.Predicate filter); + Stream solve(InputProgram program, java.util.function.Predicate filter); /** * Solves the given {@link NormalProgram}. @@ -126,7 +126,7 @@ public interface Alpha { * @param program An {@link ASPCore2Program} to normalize * @return a {@link NormalProgram} that is a semantic equivalent to the given input program */ - NormalProgram normalizeProgram(ASPCore2Program program); + NormalProgram normalizeProgram(InputProgram program); /** * Constructs a @{link Solver} pre-loaded with the given {@link ASPCore2Program} from which {@link AnswerSet}s can be obtained via {@link Solver#stream()}. @@ -135,7 +135,7 @@ public interface Alpha { * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Solver} pre-loaded withthe given program */ - Solver prepareSolverFor(ASPCore2Program program, java.util.function.Predicate filter); + Solver prepareSolverFor(InputProgram program, java.util.function.Predicate filter); /** * Constructs a @{link Solver} pre-loaded with the given {@link NormalProgram} from which {@link AnswerSet}s can be obtained via {@link Solver#stream()}. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java index b6cbfb168..7b8343b8e 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java @@ -1,11 +1,11 @@ package at.ac.tuwien.kr.alpha.api; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; /** - * A comparison operator that can be used in {@link ASPCore2Program}s. + * A comparison operator that can be used in {@link InputProgram}s. * * Copyright (c) 2021, the Alpha Team. */ diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java index 60966193a..2f9ab8fcf 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.api; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; @@ -13,13 +13,13 @@ public interface DebugSolvingContext { /** - * The normalized version of the {@link ASPCore2Program} that is being solved. - * See {@link Alpha#normalizeProgram(ASPCore2Program)}. + * The normalized version of the {@link InputProgram} that is being solved. + * See {@link Alpha#normalizeProgram(InputProgram)}. */ NormalProgram getNormalizedProgram(); /** - * The fully preprocessed version of the {@link ASPCore2Program} that is being solved. + * The fully preprocessed version of the {@link InputProgram} that is being solved. * This differs from the value of {@link DebugSolvingContext#getNormalizedProgram()} in the stratified part of the normalized program may * already be evaluated depending on the respective configuration of {@link Alpha}. */ diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java index 27019ce10..e5c94fefd 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java @@ -44,13 +44,11 @@ public class SystemConfig { // initializing from those values in order to have the values accessible in // contexts where no AlphaConfig instance exists (e.g. argument parsing from // command line) - public static final String DEFAULT_GROUNDER_NAME = "naive"; public static final String DEFAULT_SOLVER_NAME = "default"; public static final String DEFAULT_NOGOOD_STORE_NAME = "alphaRoaming"; public static final Heuristic DEFAULT_BRANCHING_HEURISTIC = Heuristic.VSIDS; public static final BinaryNoGoodPropagationEstimationStrategy DEFAULT_MOMS_STRATEGY = BinaryNoGoodPropagationEstimationStrategy.CountBinaryWatches; public static final long DEFAULT_SEED = System.nanoTime(); - public static final boolean DEFAULT_DETERMINISTIC = false; public static final boolean DEFAULT_PRINT_STATS = false; public static final boolean DEFAULT_QUIET = false; public static final boolean DEFAULT_DISABLE_JUSTIFICATION_SEARCH = false; @@ -65,10 +63,8 @@ public class SystemConfig { public static final String DEFAULT_ATOM_SEPARATOR = ", "; public static final AggregateRewritingConfig DEFAULT_AGGREGATE_REWRITING_CONFIG = new AggregateRewritingConfig(); - private String grounderName = DEFAULT_GROUNDER_NAME; private String solverName = DEFAULT_SOLVER_NAME; private String nogoodStoreName = DEFAULT_NOGOOD_STORE_NAME; - private boolean deterministic = DEFAULT_DETERMINISTIC; private long seed = DEFAULT_SEED; private boolean debugInternalChecks = DEFAULT_DEBUG_INTERNAL_CHECKS; private Heuristic branchingHeuristic = DEFAULT_BRANCHING_HEURISTIC; @@ -86,17 +82,6 @@ public class SystemConfig { private String atomSeparator = DEFAULT_ATOM_SEPARATOR; private AggregateRewritingConfig aggregateRewritingConfig = DEFAULT_AGGREGATE_REWRITING_CONFIG; - public String getGrounderName() { - return this.grounderName; - } - - /** - * Sets the name of the grounder implementation to use. - */ - public void setGrounderName(String grounderName) { - this.grounderName = grounderName; - } - public String getSolverName() { return this.solverName; } @@ -119,18 +104,6 @@ public void setNogoodStoreName(String nogoodStoreName) { this.nogoodStoreName = nogoodStoreName; } - public boolean isDeterministic() { - return this.deterministic; - } - - /** - * If set, 0 will be used as random seed for solver-internal branching heuristics, resulting in answer sets of the same program being found - * in a fixed sequence. - */ - public void setDeterministic(boolean deterministic) { - this.deterministic = deterministic; - } - public long getSeed() { return this.seed; } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java deleted file mode 100644 index 00d11f974..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java +++ /dev/null @@ -1,13 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.programs; - -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; - -/** - * A {@link Program} that conforms to Alphas implementation of the ASP-Core2-Standard. - * - * Copyright (c) 2021, the Alpha Team. - */ -public interface ASPCore2Program extends Program> { - -} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java new file mode 100644 index 000000000..c7be5bd2f --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java @@ -0,0 +1,9 @@ +package at.ac.tuwien.kr.alpha.api.programs; + +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; + +// TODO javadoc +public interface InputProgram extends Program> { + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java index 39f23cae8..d8195a9f6 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java @@ -9,40 +9,40 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; /** - * A parser for {@link ASPCore2Program}s. + * A parser for {@link InputProgram}s. * * Copyright (c) 2021, the Alpha Team. */ public interface ProgramParser { - default ASPCore2Program parse(String programString) { + default InputProgram parse(String programString) { return parse(programString, Collections.emptyMap()); } - default ASPCore2Program parse(InputStream programSource) throws IOException { + default InputProgram parse(InputStream programSource) throws IOException { return parse(programSource, Collections.emptyMap()); } - default ASPCore2Program parse(Path programPath) throws IOException { + default InputProgram parse(Path programPath) throws IOException { return parse(programPath, Collections.emptyMap()); } - default ASPCore2Program parse(Path... programSources) throws IOException { + default InputProgram parse(Path... programSources) throws IOException { return parse(Collections.emptyMap(), programSources); } - default ASPCore2Program parse(Iterable programSources) throws IOException { + default InputProgram parse(Iterable programSources) throws IOException { return parse(programSources, Collections.emptyMap()); } - ASPCore2Program parse(String programString, Map externalPredicateDefinitions); + InputProgram parse(String programString, Map externalPredicateDefinitions); - ASPCore2Program parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException; + InputProgram parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException; - ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions) throws IOException; + InputProgram parse(Path programPath, Map externalPredicateDefinitions) throws IOException; - ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources) throws IOException; + InputProgram parse(Map externalPredicateDefinitions, Path... programSources) throws IOException; - ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException; + InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException; } diff --git a/alpha-cli-app/build.gradle.kts b/alpha-cli-app/build.gradle.kts index a62227309..c96c15b31 100644 --- a/alpha-cli-app/build.gradle.kts +++ b/alpha-cli-app/build.gradle.kts @@ -69,5 +69,6 @@ tasks.create("bundledJar") { } tasks.test { + dependsOn(":alpha-solver:test") useJUnitPlatform() } diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java index 487e25099..4fd32e07e 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java @@ -50,8 +50,8 @@ import at.ac.tuwien.kr.alpha.api.config.AlphaConfig; import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; @@ -80,9 +80,9 @@ public static void main(String[] args) { Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); } - Alpha alpha = new AlphaImpl(cfg.getSystemConfig()); + Alpha alpha = AlphaFactory.newAlpha(cfg.getSystemConfig()); - ASPCore2Program program = null; + InputProgram program = null; try { program = alpha.readProgram(cfg.getInputConfig()); } catch (FileNotFoundException e) { diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java index 4b3ccf1f5..b8a27f880 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java @@ -90,16 +90,12 @@ public class CommandLineParser { .desc("Write answer sets to excel files, i.e. xlsx workbooks (one workbook per answer set)").build(); // general system-wide config - private static final Option OPT_GROUNDER = Option.builder("g").longOpt("grounder").hasArg(true).argName("grounder") - .desc("the grounder implementation to use (default: " + SystemConfig.DEFAULT_GROUNDER_NAME + ")").build(); private static final Option OPT_SOLVER = Option.builder("s").longOpt("solver").hasArg(true).argName("solver") .desc("the solver implementation to use (default: " + SystemConfig.DEFAULT_SOLVER_NAME + ")").build(); private static final Option OPT_NOGOOD_STORE = Option.builder("r").longOpt("store").hasArg(true).argName("store") .desc("the nogood store to use (default: " + SystemConfig.DEFAULT_NOGOOD_STORE_NAME + ")").build(); private static final Option OPT_SORT = Option.builder("sort").longOpt("sort").hasArg(false) .desc("sort answer sets (default: " + SystemConfig.DEFAULT_SORT_ANSWER_SETS + ")").build(); - private static final Option OPT_DETERMINISTIC = Option.builder("d").longOpt("deterministic").hasArg(false) - .desc("disables randomness (default: " + SystemConfig.DEFAULT_DETERMINISTIC + ")").build(); private static final Option OPT_SEED = Option.builder("e").longOpt("seed").hasArg(true).argName("seed").type(Integer.class) .desc("set seed (default: System.nanoTime())").build(); private static final Option OPT_DEBUG_INTERNAL_CHECKS = Option.builder("dbgs").longOpt("DebugEnableInternalChecks") @@ -167,11 +163,9 @@ public class CommandLineParser { CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_DEBUG_PREPROCESSING); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_XSLX); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_SOLVER); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NOGOOD_STORE); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_SORT); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_DETERMINISTIC); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_SEED); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_DEBUG_INTERNAL_CHECKS); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_BRANCHING_HEURISTIC); @@ -225,11 +219,9 @@ private void initializeGlobalOptionHandlers() { */ // help is handled separately, therefore dummy handler this.globalOptionHandlers.put(CommandLineParser.OPT_HELP.getOpt(), (o, c) -> { }); - this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER.getOpt(), this::handleGrounder); this.globalOptionHandlers.put(CommandLineParser.OPT_SOLVER.getOpt(), this::handleSolver); this.globalOptionHandlers.put(CommandLineParser.OPT_NOGOOD_STORE.getOpt(), this::handleNogoodStore); this.globalOptionHandlers.put(CommandLineParser.OPT_SORT.getOpt(), this::handleSort); - this.globalOptionHandlers.put(CommandLineParser.OPT_DETERMINISTIC.getOpt(), this::handleDeterministic); this.globalOptionHandlers.put(CommandLineParser.OPT_SEED.getOpt(), this::handleSeed); this.globalOptionHandlers.put(CommandLineParser.OPT_DEBUG_INTERNAL_CHECKS.getOpt(), this::handleInternalChecks); this.globalOptionHandlers.put(CommandLineParser.OPT_BRANCHING_HEURISTIC.getOpt(), this::handleBranchingHeuristic); @@ -335,10 +327,6 @@ private void handleInput(Option opt, InputConfig cfg) { cfg.getFiles().add(optVal); } - private void handleGrounder(Option opt, SystemConfig cfg) { - cfg.setGrounderName(opt.getValue(SystemConfig.DEFAULT_GROUNDER_NAME)); - } - private void handleSolver(Option opt, SystemConfig cfg) { cfg.setSolverName(opt.getValue(SystemConfig.DEFAULT_SOLVER_NAME)); } @@ -362,12 +350,10 @@ private void handleSort(Option opt, SystemConfig cfg) { } private void handleDeterministic(Option opt, SystemConfig cfg) { - cfg.setDeterministic(true); cfg.setSeed(0); } private void handleSeed(Option opt, SystemConfig cfg) { - cfg.setDeterministic(false); String optVal = opt.getValue(); long seed; if (optVal != null) { diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java index 97fec5bee..35ef774fc 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java @@ -49,10 +49,10 @@ public class MainTest { private static Stream provideCommandLineArguments() { return Stream.of( - Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-e", "1119654162577372", "-n", "20", "-str", INPUT}), - Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "0", "-str", INPUT}), - Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "1", "-str", INPUT}), - Arguments.of((Object) new String[]{"-g", "naive", "-s", "default", "-r", "naive", "-e", "1119654162577372", "--numAS", "1", "-str", INPUT})); + Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-s", "default", "-e", "1119654162577372", "-n", "20", "-str", INPUT}), + Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-s", "default", "-n", "0", "-str", INPUT}), + Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-s", "default", "-n", "1", "-str", INPUT}), + Arguments.of((Object) new String[]{"-s", "default", "-r", "naive", "-e", "1119654162577372", "--numAS", "1", "-str", INPUT})); } /** diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java index 39273cf20..23655f106 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; // TODO This is a functional test and should not be run with standard unit tests @@ -54,7 +54,7 @@ public void smokeTest() { "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + "n2 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); ComponentGraph compgraph = dbgResult.getComponentGraph(); ComponentGraphWriter writer = new ComponentGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java index 942da90a5..8d5929e80 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; // TODO This is a functional test and should not be run with standard unit tests @@ -51,7 +51,7 @@ public void smokeTest() { "n6 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + "n6 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); DependencyGraph depgraph = dbgResult.getDependencyGraph(); DependencyGraphWriter writer = new DependencyGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java index b528cd500..75a2d7cb6 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -47,7 +47,7 @@ public void solveAndWriteWorkbookTest() { + "p(N) :- p(I), N = I + 1, N <= MX, maxP(MX)." + "q(A, B) :- p(A), p(B)."; //@formatter:on - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); List answerSets = alpha.solve(alpha.readProgramString(progstr)).collect(Collectors.toList()); assertEquals(1, answerSets.size()); AnswerSet as = answerSets.get(0); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java index 1228c74b5..ad6f80701 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java @@ -35,22 +35,22 @@ import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; public final class GrounderFactory { - public static Grounder getInstance(String name, CompiledProgram program, AtomStore atomStore, java.util.function.Predicate filter, - GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { - switch (name.toLowerCase()) { - case "naive": - return new NaiveGrounder(program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, bridges); - } - throw new IllegalArgumentException("Unknown grounder requested."); + + private final GrounderHeuristicsConfiguration heuristicsConfig; + private final boolean enableDebugChecks; + + public GrounderFactory(GrounderHeuristicsConfiguration heuristicsConfig, boolean enabledDebugChecks) { + this.heuristicsConfig = heuristicsConfig; + this.enableDebugChecks = enabledDebugChecks; } - - public static Grounder getInstance(String name, CompiledProgram program, AtomStore atomStore, java.util.function.Predicate filter, - GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); + + public Grounder createGrounder(CompiledProgram program, AtomStore atomStore) { + return createGrounder(program, atomStore, InputConfig.DEFAULT_FILTER); } - public static Grounder getInstance(String name, CompiledProgram program, AtomStore atomStore, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, - new GrounderHeuristicsConfiguration(), debugInternalChecks); + // TODO eliminate this method, filter should never go this deep into core, can be applied on answer sets from top-level + public Grounder createGrounder(CompiledProgram program, AtomStore atomStore, java.util.function.Predicate filter) { + return new NaiveGrounder(program, atomStore, filter, heuristicsConfig, enableDebugChecks, new Bridge[] {}); } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java index 1e498d50d..4d695d6af 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java @@ -108,6 +108,10 @@ public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGr private final LiteralInstantiator ruleInstantiator; private final DefaultLazyGroundingInstantiationStrategy instantiationStrategy; + public NaiveGrounder(CompiledProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { + this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); + } + public NaiveGrounder(CompiledProgram program, AtomStore atomStore, boolean debugInternalChecks, Bridge... bridges) { this(program, atomStore, new GrounderHeuristicsConfiguration(), debugInternalChecks, bridges); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 1498a4f0c..3042a1183 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -46,6 +46,7 @@ import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -74,7 +75,7 @@ import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2BaseVisitor; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -84,7 +85,7 @@ public class ParseTreeVisitor extends ASPCore2BaseVisitor { private final Map externals; private final boolean acceptVariables; - private InputProgram.Builder programBuilder; + private InputProgramImpl.Builder programBuilder; private InlineDirectives inlineDirectives; public ParseTreeVisitor(Map externals) { @@ -160,10 +161,10 @@ public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { } if (ctx.statements() == null) { - return InputProgram.EMPTY; + return InputProgramImpl.EMPTY; } inlineDirectives = new InlineDirectivesImpl(); - programBuilder = InputProgram.builder(); + programBuilder = InputProgramImpl.builder(); visitStatements(ctx.statements()); programBuilder.addInlineDirectives(inlineDirectives); return programBuilder.build(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java index a0a71d8a5..e67cfaa4a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java @@ -17,12 +17,12 @@ import org.antlr.v4.runtime.misc.ParseCancellationException; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; public class ProgramParserImpl implements ProgramParser { @@ -38,12 +38,12 @@ public ProgramParserImpl(Map externals) { } @Override - public ASPCore2Program parse(String s) { + public InputProgram parse(String s) { return parse(s, Collections.emptyMap()); } @Override - public ASPCore2Program parse(String s, Map externals) { + public InputProgram parse(String s, Map externals) { try { return parse(CharStreams.fromString(s), externals); } catch (RecognitionException | ParseCancellationException e) { @@ -54,11 +54,11 @@ public ASPCore2Program parse(String s, Map exte } } - public ASPCore2Program parse(CharStream stream) { + public InputProgram parse(CharStream stream) { return parse(stream, Collections.emptyMap()); } - public ASPCore2Program parse(CharStream stream, Map externals) { + public InputProgram parse(CharStream stream, Map externals) { //@formatter:off /* * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. @@ -131,18 +131,18 @@ public ASPCore2Program parse(CharStream stream, Map externalPredicateDefinitions) throws IOException { + public InputProgram parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException { return parse(CharStreams.fromStream(programSource), externalPredicateDefinitions); } @Override - public ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions) throws IOException { + public InputProgram parse(Path programPath, Map externalPredicateDefinitions) throws IOException { return parse(CharStreams.fromPath(programPath), externalPredicateDefinitions); } @Override - public ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { - InputProgram.Builder bld = InputProgram.builder(); + public InputProgram parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { + InputProgramImpl.Builder bld = InputProgramImpl.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); } @@ -150,8 +150,8 @@ public ASPCore2Program parse(Map externalPredic } @Override - public ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { - InputProgram.Builder bld = InputProgram.builder(); + public InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { + InputProgramImpl.Builder bld = InputProgramImpl.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java similarity index 82% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java index e9ba20032..3ab39a124 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java @@ -31,7 +31,7 @@ import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.rules.Rule; @@ -43,15 +43,15 @@ *

* Copyright (c) 2017-2019, the Alpha Team. */ -public class InputProgram extends AbstractProgram> implements ASPCore2Program{ +public class InputProgramImpl extends AbstractProgram> implements InputProgram { - public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl()); + public static final InputProgramImpl EMPTY = new InputProgramImpl(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl()); - public InputProgram(List> rules, List facts, InlineDirectives inlineDirectives) { + public InputProgramImpl(List> rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } - public InputProgram() { + public InputProgramImpl() { super(new ArrayList<>(), new ArrayList<>(), new InlineDirectivesImpl()); } @@ -59,12 +59,12 @@ public static Builder builder() { return new Builder(); } - public static Builder builder(ASPCore2Program prog) { + public static Builder builder(InputProgram prog) { return new Builder(prog); } /** - * Builder for more complex program construction scenarios, ensuring that an {@link InputProgram} is immutable + * Builder for more complex program construction scenarios, ensuring that an {@link InputProgramImpl} is immutable */ public static class Builder { @@ -72,7 +72,7 @@ public static class Builder { private List facts = new ArrayList<>(); private InlineDirectives inlineDirectives = new InlineDirectivesImpl(); - public Builder(ASPCore2Program prog) { + public Builder(InputProgram prog) { this.addRules(prog.getRules()); this.addFacts(prog.getFacts()); this.addInlineDirectives(prog.getInlineDirectives()); @@ -107,12 +107,12 @@ public Builder addInlineDirectives(InlineDirectives inlineDirectives) { return this; } - public Builder accumulate(ASPCore2Program prog) { + public Builder accumulate(InputProgram prog) { return this.addRules(prog.getRules()).addFacts(prog.getFacts()).addInlineDirectives(prog.getInlineDirectives()); } public InputProgram build() { - return new InputProgram(this.rules, this.facts, this.inlineDirectives); + return new InputProgramImpl(this.rules, this.facts, this.inlineDirectives); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java index dc886e47a..ad65431e0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -23,7 +23,7 @@ public NormalProgramImpl(List rules, List facts, InlineDirecti super(rules, facts, inlineDirectives); } - public static NormalProgramImpl fromInputProgram(ASPCore2Program inputProgram) { + public static NormalProgramImpl fromInputProgram(InputProgram inputProgram) { List normalRules = new ArrayList<>(); for (Rule r : inputProgram.getRules()) { normalRules.add(NormalRuleImpl.fromBasicRule(r)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java index e467c657f..e3f184886 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java @@ -7,7 +7,7 @@ import org.antlr.v4.runtime.CharStreams; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; public class Programs { @@ -16,7 +16,7 @@ private Programs() { throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); } - public static ASPCore2Program fromInputStream(InputStream is, Map externals) throws IOException { + public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { ProgramParserImpl parser = new ProgramParserImpl(); return parser.parse(CharStreams.fromStream(is), externals); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java index f54778b8c..6c20981d0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java @@ -31,7 +31,7 @@ import java.util.Iterator; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -46,19 +46,19 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Copyright (c) 2017-2021, the Alpha Team. */ // TODO this could already give NormalProgram as result type -public class ChoiceHeadToNormal extends ProgramTransformation { +public class ChoiceHeadToNormal extends ProgramTransformation { private final static String PREDICATE_NEGATION_PREFIX = "_n"; @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { - InputProgram.Builder programBuilder = InputProgram.builder(); + public InputProgram apply(InputProgram inputProgram) { + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); List> additionalRules = new ArrayList<>(); List> srcRules = new ArrayList<>(inputProgram.getRules()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java index ca1c6a54a..f9498270e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java @@ -7,7 +7,7 @@ import java.util.LinkedList; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral; @@ -20,7 +20,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -30,10 +30,10 @@ * Copyright (c) 2017-2020, the Alpha Team. */ // TODO this should happen during/after internalization -public class EnumerationRewriting extends ProgramTransformation { +public class EnumerationRewriting extends ProgramTransformation { @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { + public InputProgram apply(InputProgram inputProgram) { // Read enumeration predicate from directive. String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectivesImpl.DIRECTIVE.enum_predicate_is); if (enumDirective == null) { @@ -42,7 +42,7 @@ public ASPCore2Program apply(ASPCore2Program inputProgram) { } Predicate enumPredicate = Predicates.getPredicate(enumDirective, 3); - InputProgram.Builder programBuilder = InputProgram.builder().addInlineDirectives(inputProgram.getInlineDirectives()); + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder().addInlineDirectives(inputProgram.getInlineDirectives()); checkFactsAreEnumerationFree(inputProgram.getFacts(), enumPredicate); programBuilder.addFacts(inputProgram.getFacts()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java index a2f503ec2..341c46eb1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java @@ -1,7 +1,8 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.api.config.AggregateRewritingConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import java.util.function.Supplier; + +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; @@ -12,23 +13,23 @@ * * Copyright (c) 2019-2021, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformation { +public class NormalizeProgramTransformation extends ProgramTransformation { - private final AggregateRewritingConfig aggregateRewritingCfg; + private final Supplier aggregateRewritingFactory; - public NormalizeProgramTransformation(AggregateRewritingConfig aggregateCfg) { - this.aggregateRewritingCfg = aggregateCfg; + public NormalizeProgramTransformation(Supplier aggregateRewritingFactory) { + this.aggregateRewritingFactory = aggregateRewritingFactory; } @Override - public NormalProgram apply(ASPCore2Program inputProgram) { - ASPCore2Program tmpPrg; + public NormalProgram apply(InputProgram inputProgram) { + InputProgram tmpPrg; // Remove variable equalities. tmpPrg = new VariableEqualityRemoval().apply(inputProgram); // Transform choice rules. tmpPrg = new ChoiceHeadToNormal().apply(tmpPrg); // Transform aggregates. - tmpPrg = new AggregateRewriting(aggregateRewritingCfg.isUseSortingGridEncoding(), aggregateRewritingCfg.isSupportNegativeValuesInSums()).apply(tmpPrg); + tmpPrg = aggregateRewritingFactory.get().apply(tmpPrg); // Transform enumeration atoms. tmpPrg = new EnumerationRewriting().apply(tmpPrg); EnumerationAtom.resetEnumerations(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index 6a71a1092..9deb24b06 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -15,7 +15,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -26,8 +26,8 @@ */ public class PredicateInternalizer { - public static ASPCore2Program makePrefixedPredicatesInternal(ASPCore2Program program, String prefix) { - InputProgram.Builder prgBuilder = InputProgram.builder(); + public static InputProgram makePrefixedPredicatesInternal(InputProgram program, String prefix) { + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); for (Atom atom : program.getFacts()) { if (atom.getPredicate().getName().startsWith(prefix)) { prgBuilder.addFact(PredicateInternalizer.makePredicateInternal((BasicAtom) atom)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 9dfc543e2..2c3105134 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -52,7 +52,7 @@ public class StratifiedEvaluation extends ProgramTransformation> modifiedInLastEvaluationRun = new HashMap<>(); - private List additionalFacts = new ArrayList<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. + private Set outputFacts = new HashSet<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. private Set solvedRuleIds = new HashSet<>(); // Set of rules that have been completely evaluated. private LiteralInstantiator literalInstantiator; @@ -82,6 +82,9 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { workingMemory.reset(); + // Set up set of facts to which we'll add everything derived during stratified evaluation. + outputFacts = new HashSet<>(inputProgram.getFacts()); + // Set up literal instantiator. literalInstantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); @@ -91,13 +94,12 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { } // Build the program resulting from evaluating the stratified part. - additionalFacts.addAll(inputProgram.getFacts()); // Add original input facts to newly derived ones. List outputRules = new ArrayList<>(); inputProgram.getRulesById().entrySet().stream().filter((entry) -> !solvedRuleIds.contains(entry.getKey())) .forEach((entry) -> outputRules.add(entry.getValue())); // NOTE: if InternalProgram requires solved rules, they should be added here. - return new InternalProgram(outputRules, additionalFacts); + return new InternalProgram(outputRules, new ArrayList<>(outputFacts)); } private void evaluateComponent(ComponentGraph.SCComponent comp) { @@ -114,9 +116,7 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { evaluateRules(evaluationInfo.nonRecursiveRules, true); for (IndexedInstanceStorage instanceStorage : workingMemory.modified()) { // Directly record all newly derived instances as additional facts. - for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { - additionalFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } + recordRecentlyAddedInstances(instanceStorage); instanceStorage.markRecentlyAddedInstancesDone(); } } @@ -134,9 +134,7 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { // Since we are stratified we never have to backtrack, therefore just collect the added instances. for (IndexedInstanceStorage instanceStorage : workingMemory.modified()) { // Directly record all newly derived instances as additional facts. - for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { - additionalFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } + recordRecentlyAddedInstances(instanceStorage); modifiedInLastEvaluationRun.putIfAbsent(instanceStorage.getPredicate(), new LinkedHashSet<>()); modifiedInLastEvaluationRun.get(instanceStorage.getPredicate()).addAll(instanceStorage.getRecentlyAddedInstances()); instanceStorage.markRecentlyAddedInstancesDone(); @@ -149,6 +147,12 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { .forEach((rule) -> solvedRuleIds.add(rule.getRuleId())); } + private void recordRecentlyAddedInstances(IndexedInstanceStorage instanceStorage) { + for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { + outputFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); + } + } + private void evaluateRules(Set rules, boolean isInitialRun) { workingMemory.reset(); LOGGER.debug("Starting component evaluation run..."); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 1e1ae53a3..11f361cd4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -37,7 +37,7 @@ import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -49,7 +49,7 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -57,15 +57,15 @@ * * Copyright (c) 2017-2021, the Alpha Team. */ -public class VariableEqualityRemoval extends ProgramTransformation { +public class VariableEqualityRemoval extends ProgramTransformation { @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { + public InputProgram apply(InputProgram inputProgram) { List> rewrittenRules = new ArrayList<>(); for (Rule rule : inputProgram.getRules()) { rewrittenRules.add(findAndReplaceVariableEquality(rule)); } - return new InputProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + return new InputProgramImpl(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); } private Rule findAndReplaceVariableEquality(Rule rule) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java index 10625da60..66d93a737 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java @@ -5,6 +5,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom; @@ -19,7 +20,6 @@ import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java index a810ee3db..da9352b3a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java @@ -8,7 +8,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AbstractAggregateEncoder; @@ -30,7 +30,7 @@ * * Copyright (c) 2020, the Alpha Team. */ -public class AggregateRewriting extends ProgramTransformation { +public class AggregateRewriting extends ProgramTransformation { private final AbstractAggregateEncoder countEqualsEncoder; private final AbstractAggregateEncoder countLessOrEqualEncoder; @@ -49,13 +49,14 @@ public class AggregateRewriting extends ProgramTransformation> outputRules = new ArrayList<>(); for (Rule inputRule : inputProgram.getRules()) { @@ -88,7 +89,7 @@ public ASPCore2Program apply(ASPCore2Program inputProgram) { } // Substitute AggregateLiterals with generated result literals. outputRules.addAll(rewriteRulesWithAggregates(ctx)); - InputProgram.Builder resultBuilder = InputProgram.builder().addRules(outputRules).addFacts(inputProgram.getFacts()) + InputProgramImpl.Builder resultBuilder = InputProgramImpl.builder().addRules(outputRules).addFacts(inputProgram.getFacts()) .addInlineDirectives(inputProgram.getInlineDirectives()); // Add sub-programs deriving respective aggregate literals. for (Map.Entry, Set> aggToRewrite : ctx.getAggregateFunctionsToRewrite() diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java index 1e257d30a..e609c3984 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java @@ -7,7 +7,7 @@ import org.apache.commons.collections4.ListUtils; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; @@ -22,7 +22,7 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.PredicateInternalizer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -51,8 +51,8 @@ protected AbstractAggregateEncoder(AggregateFunctionSymbol aggregateFunctionToEn * @param aggregatesToEncode the aggregates to encode. * @return all rules encoding the given aggregates as an {@link InputProgram}. */ - public ASPCore2Program encodeAggregateLiterals(Set aggregatesToEncode) { - InputProgram.Builder programBuilder = InputProgram.builder(); + public InputProgram encodeAggregateLiterals(Set aggregatesToEncode) { + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); for (AggregateInfo aggregateInfo : aggregatesToEncode) { programBuilder.accumulate(encodeAggregateLiteral(aggregateInfo)); } @@ -65,7 +65,7 @@ public ASPCore2Program encodeAggregateLiterals(Set aggregatesToEn * @param aggregateToEncode * @return */ - public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { + public InputProgram encodeAggregateLiteral(AggregateInfo aggregateToEncode) { AggregateLiteral literalToEncode = aggregateToEncode.getLiteral(); if (literalToEncode.getAtom().getAggregateFunction() != this.aggregateFunctionToEncode) { throw new IllegalArgumentException( @@ -76,13 +76,13 @@ public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { + literalToEncode.getAtom().getAggregateFunction() + " with operator " + literalToEncode.getAtom().getLowerBoundOperator()); } String aggregateId = aggregateToEncode.getId(); - ASPCore2Program literalEncoding = PredicateInternalizer.makePrefixedPredicatesInternal(encodeAggregateResult(aggregateToEncode), aggregateId); + InputProgram literalEncoding = PredicateInternalizer.makePrefixedPredicatesInternal(encodeAggregateResult(aggregateToEncode), aggregateId); List> elementEncodingRules = new ArrayList<>(); for (AggregateElement elementToEncode : literalToEncode.getAtom().getAggregateElements()) { Rule elementRule = encodeAggregateElement(aggregateToEncode, elementToEncode); elementEncodingRules.add(PredicateInternalizer.makePrefixedPredicatesInternal(elementRule, aggregateId)); } - return new InputProgram(ListUtils.union(literalEncoding.getRules(), elementEncodingRules), literalEncoding.getFacts(), new InlineDirectivesImpl()); + return new InputProgramImpl(ListUtils.union(literalEncoding.getRules(), elementEncodingRules), literalEncoding.getFacts(), new InlineDirectivesImpl()); } /** @@ -93,7 +93,7 @@ public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { * @param aggregateToEncode * @return */ - protected abstract ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode); + protected abstract InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode); /** * Encodes individual aggregate elements. For each aggregate element, a rule is created that fires for each tuple matching the element. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java new file mode 100644 index 000000000..cb3d1152a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java @@ -0,0 +1,44 @@ +package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; + +import java.util.function.Supplier; + +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; + +public class AggregateEncoderFactory { + + private final Supplier parserFactory; + private final boolean useSortingGridEncoding; + private final boolean supportNegativeSumElements; + + public AggregateEncoderFactory(Supplier parserFactory, boolean useSortingGridEncoding, boolean supportNegativeSumElements) { + this.parserFactory = parserFactory; + this.useSortingGridEncoding = useSortingGridEncoding; + this.supportNegativeSumElements = supportNegativeSumElements; + } + + public CountEncoder newCountEqualsEncoder() { + return CountEncoder.buildCountEqualsEncoder(parserFactory.get()); + } + + public CountEncoder newCountLessOrEqualEncoder() { + return CountEncoder.buildCountLessOrEqualEncoder(parserFactory.get(), useSortingGridEncoding); + } + + public SumEncoder newSumEqualsEncoder() { + return SumEncoder.buildSumEqualsEncoder(parserFactory.get(), supportNegativeSumElements); + } + + public SumEncoder newSumLessOrEqualEncoder() { + return SumEncoder.buildSumLessOrEqualEncoder(parserFactory.get(), supportNegativeSumElements); + } + + public MinMaxEncoder newMinEncoder() { + return new MinMaxEncoder(AggregateFunctionSymbol.MIN); + } + + public MinMaxEncoder newMaxEncoder() { + return new MinMaxEncoder(AggregateFunctionSymbol.MAX); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java index 0789c0330..be64efabd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java @@ -4,6 +4,7 @@ import org.stringtemplate.v4.STGroup; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.util.Util; @@ -16,17 +17,17 @@ public final class CountEncoder extends StringtemplateBasedAggregateEncoder { private static final ST CNT_LE_SORTING_GRID_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_le_sorting_grid"); private static final ST CNT_EQ_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_eq"); private static final ST CNT_LE_COUNTING_GRID_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_le_counting_grid"); - - private CountEncoder(ComparisonOperator acceptedOperator, ST encodingTemplate) { - super(AggregateFunctionSymbol.COUNT, acceptedOperator, encodingTemplate); + + private CountEncoder(ProgramParser parser, ComparisonOperator acceptedOperator, ST encodingTemplate) { + super(parser, AggregateFunctionSymbol.COUNT, acceptedOperator, encodingTemplate); } - public static CountEncoder buildCountLessOrEqualEncoder(boolean useSortingGrid) { - return new CountEncoder(ComparisonOperators.LE, useSortingGrid ? CNT_LE_SORTING_GRID_TEMPLATE : CNT_LE_COUNTING_GRID_TEMPLATE); + static CountEncoder buildCountLessOrEqualEncoder(ProgramParser parser, boolean useSortingGrid) { + return new CountEncoder(parser, ComparisonOperators.LE, useSortingGrid ? CNT_LE_SORTING_GRID_TEMPLATE : CNT_LE_COUNTING_GRID_TEMPLATE); } - public static CountEncoder buildCountEqualsEncoder() { - return new CountEncoder(ComparisonOperators.EQ, CNT_EQ_TEMPLATE); + static CountEncoder buildCountEqualsEncoder(ProgramParser parser) { + return new CountEncoder(parser, ComparisonOperators.EQ, CNT_EQ_TEMPLATE); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java index 8e007f78b..316d1ad5c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java @@ -7,7 +7,7 @@ import org.stringtemplate.v4.ST; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; @@ -27,7 +27,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -69,7 +69,7 @@ public MinMaxEncoder(AggregateFunctionSymbol func) { } @Override - protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) { + protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { ST encodingTemplate = null; if (this.getAggregateFunctionToEncode() == AggregateFunctionSymbol.MAX) { encodingTemplate = new ST(MAX_LITERAL_ENCODING); @@ -118,7 +118,7 @@ protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) resultRuleBody.add(aggregateResult); resultRuleBody.add(aggregateValueComparison); resultRuleBody.addAll(aggregateToEncode.getDependencies()); - InputProgram.Builder bld = InputProgram.builder(parser.parse(encodingTemplate.render())); + InputProgramImpl.Builder bld = InputProgramImpl.builder(parser.parse(encodingTemplate.render())); BasicRule resultRule = new BasicRule(resultRuleHead, resultRuleBody); bld.addRule(resultRule); return bld.build(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java index ad8a9c932..c025a6d55 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java @@ -7,7 +7,7 @@ import org.stringtemplate.v4.ST; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -19,8 +19,7 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationRewriting; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -37,13 +36,14 @@ */ public abstract class StringtemplateBasedAggregateEncoder extends AbstractAggregateEncoder { - private final ProgramParser parser = new ProgramParserImpl(); + private final ProgramParser parser; private final ST encodingTemplate; private final boolean needsBoundRule; - protected StringtemplateBasedAggregateEncoder(AggregateFunctionSymbol aggregateFunctionToEncode, ComparisonOperator acceptedOperator, ST encodingTemplate) { + protected StringtemplateBasedAggregateEncoder(ProgramParser parser, AggregateFunctionSymbol aggregateFunctionToEncode, ComparisonOperator acceptedOperator, ST encodingTemplate) { super(aggregateFunctionToEncode, Collections.singleton(acceptedOperator)); this.encodingTemplate = encodingTemplate; + this.parser = parser; if (acceptedOperator.equals(ComparisonOperators.EQ)) { this.needsBoundRule = false; } else if (acceptedOperator.equals(ComparisonOperators.LE)) { @@ -54,7 +54,7 @@ protected StringtemplateBasedAggregateEncoder(AggregateFunctionSymbol aggregateF } @Override - protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) { + protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { String aggregateId = aggregateToEncode.getId(); /* @@ -82,10 +82,10 @@ protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) String coreEncodingAsp = coreEncodingTemplate.render(); // Create the basic program - ASPCore2Program coreEncoding = new EnumerationRewriting().apply(parser.parse(coreEncodingAsp)); + InputProgram coreEncoding = new EnumerationRewriting().apply(parser.parse(coreEncodingAsp)); // Add the programatically created bound rule and return - return new InputProgram(ListUtils.union(coreEncoding.getRules(), Collections.singletonList(boundRule)), coreEncoding.getFacts(), + return new InputProgramImpl(ListUtils.union(coreEncoding.getRules(), Collections.singletonList(boundRule)), coreEncoding.getFacts(), new InlineDirectivesImpl()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java index 0a12b8752..95d9737a3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java @@ -5,6 +5,7 @@ import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -32,16 +33,16 @@ public final class SumEncoder extends StringtemplateBasedAggregateEncoder { private static final ST NON_NEG_ELEMENTS_SUM_LE_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("sum_le_no_negative_elements"); private static final ST NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("sum_eq_no_negative_elements"); - private SumEncoder(ComparisonOperator acceptedOperator, ST encodingTemplate) { - super(AggregateFunctionSymbol.SUM, acceptedOperator, encodingTemplate); + private SumEncoder(ProgramParser parser, ComparisonOperator acceptedOperator, ST encodingTemplate) { + super(parser, AggregateFunctionSymbol.SUM, acceptedOperator, encodingTemplate); } - public static SumEncoder buildSumLessOrEqualEncoder(boolean supportNegativeIntegers) { - return new SumEncoder(ComparisonOperators.LE, supportNegativeIntegers ? SUM_LE_TEMPLATE : NON_NEG_ELEMENTS_SUM_LE_TEMPLATE); + public static SumEncoder buildSumLessOrEqualEncoder(ProgramParser parser, boolean supportNegativeIntegers) { + return new SumEncoder(parser, ComparisonOperators.LE, supportNegativeIntegers ? SUM_LE_TEMPLATE : NON_NEG_ELEMENTS_SUM_LE_TEMPLATE); } - public static SumEncoder buildSumEqualsEncoder(boolean supportNegativeIntegers) { - return new SumEncoder(ComparisonOperators.EQ, supportNegativeIntegers ? SUM_EQ_TEMPLATE : NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE); + public static SumEncoder buildSumEqualsEncoder(ProgramParser parser, boolean supportNegativeIntegers) { + return new SumEncoder(parser, ComparisonOperators.EQ, supportNegativeIntegers ? SUM_EQ_TEMPLATE : NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE); } /** @@ -56,4 +57,4 @@ protected BasicAtom buildElementRuleHead(String aggregateId, AggregateElement el return Atoms.newBasicAtom(headPredicate, aggregateArguments, elementTuple, element.getElementTerms().get(0)); } -} \ No newline at end of file +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java index 50d78db70..dad66bc2d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java @@ -1,5 +1,6 @@ package at.ac.tuwien.kr.alpha.core.rules; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; @@ -47,6 +48,10 @@ public AbstractRule(H head, List body) { + "Notice: A rule is considered safe if all variables occurring in negative literals, builtin atoms, and the head of the rule also occur in some positive literal."); } } + + public AbstractRule(H head, Set body) { + this(head, new ArrayList<>(body)); + } /** * Checks whether a rule is safe. The actual safety condition may vary over the next improvements. Currently, a rule is diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java index c75bdcbc9..5283a6a6d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -24,6 +25,10 @@ public NormalRuleImpl(NormalHead head, List body) { super(head, body); } + public NormalRuleImpl(NormalHead head, Set body) { + super(head, body); + } + public static NormalRuleImpl fromBasicRule(Rule rule) { BasicAtom headAtom = null; if (!rule.isConstraint()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java index b6d952e23..b66ff1e01 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java @@ -51,7 +51,6 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.StatisticsReportingSolver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -103,17 +102,17 @@ private static class SearchState { private final PerformanceLog performanceLog; - public DefaultSolver(AtomStore atomStore, Grounder grounder, NoGoodStore store, WritableAssignment assignment, Random random, SystemConfig config, HeuristicsConfiguration heuristicsConfiguration) { + public DefaultSolver(SolverConfig cfg, AtomStore atomStore, Grounder grounder, NoGoodStore store, WritableAssignment assignment) { super(atomStore, grounder); this.assignment = assignment; this.store = store; this.choiceManager = new ChoiceManager(assignment, store); - this.choiceManager.setChecksEnabled(config.isDebugInternalChecks()); + this.choiceManager.setChecksEnabled(cfg.isEnableDebugChecks()); this.learner = new GroundConflictNoGoodLearner(assignment, atomStore); - this.branchingHeuristic = chainFallbackHeuristic(grounder, assignment, random, heuristicsConfiguration); - this.disableJustifications = config.isDisableJustificationSearch(); - this.disableNoGoodDeletion = config.isDisableNoGoodDeletion(); + this.branchingHeuristic = chainFallbackHeuristic(grounder, assignment, new Random(cfg.getRandomSeed()), cfg.getHeuristicsConfiguration()); + this.disableJustifications = cfg.isDisableJustifications(); + this.disableNoGoodDeletion = cfg.isDisableNogoodDeletion(); this.performanceLog = new PerformanceLog(choiceManager, (TrailAssignment) assignment, 1000); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverConfig.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverConfig.java new file mode 100644 index 000000000..7af9920ea --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverConfig.java @@ -0,0 +1,53 @@ +package at.ac.tuwien.kr.alpha.core.solver; + +import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; + +public class SolverConfig { + + private boolean enableDebugChecks; + private boolean disableJustifications; + private boolean disableNogoodDeletion; + private HeuristicsConfiguration heuristicsConfiguration; + private long randomSeed; + + public boolean isEnableDebugChecks() { + return this.enableDebugChecks; + } + + public void setEnableDebugChecks(boolean enableDebugChecks) { + this.enableDebugChecks = enableDebugChecks; + } + + public boolean isDisableJustifications() { + return this.disableJustifications; + } + + public void setDisableJustifications(boolean disableJustifications) { + this.disableJustifications = disableJustifications; + } + + public boolean isDisableNogoodDeletion() { + return this.disableNogoodDeletion; + } + + public void setDisableNogoodDeletion(boolean disableNogoodDeletion) { + this.disableNogoodDeletion = disableNogoodDeletion; + } + + public HeuristicsConfiguration getHeuristicsConfiguration() { + return this.heuristicsConfiguration; + } + + public void setHeuristicsConfiguration(HeuristicsConfiguration heuristicsConfiguration) { + this.heuristicsConfiguration = heuristicsConfiguration; + } + + public long getRandomSeed() { + return this.randomSeed; + } + + public void setRandomSeed(long randomSeed) { + this.randomSeed = randomSeed; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java index e6af12d0a..4d3df1154 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016-2017, the Alpha Team. + * Copyright (c) 2016-2021, the Alpha Team. * All rights reserved. * * Additional changes made by Siemens. @@ -28,23 +28,27 @@ package at.ac.tuwien.kr.alpha.core.solver; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfigurationBuilder; - -import java.util.Random; public final class SolverFactory { - - public static Solver getInstance(SystemConfig config, AtomStore atomStore, Grounder grounder) { - final String solverName = config.getSolverName(); - final String nogoodStoreName = config.getNogoodStoreName(); - final Random random = new Random(config.getSeed()); - final boolean debugInternalChecks = config.isDebugInternalChecks(); - final HeuristicsConfiguration heuristicsConfiguration = buildHeuristicsConfiguration(config); - final WritableAssignment assignment = new TrailAssignment(atomStore, debugInternalChecks); + + private final String solverName; + private final String nogoodStoreName; + private final SolverConfig solverConfig; + + public SolverFactory(String solverName, String noGoodStoreName, SolverConfig solverConfig) { + this.solverName = solverName; + this.nogoodStoreName = noGoodStoreName; + this.solverConfig = solverConfig; + } + + public Solver createSolver(Grounder grounder, AtomStore atomStore) { + return SolverFactory.createSolver(solverName, nogoodStoreName, solverConfig, atomStore, grounder); + } + + private static Solver createSolver(String solverName, String nogoodStoreName, SolverConfig solverConfig, AtomStore atomStore, Grounder grounder) { + final WritableAssignment assignment = new TrailAssignment(atomStore, solverConfig.isEnableDebugChecks()); NoGoodStore store; @@ -53,26 +57,19 @@ public static Solver getInstance(SystemConfig config, AtomStore atomStore, Groun store = new NaiveNoGoodStore(assignment); break; case "alpharoaming": - store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); + store = new NoGoodStoreAlphaRoaming(assignment, solverConfig.isEnableDebugChecks()); break; default: throw new IllegalArgumentException("Unknown store requested."); } switch (solverName.toLowerCase()) { - case "naive" : + case "naive": return new NaiveSolver(atomStore, grounder); case "default": - return new DefaultSolver(atomStore, grounder, store, assignment, random, config, heuristicsConfiguration); + return new DefaultSolver(solverConfig, atomStore, grounder, store, assignment); } throw new IllegalArgumentException("Unknown solver requested."); } - private static HeuristicsConfiguration buildHeuristicsConfiguration(SystemConfig config) { - HeuristicsConfigurationBuilder heuristicsConfigurationBuilder = HeuristicsConfiguration.builder(); - heuristicsConfigurationBuilder.setHeuristic(config.getBranchingHeuristic()); - heuristicsConfigurationBuilder.setMomsStrategy(config.getMomsStrategy()); - heuristicsConfigurationBuilder.setReplayChoices(config.getReplayChoices()); - return heuristicsConfigurationBuilder.build(); - } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java index 0bd692dda..0557fe2c4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.rules.Rule; @@ -41,14 +41,14 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.literals.Literals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.Rules; public class ProgramTest { @Test public void testToString() { - ASPCore2Program program; + InputProgram program; // rule := q(X) :- p(X). List body = new ArrayList<>(); body.add(Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newVariable("X")), true)); @@ -59,7 +59,7 @@ public void testToString() { facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a"))); facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("b"))); // program := p(a). p(b). q(X) :- p(X). - program = InputProgram.builder().addFacts(facts).addRule(rule).build(); + program = InputProgramImpl.builder().addFacts(facts).addRule(rule).build(); assertEquals( "p(a)." + System.lineSeparator() + "p(b)." + System.lineSeparator() + diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 33cdef134..f8346e33a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -44,7 +44,7 @@ import org.antlr.v4.runtime.CharStreams; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -69,7 +69,7 @@ public class ParserTest { @Test public void parseFact() { - ASPCore2Program parsedProgram = parser.parse("p(a,b)."); + InputProgram parsedProgram = parser.parse("p(a,b)."); assertEquals(1, parsedProgram.getFacts().size(), "Program contains one fact."); assertEquals("p", parsedProgram.getFacts().get(0).getPredicate().getName(), "Predicate name of fact is p."); @@ -80,7 +80,7 @@ public void parseFact() { @Test public void parseFactWithFunctionTerms() { - ASPCore2Program parsedProgram = parser.parse("p(f(a),g(h(Y)))."); + InputProgram parsedProgram = parser.parse("p(f(a),g(h(Y)))."); assertEquals(1, parsedProgram.getFacts().size(), "Program contains one fact."); assertEquals("p", parsedProgram.getFacts().get(0).getPredicate().getName(), "Predicate name of fact is p."); @@ -91,7 +91,7 @@ public void parseFactWithFunctionTerms() { @Test public void parseSmallProgram() { - ASPCore2Program parsedProgram = parser.parse( + InputProgram parsedProgram = parser.parse( "a :- b, not d." + System.lineSeparator() + "c(X) :- p(X,a,_), q(Xaa,xaa)." + System.lineSeparator() + ":- f(Y)."); @@ -108,7 +108,7 @@ public void parseBadSyntax() { @Test public void parseBuiltinAtom() { - ASPCore2Program parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); + InputProgram parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); assertEquals(1, parsedProgram.getRules().size()); assertEquals(3, parsedProgram.getRules().get(0).getBody().size()); } @@ -123,7 +123,7 @@ public void parseProgramWithDisjunctionInHead() { @Test public void parseInterval() { - ASPCore2Program parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); + InputProgram parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); IntervalTerm factInterval = (IntervalTerm) parsedProgram.getFacts().get(0).getTerms().get(0); assertTrue(factInterval.equals(IntervalTerm.getInstance(Terms.newConstant(2), Terms.newConstant(5)))); IntervalTerm bodyInterval = (IntervalTerm) parsedProgram.getRules().get(0).getBody().stream().findFirst().get().getTerms().get(1); @@ -132,7 +132,7 @@ public void parseInterval() { @Test public void parseChoiceRule() { - ASPCore2Program parsedProgram = parser.parse("dom(1). dom(2). { a ; b } :- dom(X)."); + InputProgram parsedProgram = parser.parse("dom(1). dom(2). { a ; b } :- dom(X)."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); @@ -143,7 +143,7 @@ public void parseChoiceRule() { @Test public void parseChoiceRuleBounded() { - ASPCore2Program parsedProgram = parser.parse("dom(1). dom(2). 1 < { a: p(v,w), not r; b } <= 13 :- dom(X). foo."); + InputProgram parsedProgram = parser.parse("dom(1). dom(2). 1 < { a: p(v,w), not r; b } <= 13 :- dom(X). foo."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); @@ -193,7 +193,7 @@ public void testMissingDotNotIgnored() { @Test public void parseEnumerationDirective() { - ASPCore2Program parsedProgram = parser.parse("p(a,1)." + + InputProgram parsedProgram = parser.parse("p(a,1)." + "# enumeration_predicate_is mune." + "r(X) :- p(X), mune(X)." + "p(b,2)."); @@ -203,7 +203,7 @@ public void parseEnumerationDirective() { @Test public void cardinalityAggregate() { - ASPCore2Program parsedProgram = parser.parse("num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K)."); + InputProgram parsedProgram = parser.parse("num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K)."); Optional optionalBodyElement = parsedProgram.getRules().get(0).getBody().stream().filter((lit) -> lit instanceof AggregateLiteral).findFirst(); assertTrue(optionalBodyElement.isPresent()); Literal bodyElement = optionalBodyElement.get(); @@ -222,7 +222,7 @@ public void cardinalityAggregate() { @Test public void stringWithEscapedQuotes() throws IOException { CharStream stream = CharStreams.fromStream(ParserTest.class.getResourceAsStream("/escaped_quotes.asp")); - ASPCore2Program prog = parser.parse(stream); + InputProgram prog = parser.parse(stream); assertEquals(1, prog.getFacts().size()); Atom stringAtom = prog.getFacts().get(0); String stringWithQuotes = stringAtom.getTerms().get(0).toString(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index cbc92ed2c..d008dd21b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -12,7 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.externals.Externals; @@ -45,11 +45,11 @@ private static String readTestResource(String resource) throws IOException { } private , O extends Program> void genericTransformationTest(ProgramTransformation transform, - Function prepareFunc, String resourceSet) { + Function prepareFunc, String resourceSet) { try { String inputCode = ProgramTransformationTest.readTestResource(resourceSet + ".in"); String expectedResult = ProgramTransformationTest.readTestResource(resourceSet + ".out"); - ASPCore2Program inputProg = PARSER.parse(inputCode, Externals.scan(ProgramTransformationTest.class)); + InputProgram inputProg = PARSER.parse(inputCode, Externals.scan(ProgramTransformationTest.class)); I transformInput = prepareFunc.apply(inputProg); String beforeTransformProg = transformInput.toString(); O transformedProg = transform.apply(transformInput); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java deleted file mode 100644 index 3c492d095..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java +++ /dev/null @@ -1,263 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; - -// TODO This is a functional test and should not be run with standard unit tests -public class StratifiedEvaluationRegressionTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluationRegressionTest.class); - - private static final String STRATIFIED_NEG_ASP = "base(X) :- req(X), not incomp(X).\n" - + "depend_base(X, Y) :- base(X), base(Y).\n" - + "dep_b_hlp(X) :- depend_base(X, _).\n" - + "fallback_base(X) :- base(X), not dep_b_hlp(X).\n" - + "depend_further(X) :- depend_base(_, X).\n" - + "depend_further(X) :- fallback_base(X)."; - - private static final String BASIC_TEST_ASP = "a. b:- a."; - private static final String BASIC_MULTI_INSTANCE_ASP = "p(a). p(b). q(X) :- p(X)."; - private static final String BASIC_NEGATION_ASP = "p(a). q(b). p(c). q(d). r(c). s(X, Y) :- p(X), q(Y), not r(X)."; - private static final String PART_STRATIFIED_ASP = "p(a). q(a). p(b). m(c). n(d).\n" + "r(X) :- p(X), q(X).\n" + "s(X, Y, Z) :- r(X), m(Y), n(Z).\n" - + "t(X, Y) :- p(X), q(X), p(Y), not q(Y).\n" + "either(X) :- t(X, _), not or(X).\n" + "or(X) :- t(X, _), not either(X)."; - private static final String POSITIVE_RECURSION_ASP = "num(0).\n" + "max_num(10).\n" + "num(S) :- num(N), S = N + 1, S <= M, max_num(M)."; - private static final String EMPTY_PROG_ASP = ""; - private static final String FACTS_ONLY_ASP = "a. b. c. p(a). q(b, c). r(c, c, a). s(b)."; - private static final String STRATIFIED_NO_FACTS_ASP = STRATIFIED_NEG_ASP; - private static final String STRATIFIED_W_FACTS_ASP = "req(a). req(b). incomp(b).\n" + STRATIFIED_NEG_ASP; - private static final String EQUALITY_ASP = "equal :- 1 = 1."; - private static final String EQUALITY_WITH_VAR_ASP = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; - - private static final ImmutablePair, Consumer>> BASIC_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasic, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasic); - private static final ImmutablePair, Consumer>> BASIC_MULTI_INSTANCE_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasicMultiInstance, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicMultiInstance); - private static final ImmutablePair, Consumer>> BASIC_NEGATION_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasicNegation, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicNegation); - private static final ImmutablePair, Consumer>> PART_STRATIFIED_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramPartStratified, StratifiedEvaluationRegressionTest::verifyAnswerSetsPartStratified); - private static final ImmutablePair, Consumer>> POSITIVE_RECURSIVE_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramPositiveRecursive, StratifiedEvaluationRegressionTest::verifyAnswerSetsPositiveRecursive); - private static final ImmutablePair, Consumer>> EMPTY_PROG_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEmptyProg, StratifiedEvaluationRegressionTest::verifyAnswerSetsEmptyProg); - private static final ImmutablePair, Consumer>> FACTS_ONLY_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramFactsOnly, StratifiedEvaluationRegressionTest::verifyAnswerSetsFactsOnly); - private static final ImmutablePair, Consumer>> STRATIFIED_NO_FACTS_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramStratNoFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratNoFacts); - private static final ImmutablePair, Consumer>> STRATIFIED_W_FACTS_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramStratWithFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratWithFacts); - private static final ImmutablePair, Consumer>> EQUALITY_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEquality, StratifiedEvaluationRegressionTest::verifyAnswerSetsEquality); - private static final ImmutablePair, Consumer>> EQUALITY_WITH_VAR_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEqualityWithVar, StratifiedEvaluationRegressionTest::verifyAnswerSetsEqualityWithVar); - - public static List params() { - List, Consumer>>>> testCases = new ArrayList<>(); - List paramList = new ArrayList<>(); - testCases.add(new ImmutablePair<>(BASIC_TEST_ASP, BASIC_VERIFIERS)); - testCases.add(new ImmutablePair<>(BASIC_MULTI_INSTANCE_ASP, BASIC_MULTI_INSTANCE_VERIFIERS)); - testCases.add(new ImmutablePair<>(BASIC_NEGATION_ASP, BASIC_NEGATION_VERIFIERS)); - testCases.add(new ImmutablePair<>(PART_STRATIFIED_ASP, PART_STRATIFIED_VERIFIERS)); - testCases.add(new ImmutablePair<>(POSITIVE_RECURSION_ASP, POSITIVE_RECURSIVE_VERIFIERS)); - testCases.add(new ImmutablePair<>(EMPTY_PROG_ASP, EMPTY_PROG_VERIFIERS)); - testCases.add(new ImmutablePair<>(FACTS_ONLY_ASP, FACTS_ONLY_VERIFIERS)); - testCases.add(new ImmutablePair<>(STRATIFIED_NO_FACTS_ASP, STRATIFIED_NO_FACTS_VERIFIERS)); - testCases.add(new ImmutablePair<>(STRATIFIED_W_FACTS_ASP, STRATIFIED_W_FACTS_VERIFIERS)); - testCases.add(new ImmutablePair<>(EQUALITY_ASP, EQUALITY_VERIFIERS)); - testCases.add(new ImmutablePair<>(EQUALITY_WITH_VAR_ASP, EQUALITY_WITH_VAR_VERIFIERS)); - - testCases.forEach((pair) -> paramList.add(Arguments.of(pair.left, pair.right.left, pair.right.right))); - return paramList; - } - - @ParameterizedTest - @MethodSource("at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluationRegressionTest#params") - public void runTest(String aspString, Consumer programVerifier, Consumer> resultVerifier) { - // Parse and pre-evaulate program - ProgramParser parser = new ProgramParserImpl(); - ASPCore2Program prog = parser.parse(aspString); - AnalyzedProgram analyzed = AnalyzedProgram - .analyzeNormalProgram(new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG).apply(prog)); - CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); - // Verify stratified evaluation result - programVerifier.accept(evaluated); - // Solve remaining program - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", evaluated, atomStore, false); - Solver solver = SolverFactory.getInstance(new SystemConfig(), atomStore, grounder); - Set answerSets = solver.collectSet(); - resultVerifier.accept(answerSets); - } - - private static void verifyProgramBasic(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("a"), TestUtils.basicAtomWithSymbolicTerms("b")); - assertEquals(2, evaluated.getFacts().size()); - assertTrue(evaluated.getRules().size() == 0); - } - - private static void verifyAnswerSetsBasic(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a, b", answerSets); - } - - private static void verifyProgramBasicMultiInstance(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("q", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "b")); - assertTrue(evaluated.getRules().size() == 0); - } - - private static void verifyAnswerSetsBasicMultiInstance(Set answerSets) { - TestUtils.assertAnswerSetsEqual("p(a), p(b), q(a), q(b)", answerSets); - } - - private static void verifyProgramBasicNegation(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("s", "a", "b"), - TestUtils.basicAtomWithSymbolicTerms("s", "a", "d")); - assertEquals(7, evaluated.getFacts().size()); - assertEquals(0, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsBasicNegation(Set answerSets) { - TestUtils.assertAnswerSetsEqual("p(a), q(b), p(c), q(d), r(c), s(a,b), s(a,d)", answerSets); - } - - private static void verifyProgramPartStratified(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("p", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "a"), - TestUtils.basicAtomWithSymbolicTerms("p", "b"), - TestUtils.basicAtomWithSymbolicTerms("m", "c"), TestUtils.basicAtomWithSymbolicTerms("n", "d"), TestUtils.basicAtomWithSymbolicTerms("r", "a"), - TestUtils.basicAtomWithSymbolicTerms("s", "a", "c", "d"), - TestUtils.basicAtomWithSymbolicTerms("t", "a", "b")); - LOGGER.debug("part stratified evaluated prog is:\n{}", evaluated.toString()); - assertEquals(2, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsPartStratified(Set answerSets) { - TestUtils.assertAnswerSetsEqual(new String[] {"p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), either(a)", - "p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), or(a)" }, answerSets); - } - - private static void verifyProgramPositiveRecursive(CompiledProgram evaluated) { - Predicate num = Predicates.getPredicate("num", 1); - TestUtils.assertFactsContainedInProgram(evaluated, Atoms.newBasicAtom(Predicates.getPredicate("max_num", 1), Terms.newConstant(10)), - Atoms.newBasicAtom(num, Terms.newConstant(0)), - Atoms.newBasicAtom(num, Terms.newConstant(1)), Atoms.newBasicAtom(num, Terms.newConstant(2)), - Atoms.newBasicAtom(num, Terms.newConstant(3)), Atoms.newBasicAtom(num, Terms.newConstant(4)), - Atoms.newBasicAtom(num, Terms.newConstant(5)), Atoms.newBasicAtom(num, Terms.newConstant(6)), - Atoms.newBasicAtom(num, Terms.newConstant(7)), Atoms.newBasicAtom(num, Terms.newConstant(8)), - Atoms.newBasicAtom(num, Terms.newConstant(9)), Atoms.newBasicAtom(num, Terms.newConstant(10))); - LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); - assertEquals(0, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsPositiveRecursive(Set answerSets) { - TestUtils.assertAnswerSetsEqual("max_num(10), num(0), num(1), num(2), num(3), num(4), num(5), num(6), num(7), num(8), num(9), num(10)", answerSets); - } - - private static void verifyProgramEmptyProg(CompiledProgram evaluated) { - assertTrue(evaluated.getRules().isEmpty()); - assertTrue(evaluated.getRulesById().isEmpty()); - assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - assertTrue(evaluated.getFacts().isEmpty()); - assertTrue(evaluated.getFactsByPredicate().isEmpty()); - } - - private static void verifyAnswerSetsEmptyProg(Set answerSets) { - assertEquals(1, answerSets.size()); - assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramFactsOnly(CompiledProgram evaluated) { - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("b"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("c"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("p", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "b", "c"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("r", "c", "c", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("s", "b"))); - } - - private static void verifyAnswerSetsFactsOnly(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a, b, c, p(a), q(b,c), r(c,c,a), s(b)", answerSets); - } - - private static void verifyProgramStratNoFacts(CompiledProgram evaluated) { - assertTrue(evaluated.getFacts().isEmpty()); - } - - private static void verifyAnswerSetsStratNoFacts(Set answerSets) { - assertEquals(1, answerSets.size()); - assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramStratWithFacts(CompiledProgram evaluated) { - // rules should all be taken care of at this point - assertTrue(evaluated.getRules().isEmpty()); - assertTrue(evaluated.getRulesById().isEmpty()); - assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - - // facts should be the full answer set - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "b"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("incomp", "b"))); - - // below facts from stratified evaluation - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("base", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_base", "a", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("dep_b_hlp", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_further", "a"))); - } - - private static void verifyAnswerSetsStratWithFacts(Set answerSets) { - TestUtils.assertAnswerSetsEqual("req(a), req(b), incomp(b), base(a), depend_base(a,a), dep_b_hlp(a), depend_further(a)", answerSets); - } - - private static void verifyProgramEquality(CompiledProgram evaluated) { - assertEquals(0, evaluated.getRules().size()); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("equal"))); - } - - private static void verifyAnswerSetsEquality(Set answerSets) { - TestUtils.assertAnswerSetsEqual("equal", answerSets); - } - - private static void verifyProgramEqualityWithVar(CompiledProgram evaluated) { - assertEquals(0, evaluated.getRules().size()); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newConstant(1)))); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newConstant(2)))); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newConstant(3)))); - } - - private static void verifyAnswerSetsEqualityWithVar(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java deleted file mode 100644 index 4d2aab5af..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.solver; - -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSet; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSetsWithBase; - -/** - * Tests ASP programs containing arithmetic terms at arbitrary positions. - * - * Copyright (c) 2020, the Alpha Team. - */ -// TODO This is a functional test and should not be run with standard unit tests -public class ArithmeticTermsTest { - - @RegressionTest - public void testArithmeticTermInHead(RegressionTestConfig cfg) { - String program = "dom(1). dom(2)." - + "p(X+3) :- dom(X)."; - assertRegressionTestAnswerSet(cfg, program, "dom(1),dom(2),p(4),p(5)"); - } - - @RegressionTest - public void testArithmeticTermInRule(RegressionTestConfig cfg) { - String program = "dom(1). dom(2)." - + "p(Y+4) :- dom(X+1), dom(X), Y=X, X=Y."; - assertRegressionTestAnswerSet(cfg, program, "dom(1),dom(2),p(5)"); - } - - @RegressionTest - public void testArithmeticTermInChoiceRule(RegressionTestConfig cfg) { - String program = "cycle_max(4). cycle(1)." + - "{ cycle(N+1) } :- cycle(N), cycle_max(K), N collectRegressionTestAnswerSets(ASPCore2Program prog, RegressionTestConfig cfg) { - return buildSolverForRegressionTest(prog, cfg).collectSet(); - } - - public static Set collectRegressionTestAnswerSets(String aspstr, RegressionTestConfig cfg) { - ASPCore2Program prog = new ProgramParserImpl().parse(aspstr); - return collectRegressionTestAnswerSets(prog, cfg); - } - - public static void assertRegressionTestAnswerSet(RegressionTestConfig cfg, String program, String answerSet) { - Set actualAnswerSets = collectRegressionTestAnswerSets(program, cfg); - TestUtils.assertAnswerSetsEqual(answerSet, actualAnswerSets); - } - - public static void assertRegressionTestAnswerSets(RegressionTestConfig cfg, String program, String... answerSets) { - Set actualAnswerSets = collectRegressionTestAnswerSets(program, cfg); - TestUtils.assertAnswerSetsEqual(answerSets, actualAnswerSets); - } - - public static void assertRegressionTestAnswerSetsWithBase(RegressionTestConfig cfg, String program, String base, String... answerSets) { - Set actualAnswerSets = collectRegressionTestAnswerSets(program, cfg); - TestUtils.assertAnswerSetsEqualWithBase(base, answerSets, actualAnswerSets); - } - - public static void runWithTimeout(RegressionTestConfig cfg, long baseTimeout, long timeoutFactor, Executable action) { - long timeout = cfg.isDebugChecks() ? timeoutFactor * baseTimeout : baseTimeout; - assertTimeoutPreemptively(Duration.ofMillis(timeout), action); - } - - public static void ignoreTestForNaiveSolver(RegressionTestConfig cfg) { - Assumptions.assumeFalse(cfg.getSolverName().equals("naive")); - } - - public static void ignoreTestForNonDefaultDomainIndependentHeuristics(RegressionTestConfig cfg) { - Assumptions.assumeTrue(cfg.getBranchingHeuristic() == Heuristic.VSIDS); - } - - public static void ignoreTestForSimplifiedSumAggregates(RegressionTestConfig cfg) { - Assumptions.assumeTrue(cfg.isSupportNegativeSumElements()); - } - } diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java new file mode 100644 index 000000000..7de3ef84d --- /dev/null +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java @@ -0,0 +1,75 @@ +package at.ac.tuwien.kr.alpha.test; + + +import static java.util.Collections.emptySet; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.StringJoiner; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.programs.Program; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; + +public class AlphaAssertions { + + public static void assertAnswerSetsEqual(Set expected, Set actual) { + if (expected == null) { + if (actual != null) { + throw new AssertionError("Expected answer sets are null, but actual are not!"); + } + } + try { + assertEquals(expected, actual); + } catch (AssertionError e) { + Set expectedMinusActual = new LinkedHashSet<>(expected); + expectedMinusActual.removeAll(actual); + Set actualMinusExpected = new LinkedHashSet<>(actual); + actualMinusExpected.removeAll(expected); + String setDiffs = "Expected and actual answer sets do not agree, differences are:\nExpected \\ Actual:\n" + expectedMinusActual + + "\nActual \\ Expected:\n" + actualMinusExpected; + throw new AssertionError(setDiffs + e.getMessage(), e); + } + } + + public static void assertAnswerSetsEqual(String[] expected, Set actual) { + if (expected.length == 0) { + assertAnswerSetsEqual(emptySet(), actual); + return; + } + StringJoiner joiner = new StringJoiner("} {", "{", "}"); + Arrays.stream(expected).forEach(joiner::add); + assertAnswerSetsEqual(AnswerSetsParser.parse(joiner.toString()), actual); + } + + public static void assertAnswerSetsEqual(String expectedAnswerSet, Set actual) { + assertAnswerSetsEqual(AnswerSetsParser.parse("{ " + expectedAnswerSet + " }"), actual); + } + + public static void assertAnswerSetsEqualWithBase(String base, String[] expectedAnswerSets, Set actual) { + base = base.trim(); + if (!base.endsWith(",")) { + base += ", "; + } + + for (int i = 0; i < expectedAnswerSets.length; i++) { + expectedAnswerSets[i] = base + expectedAnswerSets[i]; + // Remove trailing ",". + expectedAnswerSets[i] = expectedAnswerSets[i].trim(); + if (expectedAnswerSets[i].endsWith(",")) { + expectedAnswerSets[i] = expectedAnswerSets[i].substring(0, expectedAnswerSets[i].length() - 1); + } + } + assertAnswerSetsEqual(expectedAnswerSets, actual); + } + + public static void assertFactsContainedInProgram(Program prog, Atom... facts) { + for (Atom fact : facts) { + assertTrue(prog.getFacts().contains(fact)); + } + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/AnswerSetsParser.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/AnswerSetsParser.java rename to alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java index b78ebc20c..c98e29f3a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/AnswerSetsParser.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.test.util; +package at.ac.tuwien.kr.alpha.test; import java.util.Collections; import java.util.Set; diff --git a/alpha-core/benchmarks/omiga/omiga-testcases.tar.gz b/alpha-solver/benchmarks/omiga/omiga-testcases.tar.gz similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases.tar.gz rename to alpha-solver/benchmarks/omiga/omiga-testcases.tar.gz diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-1.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-1.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-1.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-1.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-4.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-4.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-4.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-4.txt diff --git a/alpha-core/benchmarks/siemens/racks/racks.lp b/alpha-solver/benchmarks/siemens/racks/racks.lp similarity index 100% rename from alpha-core/benchmarks/siemens/racks/racks.lp rename to alpha-solver/benchmarks/siemens/racks/racks.lp diff --git a/alpha-solver/build.gradle.kts b/alpha-solver/build.gradle.kts index b0c59c197..aff85c7cc 100644 --- a/alpha-solver/build.gradle.kts +++ b/alpha-solver/build.gradle.kts @@ -6,6 +6,8 @@ dependencies { api(project(":alpha-api")) api(project(":alpha-commons")) implementation(project(":alpha-core")) + + testImplementation(testFixtures(project(":alpha-core"))) } tasks.test { diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java new file mode 100644 index 000000000..9a3093255 --- /dev/null +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -0,0 +1,77 @@ +package at.ac.tuwien.kr.alpha.api.impl; + +import java.util.function.Supplier; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewriting; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AggregateEncoderFactory; +import at.ac.tuwien.kr.alpha.core.solver.SolverConfig; +import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; + +public final class AlphaFactory { + + private AlphaFactory() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static Alpha newAlpha(SystemConfig cfg) { + Supplier parserFactory = () -> new ProgramParserImpl(); + + // AggregateEncoderFactory depends on parser factory since stringtemplate-based aggregate encoders need to use the same parser that's used + // for input programs. + AggregateEncoderFactory aggregateEncoderFactory = new AggregateEncoderFactory(parserFactory, + cfg.getAggregateRewritingConfig().isUseSortingGridEncoding(), cfg.getAggregateRewritingConfig().isSupportNegativeValuesInSums()); + + // Factory for aggregate rewriting (depends on encoders provided by above factory). + Supplier aggregateRewritingFactory = () -> new AggregateRewriting(aggregateEncoderFactory.newCountEqualsEncoder(), + aggregateEncoderFactory.newCountLessOrEqualEncoder(), aggregateEncoderFactory.newSumEqualsEncoder(), + aggregateEncoderFactory.newSumLessOrEqualEncoder(), aggregateEncoderFactory.newMinEncoder(), aggregateEncoderFactory.newMaxEncoder()); + + // Factory for NormalizeProgramTransformation - needs a supplier for AggregateRewriting due to AggregateRewritings' dependency to encoder + // factory. + Supplier> programNormalizationFactory = () -> new NormalizeProgramTransformation( + aggregateRewritingFactory); + + // GrounderFactory - Since every grounder instance is only good for one program instance, we need a factory. + GrounderHeuristicsConfiguration grounderHeuristicsCfg = GrounderHeuristicsConfiguration.getInstance(cfg.getGrounderToleranceConstraints(), + cfg.getGrounderToleranceRules()); + grounderHeuristicsCfg.setAccumulatorEnabled(cfg.isGrounderAccumulatorEnabled()); + GrounderFactory grounderFactory = new GrounderFactory( + grounderHeuristicsCfg, + cfg.isDebugInternalChecks()); + + // SolverFactory - Same as for GrounderFactory, we need a new Solver for each program. + SolverConfig solverCfg = new SolverConfig(); + solverCfg.setDisableJustifications(cfg.isDisableJustificationSearch()); + solverCfg.setDisableNogoodDeletion(cfg.isDisableNoGoodDeletion()); + solverCfg.setEnableDebugChecks(cfg.isDebugInternalChecks()); + solverCfg.setRandomSeed(cfg.getSeed()); + solverCfg.setHeuristicsConfiguration( + HeuristicsConfiguration.builder() + .setHeuristic(cfg.getBranchingHeuristic()) + .setMomsStrategy(cfg.getMomsStrategy()) + .setReplayChoices(cfg.getReplayChoices()) + .build()); + SolverFactory solverFactory = new SolverFactory(cfg.getSolverName(), cfg.getNogoodStoreName(), solverCfg); + + // Now that all dependencies are taken care of, build new Alpha instance. + return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, cfg.isEvaluateStratifiedPart(), + cfg.isSortAnswerSets()); + } + + // Create Alpha instance with default config. + public static Alpha newAlpha() { + return newAlpha(new SystemConfig()); + } + +} diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index c49a5ca39..934ce13bd 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -36,24 +36,23 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.common.annotations.VisibleForTesting; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; - import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.config.InputConfig; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; @@ -64,12 +63,11 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; @@ -77,20 +75,31 @@ public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); - private SystemConfig config = new SystemConfig(); // Config is initialized with default values. - private ProgramParser parser = new ProgramParserImpl(); - - public AlphaImpl(SystemConfig cfg) { - this.config = cfg; - } - - public AlphaImpl() { + private final Supplier parserFactory; + private final Supplier> programNormalizationFactory; + + private final GrounderFactory grounderFactory; + private final SolverFactory solverFactory; + + private final boolean enableStratifiedEvaluation; + private final boolean sortAnswerSets; + + AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, + GrounderFactory grounderFactory, + SolverFactory solverFactory, + boolean enableStratifiedEvaluation, boolean sortAnswerSets) { + this.parserFactory = parserFactory; + this.programNormalizationFactory = programNormalizationFactory; + this.grounderFactory = grounderFactory; + this.solverFactory = solverFactory; + this.enableStratifiedEvaluation = enableStratifiedEvaluation; + this.sortAnswerSets = sortAnswerSets; } @Override - public ASPCore2Program readProgram(InputConfig cfg) throws IOException { - InputProgram.Builder prgBuilder = InputProgram.builder(); - ASPCore2Program tmpProg; + public InputProgram readProgram(InputConfig cfg) throws IOException { + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); + InputProgram tmpProg; if (!cfg.getFiles().isEmpty()) { tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); prgBuilder.accumulate(tmpProg); @@ -103,14 +112,16 @@ public ASPCore2Program readProgram(InputConfig cfg) throws IOException { } @Override - public ASPCore2Program readProgramFiles(boolean literate, Map externals, List paths) throws IOException { + public InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException { return readProgramFiles(literate, externals, paths.stream().map(Paths::get).collect(Collectors.toList()).toArray(new Path[] {})); } @Override - public ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - InputProgram.Builder prgBuilder = InputProgram.builder(); - ASPCore2Program tmpProg; + @SuppressWarnings("resource") + public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { + ProgramParser parser = parserFactory.get(); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); + InputProgram tmpProg; for (Path path : paths) { InputStream stream; if (!literate) { @@ -125,25 +136,25 @@ public ASPCore2Program readProgramFiles(boolean literate, Map externals) { - return parser.parse(aspString, externals); + public InputProgram readProgramString(String aspString, Map externals) { + return parserFactory.get().parse(aspString, externals); } @Override - public ASPCore2Program readProgramString(String aspString) { + public InputProgram readProgramString(String aspString) { return readProgramString(aspString, Collections.emptyMap()); } @Override - public NormalProgram normalizeProgram(ASPCore2Program program) { - return new NormalizeProgramTransformation(config.getAggregateRewritingConfig()).apply(program); + public NormalProgram normalizeProgram(InputProgram program) { + return programNormalizationFactory.get().apply(program); } @VisibleForTesting InternalProgram performProgramPreprocessing(NormalProgram program) { LOGGER.debug("Preprocessing InternalProgram!"); InternalProgram retVal = InternalProgram.fromNormalProgram(program); - if (config.isEvaluateStratifiedPart()) { + if (enableStratifiedEvaluation) { AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); retVal = new StratifiedEvaluation().apply(analyzed); } @@ -155,7 +166,7 @@ InternalProgram performProgramPreprocessing(NormalProgram program) { * program analysis and normalization aren't of interest. */ @Override - public Stream solve(ASPCore2Program program) { + public Stream solve(InputProgram program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -164,7 +175,7 @@ public Stream solve(ASPCore2Program program) { * details of the program analysis and normalization aren't of interest. */ @Override - public Stream solve(ASPCore2Program program, java.util.function.Predicate filter) { + public Stream solve(InputProgram program, java.util.function.Predicate filter) { NormalProgram normalized = normalizeProgram(program); return solve(normalized, filter); } @@ -193,7 +204,7 @@ public Stream solve(NormalProgram program, java.util.function.Predica */ private Stream solve(CompiledProgram program, java.util.function.Predicate filter) { Stream retVal = prepareSolverFor(program, filter).stream(); - return config.isSortAnswerSets() ? retVal.sorted() : retVal; + return sortAnswerSets ? retVal.sorted() : retVal; } /** @@ -206,35 +217,23 @@ private Stream solve(CompiledProgram program, java.util.function.Pred * @return a solver (and accompanying grounder) instance pre-loaded with the given program. */ private Solver prepareSolverFor(CompiledProgram program, java.util.function.Predicate filter) { - String grounderName = config.getGrounderName(); - boolean doDebugChecks = config.isDebugInternalChecks(); - - GrounderHeuristicsConfiguration grounderHeuristicConfiguration = GrounderHeuristicsConfiguration - .getInstance(config.getGrounderToleranceConstraints(), config.getGrounderToleranceRules()); - grounderHeuristicConfiguration.setAccumulatorEnabled(config.isGrounderAccumulatorEnabled()); - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance(grounderName, program, atomStore, filter, grounderHeuristicConfiguration, doDebugChecks); - - return SolverFactory.getInstance(config, atomStore, grounder); - } - - public void setConfig(SystemConfig config) { - this.config = config; + Grounder grounder = grounderFactory.createGrounder(program, atomStore, filter); + return solverFactory.createSolver(grounder, atomStore); } @Override - public DebugSolvingContext prepareDebugSolve(ASPCore2Program program) { + public DebugSolvingContext prepareDebugSolve(InputProgram program) { return prepareDebugSolve(program, InputConfig.DEFAULT_FILTER); } @Override public DebugSolvingContext prepareDebugSolve(NormalProgram program) { return prepareDebugSolve(program, InputConfig.DEFAULT_FILTER); - } - + } + @Override - public DebugSolvingContext prepareDebugSolve(final ASPCore2Program program, java.util.function.Predicate filter) { + public DebugSolvingContext prepareDebugSolve(final InputProgram program, java.util.function.Predicate filter) { return prepareDebugSolve(normalizeProgram(program), filter); } @@ -244,7 +243,7 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final ComponentGraph compGraph; final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; - if (this.config.isEvaluateStratifiedPart()) { + if (enableStratifiedEvaluation) { preprocessed = new StratifiedEvaluation().apply(analyzed).toNormalProgram(); } else { preprocessed = program; @@ -253,27 +252,27 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u compGraph = analyzed.getComponentGraph(); final Solver solver = prepareSolverFor(analyzed, filter); return new DebugSolvingContext() { - + @Override public Solver getSolver() { return solver; } - + @Override public NormalProgram getPreprocessedProgram() { return preprocessed; } - + @Override public NormalProgram getNormalizedProgram() { return program; } - + @Override public DependencyGraph getDependencyGraph() { return depGraph; } - + @Override public ComponentGraph getComponentGraph() { return compGraph; @@ -282,7 +281,7 @@ public ComponentGraph getComponentGraph() { } @Override - public Solver prepareSolverFor(ASPCore2Program program, java.util.function.Predicate filter) { + public Solver prepareSolverFor(InputProgram program, java.util.function.Predicate filter) { return prepareSolverFor(normalizeProgram(program), filter); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java similarity index 81% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java index e7dc1543f..df015f477 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java @@ -1,49 +1,27 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import java.util.function.Function; +import java.util.stream.Collectors; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; // TODO This is a functional test and should not be run with standard unit tests public class AggregateRewritingTest { - private static final ProgramParser PARSER = new ProgramParserImpl(); - private static final Function> NORMALIZE_AND_SOLVE = (str) -> { - SystemConfig cfg = new SystemConfig(); - ASPCore2Program prog = PARSER.parse(str); - NormalProgram normalized = new NormalizeProgramTransformation(cfg.getAggregateRewritingConfig()).apply(prog); - CompiledProgram compiled = InternalProgram.fromNormalProgram(normalized); - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", compiled, atomStore, cfg.isDebugInternalChecks()); - Solver solver = SolverFactory.getInstance(cfg, atomStore, grounder); - return solver.collectList(); - }; - //@formatter:off // Smoke-test case for "X <= #count{...}" aggregate private static final String CNT_LE1_ASP = @@ -100,9 +78,16 @@ public class AggregateRewritingTest { + " Y = #count { X : p( X ) }, 1 <= #count { X : p( X ) }, Z = #max { W : p( W ) }."; //@formatter:on + // Use an alpha instance with default config for all test cases + private final Alpha alpha = AlphaFactory.newAlpha(); + private final Function> solve = (asp) -> { + InputProgram prog = alpha.readProgramString(asp); + return alpha.solve(prog).collect(Collectors.toList()); + }; + @Test public void countLeSortingGridSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_LE1_ASP); + List answerSets = solve.apply(CNT_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -124,7 +109,7 @@ public void countLeSortingGridSimple() { @Test public void countEqSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_EQ1_ASP); + List answerSets = solve.apply(CNT_EQ1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -142,7 +127,7 @@ public void countEqSimple() { @Test public void countLeCountingGridSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_LE1_ASP); + List answerSets = solve.apply(CNT_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -164,7 +149,7 @@ public void countLeCountingGridSimple() { @Test public void countEqGlobalVars() { - List answerSets = NORMALIZE_AND_SOLVE.apply(VERTEX_DEGREE_ASP); + List answerSets = solve.apply(VERTEX_DEGREE_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate vertexDegree = Predicates.getPredicate("graph_vertex_degree", 3); @@ -183,7 +168,7 @@ public void countEqGlobalVars() { @Test // Test "count eq" and "max eq" together with global vars public void graphVerticesOfMaxDegree() { - List answerSets = NORMALIZE_AND_SOLVE.apply(NUM_MAX_DEGREE_VERTICES_ASP); + List answerSets = solve.apply(NUM_MAX_DEGREE_VERTICES_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate maxDegreeVertices = Predicates.getPredicate("graph_max_degree_vertices", 3); @@ -197,7 +182,7 @@ public void graphVerticesOfMaxDegree() { @Test public void greaterMin() { - List answerSets = NORMALIZE_AND_SOLVE.apply(MIN_GT1_ASP); + List answerSets = solve.apply(MIN_GT1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate greaterMin = Predicates.getPredicate("greater_min_acceptable", 1); @@ -211,7 +196,7 @@ public void greaterMin() { @Test public void sumEquals1() { - List answerSets = NORMALIZE_AND_SOLVE.apply(SUM_EQ1_ASP); + List answerSets = solve.apply(SUM_EQ1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate sumThings = Predicates.getPredicate("sum_things", 1); @@ -225,7 +210,7 @@ public void sumEquals1() { @Test public void sumLessOrEqual1() { - List answerSets = NORMALIZE_AND_SOLVE.apply(SUM_LE1_ASP); + List answerSets = solve.apply(SUM_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate boundLe = Predicates.getPredicate("bound_le_sum", 1); @@ -239,7 +224,7 @@ public void sumLessOrEqual1() { @Test @Disabled("Open issue, as dependency analysis includes cyclic output-dependency, which it should not.") public void setComplexEqualityWithGlobals() { - List answerSets = NORMALIZE_AND_SOLVE.apply(COMPLEX_EQUALITY_WITH_GLOBALS); + List answerSets = solve.apply(COMPLEX_EQUALITY_WITH_GLOBALS); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate q = Predicates.getPredicate("q", 0); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java similarity index 59% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java index ac7c30ec4..1a53a980f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java @@ -25,72 +25,57 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.programs.transformation; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; + import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; +import java.util.stream.Collectors; import org.junit.jupiter.api.Test; +import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.externals.Externals; -import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.programs.Programs; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; -// TODO This is a functional test and should not be run with standard unit tests +// TODO This is an integration test and should be run in an extra suite public class StratifiedEvaluationTest { - private final ProgramParser parser = new ProgramParserImpl(); - private final NormalizeProgramTransformation normalizer = new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - private final StratifiedEvaluation evaluator = new StratifiedEvaluation(); - private final Function parseAndEvaluate = (str) -> { - return evaluator.apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parser.parse(str)))); - }; - - private final Function> solveCompiledProg = (prog) -> { - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, false); - Solver solver = SolverFactory.getInstance(new SystemConfig(), atomStore, grounder); - return solver.collectSet(); - }; + // Alpha instance with default configuration (evolog support and stratified evaluation enabled) + private final Alpha alpha = AlphaFactory.newAlpha(); + /** + * Verifies that facts are not duplicated by stratified evaluation. + */ @Test public void testDuplicateFacts() { String aspStr = "p(a). p(b). q(b). q(X) :- p(X)."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Instance qOfB = new Instance(TestUtils.basicAtomWithSymbolicTerms("q", "b").getTerms()); - Set facts = evaluated.getFactsByPredicate().get(Predicates.getPredicate("q", 1)); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(aspStr)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + BasicAtom qOfB = Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("b")); int numQOfB = 0; - for (Instance at : facts) { - if (at.equals(qOfB)) { + for (Atom fact : evaluated.getFacts()) { + if (fact.equals(qOfB)) { numQOfB++; } } @@ -100,41 +85,38 @@ public void testDuplicateFacts() { @Test public void testEqualityWithConstantTerms() { String aspStr = "equal :- 1 = 1."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Atom equal = TestUtils.basicAtomWithSymbolicTerms("equal"); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(aspStr)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + Atom equal = Atoms.newBasicAtom(Predicates.getPredicate("equal", 0)); assertTrue(evaluated.getFacts().contains(equal)); } @Test public void testEqualityWithVarTerms() { String aspStr = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(aspStr)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); } @Test public void testNonGroundableRule() { String asp = "p(a). q(a, b). s(X, Y) :- p(X), q(X, Y), r(Y)."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("p(a), q(a,b)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("p(a), q(a,b)", answerSets); } @Test public void testCountAggregate() { String asp = "a. b :- 1 <= #count { 1 : a }."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a, b", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a, b", answerSets); } @Test public void testIntervalFact() { String asp = "a(1..3)."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); } @Test @@ -143,18 +125,18 @@ public void testAggregateSpecial() { + "{ chosenThing(X) : thing(X) }.\n" + "chosenSomething :- chosenThing(X).\n" + ":- not chosenSomething.\n" + ":- chosenThing(X), chosenThing(Y), X != Y.\n" + "allThings :- 3 <= #count{ X : thing(X)}. \n" + "chosenMaxThing :- allThings, chosenThing(3).\n" + ":- not chosenMaxThing."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("allThings"))); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("allThings, thing(1), thing(2), thing(3), chosenMaxThing, chosenSomething, chosenThing(3)", answerSets); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(asp)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("allThings", 0)))); + Set answerSets = dbgInfo.getSolver().collectSet(); + assertAnswerSetsEqual("allThings, thing(1), thing(2), thing(3), chosenMaxThing, chosenSomething, chosenThing(3)", answerSets); } @Test public void testNegatedFixedInterpretationLiteral() { String asp = "stuff(1). stuff(2). smallStuff(X) :- stuff(X), not X > 1."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); } @SuppressWarnings("unused") @@ -168,11 +150,8 @@ public void testNegatedExternalLiteral() throws Exception { String asp = "claimedTruth(bla). truth(X) :- claimedTruth(X), &sayTrue[X]. lie(X) :- claimedTruth(X), not &sayTrue[X]."; Map externals = new HashMap<>(); externals.put("sayTrue", Externals.processPredicateMethod(this.getClass().getMethod("sayTrue", Object.class))); - ProgramParser parserWithExternals = new ProgramParserImpl(); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parserWithExternals.parse(asp, externals))); - CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp, externals)).collect(Collectors.toSet()); + assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); } /** @@ -181,8 +160,11 @@ public void testNegatedExternalLiteral() throws Exception { */ @Test public void testPartnerUnitsProblemTopologicalOrder() throws IOException { - ASPCore2Program prg = parser.parse(StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp")); - CompiledProgram evaluated = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prg))); + InputProgram prg = Programs.fromInputStream( + StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp"), + new HashMap<>()); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(prg); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); assertTrue(evaluated.getRules().isEmpty(), "Not all rules eliminated by stratified evaluation"); assertEquals(57, evaluated.getFacts().size()); } @@ -202,19 +184,25 @@ public void testNegatedLiteralInRecursiveRule() throws IOException { + "inc_value(4), inc_value(5), inc_value(6), inc_value(7), " + "inc_value(8)"; //@formatter:on - ASPCore2Program prog = Programs.fromInputStream( + InputProgram prog = Programs.fromInputStream( StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), new HashMap<>()); // Run stratified evaluation and solve - CompiledProgram inputStratEval = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prog))); - Set asStrat = solveCompiledProg.apply(inputStratEval); - TestUtils.assertAnswerSetsEqual(expectedAnswerSet, asStrat); + SystemConfig cfgWithStratEval = new SystemConfig(); + cfgWithStratEval.setEvaluateStratifiedPart(true); + Alpha alphaStratEval = AlphaFactory.newAlpha(cfgWithStratEval); + DebugSolvingContext dbgWithStratEval = alphaStratEval.prepareDebugSolve(prog); + Set asStrat = dbgWithStratEval.getSolver().collectSet(); + assertAnswerSetsEqual(expectedAnswerSet, asStrat); // Solve without stratified evaluation - CompiledProgram inputNoStratEval = InternalProgram.fromNormalProgram(normalizer.apply(prog)); - Set as = solveCompiledProg.apply(inputNoStratEval); - TestUtils.assertAnswerSetsEqual(expectedAnswerSet, as); + SystemConfig cfgNoStratEval = new SystemConfig(); + cfgNoStratEval.setEvaluateStratifiedPart(false); + Alpha alphaNoStratEval = AlphaFactory.newAlpha(cfgNoStratEval); + DebugSolvingContext dbgNoStratEval = alphaNoStratEval.prepareDebugSolve(prog); + Set as = dbgNoStratEval.getSolver().collectSet(); + assertAnswerSetsEqual(expectedAnswerSet, as); } @Test @@ -246,7 +234,8 @@ public void testRecursiveRanking() { " thing_rank(Y, K),\n" + " R = K + 1."; //@formatter:on - CompiledProgram evaluated = parseAndEvaluate.apply(asp); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(asp)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); Predicate rank = Predicates.getPredicate("thing_rank", 2); BasicAtom rank1 = Atoms.newBasicAtom(rank, Terms.newSymbolicConstant("a"), Terms.newConstant(1)); BasicAtom rank2 = Atoms.newBasicAtom(rank, Terms.newSymbolicConstant("b"), Terms.newConstant(2)); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java index 92b41c9d8..d98e6a4f4 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; @@ -60,7 +60,7 @@ public class AggregateRewritingContextTest { //@formatter:on private static final AggregateRewritingContext rewritingContextForAspString(String asp) { - ASPCore2Program program = new ProgramParserImpl().parse(asp); + InputProgram program = new ProgramParserImpl().parse(asp); AggregateRewritingContext ctx = new AggregateRewritingContext(); for (Rule rule : program.getRules()) { ctx.registerRule(rule); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 9eba7a24f..96907fad6 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -60,7 +60,7 @@ import at.ac.tuwien.kr.alpha.api.config.Heuristic; import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -77,8 +77,9 @@ import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; // TODO This is a functional test and should not be run with standard unit tests public class AlphaImplTest { @@ -134,10 +135,10 @@ public static boolean thinger(Thingy thingy) { @Test public void withExternal() throws Exception { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isOne[1]."); inputCfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program program = alpha.readProgram(inputCfg); + InputProgram program = alpha.readProgram(inputCfg); Set actual = alpha.solve(program).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); assertEquals(expected, actual); @@ -145,11 +146,11 @@ public void withExternal() throws Exception { @Test public void addsFacts() { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Thingy a = new Thingy(); Thingy b = new Thingy(); List things = asList(a, b); - InputProgram program = InputProgram.builder().addFacts(Externals.asFacts(Thingy.class, things)).build(); + InputProgram program = InputProgramImpl.builder().addFacts(Externals.asFacts(Thingy.class, things)).build(); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("thingy").instance(a).instance(b).build())); assertEquals(expected, actual); @@ -158,7 +159,7 @@ public void addsFacts() { @Test public void withExternalTypeConflict() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isFoo[\"adsfnfdsf\"]."); inputCfg.addPredicateMethod("isFoo", Externals.processPredicateMethod(this.getClass().getMethod("isFoo", Integer.class))); Set actual = system.solve(system.readProgram(inputCfg)).collect(Collectors.toSet()); @@ -169,10 +170,10 @@ public void withExternalTypeConflict() { @Test public void smallGraph() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). node(3). a :- &connected[1,2]."); inputCfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); - ASPCore2Program program = system.readProgram(inputCfg); + InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); @@ -181,12 +182,12 @@ public void smallGraph() throws Exception { @Test public void filterOutput() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); inputCfg.addPredicateMethod("getLargeGraphEdges", Externals.processPredicate(() -> new HashSet<>(asList(asList(Terms.newConstant(1), Terms.newConstant(2)), asList(Terms.newConstant(2), Terms.newConstant(1)), asList(Terms.newConstant(13), Terms.newConstant(1)))))); - ASPCore2Program program = system.readProgram(inputCfg); + InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ node(1), node(2), outgoing13(1) }"); assertEquals(expected, actual); @@ -194,10 +195,10 @@ public void filterOutput() throws Exception { @Test public void supplier() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicate(() -> singleton(singletonList(Terms.newConstant(1))))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ node(1), a }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -211,10 +212,10 @@ public static Set>> bestNode() { @Test public void noInput() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicateMethod(this.getClass().getMethod("bestNode"))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ node(1), a }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -224,10 +225,10 @@ public void noInput() throws Exception { @Test public void smallGraphWithWrongType() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &connected[\"hello\",2]."); cfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); system.solve(prog).collect(Collectors.toSet()); }); @@ -250,10 +251,10 @@ public static Set>> coolNode(int node) { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphNoNeighbors() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("noNeighbors(2) :- not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ noNeighbors(2) }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -262,10 +263,10 @@ public void smallGraphNoNeighbors() throws Exception { @Test public void smallGraphCoolNode() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1..2). in(X) :- node(X), &coolNode[X]."); cfg.addPredicateMethod("coolNode", Externals.processPredicateMethod(this.getClass().getMethod("coolNode", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ in(1), node(1), node(2) }"); @@ -274,10 +275,10 @@ public void smallGraphCoolNode() throws Exception { @Test public void smallGraphSingleNeighbor() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1..3). in(1,X) :- &neighbors[1](X), node(X)."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ in(1,2), in(1,3), node(1), node(2), node(3) }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -287,10 +288,10 @@ public void smallGraphSingleNeighbor() throws Exception { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphSingleNeighborNoTerm() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("success :- &neighbors[1], not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ success }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -307,6 +308,22 @@ public String toString() { public int compareTo(Thingy o) { return 0; } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!(o instanceof Thingy)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return 1; + } } private static class SubThingy extends Thingy { @@ -322,9 +339,9 @@ public void withExternalSubtype() throws Exception { new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true))); - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); - InputProgram prog = new InputProgram(singletonList(rule), emptyList(), new InlineDirectivesImpl()); + InputProgram prog = new InputProgramImpl(singletonList(rule), emptyList(), new InlineDirectivesImpl()); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("x").build())); @@ -333,10 +350,10 @@ public void withExternalSubtype() throws Exception { @Test public void withExternalViaAnnotation() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1]."); cfg.addPredicateMethods(Externals.scan(this.getClass())); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); @@ -359,10 +376,10 @@ public void errorDuplicateExternal() { @Test public void withNativeExternal() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isTwo[2]."); cfg.addPredicateMethod("isTwo", Externals.processPredicate((Integer t) -> t == 2)); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); @@ -372,10 +389,10 @@ public void withNativeExternal() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted1() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], &isOne[1]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -390,10 +407,10 @@ public void withExternalInvocationCounted1() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted2() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a. b :- &isOne[1], &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -408,10 +425,10 @@ public void withExternalInvocationCounted2() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted3() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], not &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -426,8 +443,8 @@ public void withExternalInvocationCounted3() throws Exception { @Test @SuppressWarnings("unchecked") public void programWithExternalStringStuff() throws IOException { - Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); + Alpha alpha = AlphaFactory.newAlpha(); + InputProgram prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); // Verify every result string has length 6 and contains "foo" for (AnswerSet as : answerSets) { @@ -442,8 +459,8 @@ public void programWithExternalStringStuff() throws IOException { @Test @SuppressWarnings("unchecked") public void withNegatedExternal() throws IOException { - Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); + Alpha alpha = AlphaFactory.newAlpha(); + InputProgram prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); assertEquals(31, answerSets.size()); // Verify every result string has length 6 and contains "foo" @@ -459,7 +476,7 @@ public void withNegatedExternal() throws IOException { @Test public void basicUsage() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(a)."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").symbolicInstance("a").build())); assertEquals(expected, actual); @@ -467,7 +484,7 @@ public void basicUsage() throws Exception { @Test public void basicUsageWithString() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(\"a\")."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("a").build())); assertEquals(expected, actual); @@ -479,8 +496,8 @@ public void basicUsageWithString() throws Exception { @Test public void filterTest() { String progstr = "a. b. c. d :- c. e(a, b) :- d."; - Alpha system = new AlphaImpl(); - ASPCore2Program prog = system.readProgramString(progstr); + Alpha system = AlphaFactory.newAlpha(); + InputProgram prog = system.readProgramString(progstr); Set actual = system.solve(prog, (p) -> p.equals(Predicates.getPredicate("a", 0)) || p.equals(Predicates.getPredicate("e", 2))) .collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").predicate("e").symbolicInstance("a", "b").build())); @@ -496,8 +513,8 @@ public void disableStratifiedEvalTest() { String progstr = "p(a). q(X) :- p(X)."; SystemConfig cfg = new SystemConfig(); cfg.setEvaluateStratifiedPart(false); - AlphaImpl system = new AlphaImpl(cfg); - ASPCore2Program input = system.readProgramString(progstr); + AlphaImpl system = (AlphaImpl) AlphaFactory.newAlpha(cfg); + InputProgram input = system.readProgramString(progstr); NormalProgram normal = system.normalizeProgram(input); CompiledProgram preprocessed = system.performProgramPreprocessing(normal); assertFalse(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), @@ -512,8 +529,8 @@ public void enableStratifiedEvalTest() { // Note: This might be cleaner if the test used the debugSolve method from the interface String progstr = "p(a). q(X) :- p(X)."; SystemConfig cfg = new SystemConfig(); - AlphaImpl system = new AlphaImpl(cfg); - ASPCore2Program input = system.readProgramString(progstr); + AlphaImpl system = (AlphaImpl) AlphaFactory.newAlpha(cfg); + InputProgram input = system.readProgramString(progstr); NormalProgram normal = system.normalizeProgram(input); CompiledProgram preprocessed = system.performProgramPreprocessing(normal); assertTrue(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), @@ -568,19 +585,18 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException * -DebugEnableInternalChecks -q -g naive -s default -sort -n 400 -i 3col-20-38.txt */ SystemConfig cfg = new SystemConfig(); - cfg.setGrounderName("naive"); cfg.setSolverName("default"); cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(1119718541727902L); - final Alpha system = new AlphaImpl(cfg); + final Alpha system = AlphaFactory.newAlpha(cfg); final Path path = Paths.get("src", "test", "resources", "PreviouslyProblematic").resolve("3col-20-38.txt"); InputConfig inputCfg = new InputConfig(); List files = new ArrayList<>(); files.add(path.toString()); inputCfg.setFiles(files); - ASPCore2Program prog = system.readProgram(inputCfg); + InputProgram prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).sorted().limit(400).collect(Collectors.toList()).isEmpty()); } @@ -588,17 +604,16 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException private void problematicRun(String program, long seed, int limit) throws IOException { final Path base = Paths.get("src", "test", "resources", "PreviouslyProblematic"); SystemConfig cfg = new SystemConfig(); - cfg.setGrounderName("naive"); cfg.setSolverName("default"); cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(seed); - final Alpha system = new AlphaImpl(cfg); + final Alpha system = AlphaFactory.newAlpha(cfg); InputConfig inputCfg = new InputConfig(); List files = new ArrayList<>(); files.add(base.resolve(program).toString()); inputCfg.setFiles(files); - ASPCore2Program prog = system.readProgram(inputCfg); + InputProgram prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).limit(limit).collect(Collectors.toList()).isEmpty()); } @@ -606,7 +621,7 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep @Test public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { final ProgramParser parser = new ProgramParserImpl(); - InputProgram.Builder bld = InputProgram.builder(); + InputProgramImpl.Builder bld = InputProgramImpl.builder(); bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), StandardOpenOption.READ))); bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"), StandardOpenOption.READ))); InputProgram parsedProgram = bld.build(); @@ -623,7 +638,7 @@ public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOE 433, 427, 442, 421, 415, 436, 409, 430, 397, 391, 424, 385, 379, 418, 373, 412, 406, 394, 388, 382, 245, 232, 208 )); - Alpha alpha = new AlphaImpl(config); + Alpha alpha = AlphaFactory.newAlpha(config); Optional answerSet = alpha.solve(parsedProgram).findFirst(); assertTrue(answerSet.isPresent()); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AnswerSetsParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AnswerSetsParser.java deleted file mode 100644 index a197d62e8..000000000 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AnswerSetsParser.java +++ /dev/null @@ -1,45 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.impl; - -import java.util.Collections; -import java.util.Set; - -import org.antlr.v4.runtime.BailErrorStrategy; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; - -import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.parser.ParseTreeVisitor; - -// TODO this is duplicated from core module, need to pull out test utils into separate testsupport module -public class AnswerSetsParser { - - private static final ParseTreeVisitor VISITOR = new ParseTreeVisitor(Collections.emptyMap(), false); - - public static Set parse(String s) { - try { - return parse(CharStreams.fromString(s)); - } catch (RecognitionException | ParseCancellationException e) { - // If there were issues parsing the given string, we - // throw something that suggests that the input string - // is malformed. - throw new IllegalArgumentException("Could not parse answer sets.", e); - } - } - - public static Set parse(CharStream stream) { - final ASPCore2Parser parser = new ASPCore2Parser(new CommonTokenStream(new ASPCore2Lexer(stream))); - - // Try SLL parsing mode (faster but may terminate incorrectly). - parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - parser.removeErrorListeners(); - parser.setErrorHandler(new BailErrorStrategy()); - - return VISITOR.translate(parser.answer_sets()); - } -} diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java index ef0a1a625..3e7a2e7af 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java @@ -80,7 +80,7 @@ public static Set>> connection(String dummy) { private Map externals; public FixedInterpretationLiteralsTest() { - this.alpha = new AlphaImpl(); + this.alpha = AlphaFactory.newAlpha(); this.externals = new HashMap<>(); this.externals.putAll(Externals.scan(AspStandardLibrary.class)); this.externals.putAll(Externals.scan(FixedInterpretationLiteralsTest.class)); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java index 0033015e6..43c0331fa 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.api.impl; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; @@ -10,7 +10,7 @@ public class RuleParser { public static Rule parse(String str) { ProgramParser parser = new ProgramParserImpl(); - ASPCore2Program prog = parser.parse(str); + InputProgram prog = parser.parse(str); if (!prog.getFacts().isEmpty()) { throw new IllegalArgumentException("Expected exactly one rule and no facts!"); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java index 9cf689a0b..8fb606776 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; @@ -98,7 +98,7 @@ private void constructNonGroundRuleAndCheckToString(String textualRule) { } private Rule parseSingleRule(String rule) { - ASPCore2Program program = parser.parse(rule); + InputProgram program = parser.parse(rule); List> rules = program.getRules(); assertEquals(1, rules.size(), "Number of rules"); return rules.get(0); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregateRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregateRegressionTest.java similarity index 72% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregateRegressionTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregateRegressionTest.java index 8b12f3866..9479744eb 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregateRegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregateRegressionTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -11,7 +11,7 @@ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @ParameterizedTest -@MethodSource("at.ac.tuwien.kr.alpha.core.solver.RegressionTestConfigProvider#provideAggregateTestConfigs") +@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.RegressionTestConfigProvider#provideAggregateTestConfigs") public @interface AggregateRegressionTest { } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java similarity index 76% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java index d81c3e435..525fae05d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java @@ -23,13 +23,14 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSet; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSetsWithBase; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.ignoreTestForNaiveSolver; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.ignoreTestForSimplifiedSumAggregates; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNaiveSolver; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForSimplifiedSumAggregates; + +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; /** * Tests if correct answer sets for programs containing aggregates are computed. @@ -40,68 +41,68 @@ public class AggregatesTest { private static final String LS = System.lineSeparator(); @AggregateRegressionTest - public void aggregateCountLeGroundPositive(RegressionTestConfig cfg) { + public void aggregateCountLeGroundPositive(SystemConfig cfg) { String program = "a." + LS + "b :- 1 <= #count { 1 : a }."; - assertRegressionTestAnswerSet(cfg, program, "a,b"); + assertRegressionTestAnswerSets(cfg, program, "a,b"); } @AggregateRegressionTest - public void aggregateCountEqSingleElementPositive(RegressionTestConfig cfg) { + public void aggregateCountEqSingleElementPositive(SystemConfig cfg) { String program = "thing(1..3)." + "cnt_things(N) :- N = #count{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(1), thing(2), thing(3), cnt_things(3)"); + assertRegressionTestAnswerSets(cfg, program, "thing(1), thing(2), thing(3), cnt_things(3)"); } @AggregateRegressionTest - public void aggregateCountEqEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateCountEqEmptySetPositive(SystemConfig cfg) { String program = "cnt_things(N) :- N = #count{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "cnt_things(0)"); + assertRegressionTestAnswerSets(cfg, program, "cnt_things(0)"); } @AggregateRegressionTest - public void aggregateCountLeEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateCountLeEmptySetPositive(SystemConfig cfg) { String program = "zero_leq_cnt :- 0 <= #count{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "zero_leq_cnt"); + assertRegressionTestAnswerSets(cfg, program, "zero_leq_cnt"); } @AggregateRegressionTest - public void aggregateSumEqEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateSumEqEmptySetPositive(SystemConfig cfg) { String program = "sum_things(S) :- S = #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "sum_things(0)"); + assertRegressionTestAnswerSets(cfg, program, "sum_things(0)"); } @AggregateRegressionTest - public void aggregateSumEqNegativeSum(RegressionTestConfig cfg) { + public void aggregateSumEqNegativeSum(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(-1). thing(-2). thing(-3). sum_things(S) :- S = #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(-1), thing(-2), thing(-3), sum_things(-6)"); + assertRegressionTestAnswerSets(cfg, program, "thing(-1), thing(-2), thing(-3), sum_things(-6)"); } @AggregateRegressionTest - public void aggregateSumEqMixedElementsSum(RegressionTestConfig cfg) { + public void aggregateSumEqMixedElementsSum(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(-1). thing(6). thing(-3). sum_things(S) :- S = #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(-1), thing(6), thing(-3), sum_things(2)"); + assertRegressionTestAnswerSets(cfg, program, "thing(-1), thing(6), thing(-3), sum_things(2)"); } @AggregateRegressionTest - public void aggregateSumLeEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateSumLeEmptySetPositive(SystemConfig cfg) { String program = "zero_leq_sum :- 0 <= #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "zero_leq_sum"); + assertRegressionTestAnswerSets(cfg, program, "zero_leq_sum"); } @AggregateRegressionTest - public void aggregateSumLeNegativeSum(RegressionTestConfig cfg) { + public void aggregateSumLeNegativeSum(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(-3). thing(4). " + "minus_three_leq_sum :- -3 <= #sum{X : thing(X)}." + "two_gt_sum :- 2 > #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(-3), thing(4), minus_three_leq_sum, two_gt_sum"); + assertRegressionTestAnswerSets(cfg, program, "thing(-3), thing(4), minus_three_leq_sum, two_gt_sum"); } @AggregateRegressionTest - public void aggregateSumLeNegativeElementsWithChoice(RegressionTestConfig cfg) { + public void aggregateSumLeNegativeElementsWithChoice(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(3). thing(-5). thing(5). " + "{summed_up_thing(X) : thing(X)}. " @@ -119,7 +120,7 @@ public void aggregateSumLeNegativeElementsWithChoice(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountLeWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateCountLeWithChoicePositive(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -138,7 +139,7 @@ public void aggregateCountLeWithChoicePositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountEqWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateCountEqWithChoicePositive(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -157,7 +158,7 @@ public void aggregateCountEqWithChoicePositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumEqWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateSumEqWithChoicePositive(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -176,7 +177,7 @@ public void aggregateSumEqWithChoicePositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumEqOverMixedValuesWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateSumEqOverMixedValuesWithChoicePositive(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "potential_thing(-2). potential_thing(-1). potential_thing(0). potential_thing(1). " + "{ thing(N) : potential_thing(N)}." @@ -196,7 +197,7 @@ public void aggregateSumEqOverMixedValuesWithChoicePositive(RegressionTestConfig } @AggregateRegressionTest - public void aggregateSumBetweenNegative(RegressionTestConfig cfg) { + public void aggregateSumBetweenNegative(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -215,7 +216,7 @@ public void aggregateSumBetweenNegative(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateMaxNegative(RegressionTestConfig cfg) { + public void aggregateMaxNegative(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N) }." + "one_chosen :- thing(_)." @@ -223,12 +224,12 @@ public void aggregateMaxNegative(RegressionTestConfig cfg) { + ":- thing(N1), thing(N2), N1 != N2." + "max_chosen :- thing(X), not X < #max{M : potential_thing(M)}." + ":- not max_chosen."; - assertRegressionTestAnswerSet(cfg, program, + assertRegressionTestAnswerSets(cfg, program, "potential_thing(1), potential_thing(2), potential_thing(3), potential_thing(4), one_chosen, max_chosen, thing(4)"); } @AggregateRegressionTest - public void aggregateCountGroundNegative(RegressionTestConfig cfg) { + public void aggregateCountGroundNegative(SystemConfig cfg) { String program = "{a}." + LS + "b :- not c." + LS + "c :- 1 <= #count { 1 : a }."; @@ -236,7 +237,7 @@ public void aggregateCountGroundNegative(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountNonGroundPositive(RegressionTestConfig cfg) { + public void aggregateCountNonGroundPositive(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(3)." + LS @@ -247,7 +248,7 @@ public void aggregateCountNonGroundPositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountNonGroundLowerAndUpper(RegressionTestConfig cfg) { + public void aggregateCountNonGroundLowerAndUpper(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(2)." + LS @@ -261,14 +262,14 @@ public void aggregateCountNonGroundLowerAndUpper(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumGroundLower(RegressionTestConfig cfg) { + public void aggregateSumGroundLower(SystemConfig cfg) { String program = "a." + LS + "b :- 5 <= #sum { 2 : a; 3 }."; - assertRegressionTestAnswerSet(cfg, program, "a,b"); + assertRegressionTestAnswerSets(cfg, program, "a,b"); } @AggregateRegressionTest - public void aggregateSumNonGroundLowerAndUpper(RegressionTestConfig cfg) { + public void aggregateSumNonGroundLowerAndUpper(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(3)." + LS @@ -282,7 +283,7 @@ public void aggregateSumNonGroundLowerAndUpper(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumNonGroundLower(RegressionTestConfig cfg) { + public void aggregateSumNonGroundLower(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(3)." + LS @@ -294,7 +295,7 @@ public void aggregateSumNonGroundLower(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumComputed(RegressionTestConfig cfg) { + public void aggregateSumComputed(SystemConfig cfg) { ignoreTestForNaiveSolver(cfg); // Do not run this test case with the naive solver. String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS @@ -314,7 +315,7 @@ public void aggregateSumComputed(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountGlobalVariable(RegressionTestConfig cfg) { + public void aggregateCountGlobalVariable(SystemConfig cfg) { String program = "box(1..2)." + LS + "in(1,1)." + LS + "in(1,2)." + LS @@ -325,7 +326,7 @@ public void aggregateCountGlobalVariable(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumGlobalVariable(RegressionTestConfig cfg) { + public void aggregateSumGlobalVariable(SystemConfig cfg) { String program = "box(1..2)." + LS + "item_size(I,I) :- I=1..2." + LS + "in(1,1)." + LS @@ -337,35 +338,35 @@ public void aggregateSumGlobalVariable(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateRightHandTermCountGreater(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountGreater(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } > 1."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } @AggregateRegressionTest - public void aggregateRightHandTermCountEqAssigning(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountEqAssigning(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } = 2."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } @AggregateRegressionTest - public void aggregateRightHandTermCountNeqAssigning(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountNeqAssigning(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } != 1."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } @AggregateRegressionTest - public void aggregateRightHandTermCountLt(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountLt(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } < 3."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java new file mode 100644 index 000000000..bda0b27d3 --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java @@ -0,0 +1,58 @@ +package at.ac.tuwien.kr.alpha.regressiontests; + +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; + +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; + +/** + * Tests ASP programs containing arithmetic terms at arbitrary positions. + * + * Copyright (c) 2020, the Alpha Team. + */ +// TODO This is a functional test and should not be run with standard unit tests +public class ArithmeticTermsTest { + + @RegressionTest + public void testArithmeticTermInHead(SystemConfig cfg) { + String program = "dom(1). dom(2)." + + "p(X+3) :- dom(X)."; + assertRegressionTestAnswerSets(cfg, program, "dom(1),dom(2),p(4),p(5)"); + } + + @RegressionTest + public void testArithmeticTermInRule(SystemConfig cfg) { + String program = "dom(1). dom(2)." + + "p(Y+4) :- dom(X+1), dom(X), Y=X, X=Y."; + assertRegressionTestAnswerSets(cfg, program, "dom(1),dom(2),p(5)"); + } + + @RegressionTest + public void testArithmeticTermInChoiceRule(SystemConfig cfg) { + String program = "cycle_max(4). cycle(1)." + + "{ cycle(N+1) } :- cycle(N), cycle_max(K), N testHanoiTower(1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance2(RegressionTestConfig cfg) { + public void testInstance2(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance3(RegressionTestConfig cfg) { + public void testInstance3(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance4(RegressionTestConfig cfg) { + public void testInstance4(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(4, cfg)); } @RegressionTest - public void testSimple(RegressionTestConfig cfg) { - TestUtils.ignoreTestForNaiveSolver(cfg); - TestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); + public void testSimple(SystemConfig cfg) { + ignoreTestForNaiveSolver(cfg); + ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower("simple", cfg)); } - private void testHanoiTower(int instance, RegressionTestConfig cfg) throws IOException { + private void testHanoiTower(int instance, SystemConfig cfg) throws IOException { testHanoiTower(String.valueOf(instance), cfg); } - private void testHanoiTower(String instance, RegressionTestConfig cfg) throws IOException { - ASPCore2Program prog = new ProgramParserImpl().parse( + private void testHanoiTower(String instance, SystemConfig cfg) throws IOException { + // TODO should be read by the Alpha instance constructed in buildSolverForRegressionTest, + // do not instantiate parsers "free-style"! + InputProgram prog = new ProgramParserImpl().parse( Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); - Solver solver = TestUtils.buildSolverForRegressionTest(prog, cfg); + Solver solver = buildSolverForRegressionTest(prog, cfg); Optional answerSet = solver.stream().findFirst(); assertTrue(answerSet.isPresent()); checkGoal(prog, answerSet.get()); @@ -116,7 +121,7 @@ private void testHanoiTower(String instance, RegressionTestConfig cfg) throws IO * for every goal/3 * fact in the input there is a corresponding on/3 atom in the output. */ - private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { + private void checkGoal(InputProgram parsedProgram, AnswerSet answerSet) { Predicate ongoal = Predicates.getPredicate("ongoal", 2); Predicate on = Predicates.getPredicate("on", 3); int steps = getSteps(parsedProgram); @@ -132,7 +137,7 @@ private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { } } - private int getSteps(ASPCore2Program parsedProgram) { + private int getSteps(InputProgram parsedProgram) { Predicate steps = Predicates.getPredicate("steps", 1); for (Atom atom : parsedProgram.getFacts()) { if (atom.getPredicate().getName().equals(steps.getName()) && atom.getPredicate().getArity() == steps.getArity()) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java similarity index 65% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java index 07839eda8..cb098c85b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java @@ -23,8 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -38,10 +40,9 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; - /** * Tests rule transformations described in the following research paper, and their effects on performance: * @@ -55,131 +56,131 @@ public class HeadBodyTransformationTests { @RegressionTest - public void testProgramB_N1(RegressionTestConfig cfg) { + public void testProgramB_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(1), cfg)); } @RegressionTest - public void testProgramB_Transformed_N1(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(1), cfg)); } @RegressionTest - public void testProgramA_N1(RegressionTestConfig cfg) { + public void testProgramA_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(1), cfg)); } @RegressionTest - public void testProgramA_Transformed_N1(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(1), cfg)); } @RegressionTest - public void testProgramB_N2(RegressionTestConfig cfg) { + public void testProgramB_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(2), cfg)); } @RegressionTest - public void testProgramB_Transformed_N2(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(2), cfg)); } @RegressionTest - public void testProgramA_N2(RegressionTestConfig cfg) { + public void testProgramA_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(2), cfg)); } @RegressionTest - public void testProgramA_Transformed_N2(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(2), cfg)); } @RegressionTest - public void testProgramB_N4(RegressionTestConfig cfg) { + public void testProgramB_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(4), cfg)); } @RegressionTest - public void testProgramB_Transformed_N4(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(4), cfg)); } @RegressionTest - public void testProgramA_N4(RegressionTestConfig cfg) { + public void testProgramA_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(4), cfg)); } @RegressionTest - public void testProgramA_Transformed_N4(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(4), cfg)); } @RegressionTest - public void testProgramB_N8(RegressionTestConfig cfg) { + public void testProgramB_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(8), cfg)); } @RegressionTest - public void testProgramB_Transformed_N8(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(8), cfg)); } @RegressionTest - public void testProgramA_N8(RegressionTestConfig cfg) { + public void testProgramA_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(8), cfg)); } @RegressionTest - public void testProgramA_Transformed_N8(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(8), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramB_N16(RegressionTestConfig cfg) { + public void testProgramB_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(16), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramB_Transformed_N16(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(16), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramA_N16(RegressionTestConfig cfg) { + public void testProgramA_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(16), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramA_Transformed_N16(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(16), cfg)); } - private void test(ASPCore2Program program, RegressionTestConfig cfg) { - Solver solver = TestUtils.buildSolverForRegressionTest(program, cfg); + private void test(InputProgram program, SystemConfig cfg) { + Solver solver = buildSolverForRegressionTest(program, cfg); Optional answerSet = solver.stream().findFirst(); assertFalse(answerSet.isPresent()); } @@ -189,7 +190,7 @@ private void test(ASPCore2Program program, RegressionTestConfig cfg) { * * @param n */ - private ASPCore2Program constructProgramB(int n) { + private InputProgram constructProgramB(int n) { int numberOfRules = 3 * n + 1; List strRules = new ArrayList<>(numberOfRules); strRules.add("x :- not x."); @@ -203,7 +204,7 @@ private ASPCore2Program constructProgramB(int n) { * * @param n */ - private ASPCore2Program constructProgramB_TransformationB(int n) { + private InputProgram constructProgramB_TransformationB(int n) { int numberOfRules = 6 * n + 2; List strRules = new ArrayList<>(numberOfRules); strRules.add("b_notX :- not x."); @@ -218,7 +219,7 @@ private ASPCore2Program constructProgramB_TransformationB(int n) { * * @param n */ - private ASPCore2Program constructProgramA(int n) { + private InputProgram constructProgramA(int n) { int numberOfRules = 4 * n + 1; List strRules = new ArrayList<>(numberOfRules); strRules.add(createXCRule(n)); @@ -232,7 +233,7 @@ private ASPCore2Program constructProgramA(int n) { * * @param n */ - private ASPCore2Program constructProgramA_TransformationA(int n) { + private InputProgram constructProgramA_TransformationA(int n) { int numberOfRules = 7 * n + 2; List strRules = new ArrayList<>(numberOfRules); strRules.addAll(createXCRules_TransformationA(n)); @@ -241,10 +242,10 @@ private ASPCore2Program constructProgramA_TransformationA(int n) { return checkNumberOfRulesAndParse(strRules, numberOfRules); } - private ASPCore2Program checkNumberOfRulesAndParse(List strRules, int numberOfRules) { + private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { assertEquals(numberOfRules, strRules.size()); String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - ASPCore2Program parsedProgram = new ProgramParserImpl().parse(strProgram); + InputProgram parsedProgram = new ProgramParserImpl().parse(strProgram); assertEquals(numberOfRules, parsedProgram.getRules().size()); return parsedProgram; } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java similarity index 52% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java index 2d5713e14..125b5722a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java @@ -23,7 +23,12 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; + +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNaiveSolver; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; import java.io.IOException; import java.nio.file.Files; @@ -35,80 +40,79 @@ import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; /** * Tests {@link AbstractSolver} using Omiga benchmark problems. * */ -// TODO This is a functional test and should not be run with standard unit tests +// TODO This is actually a performance benchmark and should not be run with standard unit tests public class OmigaBenchmarksTest { @SuppressWarnings("unused") private static final Logger LOGGER = LoggerFactory.getLogger(OmigaBenchmarksTest.class); - private static final int DEBUG_TIMEOUT_FACTOR = 15; + private static final int DEBUG_TIMEOUT_FACTOR = 20; @RegressionTest - public void test3Col_10_18(RegressionTestConfig cfg) { + public void test3Col_10_18(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-10-18.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-10-18.txt", cfg)); } @RegressionTest - public void test3Col_20_38(RegressionTestConfig cfg) { + public void test3Col_20_38(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-20-38.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-20-38.txt", cfg)); } @RegressionTest - public void testCutedge_100_30(RegressionTestConfig cfg) { + public void testCutedge_100_30(SystemConfig cfg) { long timeout = 15000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-30.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-30.txt", cfg)); } @RegressionTest - public void testCutedge_100_50(RegressionTestConfig cfg) { + public void testCutedge_100_50(SystemConfig cfg) { long timeout = 15000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-50.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-50.txt", cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testLocstrat_200(RegressionTestConfig cfg) { + public void testLocstrat_200(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-200.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-200.txt", cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testLocstrat_400(RegressionTestConfig cfg) { + public void testLocstrat_400(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-400.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-400.txt", cfg)); } @RegressionTest - public void testReach_1(RegressionTestConfig cfg) { - long timeout = 15000L; - TestUtils.ignoreTestForNaiveSolver(cfg); - TestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-1.txt", cfg)); + public void testReach_1(SystemConfig cfg) { + long timeout = 20000L; + ignoreTestForNaiveSolver(cfg); + ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-1.txt", cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testReach_4(RegressionTestConfig cfg) { + public void testReach_4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-4.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-4.txt", cfg)); } - private void test(String folder, String aspFileName, RegressionTestConfig cfg) throws IOException { + private void test(String folder, String aspFileName, SystemConfig cfg) throws IOException { @SuppressWarnings("unused") - Optional answerSet = TestUtils - .buildSolverForRegressionTest( - new ProgramParserImpl().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) - .stream().findFirst(); + Optional answerSet = buildSolverForRegressionTest( + new ProgramParserImpl().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) + .stream().findFirst(); // System.out.println(answerSet); // TODO: check correctness of answer set } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java similarity index 86% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java index 670195ea1..63b1d3326 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.collectRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertFalse; import java.util.ArrayList; @@ -36,6 +36,8 @@ import org.junit.jupiter.api.Disabled; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; + /** * Tests {@link AbstractSolver} using some configuration test cases in which subparts are assigned to parts. * @@ -46,61 +48,61 @@ public class PartSubpartConfigurationTest { private static final int DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN2(RegressionTestConfig cfg) { + public void testN2(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(4, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN8(RegressionTestConfig cfg) { + public void testN8(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(8, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN16(RegressionTestConfig cfg) { + public void testN16(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(16, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN32(RegressionTestConfig cfg) { + public void testN32(SystemConfig cfg) { long timeout = 61000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(32, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN60(RegressionTestConfig cfg) { + public void testN60(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(60, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN75(RegressionTestConfig cfg) { + public void testN75(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(75, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN100(RegressionTestConfig cfg) { + public void testN100(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(100, cfg)); } - private void testPartSubpart(int n, RegressionTestConfig cfg) { + private void testPartSubpart(int n, SystemConfig cfg) { List rules = new ArrayList<>(); for (int i = 1; i <= n; i++) { rules.add(String.format("n(%d).", i)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java similarity index 84% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java index 318452c64..7babe7ef7 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java @@ -23,11 +23,11 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.collectRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; @@ -38,6 +38,7 @@ import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; /** * Tests {@link AbstractSolver} using some pigeon-hole test cases (see https://en.wikipedia.org/wiki/Pigeonhole_principle). @@ -48,49 +49,49 @@ public class PigeonHoleTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void test2Pigeons2Holes(RegressionTestConfig cfg) { + public void test2Pigeons2Holes(SystemConfig cfg) { long timeout = 5000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(2, 2, cfg)); } @RegressionTest - public void test3Pigeons2Holes(RegressionTestConfig cfg) { + public void test3Pigeons2Holes(SystemConfig cfg) { long timeout = 5000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(3, 2, cfg)); } @RegressionTest - public void test2Pigeons3Holes(RegressionTestConfig cfg) { + public void test2Pigeons3Holes(SystemConfig cfg) { long timeout = 5000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(2, 3, cfg)); } @RegressionTest - public void test3Pigeons3Holes(RegressionTestConfig cfg) { + public void test3Pigeons3Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(3, 3, cfg)); } @RegressionTest - public void test4Pigeons3Holes(RegressionTestConfig cfg) { + public void test4Pigeons3Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(4, 3, cfg)); } @RegressionTest - public void test3Pigeons4Holes(RegressionTestConfig cfg) { + public void test3Pigeons4Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(3, 4, cfg)); } @RegressionTest - public void test4Pigeons4Holes(RegressionTestConfig cfg) { + public void test4Pigeons4Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(4, 4, cfg)); @@ -98,42 +99,42 @@ public void test4Pigeons4Holes(RegressionTestConfig cfg) { @RegressionTest @Disabled("disabled to save resources during CI") - public void test10Pigeons10Holes(RegressionTestConfig cfg) { + public void test10Pigeons10Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(10, 10, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test19Pigeons20Holes(RegressionTestConfig cfg) { + public void test19Pigeons20Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(19, 20, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test28Pigeons30Holes(RegressionTestConfig cfg) { + public void test28Pigeons30Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(28, 30, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test37Pigeons40Holes(RegressionTestConfig cfg) { + public void test37Pigeons40Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(37, 40, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test46Pigeons50Holes(RegressionTestConfig cfg) { + public void test46Pigeons50Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(46, 50, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test55Pigeons60Holes(RegressionTestConfig cfg) { + public void test55Pigeons60Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(55, 60, cfg)); } @@ -141,7 +142,7 @@ public void test55Pigeons60Holes(RegressionTestConfig cfg) { /** * Tries to solve the problem of assigning P pigeons to H holes. */ - private void testPigeonsHoles(int pigeons, int holes, RegressionTestConfig cfg) { + private void testPigeonsHoles(int pigeons, int holes, SystemConfig cfg) { List rules = new ArrayList<>(); rules.add("pos(P,H) :- pigeon(P), hole(H), not negpos(P,H)."); rules.add("negpos(P,H) :- pigeon(P), hole(H), not pos(P,H)."); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java similarity index 86% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java index 4c9150ca0..3c6a5cd0c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; import java.io.IOException; import java.nio.file.Paths; @@ -38,6 +38,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; /** @@ -51,12 +52,12 @@ public class RacksTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testRacks(RegressionTestConfig cfg) { + public void testRacks(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(cfg)); } - private void test(RegressionTestConfig cfg) throws IOException { + private void test(SystemConfig cfg) throws IOException { CharStream programInputStream = CharStreams.fromPath( Paths.get("benchmarks", "siemens", "racks", "racks.lp")); Solver solver = buildSolverForRegressionTest(new ProgramParserImpl().parse(programInputStream), cfg); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTest.java similarity index 73% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTest.java index f6f3e28a2..6c2497829 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -11,7 +11,7 @@ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @ParameterizedTest -@MethodSource("at.ac.tuwien.kr.alpha.core.solver.RegressionTestConfigProvider#provideConfigs") +@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.RegressionTestConfigProvider#provideConfigs") public @interface RegressionTest { - + } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTestConfigProvider.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestConfigProvider.java similarity index 57% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTestConfigProvider.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestConfigProvider.java index 20f139581..bb9af932d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTestConfigProvider.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestConfigProvider.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; import java.lang.reflect.Field; import java.util.ArrayList; @@ -7,13 +7,14 @@ import org.junit.jupiter.params.provider.Arguments; +import at.ac.tuwien.kr.alpha.api.config.AggregateRewritingConfig; import at.ac.tuwien.kr.alpha.api.config.Heuristic; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; public class RegressionTestConfigProvider { private static final String DEFAULT_SOLVER_NAME = "default"; - private static final String DEFAULT_GROUNDER_NAME = "naive"; - private static final String DEFAULT_ATOM_STORE = "alpharoaming"; + private static final String DEFAULT_NOGOOD_STORE = "alpharoaming"; private static final String DEFAULT_BRANCHING_HEURISTIC = "VSIDS"; private static final String DEFAULT_GROUNDER_TOLERANCE = "strict"; private static final boolean DEFAULT_DISABLE_INSTANCE_REMOVAL = false; @@ -27,18 +28,17 @@ public class RegressionTestConfigProvider { * * @return */ - private static List buildConfigs() { + private static List buildConfigs() { // Check whether we are running in a CI environment. boolean ci = Boolean.valueOf(System.getenv("CI")); //@formatter:off String[] solvers = ci ? new String[]{DEFAULT_SOLVER_NAME, "naive" } : new String[]{DEFAULT_SOLVER_NAME }; - String grounder = DEFAULT_GROUNDER_NAME; - String[] atomStores = ci ? new String[]{DEFAULT_ATOM_STORE, "naive" } : new String[]{DEFAULT_ATOM_STORE }; + String[] nogoodStores = ci ? new String[]{DEFAULT_NOGOOD_STORE, "naive" } : new String[]{DEFAULT_NOGOOD_STORE }; String[] heuristics = ci ? nonDeprecatedHeuristics() : new String[]{"NAIVE", DEFAULT_BRANCHING_HEURISTIC }; String[] gtcValues = new String[]{DEFAULT_GROUNDER_TOLERANCE, "permissive" }; - String gtrValue = DEFAULT_GROUNDER_TOLERANCE; - boolean[] disableInstanceRemovalValues = ci ? new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL, true } : new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL }; + String grounderToleranceRules = DEFAULT_GROUNDER_TOLERANCE; + boolean[] grounderAccumulatorValues = ci ? new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL, true } : new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL }; boolean[] evaluateStratifiedValues = new boolean[]{false, true }; boolean[] enableDebugChecksValues = new boolean[]{DEFAULT_ENABLE_DEBUG_CHECKS, true }; //@formatter:on @@ -52,18 +52,26 @@ private static List buildConfigs() { String seedProperty = System.getProperty("seed", ci ? "0" : ""); long seed = seedProperty.isEmpty() ? (new Random().nextLong()) : Long.valueOf(seedProperty); - List configsToTest = new ArrayList<>(); + List configsToTest = new ArrayList<>(); for (String solverName : solvers) { - for (String atomStoreName : atomStores) { + for (String nogoodStoreName : nogoodStores) { for (String branchingHeuristicName : heuristics) { - for (String grounderTolerance : gtcValues) { - for (boolean disableInstanceRemoval : disableInstanceRemovalValues) { + for (String grounderToleranceConstraints : gtcValues) { + for (boolean grounderAccumulatorEnabled : grounderAccumulatorValues) { for (boolean evaluateStratified : evaluateStratifiedValues) { for (boolean enableDebugChecks : enableDebugChecksValues) { - configsToTest.add(new RegressionTestConfig( - solverName, grounder, atomStoreName, Heuristic.valueOf(branchingHeuristicName), - seed, enableDebugChecks, grounderTolerance, gtrValue, disableInstanceRemoval, evaluateStratified, - true, true)); + SystemConfig cfg = new SystemConfig(); + cfg.setSolverName(solverName); + cfg.setNogoodStoreName(nogoodStoreName); + cfg.setBranchingHeuristicName(branchingHeuristicName); + cfg.setGrounderToleranceRules(grounderToleranceRules); + cfg.setGrounderToleranceConstraints(grounderToleranceConstraints); + cfg.setGrounderAccumulatorEnabled(grounderAccumulatorEnabled); + cfg.setEvaluateStratifiedPart(evaluateStratified); + cfg.setDebugInternalChecks(enableDebugChecks); + cfg.setSeed(seed); + + configsToTest.add(cfg); } } } @@ -82,8 +90,8 @@ private static List buildConfigs() { * * @return */ - private static List buildConfigsForAggregateTests() { - List configsToTest = new ArrayList<>(); + private static List buildConfigsForAggregateTests() { + List configsToTest = new ArrayList<>(); boolean[] evaluateStratifiedValues = new boolean[] {true, false }; boolean[] useSortingGridValues = new boolean[] {true, false }; @@ -92,12 +100,28 @@ private static List buildConfigsForAggregateTests() { for (boolean evalStratified : evaluateStratifiedValues) { for (boolean useSortingGrid : useSortingGridValues) { for (boolean supportNegativeElements : supportNegativeSumElementsValues) { - configsToTest.add( - new RegressionTestConfig( - DEFAULT_SOLVER_NAME, DEFAULT_GROUNDER_NAME, DEFAULT_ATOM_STORE, Heuristic.valueOf(DEFAULT_BRANCHING_HEURISTIC), - 0, DEFAULT_ENABLE_DEBUG_CHECKS, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_DISABLE_INSTANCE_REMOVAL, - evalStratified, - useSortingGrid, supportNegativeElements)); + // new RegressionTestConfig( + // DEFAULT_SOLVER_NAME, DEFAULT_GROUNDER_NAME, DEFAULT_NOGOOD_STORE, Heuristic.valueOf(DEFAULT_BRANCHING_HEURISTIC), + // 0, DEFAULT_ENABLE_DEBUG_CHECKS, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_DISABLE_INSTANCE_REMOVAL, + // evalStratified, + // useSortingGrid, supportNegativeElements)); + AggregateRewritingConfig aggCfg = new AggregateRewritingConfig(); + aggCfg.setUseSortingGridEncoding(useSortingGrid); + aggCfg.setSupportNegativeValuesInSums(supportNegativeElements); + + SystemConfig cfg = new SystemConfig(); + cfg.setSolverName(DEFAULT_SOLVER_NAME); + cfg.setNogoodStoreName(DEFAULT_NOGOOD_STORE); + cfg.setBranchingHeuristicName(DEFAULT_BRANCHING_HEURISTIC); + cfg.setSeed(0); + cfg.setDebugInternalChecks(DEFAULT_ENABLE_DEBUG_CHECKS); + cfg.setGrounderToleranceRules(DEFAULT_GROUNDER_TOLERANCE); + cfg.setGrounderToleranceConstraints(DEFAULT_GROUNDER_TOLERANCE); + cfg.setGrounderAccumulatorEnabled(DEFAULT_DISABLE_INSTANCE_REMOVAL); + cfg.setEvaluateStratifiedPart(evalStratified); + cfg.setAggregateRewritingConfig(aggCfg); + + configsToTest.add(cfg); } } } @@ -107,7 +131,7 @@ private static List buildConfigsForAggregateTests() { public static List provideConfigs() { List retVal = new ArrayList<>(); - for (RegressionTestConfig cfg : buildConfigs()) { + for (SystemConfig cfg : buildConfigs()) { retVal.add(Arguments.of(cfg)); } return retVal; @@ -115,7 +139,7 @@ public static List provideConfigs() { public static List provideAggregateTestConfigs() { List retVal = new ArrayList<>(); - for (RegressionTestConfig cfg : buildConfigsForAggregateTests()) { + for (SystemConfig cfg : buildConfigsForAggregateTests()) { retVal.add(Arguments.of(cfg)); } return retVal; @@ -130,4 +154,5 @@ private static final String[] nonDeprecatedHeuristics() { } return nonDeprecatedHeuristicsNames.toArray(new String[] {}); } + } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestUtils.java new file mode 100644 index 000000000..afe46f929 --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestUtils.java @@ -0,0 +1,83 @@ +package at.ac.tuwien.kr.alpha.regressiontests; + +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqualWithBase; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +import java.time.Duration; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.function.Executable; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.config.Heuristic; +import at.ac.tuwien.kr.alpha.api.config.InputConfig; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; + +public final class RegressionTestUtils { + + private RegressionTestUtils() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static void runWithTimeout(SystemConfig cfg, long baseTimeout, long timeoutFactor, Executable action) { + long timeout = cfg.isDebugInternalChecks() ? timeoutFactor * baseTimeout : baseTimeout; + assertTimeoutPreemptively(Duration.ofMillis(timeout), action); + } + + public static Solver buildSolverForRegressionTest(String programString, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + InputProgram program = alpha.readProgramString(programString); + return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); + } + + public static Solver buildSolverForRegressionTest(InputProgram program, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); + } + + public static Set collectRegressionTestAnswerSets(String program, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + InputProgram in = alpha.readProgramString(program); + return alpha.solve(in).collect(Collectors.toSet()); + } + + public static Set collectRegressionTestAnswerSets(InputProgram program, SystemConfig cfg) { + return AlphaFactory.newAlpha(cfg) + .solve(program) + .collect(Collectors.toSet()); + } + + private static Set solveForConfig(String programString, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + InputProgram program = alpha.readProgramString(programString); + return alpha.solve(program).collect(Collectors.toSet()); + } + + public static void assertRegressionTestAnswerSets(SystemConfig cfg, String programString, String... expectedAnswerSets) { + assertAnswerSetsEqual(expectedAnswerSets, solveForConfig(programString, cfg)); + } + + public static void assertRegressionTestAnswerSetsWithBase(SystemConfig cfg, String programString, String base, String... expectedAnswerSets) { + assertAnswerSetsEqualWithBase(base, expectedAnswerSets, solveForConfig(programString, cfg)); + } + + public static void ignoreTestForNaiveSolver(SystemConfig cfg) { + Assumptions.assumeFalse(cfg.getSolverName().equals("naive")); + } + + public static void ignoreTestForSimplifiedSumAggregates(SystemConfig cfg) { + Assumptions.assumeTrue(cfg.getAggregateRewritingConfig().isSupportNegativeValuesInSums()); + } + + public static void ignoreTestForNonDefaultDomainIndependentHeuristics(SystemConfig cfg) { + Assumptions.assumeTrue(cfg.getBranchingHeuristic() == Heuristic.VSIDS); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java similarity index 79% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java index c091c53e9..8f0596ba5 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java @@ -23,9 +23,9 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -36,9 +36,11 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.StatisticsReportingSolver; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithBasicProgram; +import at.ac.tuwien.kr.alpha.core.solver.DefaultSolver; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodCounter; // TODO This is a functional test and should not be run with standard unit tests public class SolverStatisticsTests { @@ -51,32 +53,33 @@ public void setUp() { } @RegressionTest - public void checkStatsStringZeroChoices(RegressionTestConfig cfg) { + public void checkStatsStringZeroChoices(SystemConfig cfg) { Solver solver = buildSolverForRegressionTest("a.", cfg); assumeTrue(solver instanceof StatisticsReportingSolver); collectAnswerSetsAndCheckStats(solver, 1, 0, 0, 0, 0, 0, 0, 0); } @RegressionTest - public void checkStatsStringOneChoice(RegressionTestConfig cfg) { + public void checkStatsStringOneChoice(SystemConfig cfg) { Solver solver = buildSolverForRegressionTest("a :- not b. b :- not a.", cfg); assumeTrue(solver instanceof StatisticsReportingSolver); collectAnswerSetsAndCheckStats(solver, 2, 1, 1, 1, 1, 0, 0, 0); } - @RegressionTest - public void checkNoGoodCounterStatsByTypeUsingDummyGrounder(RegressionTestConfig cfg) { - Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); - assumeTrue(solver instanceof StatisticsReportingSolver); - collectAnswerSetsAndCheckNoGoodCounterStatsByType(solver, 4, 0, 0, 0); - } + // TODO Why are these tests config-dependent if they use a grounder mock and seem rather like unit tests on solver statistics? + // @RegressionTest + // public void checkNoGoodCounterStatsByTypeUsingDummyGrounder(SystemConfig cfg) { + // Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); + // assumeTrue(solver instanceof StatisticsReportingSolver); + // collectAnswerSetsAndCheckNoGoodCounterStatsByType(solver, 4, 0, 0, 0); + // } - @RegressionTest - public void checkNoGoodCounterStatsByCardinalityUsingDummyGrounder(RegressionTestConfig cfg) { - Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); - assumeTrue(solver instanceof StatisticsReportingSolver); - collectAnswerSetsAndCheckNoGoodCounterStatsByCardinality(solver, 2, 1, 1); - } + // @RegressionTest + // public void checkNoGoodCounterStatsByCardinalityUsingDummyGrounder(SystemConfig cfg) { + // Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); + // assumeTrue(solver instanceof StatisticsReportingSolver); + // collectAnswerSetsAndCheckNoGoodCounterStatsByCardinality(solver, 2, 1, 1); + // } private void collectAnswerSetsAndCheckStats(Solver solver, int expectedNumberOfAnswerSets, int expectedNumberOfGuesses, int expectedTotalNumberOfBacktracks, int expectedNumberOfBacktracksWithinBackjumps, int expectedNumberOfBackjumps, int expectedNumberOfMBTs, int expectedNumberOfConflictsAfterClosing, int expectedNumberOfDeletedNoGoods) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java similarity index 78% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java index d7cf1ad99..5b3cf84e6 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java @@ -25,13 +25,12 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSet; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSetsWithBase; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.collectRegressionTestAnswerSets; import static java.util.Collections.singleton; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -44,6 +43,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; @@ -51,15 +52,11 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithChoice; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithBasicProgram; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.test.util.AnswerSetsParser; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; -// // TODO This is a functional test and should not be run with standard unit tests +// TODO This is a functional test and should not be run with standard unit tests public class SolverTests { private static class Thingy implements Comparable { @@ -75,12 +72,12 @@ public int compareTo(Thingy o) { } @RegressionTest - public void testObjectProgram(RegressionTestConfig cfg) { + public void testObjectProgram(SystemConfig cfg) { final Thingy thingy = new Thingy(); final Atom fact = Atoms.newBasicAtom(Predicates.getPredicate("foo", 1), Terms.newConstant(thingy)); - final InputProgram program = new InputProgram( + final InputProgram program = new InputProgramImpl( Collections.emptyList(), Collections.singletonList(fact), new InlineDirectivesImpl() @@ -92,8 +89,8 @@ public void testObjectProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testFactsOnlyProgram(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testFactsOnlyProgram(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(a). p(b). foo(13). foo(16). q(a). q(c).", @@ -102,8 +99,8 @@ public void testFactsOnlyProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testSimpleRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testSimpleRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(a). p(b). r(X) :- p(X).", @@ -112,8 +109,8 @@ public void testSimpleRule(RegressionTestConfig cfg) { } @RegressionTest - public void testSimpleRuleWithGroundPart(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testSimpleRuleWithGroundPart(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(1)." + "p(2)." + @@ -124,8 +121,8 @@ public void testSimpleRuleWithGroundPart(RegressionTestConfig cfg) { } @RegressionTest - public void testProgramZeroArityPredicates(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testProgramZeroArityPredicates(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "a. p(X) :- b, r(X).", @@ -134,7 +131,7 @@ public void testProgramZeroArityPredicates(RegressionTestConfig cfg) { } @RegressionTest - public void testChoiceGroundProgram(RegressionTestConfig cfg) { + public void testChoiceGroundProgram(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not b. b :- not a.", @@ -145,7 +142,7 @@ public void testChoiceGroundProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testChoiceProgramNonGround(RegressionTestConfig cfg) { + public void testChoiceProgramNonGround(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1). dom(2). dom(3)." + @@ -166,7 +163,7 @@ public void testChoiceProgramNonGround(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgram3Way(RegressionTestConfig cfg) { + public void choiceProgram3Way(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not b, not c." + @@ -180,12 +177,12 @@ public void choiceProgram3Way(RegressionTestConfig cfg) { } @RegressionTest - public void emptyProgramYieldsEmptyAnswerSet(RegressionTestConfig cfg) { + public void emptyProgramYieldsEmptyAnswerSet(SystemConfig cfg) { assertRegressionTestAnswerSets(cfg, "", ""); } @RegressionTest - public void chooseMultipleAnswerSets(RegressionTestConfig cfg) { + public void chooseMultipleAnswerSets(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not nota." + @@ -207,8 +204,8 @@ public void chooseMultipleAnswerSets(RegressionTestConfig cfg) { } @RegressionTest - public void builtinAtoms(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void builtinAtoms(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "dom(1). dom(2). dom(3). dom(4). dom(5)." + "p(X) :- dom(X), X = 4." + @@ -219,8 +216,8 @@ public void builtinAtoms(RegressionTestConfig cfg) { } @RegressionTest - public void builtinAtomsGroundRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void builtinAtomsGroundRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "a :- 13 != 4." + "b :- 2 != 3, 2 = 3." + @@ -232,8 +229,8 @@ public void builtinAtomsGroundRule(RegressionTestConfig cfg) { @RegressionTest - public void choiceProgramConstraintSimple(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void choiceProgramConstraintSimple(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "fact(a).\n" + "choice(either, X) :- fact(X), not choice(or, X).\n" + @@ -245,8 +242,8 @@ public void choiceProgramConstraintSimple(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraintSimple2(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void choiceProgramConstraintSimple2(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "fact(a).\n" + "desired(either).\n" + @@ -259,7 +256,7 @@ public void choiceProgramConstraintSimple2(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraint(RegressionTestConfig cfg) { + public void choiceProgramConstraint(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "eq(1,1)." + @@ -285,7 +282,7 @@ public void choiceProgramConstraint(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraintPermutation(RegressionTestConfig cfg) { + public void choiceProgramConstraintPermutation(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "eq(1,1)." + @@ -311,8 +308,8 @@ public void choiceProgramConstraintPermutation(RegressionTestConfig cfg) { } @RegressionTest - public void simpleNoPropagation(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void simpleNoPropagation(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "val(1,1)." + "val(2,2)." + @@ -323,7 +320,7 @@ public void simpleNoPropagation(RegressionTestConfig cfg) { } @RegressionTest - public void choiceAndPropagationAfterwards(RegressionTestConfig cfg) { + public void choiceAndPropagationAfterwards(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "node(a)." + @@ -342,7 +339,7 @@ public void choiceAndPropagationAfterwards(RegressionTestConfig cfg) { } @RegressionTest - public void choiceAndConstraints(RegressionTestConfig cfg) { + public void choiceAndConstraints(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "node(a)." + @@ -361,13 +358,13 @@ public void choiceAndConstraints(RegressionTestConfig cfg) { } @RegressionTest - public void testUnsatisfiableProgram(RegressionTestConfig cfg) { + public void testUnsatisfiableProgram(SystemConfig cfg) { assertRegressionTestAnswerSets(cfg, "p(a). p(b). :- p(a), p(b)."); } @RegressionTest - public void testFunctionTermEquality(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testFunctionTermEquality(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "r1(f(a,b)). r2(f(a,b)). a :- r1(X), r2(Y), X = Y.", @@ -376,7 +373,7 @@ public void testFunctionTermEquality(RegressionTestConfig cfg) { } @RegressionTest - public void builtinInequality(RegressionTestConfig cfg) { + public void builtinInequality(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "location(a1)." + @@ -399,7 +396,7 @@ public void builtinInequality(RegressionTestConfig cfg) { } @RegressionTest - public void choiceConstraintsInequality(RegressionTestConfig cfg) { + public void choiceConstraintsInequality(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "assign(L, R) :- not nassign(L, R), possible(L, R)." + @@ -457,7 +454,7 @@ public void choiceConstraintsInequality(RegressionTestConfig cfg) { } @RegressionTest - public void sameVariableTwiceInAtom(RegressionTestConfig cfg) { + public void sameVariableTwiceInAtom(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(a, a)." + @@ -468,7 +465,7 @@ public void sameVariableTwiceInAtom(RegressionTestConfig cfg) { } @RegressionTest - public void sameVariableTwiceInAtomConstraint(RegressionTestConfig cfg) { + public void sameVariableTwiceInAtomConstraint(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(a, a)." + @@ -477,7 +474,7 @@ public void sameVariableTwiceInAtomConstraint(RegressionTestConfig cfg) { } @RegressionTest - public void noPositiveSelfFounding(RegressionTestConfig cfg) { + public void noPositiveSelfFounding(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- b." + @@ -487,7 +484,7 @@ public void noPositiveSelfFounding(RegressionTestConfig cfg) { } @RegressionTest - public void noPositiveCycleSelfFoundingChoice(RegressionTestConfig cfg) { + public void noPositiveCycleSelfFoundingChoice(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "c :- not d." + @@ -499,8 +496,8 @@ public void noPositiveCycleSelfFoundingChoice(RegressionTestConfig cfg) { } @RegressionTest - public void conflictFromUnaryNoGood(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void conflictFromUnaryNoGood(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "d(b)." + "sel(X) :- not nsel(X), d(X)." + @@ -513,7 +510,7 @@ public void conflictFromUnaryNoGood(RegressionTestConfig cfg) { } @RegressionTest - public void intervalsInFacts(RegressionTestConfig cfg) { + public void intervalsInFacts(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a." + @@ -550,7 +547,7 @@ public void intervalsInFacts(RegressionTestConfig cfg) { } @RegressionTest - public void intervalInRules(RegressionTestConfig cfg) { + public void intervalInRules(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- 3 = 1..4 ." + @@ -571,7 +568,7 @@ public void intervalInRules(RegressionTestConfig cfg) { } @RegressionTest - public void emptyIntervals(RegressionTestConfig cfg) { + public void emptyIntervals(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(3..1)." + @@ -582,7 +579,7 @@ public void emptyIntervals(RegressionTestConfig cfg) { } @RegressionTest - public void intervalInFunctionTermsInRules(RegressionTestConfig cfg) { + public void intervalInFunctionTermsInRules(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- q(f(1..3,g(4..5)))." + @@ -607,8 +604,8 @@ public void intervalInFunctionTermsInRules(RegressionTestConfig cfg) { } @RegressionTest - public void groundAtomInRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void groundAtomInRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p :- dom(X), q, q2." + "dom(1)." + @@ -623,7 +620,7 @@ public void groundAtomInRule(RegressionTestConfig cfg) { } @RegressionTest - public void simpleChoiceRule(RegressionTestConfig cfg) { + public void simpleChoiceRule(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "{ a; b; c} :- d." + @@ -642,7 +639,7 @@ public void simpleChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void conditionalChoiceRule(RegressionTestConfig cfg) { + public void conditionalChoiceRule(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1..3)." + @@ -666,7 +663,7 @@ public void conditionalChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void doubleChoiceRule(RegressionTestConfig cfg) { + public void doubleChoiceRule(SystemConfig cfg) { Solver solver = buildSolverForRegressionTest("{ a }. { a }.", cfg); // Make sure that no superfluous answer sets that only differ on hidden atoms occur. List actual = solver.collectList(); @@ -675,8 +672,8 @@ public void doubleChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void simpleArithmetics(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void simpleArithmetics(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "eight(X) :- X = 4 + 5 - 1." + "three(X) :- X = Z, Y = 1..10, Z = Y / 3, Z > 2, Z < 4.", @@ -685,8 +682,8 @@ public void simpleArithmetics(RegressionTestConfig cfg) { } @RegressionTest - public void arithmeticsMultiplicationBeforeAddition(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void arithmeticsMultiplicationBeforeAddition(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "seven(X) :- 1+2 * 3 = X.", @@ -697,7 +694,7 @@ public void arithmeticsMultiplicationBeforeAddition(RegressionTestConfig cfg) { * Tests the fix for issue #101 */ @RegressionTest - public void involvedUnsatisfiableProgram(RegressionTestConfig cfg) { + public void involvedUnsatisfiableProgram(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "x :- c1, c2, not x." + @@ -712,7 +709,7 @@ public void involvedUnsatisfiableProgram(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationAtom(RegressionTestConfig cfg) { + public void instanceEnumerationAtom(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(1). dom(2). dom(3)." + "p(X) :- dom(X)." + @@ -729,7 +726,7 @@ public void instanceEnumerationAtom(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationArbitraryTerms(RegressionTestConfig cfg) { + public void instanceEnumerationArbitraryTerms(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(a). dom(f(a,b)). dom(d)." + "p(X) :- dom(X)." + @@ -746,7 +743,7 @@ public void instanceEnumerationArbitraryTerms(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationMultipleIdentifiers(RegressionTestConfig cfg) { + public void instanceEnumerationMultipleIdentifiers(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(a). dom(b). dom(c). dom(d)." + "p(X) :- dom(X)." + @@ -784,7 +781,7 @@ private void assertEnumerationPositions(SortedSet positions, int numPositi } @RegressionTest - public void smallCardinalityAggregate(RegressionTestConfig cfg) { + public void smallCardinalityAggregate(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1..3)." + @@ -805,16 +802,17 @@ public void smallCardinalityAggregate(RegressionTestConfig cfg) { ); } - @RegressionTest - public void dummyGrounder(RegressionTestConfig cfg) { - AtomStore atomStore = new AtomStoreImpl(); - assertEquals(GrounderMockWithBasicProgram.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg).collectSet()); - } + // TODO @AntoniusW what are these? Can we get rid of them? If not, where do I move them? + // @RegressionTest + // public void dummyGrounder(SystemConfig cfg) { + // AtomStore atomStore = new AtomStoreImpl(); + // assertEquals(GrounderMockWithBasicProgram.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg).collectSet()); + // } - @RegressionTest - public void choiceGrounder(RegressionTestConfig cfg) { - AtomStore atomStore = new AtomStoreImpl(); - assertEquals(GrounderMockWithChoice.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithChoice(atomStore), cfg).collectSet()); - } + // @RegressionTest + // public void choiceGrounder(SystemConfig cfg) { + // AtomStore atomStore = new AtomStoreImpl(); + // assertEquals(GrounderMockWithChoice.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithChoice(atomStore), cfg).collectSet()); + // } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java new file mode 100644 index 000000000..62ba483dd --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java @@ -0,0 +1,293 @@ +package at.ac.tuwien.kr.alpha.regressiontests; + +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertFactsContainedInProgram; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; + +// TODO This is a functional test and should not be run with standard unit tests +public class StratifiedEvaluationRegressionTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluationRegressionTest.class); + + //@formatter:off + private static final String STRATIFIED_NEG_ASP = "base(X) :- req(X), not incomp(X).\n" + + "depend_base(X, Y) :- base(X), base(Y).\n" + + "dep_b_hlp(X) :- depend_base(X, _).\n" + + "fallback_base(X) :- base(X), not dep_b_hlp(X).\n" + + "depend_further(X) :- depend_base(_, X).\n" + + "depend_further(X) :- fallback_base(X)."; + + private static final String BASIC_TEST_ASP = "a. b:- a."; + private static final String BASIC_MULTI_INSTANCE_ASP = "p(a). p(b). q(X) :- p(X)."; + private static final String BASIC_NEGATION_ASP = "p(a). q(b). p(c). q(d). r(c). s(X, Y) :- p(X), q(Y), not r(X)."; + private static final String PART_STRATIFIED_ASP = + "p(a). q(a). p(b). m(c). n(d).\n" + + "r(X) :- p(X), q(X).\n" + + "s(X, Y, Z) :- r(X), m(Y), n(Z).\n" + + "t(X, Y) :- p(X), q(X), p(Y), not q(Y).\n" + + "either(X) :- t(X, _), not or(X).\n" + + "or(X) :- t(X, _), not either(X)."; + private static final String POSITIVE_RECURSION_ASP = + "num(0).\n" + + "max_num(10).\n" + + "num(S) :- num(N), S = N + 1, S <= M, max_num(M)."; + private static final String EMPTY_PROG_ASP = ""; + private static final String FACTS_ONLY_ASP = "a. b. c. p(a). q(b, c). r(c, c, a). s(b)."; + private static final String STRATIFIED_NO_FACTS_ASP = STRATIFIED_NEG_ASP; + private static final String STRATIFIED_W_FACTS_ASP = "req(a). req(b). incomp(b).\n" + STRATIFIED_NEG_ASP; + private static final String EQUALITY_ASP = "equal :- 1 = 1."; + private static final String EQUALITY_WITH_VAR_ASP = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; + + private static final ImmutablePair, Consumer>> BASIC_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramBasic, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasic); + private static final ImmutablePair, Consumer>> BASIC_MULTI_INSTANCE_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramBasicMultiInstance, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicMultiInstance); + private static final ImmutablePair, Consumer>> BASIC_NEGATION_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramBasicNegation, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicNegation); + private static final ImmutablePair, Consumer>> PART_STRATIFIED_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramPartStratified, StratifiedEvaluationRegressionTest::verifyAnswerSetsPartStratified); + private static final ImmutablePair, Consumer>> POSITIVE_RECURSIVE_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramPositiveRecursive, StratifiedEvaluationRegressionTest::verifyAnswerSetsPositiveRecursive); + private static final ImmutablePair, Consumer>> EMPTY_PROG_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramEmptyProg, StratifiedEvaluationRegressionTest::verifyAnswerSetsEmptyProg); + private static final ImmutablePair, Consumer>> FACTS_ONLY_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramFactsOnly, StratifiedEvaluationRegressionTest::verifyAnswerSetsFactsOnly); + private static final ImmutablePair, Consumer>> STRATIFIED_NO_FACTS_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramStratNoFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratNoFacts); + private static final ImmutablePair, Consumer>> STRATIFIED_W_FACTS_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramStratWithFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratWithFacts); + private static final ImmutablePair, Consumer>> EQUALITY_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramEquality, StratifiedEvaluationRegressionTest::verifyAnswerSetsEquality); + private static final ImmutablePair, Consumer>> EQUALITY_WITH_VAR_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramEqualityWithVar, StratifiedEvaluationRegressionTest::verifyAnswerSetsEqualityWithVar); + + public static List params() { + List, Consumer>>>> testCases = new ArrayList<>(); + List paramList = new ArrayList<>(); + testCases.add(new ImmutablePair<>(BASIC_TEST_ASP, BASIC_VERIFIERS)); + testCases.add(new ImmutablePair<>(BASIC_MULTI_INSTANCE_ASP, BASIC_MULTI_INSTANCE_VERIFIERS)); + testCases.add(new ImmutablePair<>(BASIC_NEGATION_ASP, BASIC_NEGATION_VERIFIERS)); + testCases.add(new ImmutablePair<>(PART_STRATIFIED_ASP, PART_STRATIFIED_VERIFIERS)); + testCases.add(new ImmutablePair<>(POSITIVE_RECURSION_ASP, POSITIVE_RECURSIVE_VERIFIERS)); + testCases.add(new ImmutablePair<>(EMPTY_PROG_ASP, EMPTY_PROG_VERIFIERS)); + testCases.add(new ImmutablePair<>(FACTS_ONLY_ASP, FACTS_ONLY_VERIFIERS)); + testCases.add(new ImmutablePair<>(STRATIFIED_NO_FACTS_ASP, STRATIFIED_NO_FACTS_VERIFIERS)); + testCases.add(new ImmutablePair<>(STRATIFIED_W_FACTS_ASP, STRATIFIED_W_FACTS_VERIFIERS)); + testCases.add(new ImmutablePair<>(EQUALITY_ASP, EQUALITY_VERIFIERS)); + testCases.add(new ImmutablePair<>(EQUALITY_WITH_VAR_ASP, EQUALITY_WITH_VAR_VERIFIERS)); + + testCases.forEach((pair) -> paramList.add(Arguments.of(pair.left, pair.right.left, pair.right.right))); + return paramList; + } + //@formatter:on + + @ParameterizedTest + @MethodSource("at.ac.tuwien.kr.alpha.regressiontests.StratifiedEvaluationRegressionTest#params") + public void runTest(String aspString, Consumer programVerifier, + Consumer> resultVerifier) { + LOGGER.debug("Testing ASP String {}", aspString); + // Parse and pre-evaluate program + // Alpha instance with default config, stratified evaluation enabled + Alpha alpha = AlphaFactory.newAlpha(); + InputProgram input = alpha.readProgramString(aspString); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(input); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + // Verify stratified evaluation result + programVerifier.accept(evaluated); + // Solve remaining program + Solver solver = dbgInfo.getSolver(); + Set answerSets = solver.collectSet(); + resultVerifier.accept(answerSets); + } + + private static void verifyProgramBasic(NormalProgram evaluated) { + assertFactsContainedInProgram(evaluated, Atoms.newBasicAtom(Predicates.getPredicate("a", 0)), + Atoms.newBasicAtom(Predicates.getPredicate("b", 0))); + assertEquals(2, evaluated.getFacts().size()); + assertTrue(evaluated.getRules().size() == 0); + } + + private static void verifyAnswerSetsBasic(Set answerSets) { + assertAnswerSetsEqual("a, b", answerSets); + } + + private static void verifyProgramBasicMultiInstance(NormalProgram evaluated) { + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("b"))); + assertTrue(evaluated.getRules().size() == 0); + } + + private static void verifyAnswerSetsBasicMultiInstance(Set answerSets) { + assertAnswerSetsEqual("p(a), p(b), q(a), q(b)", answerSets); + } + + private static void verifyProgramBasicNegation(NormalProgram evaluated) { + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("s", 2), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("b")), + Atoms.newBasicAtom(Predicates.getPredicate("s", 2), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("d"))); + assertEquals(7, evaluated.getFacts().size()); + assertEquals(0, evaluated.getRules().size()); + } + + private static void verifyAnswerSetsBasicNegation(Set answerSets) { + assertAnswerSetsEqual("p(a), q(b), p(c), q(d), r(c), s(a,b), s(a,d)", answerSets); + } + + private static void verifyProgramPartStratified(NormalProgram evaluated) { + LOGGER.debug("part stratified evaluated prog is:\n{}", evaluated.toString()); + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("b")), + Atoms.newBasicAtom(Predicates.getPredicate("m", 1), Terms.newSymbolicConstant("c")), + Atoms.newBasicAtom(Predicates.getPredicate("n", 1), Terms.newSymbolicConstant("d")), + Atoms.newBasicAtom(Predicates.getPredicate("r", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("s", 3), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("c"), Terms.newSymbolicConstant("d")), + Atoms.newBasicAtom(Predicates.getPredicate("t", 2), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("b"))); + assertEquals(2, evaluated.getRules().size()); + } + + private static void verifyAnswerSetsPartStratified(Set answerSets) { + assertAnswerSetsEqual(new String[] {"p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), either(a)", + "p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), or(a)" }, answerSets); + } + + private static void verifyProgramPositiveRecursive(NormalProgram evaluated) { + Predicate num = Predicates.getPredicate("num", 1); + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("max_num", 1), Terms.newConstant(10)), + Atoms.newBasicAtom(num, Terms.newConstant(0)), Atoms.newBasicAtom(num, Terms.newConstant(1)), + Atoms.newBasicAtom(num, Terms.newConstant(2)), Atoms.newBasicAtom(num, Terms.newConstant(3)), + Atoms.newBasicAtom(num, Terms.newConstant(4)), Atoms.newBasicAtom(num, Terms.newConstant(5)), + Atoms.newBasicAtom(num, Terms.newConstant(6)), Atoms.newBasicAtom(num, Terms.newConstant(7)), + Atoms.newBasicAtom(num, Terms.newConstant(8)), Atoms.newBasicAtom(num, Terms.newConstant(9)), + Atoms.newBasicAtom(num, Terms.newConstant(10))); + LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); + assertEquals(0, evaluated.getRules().size()); + } + + private static void verifyAnswerSetsPositiveRecursive(Set answerSets) { + assertAnswerSetsEqual( + "max_num(10), num(0), num(1), num(2), num(3), num(4), num(5), num(6), num(7), num(8), num(9), num(10)", + answerSets); + } + + private static void verifyProgramEmptyProg(NormalProgram evaluated) { + assertTrue(evaluated.getRules().isEmpty()); + assertTrue(evaluated.getFacts().isEmpty()); + } + + private static void verifyAnswerSetsEmptyProg(Set answerSets) { + assertEquals(1, answerSets.size()); + assertTrue(answerSets.iterator().next().isEmpty()); + } + + private static void verifyProgramFactsOnly(NormalProgram evaluated) { + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("a", 0)))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("b", 0)))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("c", 0)))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 2), + Terms.newSymbolicConstant("b"), Terms.newSymbolicConstant("c")))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("r", 3), + Terms.newSymbolicConstant("c"), Terms.newSymbolicConstant("c"), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("s", 1), Terms.newSymbolicConstant("b")))); + } + + private static void verifyAnswerSetsFactsOnly(Set answerSets) { + assertAnswerSetsEqual("a, b, c, p(a), q(b,c), r(c,c,a), s(b)", answerSets); + } + + private static void verifyProgramStratNoFacts(NormalProgram evaluated) { + assertTrue(evaluated.getFacts().isEmpty()); + } + + private static void verifyAnswerSetsStratNoFacts(Set answerSets) { + assertEquals(1, answerSets.size()); + assertTrue(answerSets.iterator().next().isEmpty()); + } + + private static void verifyProgramStratWithFacts(NormalProgram evaluated) { + // rules should all be taken care of at this point + assertTrue(evaluated.getRules().isEmpty()); + + // facts should be the full answer set + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("req", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("req", 1), Terms.newSymbolicConstant("b")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("incomp", 1), Terms.newSymbolicConstant("b")))); + + // below facts from stratified evaluation + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("base", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("depend_base", 2), + Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("dep_b_hlp", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts().contains( + Atoms.newBasicAtom(Predicates.getPredicate("depend_further", 1), Terms.newSymbolicConstant("a")))); + } + + private static void verifyAnswerSetsStratWithFacts(Set answerSets) { + assertAnswerSetsEqual("req(a), req(b), incomp(b), base(a), depend_base(a,a), dep_b_hlp(a), depend_further(a)", + answerSets); + } + + private static void verifyProgramEquality(NormalProgram evaluated) { + assertEquals(0, evaluated.getRules().size()); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("equal", 0)))); + } + + private static void verifyAnswerSetsEquality(Set answerSets) { + assertAnswerSetsEqual("equal", answerSets); + } + + private static void verifyProgramEqualityWithVar(NormalProgram evaluated) { + assertEquals(0, evaluated.getRules().size()); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newConstant(1)))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newConstant(2)))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newConstant(3)))); + } + + private static void verifyAnswerSetsEqualityWithVar(Set answerSets) { + assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); + } + +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java similarity index 85% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java index 424ce245d..03120cdcb 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.List; @@ -36,14 +36,15 @@ import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; // TODO This is a functional test and should not be run with standard unit tests public class ThreeColouringRandomGraphTest { @@ -51,62 +52,62 @@ public class ThreeColouringRandomGraphTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testV3E3(RegressionTestConfig cfg) { + public void testV3E3(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV10E18(RegressionTestConfig cfg) { + public void testV10E18(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, 18, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV20E38(RegressionTestConfig cfg) { + public void testV20E38(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(20, 38, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV30E48(RegressionTestConfig cfg) { + public void testV30E48(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(30, 48, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV200E300(RegressionTestConfig cfg) { + public void testV200E300(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(200, 300, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV300E200(RegressionTestConfig cfg) { + public void testV300E200(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(300, 200, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV300E300(RegressionTestConfig cfg) { + public void testV300E300(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(300, 300, cfg)); } - private void testThreeColouring(int nVertices, int nEdges, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl().parse( + private void testThreeColouring(int nVertices, int nEdges, SystemConfig cfg) { + InputProgram tmpPrg = new ProgramParserImpl().parse( "blue(N) :- v(N), not red(N), not green(N)." + "red(N) :- v(N), not blue(N), not green(N)." + "green(N) :- v(N), not red(N), not blue(N)." + ":- e(N1,N2), blue(N1), blue(N2)." + ":- e(N1,N2), red(N1), red(N2)." + ":- e(N1,N2), green(N1), green(N2)."); - InputProgram.Builder prgBuilder = InputProgram.builder(tmpPrg); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(tmpPrg); prgBuilder.addFacts(createVertices(nVertices)); prgBuilder.addFacts(createEdges(nVertices, nEdges)); InputProgram program = prgBuilder.build(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java similarity index 85% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java index 821499ce4..8c94b383e 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.Collections; @@ -38,7 +38,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -46,7 +47,7 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: @@ -61,133 +62,133 @@ public class ThreeColouringTestWithRandom { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN3(RegressionTestConfig cfg) { + public void testN3(SystemConfig cfg) { long timeout = 3000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, false, 0, cfg)); } @RegressionTest - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 4000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(4, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN5(RegressionTestConfig cfg) { + public void testN5(SystemConfig cfg) { long timeout = 5000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(5, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN6(RegressionTestConfig cfg) { + public void testN6(SystemConfig cfg) { long timeout = 6000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(6, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN7(RegressionTestConfig cfg) { + public void testN7(SystemConfig cfg) { long timeout = 7000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(7, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN8(RegressionTestConfig cfg) { + public void testN8(SystemConfig cfg) { long timeout = 8000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(8, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN9(RegressionTestConfig cfg) { + public void testN9(SystemConfig cfg) { long timeout = 9000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(9, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10(RegressionTestConfig cfg) { + public void testN10(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random0(RegressionTestConfig cfg) { + public void testN10Random0(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random1(RegressionTestConfig cfg) { + public void testN10Random1(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random2(RegressionTestConfig cfg) { + public void testN10Random2(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random3(RegressionTestConfig cfg) { + public void testN10Random3(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19(RegressionTestConfig cfg) { + public void testN19(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random0(RegressionTestConfig cfg) { + public void testN19Random0(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random1(RegressionTestConfig cfg) { + public void testN19Random1(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random2(RegressionTestConfig cfg) { + public void testN19Random2(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random3(RegressionTestConfig cfg) { + public void testN19Random3(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN101(RegressionTestConfig cfg) { + public void testN101(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(101, false, 0, cfg)); } - private void testThreeColouring(int n, boolean shuffle, int seed, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl() + private void testThreeColouring(int n, boolean shuffle, int seed, SystemConfig cfg) { + InputProgram tmpPrg = new ProgramParserImpl() .parse("col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); - InputProgram.Builder prgBuilder = InputProgram.builder().accumulate(tmpPrg); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder().accumulate(tmpPrg); prgBuilder.addFacts(createColors("1", "2", "3")); prgBuilder.addFacts(createVertices(n)); prgBuilder.addFacts(createEdges(n, shuffle, seed)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java similarity index 86% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java index 989f241f3..f1fbc1001 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.List; @@ -36,7 +36,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -44,7 +45,7 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: @@ -59,51 +60,51 @@ public class ThreeColouringWheelTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(4, cfg)); } @RegressionTest - public void testN5(RegressionTestConfig cfg) { + public void testN5(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(5, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN6(RegressionTestConfig cfg) { + public void testN6(SystemConfig cfg) { long timeout = 6000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(6, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN3(RegressionTestConfig cfg) { + public void testN3(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN7(RegressionTestConfig cfg) { + public void testN7(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(7, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN11(RegressionTestConfig cfg) { + public void testN11(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(11, cfg)); } - private void testThreeColouring(int n, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl().parse( + private void testThreeColouring(int n, SystemConfig cfg) { + InputProgram tmpPrg = new ProgramParserImpl().parse( "col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); - InputProgram.Builder prgBuilder = InputProgram.builder(tmpPrg); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(tmpPrg); prgBuilder.addFacts(createColors("red", "blue", "green")); prgBuilder.addFacts(createVertices(n)); prgBuilder.addFacts(createEdges(n)); diff --git a/alpha-core/src/test/resources/partial-eval/pup_topological_order.asp b/alpha-solver/src/test/resources/partial-eval/pup_topological_order.asp similarity index 100% rename from alpha-core/src/test/resources/partial-eval/pup_topological_order.asp rename to alpha-solver/src/test/resources/partial-eval/pup_topological_order.asp diff --git a/alpha-core/src/test/resources/partial-eval/recursive_w_negated_condition.asp b/alpha-solver/src/test/resources/partial-eval/recursive_w_negated_condition.asp similarity index 100% rename from alpha-core/src/test/resources/partial-eval/recursive_w_negated_condition.asp rename to alpha-solver/src/test/resources/partial-eval/recursive_w_negated_condition.asp diff --git a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts index 4f89b9542..deace0036 100644 --- a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts @@ -6,6 +6,7 @@ plugins { id("jacoco") id("checkstyle") id("maven-publish") + id("java-test-fixtures") } repositories { @@ -34,6 +35,8 @@ dependencies { // Logging for tests testImplementation("org.slf4j:slf4j-simple:1.7.32") + + testFixturesApi(jupiter("api")) } // JUnit 5 From 1b04d740b1adca3fdd0a308a0f7d1009c6a67bde Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 8 Feb 2022 15:31:57 +0100 Subject: [PATCH 04/59] alpha-solver: improve test folder structure --- .gitattributes | 2 +- .gitignore | 1 + .../{api/impl => }/AggregateLiteralSplittingTest.java | 2 +- .../impl => }/AggregateOperatorNormalizationTest.java | 2 +- .../{api/impl => }/AggregateRewritingContextTest.java | 2 +- .../{api/impl => }/ArithmeticTermsRewritingTest.java | 2 +- .../{api/impl => }/FixedInterpretationLiteralsTest.java | 3 ++- .../at/ac/tuwien/kr/alpha/{api/impl => }/RuleParser.java | 2 +- .../tuwien/kr/alpha/{api/impl => }/RuleToStringTest.java | 2 +- .../tuwien/kr/alpha/regressiontests/AggregatesTest.java | 9 +++++---- .../kr/alpha/regressiontests/ArithmeticTermsTest.java | 5 +++-- .../tuwien/kr/alpha/regressiontests/HanoiTowerTest.java | 9 +++++---- .../regressiontests/HeadBodyTransformationTests.java | 5 +++-- .../kr/alpha/regressiontests/OmigaBenchmarksTest.java | 9 +++++---- .../regressiontests/PartSubpartConfigurationTest.java | 5 +++-- .../tuwien/kr/alpha/regressiontests/PigeonHoleTest.java | 7 ++++--- .../at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java | 5 +++-- .../kr/alpha/regressiontests/SolverStatisticsTests.java | 3 ++- .../ac/tuwien/kr/alpha/regressiontests/SolverTests.java | 9 +++++---- .../regressiontests/ThreeColouringRandomGraphTest.java | 5 +++-- .../regressiontests/ThreeColouringTestWithRandom.java | 5 +++-- .../alpha/regressiontests/ThreeColouringWheelTest.java | 5 +++-- .../{ => util}/AggregateRegressionTest.java | 4 ++-- .../alpha/regressiontests/{ => util}/RegressionTest.java | 4 ++-- .../{ => util}/RegressionTestConfigProvider.java | 2 +- .../regressiontests/{ => util}/RegressionTestUtils.java | 2 +- 26 files changed, 63 insertions(+), 48 deletions(-) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/{api/impl => }/AggregateLiteralSplittingTest.java (99%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/{api/impl => }/AggregateOperatorNormalizationTest.java (99%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/{api/impl => }/AggregateRewritingContextTest.java (99%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/{api/impl => }/ArithmeticTermsRewritingTest.java (98%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/{api/impl => }/FixedInterpretationLiteralsTest.java (99%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/{api/impl => }/RuleParser.java (94%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/{api/impl => }/RuleToStringTest.java (98%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/{ => util}/AggregateRegressionTest.java (71%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/{ => util}/RegressionTest.java (72%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/{ => util}/RegressionTestConfigProvider.java (99%) rename alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/{ => util}/RegressionTestUtils.java (98%) diff --git a/.gitattributes b/.gitattributes index 6d809091d..4adffdef2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,4 +16,4 @@ *.gpg filter=lfs diff=lfs merge=lfs binary *.bin filter=lfs diff=lfs merge=lfs binary -alpha-core/benchmarks/** linguist-vendored +alpha-solver/benchmarks/** linguist-vendored diff --git a/.gitignore b/.gitignore index 7f953ccdb..748e63db9 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,4 @@ gradle-app.setting /.dbeaver /Scripts /.vscode/ +*.code-workspace diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java similarity index 99% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java index f674121de..137074843 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java similarity index 99% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java index 5813bd930..707fcd6a6 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java similarity index 99% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java index d98e6a4f4..bd7011667 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java similarity index 98% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java index 8bc8d06b3..c812bfe95 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java similarity index 99% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java index 3e7a2e7af..0aafb40c7 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -17,6 +17,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java similarity index 94% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java index 43c0331fa..4893a20d8 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java similarity index 98% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java index 8fb606776..46f359403 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java @@ -23,7 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java index 525fae05d..f0f3508e2 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java @@ -25,12 +25,13 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNaiveSolver; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForSimplifiedSumAggregates; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNaiveSolver; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForSimplifiedSumAggregates; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.AggregateRegressionTest; /** * Tests if correct answer sets for programs containing aggregates are computed. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java index bda0b27d3..a7c5b5577 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java @@ -1,9 +1,10 @@ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests ASP programs containing arithmetic terms at arbitrary positions. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java index 9c460a169..bb6231461 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java @@ -25,10 +25,10 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNaiveSolver; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNaiveSolver; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; @@ -51,6 +51,7 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some hanoi tower test cases (see https://en.wikipedia.org/wiki/Tower_of_Hanoi). diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java index cb098c85b..63b6ff59b 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -43,6 +43,7 @@ import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests rule transformations described in the following research paper, and their effects on performance: * diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java index 125b5722a..31c67bae2 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java @@ -25,10 +25,10 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNaiveSolver; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNaiveSolver; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.io.IOException; import java.nio.file.Files; @@ -42,6 +42,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using Omiga benchmark problems. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java index 63b1d3326..d559b2971 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.collectRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertFalse; import java.util.ArrayList; @@ -37,6 +37,7 @@ import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some configuration test cases in which subparts are assigned to parts. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java index 7babe7ef7..73070b487 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java @@ -25,9 +25,9 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.collectRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; @@ -39,6 +39,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some pigeon-hole test cases (see https://en.wikipedia.org/wiki/Pigeonhole_principle). diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java index 3c6a5cd0c..6bca18e5e 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.io.IOException; import java.nio.file.Paths; @@ -40,6 +40,7 @@ import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using a racks configuration problem. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java index 8f0596ba5..b2bea6687 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -41,6 +41,7 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.solver.DefaultSolver; import at.ac.tuwien.kr.alpha.core.solver.NoGoodCounter; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; // TODO This is a functional test and should not be run with standard unit tests public class SolverStatisticsTests { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java index 5b3cf84e6..b6a27ad22 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java @@ -27,10 +27,10 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.collectRegressionTestAnswerSets; import static java.util.Collections.singleton; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -54,6 +54,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; // TODO This is a functional test and should not be run with standard unit tests diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java index 03120cdcb..19bf3f7e5 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.List; @@ -45,6 +45,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; // TODO This is a functional test and should not be run with standard unit tests public class ThreeColouringRandomGraphTest { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java index 8c94b383e..9f29deae8 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.Collections; @@ -48,6 +48,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java index f1fbc1001..554b6f8b5 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.regressiontests.RegressionTestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.List; @@ -46,6 +46,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregateRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/AggregateRegressionTest.java similarity index 71% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregateRegressionTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/AggregateRegressionTest.java index 9479744eb..ee4b07305 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregateRegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/AggregateRegressionTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.regressiontests; +package at.ac.tuwien.kr.alpha.regressiontests.util; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -11,7 +11,7 @@ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @ParameterizedTest -@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.RegressionTestConfigProvider#provideAggregateTestConfigs") +@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestConfigProvider#provideAggregateTestConfigs") public @interface AggregateRegressionTest { } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTest.java similarity index 72% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTest.java index 6c2497829..4b5b6f3cd 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.regressiontests; +package at.ac.tuwien.kr.alpha.regressiontests.util; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -11,7 +11,7 @@ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @ParameterizedTest -@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.RegressionTestConfigProvider#provideConfigs") +@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestConfigProvider#provideConfigs") public @interface RegressionTest { } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestConfigProvider.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java similarity index 99% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestConfigProvider.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java index bb9af932d..7a5e06633 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestConfigProvider.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.regressiontests; +package at.ac.tuwien.kr.alpha.regressiontests.util; import java.lang.reflect.Field; import java.util.ArrayList; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java similarity index 98% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestUtils.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java index afe46f929..82f2b88df 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RegressionTestUtils.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.regressiontests; +package at.ac.tuwien.kr.alpha.regressiontests.util; import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqualWithBase; From fdc4902aa0cf4040da339c7581c85518017d4219 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 10 Feb 2022 11:48:25 +0100 Subject: [PATCH 05/59] add action heads and draft evaluation --- .../kr/alpha/api/config/SystemConfig.java | 10 ++++ .../kr/alpha/api/programs/actions/Action.java | 22 +++++++ .../programs/literals/ComparisonLiteral.java | 2 +- .../kr/alpha/api/rules/RuleInstantiator.java | 11 ++++ .../kr/alpha/api/rules/heads/ActionHead.java | 17 ++++++ .../api/rules/heads/InstantiableHead.java | 11 ++++ .../kr/alpha/api/rules/heads/NormalHead.java | 2 +- .../alpha/app/config/CommandLineParser.java | 4 -- .../commons/rules/heads/ActionHeadImpl.java | 59 +++++++++++++++++++ .../kr/alpha/commons/rules/heads/Heads.java | 8 ++- .../commons/rules/heads/NormalHeadImpl.java | 9 ++- .../ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 | 7 ++- .../tuwien/kr/alpha/core/actions/Actions.java | 21 +++++++ ...erImpl.java => AbstractProgramParser.java} | 20 ++++--- .../ASPCore2ParseTreeVisitor.java} | 27 ++++++--- .../aspcore2/ASPCore2ProgramParser.java | 23 ++++++++ .../ASPCore2ProgramPartParser.java} | 10 ++-- .../parser/evolog/EvologParseTreeVisitor.java | 43 ++++++++++++++ .../parser/evolog/EvologProgramParser.java | 23 ++++++++ .../kr/alpha/core/programs/Programs.java | 6 +- .../IntervalTermToIntervalAtom.java | 1 + .../transformation/PredicateInternalizer.java | 10 +++- .../transformation/StratifiedEvaluation.java | 58 +++++++++++++++++- .../VariableEqualityRemoval.java | 3 +- .../encoders/AggregateEncoderFactory.java | 4 +- .../aggregates/encoders/MinMaxEncoder.java | 6 +- .../tuwien/kr/alpha/core/rules/BasicRule.java | 3 +- .../kr/alpha/core/rules/InternalRule.java | 1 + .../alpha/core/solver/NaiveNoGoodStore.java | 2 + .../kr/alpha/core/util/Substitutions.java | 4 +- .../alpha/core/parser/AspCore2ParserTest.java | 11 ++++ .../alpha/core/parser/EvologParserTest.java | 13 ++++ .../kr/alpha/core/parser/ParserTest.java | 22 ++++--- .../ProgramTransformationTest.java | 5 +- .../kr/alpha/test/AnswerSetsParser.java | 4 +- .../kr/alpha/api/impl/AlphaFactory.java | 6 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 2 + .../alpha/AggregateRewritingContextTest.java | 4 +- .../alpha/ArithmeticTermsRewritingTest.java | 4 +- .../at/ac/tuwien/kr/alpha/RuleParser.java | 4 +- .../ac/tuwien/kr/alpha/RuleToStringTest.java | 4 +- .../kr/alpha/api/impl/AlphaImplTest.java | 4 +- .../alpha/regressiontests/HanoiTowerTest.java | 4 +- .../HeadBodyTransformationTests.java | 4 +- .../regressiontests/OmigaBenchmarksTest.java | 4 +- .../kr/alpha/regressiontests/RacksTest.java | 4 +- .../ThreeColouringRandomGraphTest.java | 4 +- .../ThreeColouringTestWithRandom.java | 4 +- .../ThreeColouringWheelTest.java | 4 +- 49 files changed, 453 insertions(+), 85 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/RuleInstantiator.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/InstantiableHead.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{ProgramParserImpl.java => AbstractProgramParser.java} (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{ParseTreeVisitor.java => aspcore2/ASPCore2ParseTreeVisitor.java} (95%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{ProgramPartParser.java => aspcore2/ASPCore2ProgramPartParser.java} (87%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java index e5c94fefd..ec129fbc4 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java @@ -44,6 +44,7 @@ public class SystemConfig { // initializing from those values in order to have the values accessible in // contexts where no AlphaConfig instance exists (e.g. argument parsing from // command line) + public static final boolean DEFAULT_ACCEPT_EVOLOG = true; public static final String DEFAULT_SOLVER_NAME = "default"; public static final String DEFAULT_NOGOOD_STORE_NAME = "alphaRoaming"; public static final Heuristic DEFAULT_BRANCHING_HEURISTIC = Heuristic.VSIDS; @@ -63,6 +64,7 @@ public class SystemConfig { public static final String DEFAULT_ATOM_SEPARATOR = ", "; public static final AggregateRewritingConfig DEFAULT_AGGREGATE_REWRITING_CONFIG = new AggregateRewritingConfig(); + private boolean acceptEvologPrograms = DEFAULT_ACCEPT_EVOLOG; private String solverName = DEFAULT_SOLVER_NAME; private String nogoodStoreName = DEFAULT_NOGOOD_STORE_NAME; private long seed = DEFAULT_SEED; @@ -253,4 +255,12 @@ public void setAggregateRewritingConfig(AggregateRewritingConfig aggregateRewrit this.aggregateRewritingConfig = aggregateRewritingConfig; } + public boolean isAcceptEvologPrograms() { + return this.acceptEvologPrograms; + } + + public void setAcceptEvologPrograms(boolean acceptEvologPrograms) { + this.acceptEvologPrograms = acceptEvologPrograms; + } + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java new file mode 100644 index 000000000..4c4b350b9 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java @@ -0,0 +1,22 @@ +package at.ac.tuwien.kr.alpha.api.programs.actions; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +/** + * An action that gets executed as part of an action rule in an evolog program firing. + * + * Copyright (c) 2021, the Alpha Team. + */ +@FunctionalInterface +public interface Action { + + /** + * @param input a list of (ground) terms constituting the input of the action + * @return a function term representing the result of executing the action + */ + FunctionTerm execute(List input); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ComparisonLiteral.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ComparisonLiteral.java index 01b7d6075..5abf83c95 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ComparisonLiteral.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ComparisonLiteral.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.api.programs.literals; -public interface ComparisonLiteral extends Literal, FixedInterpretationLiteral { +public interface ComparisonLiteral extends FixedInterpretationLiteral { boolean isLeftOrRightAssigning(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/RuleInstantiator.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/RuleInstantiator.java new file mode 100644 index 000000000..2a521290c --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/RuleInstantiator.java @@ -0,0 +1,11 @@ +package at.ac.tuwien.kr.alpha.api.rules; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.rules.heads.InstantiableHead; + +public interface RuleInstantiator { + + BasicAtom instantiate(InstantiableHead ruleHead, Substitution substitution); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java new file mode 100644 index 000000000..1bc4c2674 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java @@ -0,0 +1,17 @@ +package at.ac.tuwien.kr.alpha.api.rules.heads; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; + +public interface ActionHead extends NormalHead { + + Action getAction(); + + List getActionInputTerms(); + + VariableTerm getActionOutputTerm(); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/InstantiableHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/InstantiableHead.java new file mode 100644 index 000000000..33c9c5f7f --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/InstantiableHead.java @@ -0,0 +1,11 @@ +package at.ac.tuwien.kr.alpha.api.rules.heads; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.rules.RuleInstantiator; + +public interface InstantiableHead extends Head { + + BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/NormalHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/NormalHead.java index 64c335807..4080c927d 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/NormalHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/NormalHead.java @@ -7,7 +7,7 @@ * * Copyright (c) 2021, the Alpha Team. */ -public interface NormalHead extends Head { +public interface NormalHead extends InstantiableHead { BasicAtom getAtom(); diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java index b8a27f880..8b68d0dc1 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java @@ -349,10 +349,6 @@ private void handleSort(Option opt, SystemConfig cfg) { cfg.setSortAnswerSets(true); } - private void handleDeterministic(Option opt, SystemConfig cfg) { - cfg.setSeed(0); - } - private void handleSeed(Option opt, SystemConfig cfg) { String optVal = opt.getValue(); long seed; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java new file mode 100644 index 000000000..a7310a771 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java @@ -0,0 +1,59 @@ +package at.ac.tuwien.kr.alpha.commons.rules.heads; + +import java.util.Collections; +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.rules.RuleInstantiator; +import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; + +class ActionHeadImpl implements ActionHead { + + private final BasicAtom atom; + private final Action action; + private final List actionInputTerms; + private final VariableTerm actionOutputTerm; + + ActionHeadImpl(BasicAtom atom, Action action, List actionInputTerms, VariableTerm actionOutputTerm) { + this.atom = atom; + this.action = action; + this.actionInputTerms = Collections.unmodifiableList(actionInputTerms); + this.actionOutputTerm = actionOutputTerm; + } + + @Override + public BasicAtom getAtom() { + return atom; + } + + @Override + public boolean isGround() { + // TODO: an action head is conceptually a basic one with an (interpreted) function term + return false; + } + + @Override + public BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution) { + return instantiator.instantiate(this, substitution); + } + + @Override + public Action getAction() { + return action; + } + + @Override + public List getActionInputTerms() { + return actionInputTerms; + } + + @Override + public VariableTerm getActionOutputTerm() { + return actionOutputTerm; + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java index 9e529a7e7..860ca5ee7 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java @@ -3,12 +3,15 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.rules.heads.ChoiceHead; import at.ac.tuwien.kr.alpha.api.rules.heads.ChoiceHead.ChoiceElement; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.rules.heads.ChoiceHeadImpl.ChoiceElementImpl; public final class Heads { @@ -29,5 +32,8 @@ public static ChoiceHead newChoiceHead(List choiceElements, Term public static ChoiceElement newChoiceElement(BasicAtom choiceAtom, List conditionLiterals) { return new ChoiceElementImpl(choiceAtom, conditionLiterals); } - + + public static ActionHead newActionHead(BasicAtom atom, Action action, List actionInputTerms, VariableTerm actionResult) { + return new ActionHeadImpl(atom, action, actionInputTerms, actionResult); + } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/NormalHeadImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/NormalHeadImpl.java index 2cdfc4404..b06ae99b6 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/NormalHeadImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/NormalHeadImpl.java @@ -1,11 +1,13 @@ package at.ac.tuwien.kr.alpha.commons.rules.heads; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.rules.RuleInstantiator; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; /** * Represents a normal head, i.e., a head that is an Atom. - * Copyright (c) 2019, the Alpha Team. + * Copyright (c) 2019-2021, the Alpha Team. */ class NormalHeadImpl implements NormalHead { @@ -61,4 +63,9 @@ public boolean equals(Object obj) { return true; } + @Override + public BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution) { + return instantiator.instantiate(this, substitution); + } + } diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 index aeca5cc2d..a8dada32d 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 @@ -6,6 +6,7 @@ import ASPLexer; * https://www.mat.unical.it/aspcomp2013/files/ASP-CORE-2.01c.pdf * (sections 4 and 5, pages 10-12). * It is extended a bit to parse widespread syntax (e.g. used by gringo/clasp). + * Furthermore, syntax features specific to Alpha's Evolog extension (action rules, asp modules) are included. */ program : statements? query? EOF; @@ -20,7 +21,9 @@ statement : head DOT # statement_fact | WCONS body? DOT SQUARE_OPEN weight_at_level SQUARE_CLOSE # statement_weightConstraint | directive # statement_directive; // NOT Core2 syntax. -head : disjunction | choice; +head : disjunction | choice | action; + +action: classical_literal COLON AT ID SQUARE_OPEN terms SQUARE_CLOSE EQUAL variable_term; // NOT Core2 syntax body : ( naf_literal | aggregate ) (COMMA body)?; @@ -87,4 +90,4 @@ variable_term : VARIABLE | ANONYMOUS_VARIABLE; answer_set : CURLY_OPEN classical_literal? (COMMA classical_literal)* CURLY_CLOSE; -answer_sets: answer_set* EOF; \ No newline at end of file +answer_sets: answer_set* EOF; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java new file mode 100644 index 000000000..5aff462d6 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java @@ -0,0 +1,21 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; + +public class Actions { + + public static FunctionTerm printLine(List input) { + if (input.size() != 1) { + // TODO do properly + throw new RuntimeException("Incorrect arity!"); + } + // TODO this should only work on ConstantTerm + System.out.println(input.get(0).toString()); + return Terms.newFunctionTerm("ok"); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java index e67cfaa4a..17684b602 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java @@ -22,18 +22,17 @@ import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ParseTreeVisitor; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -public class ProgramParserImpl implements ProgramParser { +public abstract class AbstractProgramParser implements ProgramParser { - private final Map preloadedExternals = new HashMap<>(); - - public ProgramParserImpl() { - this.preloadedExternals.putAll(Externals.getStandardLibraryExternals()); + private final Map preloadedExternals = new HashMap<>(Externals.getStandardLibraryExternals()); + + public AbstractProgramParser() { } - - public ProgramParserImpl(Map externals) { - this(); + + public AbstractProgramParser(Map externals) { this.preloadedExternals.putAll(externals); } @@ -126,7 +125,7 @@ public InputProgram parse(CharStream stream, Map programSources, Map externals); + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java index 3042a1183..d817b57d2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.parser; +package at.ac.tuwien.kr.alpha.core.parser.aspcore2; import static java.util.Collections.emptyList; @@ -75,24 +75,25 @@ import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2BaseVisitor; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** - * Copyright (c) 2016-2018, the Alpha Team. + * Copyright (c) 2016-2021, the Alpha Team. */ -public class ParseTreeVisitor extends ASPCore2BaseVisitor { +public class ASPCore2ParseTreeVisitor extends ASPCore2BaseVisitor { private final Map externals; private final boolean acceptVariables; private InputProgramImpl.Builder programBuilder; private InlineDirectives inlineDirectives; - public ParseTreeVisitor(Map externals) { + public ASPCore2ParseTreeVisitor(Map externals) { this(externals, true); } - public ParseTreeVisitor(Map externals, boolean acceptVariables) { + public ASPCore2ParseTreeVisitor(Map externals, boolean acceptVariables) { this.externals = externals; this.acceptVariables = acceptVariables; } @@ -231,11 +232,21 @@ public Head visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { @Override public Head visitHead(ASPCore2Parser.HeadContext ctx) { - // head : disjunction | choice; + // head : disjunction | choice | action; if (ctx.choice() != null) { return visitChoice(ctx.choice()); + } else if (ctx.action() != null) { + return visitAction(ctx.action()); + } else if (ctx.disjunction() != null) { + return visitDisjunction(ctx.disjunction()); } - return visitDisjunction(ctx.disjunction()); + throw notSupported(ctx); + } + + @Override + public Head visitAction(ASPCore2Parser.ActionContext ctx) { + // Actions are an Evolog-specific feature and therefore not supported by the ASPCore2 parser. + throw notSupported(ctx); } @Override @@ -400,7 +411,7 @@ public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { } @Override - public Term visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { + public VariableTerm visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { // variable_term : VARIABLE | ANONYMOUS_VARIABLE; if (ctx.VARIABLE() != null) { return Terms.newVariable(ctx.VARIABLE().getText()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java new file mode 100644 index 000000000..c4cd13ea7 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java @@ -0,0 +1,23 @@ +package at.ac.tuwien.kr.alpha.core.parser.aspcore2; + +import java.util.Map; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; + +public class ASPCore2ProgramParser extends AbstractProgramParser { + + public ASPCore2ProgramParser() { + super(); + } + + public ASPCore2ProgramParser(Map externals) { + super(externals); + } + + @Override + protected ASPCore2ParseTreeVisitor createParseTreeVisitor(Map externals) { + return new ASPCore2ParseTreeVisitor(externals); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramPartParser.java similarity index 87% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramPartParser.java index bc2690666..75ae21fd9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramPartParser.java @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.parser; +package at.ac.tuwien.kr.alpha.core.parser.aspcore2; import java.util.Collections; @@ -41,13 +41,15 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; /** - * A parser that, in contrast to {@link ProgramParserImpl}, does not parse full programs but only program parts like + * A parser that, in contrast to {@link AbstractProgramParser}, does not parse full programs but only program parts like * atoms, terms and such. */ -public class ProgramPartParser { - private final ParseTreeVisitor visitor = new ParseTreeVisitor(Collections.emptyMap(), true); +// TODO adapt this and create evolog version +public class ASPCore2ProgramPartParser { + private final ASPCore2ParseTreeVisitor visitor = new ASPCore2ParseTreeVisitor(Collections.emptyMap(), true); public Term parseTerm(String s) { final ASPCore2Parser parser = getASPCore2Parser(s); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java new file mode 100644 index 000000000..bf10553cc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java @@ -0,0 +1,43 @@ +package at.ac.tuwien.kr.alpha.core.parser.evolog; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; +import at.ac.tuwien.kr.alpha.core.actions.Actions; +import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ParseTreeVisitor; + +public class EvologParseTreeVisitor extends ASPCore2ParseTreeVisitor { + + private final Map actionRegistry = new HashMap<>(); + + public EvologParseTreeVisitor(Map externals, boolean acceptVariables) { + super(externals, acceptVariables); + actionRegistry.put("printLine", Actions::printLine); + } + + public EvologParseTreeVisitor(Map externals) { + this(externals, true); + } + + @Override + public Head visitAction(ASPCore2Parser.ActionContext ctx) { + BasicAtom atom = visitClassical_literal(ctx.classical_literal()); + VariableTerm actionResultTerm = visitVariable_term(ctx.variable_term()); + String actionId = ctx.ID().getText(); + if (!actionRegistry.containsKey(actionId)) { + throw new UnsupportedOperationException("Could not resolve action name " + actionId); + } + List actionInputTerms = visitTerms(ctx.terms()); + return Heads.newActionHead(atom, actionRegistry.get(actionId), actionInputTerms, actionResultTerm); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java new file mode 100644 index 000000000..9f1079922 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java @@ -0,0 +1,23 @@ +package at.ac.tuwien.kr.alpha.core.parser.evolog; + +import java.util.Map; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; + +public class EvologProgramParser extends AbstractProgramParser { + + public EvologProgramParser(Map externals) { + super(externals); + } + + public EvologProgramParser() { + super(); + } + + @Override + protected EvologParseTreeVisitor createParseTreeVisitor(Map externals) { + return new EvologParseTreeVisitor(externals); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java index e3f184886..83e9ab9c9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java @@ -8,7 +8,8 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; public class Programs { @@ -16,8 +17,9 @@ private Programs() { throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); } + // TODO integrate this Method into Alpha interface so we have a parser following overall system config public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { - ProgramParserImpl parser = new ProgramParserImpl(); + AbstractProgramParser parser = new EvologProgramParser(); return parser.parse(CharStreams.fromStream(is), externals); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java index 36920ec71..fd523432b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java @@ -78,6 +78,7 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { } // Note that this cast is safe: NormalHead can only have a BasicAtom, so literalizing and getting back the Atom destroys type information, // but should never yield anything other than a BasicAtom + // TODO what about intervals in action heads? NormalHead rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead((BasicAtom) rewriteLiteral(rule.getHead().getAtom().toLiteral(), intervalReplacements).getAtom()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index 9deb24b06..7662edff1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -10,6 +10,7 @@ import at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.commons.Predicates; @@ -50,7 +51,14 @@ public static Rule makePrefixedPredicatesInternal(Rule rule, String } NormalHead head = (NormalHead) rule.getHead(); if (head.getAtom().getPredicate().getName().startsWith(prefix)) { - newHead = Heads.newNormalHead(makePredicateInternal(head.getAtom())); + // TODO do this nicely (using visitor?) + if (head instanceof ActionHead) { + ActionHead actionHead = (ActionHead) head; + newHead = Heads.newActionHead(makePredicateInternal(actionHead.getAtom()), actionHead.getAction(), actionHead.getActionInputTerms(), + actionHead.getActionOutputTerm()); + } else { + newHead = Heads.newNormalHead(makePredicateInternal(head.getAtom())); + } } else { newHead = head; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 2c3105134..379c86875 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -18,10 +18,19 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.RuleInstantiator; +import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; +import at.ac.tuwien.kr.alpha.api.rules.heads.InstantiableHead; +import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; @@ -43,7 +52,7 @@ * * Copyright (c) 2019-2020, the Alpha Team. */ -public class StratifiedEvaluation extends ProgramTransformation { +public class StratifiedEvaluation extends ProgramTransformation implements RuleInstantiator { private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluation.class); @@ -301,7 +310,13 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde } private void fireRule(CompiledRule rule, Substitution substitution) { - Atom newAtom = rule.getHeadAtom().substitute(substitution); + // BasicAtom newAtom = this.instantiate(rule.getHead(), substitution); + BasicAtom newAtom; + if (rule.getHead() instanceof ActionHead) { + newAtom = instantiateActionHead((ActionHead) rule.getHead(), substitution); + } else { + newAtom = instantiateNormalHead(rule.getHead(), substitution); + } if (!newAtom.isGround()) { throw new IllegalStateException("Trying to fire rule " + rule.toString() + " with incompatible substitution " + substitution.toString()); } @@ -309,6 +324,45 @@ private void fireRule(CompiledRule rule, Substitution substitution) { workingMemory.addInstance(newAtom, true); } + @Override + public BasicAtom instantiate(InstantiableHead ruleHead, Substitution substitution) { + return ruleHead.instantiate(this, substitution); + } + + // FIXME should be dispatched via visitor pattern + public BasicAtom instantiateNormalHead(NormalHead head, Substitution substitution) { + return head.getAtom().substitute(substitution); + } + + // FIXME should be dispatched via visitor pattern + public BasicAtom instantiateActionHead(ActionHead head, Substitution substitution) { + // TODO ensure unique action only gets executed once! + List actionInput = head.getActionInputTerms(); + List substitutedInput = new ArrayList<>(); + // Substitute all variables in action input so that all input terms are ground. + for (Term inputTerm : actionInput) { + // TODO handle variables nested in function terms as well! + if (inputTerm instanceof VariableTerm) { + VariableTerm inputVar = (VariableTerm) inputTerm; + if (!substitution.isVariableSet(inputVar)) { + throw new IllegalStateException( + "No substitute for action input variable " + inputVar.toString() + " in substitution: " + substitution.toString()); + } + substitutedInput.add(inputVar.substitute(substitution)); + } else { + substitutedInput.add(inputTerm); + } + } + // Call the actual action. + // TODO exception handling (translate EVERY throwable to an error term) + Action action = head.getAction(); + FunctionTerm actionResult = action.execute(substitutedInput); + // We have an action result. Add it to the substitution as the substitute for the variable bound to the action so we're able to obtain the + // ground BasicAtom derived by the rule + substitution.put(head.getActionOutputTerm(), actionResult); + return head.getAtom().substitute(substitution); + } + private ComponentEvaluationInfo getRulesToEvaluate(ComponentGraph.SCComponent comp) { Set nonRecursiveRules = new HashSet<>(); Set recursiveRules = new HashSet<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 11f361cd4..3d74801a1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -116,7 +116,8 @@ private Rule findAndReplaceVariableEquality(Rule rule) { if (!rule.isConstraint() && rule.getHead() instanceof DisjunctiveHead) { throw new UnsupportedOperationException("VariableEqualityRemoval cannot be applied to rule with DisjunctiveHead, yet."); } - NormalHead rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead(((NormalHead)rule.getHead()).getAtom()); + // TODO handle action heads! + NormalHead rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom()); // Use substitution for actual replacement. Unifier replacementSubstitution = new Unifier(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java index cb3d1152a..c1a6ad17e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java @@ -34,11 +34,11 @@ public SumEncoder newSumLessOrEqualEncoder() { } public MinMaxEncoder newMinEncoder() { - return new MinMaxEncoder(AggregateFunctionSymbol.MIN); + return new MinMaxEncoder(parserFactory.get(), AggregateFunctionSymbol.MIN); } public MinMaxEncoder newMaxEncoder() { - return new MinMaxEncoder(AggregateFunctionSymbol.MAX); + return new MinMaxEncoder(parserFactory.get(), AggregateFunctionSymbol.MAX); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java index 316d1ad5c..9ecb6f0b2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java @@ -26,7 +26,6 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -59,13 +58,14 @@ public class MinMaxEncoder extends AbstractAggregateEncoder { ); //@formatter:on - private final ProgramParser parser = new ProgramParserImpl(); + private final ProgramParser parser; - public MinMaxEncoder(AggregateFunctionSymbol func) { + public MinMaxEncoder(ProgramParser parser, AggregateFunctionSymbol func) { super(func, SetUtils.hashSet(ComparisonOperators.operators())); if (!(func == AggregateFunctionSymbol.MAX || func == AggregateFunctionSymbol.MIN)) { throw new IllegalArgumentException("Encoder " + this.getClass().getSimpleName() + " can only encode min/max aggregates!"); } + this.parser = parser; } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java index 1c218769a..bc3076f85 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java @@ -31,7 +31,6 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; /** @@ -40,7 +39,7 @@ * This implementation represents a rule after being parsed from a given ASP program, but before being transformed into a * {@link NormalRuleImpl}. */ -public class BasicRule extends AbstractRule implements Rule { +public class BasicRule extends AbstractRule { public BasicRule(Head head, List body) { super(head, body); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java index 3283ac64f..0df14b399 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java @@ -110,6 +110,7 @@ public static CompiledRule fromNormalRule(Rule rule) { */ @Override public InternalRule renameVariables(String newVariablePostfix) { + // TODO handle action heads! List occurringVariables = new ArrayList<>(); BasicAtom headAtom = this.getHeadAtom(); occurringVariables.addAll(headAtom.getOccurringVariables()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStore.java index 7eb8bc6a2..7a7222e5f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStore.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStore.java @@ -38,6 +38,8 @@ import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.*; public class NaiveNoGoodStore implements NoGoodStore { + + @SuppressWarnings("unused") private static final Logger LOGGER = LoggerFactory.getLogger(NaiveNoGoodStore.class); private HashMap delegate = new HashMap<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Substitutions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Substitutions.java index 40470cf09..8d92163b0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Substitutions.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Substitutions.java @@ -5,11 +5,11 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramPartParser; public final class Substitutions { - private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); + private static final ASPCore2ProgramPartParser PROGRAM_PART_PARSER = new ASPCore2ProgramPartParser(); private Substitutions() { throw new AssertionError("Cannot instantiate utility class!"); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java new file mode 100644 index 000000000..fd40c3db6 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java @@ -0,0 +1,11 @@ +package at.ac.tuwien.kr.alpha.core.parser; + +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; + +public class AspCore2ParserTest extends ParserTest { + + protected AspCore2ParserTest() { + super(new ASPCore2ProgramParser()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java new file mode 100644 index 000000000..5621615cc --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java @@ -0,0 +1,13 @@ +package at.ac.tuwien.kr.alpha.core.parser; + +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; + +public class EvologParserTest extends ParserTest { + + protected EvologParserTest() { + super(new EvologProgramParser()); + } + + + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index f8346e33a..28e1f2574 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -33,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; +import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.Arrays; import java.util.Collections; @@ -40,12 +41,11 @@ import java.util.Optional; import java.util.stream.Stream; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; @@ -62,10 +62,15 @@ import at.ac.tuwien.kr.alpha.commons.util.Util; /** - * Copyright (c) 2016, the Alpha Team. + * Copyright (c) 2016-2021, the Alpha Team. */ -public class ParserTest { - private final ProgramParserImpl parser = new ProgramParserImpl(); +public abstract class ParserTest { + + private final ProgramParser parser; + + protected ParserTest(ProgramParser parser) { + this.parser = parser; + } @Test public void parseFact() { @@ -167,7 +172,7 @@ public void literate() throws IOException { "", "Test!"))); - final String actual = new ProgramParserImpl().parse(CharStreams.fromChannel(input)).toString(); + final String actual = parser.parse(Channels.newInputStream(input)).toString(); final String expected = "p(a)." + System.lineSeparator(); assertEquals(expected, actual); @@ -221,8 +226,7 @@ public void cardinalityAggregate() { @Test public void stringWithEscapedQuotes() throws IOException { - CharStream stream = CharStreams.fromStream(ParserTest.class.getResourceAsStream("/escaped_quotes.asp")); - InputProgram prog = parser.parse(stream); + InputProgram prog = parser.parse(ParserTest.class.getResourceAsStream("/escaped_quotes.asp")); assertEquals(1, prog.getFacts().size()); Atom stringAtom = prog.getFacts().get(0); String stringWithQuotes = stringAtom.getTerms().get(0).toString(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index d008dd21b..f56f48ccf 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.externals.Externals; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; // TODO This is a functional test and should not be run with standard unit tests @@ -26,7 +26,8 @@ public class ProgramTransformationTest { private static final String TESTFILES_PATH = "/transform-test/"; - private static final ProgramParser PARSER = new ProgramParserImpl(); + // TODO should this always be an evolog parser? + private static final ProgramParser PARSER = new EvologProgramParser(); private ChoiceHeadToNormal choiceToNormal = new ChoiceHeadToNormal(); private IntervalTermToIntervalAtom intervalRewriting = new IntervalTermToIntervalAtom(); diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java index c98e29f3a..ecbac5312 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java @@ -14,11 +14,11 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.parser.ParseTreeVisitor; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ParseTreeVisitor; public class AnswerSetsParser { - private static final ParseTreeVisitor VISITOR = new ParseTreeVisitor(Collections.emptyMap(), false); + private static final ASPCore2ParseTreeVisitor VISITOR = new ASPCore2ParseTreeVisitor(Collections.emptyMap(), false); public static Set parse(String s) { try { diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index 9a3093255..b0e89d72e 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -9,7 +9,8 @@ import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewriting; @@ -25,7 +26,8 @@ private AlphaFactory() { } public static Alpha newAlpha(SystemConfig cfg) { - Supplier parserFactory = () -> new ProgramParserImpl(); + // Parser factory - Supply correct parser dependent on the accepted input language. + Supplier parserFactory = () -> cfg.isAcceptEvologPrograms() ? new EvologProgramParser() : new ASPCore2ProgramParser(); // AggregateEncoderFactory depends on parser factory since stringtemplate-based aggregate encoders need to use the same parser that's used // for input programs. diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index 934ce13bd..f2106fb5e 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -156,6 +156,8 @@ InternalProgram performProgramPreprocessing(NormalProgram program) { InternalProgram retVal = InternalProgram.fromNormalProgram(program); if (enableStratifiedEvaluation) { AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); + // TODO as Evolog moves further along, we want to integrate stratified evaluation with grounder and solver. + // Therefore, leave it as is and don't make part of factory API for now. retVal = new StratifiedEvaluation().apply(analyzed); } return retVal; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java index bd7011667..0acbb173a 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java @@ -18,7 +18,7 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; @@ -60,7 +60,7 @@ public class AggregateRewritingContextTest { //@formatter:on private static final AggregateRewritingContext rewritingContextForAspString(String asp) { - InputProgram program = new ProgramParserImpl().parse(asp); + InputProgram program = new EvologProgramParser().parse(asp); AggregateRewritingContext ctx = new AggregateRewritingContext(); for (Rule rule : program.getRules()) { ctx.registerRule(rule); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java index c812bfe95..d642e2cf8 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java @@ -23,7 +23,7 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermsRewriting; @@ -34,7 +34,7 @@ public class ArithmeticTermsRewritingTest { private final Map externalsOfThisClass = Externals.scan(ArithmeticTermsRewritingTest.class); - private final ProgramParser parser = new ProgramParserImpl(externalsOfThisClass); // Create parser that knows an implementation of external atom &extArithTest[](). + private final ProgramParser parser = new EvologProgramParser(externalsOfThisClass); // Create parser that knows an implementation of external atom &extArithTest[](). @Predicate(name = "extArithTest") public static Set>> externalForArithmeticTermsRewriting(Integer in) { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java index 4893a20d8..69982ad45 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java @@ -4,12 +4,12 @@ import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; public class RuleParser { public static Rule parse(String str) { - ProgramParser parser = new ProgramParserImpl(); + ProgramParser parser = new EvologProgramParser(); InputProgram prog = parser.parse(str); if (!prog.getFacts().isEmpty()) { throw new IllegalArgumentException("Expected exactly one rule and no facts!"); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java index 46f359403..1234baadc 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java @@ -35,7 +35,7 @@ import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; @@ -45,7 +45,7 @@ * Tests {@link BasicRule#toString()} and {@link InternalRule#toString()}. */ public class RuleToStringTest { - private final ProgramParser parser = new ProgramParserImpl(); + private final ProgramParser parser = new EvologProgramParser(); @Test public void positiveRuleToString() { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 96907fad6..4b3920483 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -75,7 +75,7 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -620,7 +620,7 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep // Detailed reproduction test-case for github issue #239. @Test public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { - final ProgramParser parser = new ProgramParserImpl(); + final ProgramParser parser = new ASPCore2ProgramParser(); InputProgramImpl.Builder bld = InputProgramImpl.builder(); bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), StandardOpenOption.READ))); bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"), StandardOpenOption.READ))); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java index bb6231461..2110e98f4 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java @@ -50,7 +50,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** @@ -108,7 +108,7 @@ private void testHanoiTower(int instance, SystemConfig cfg) throws IOException { private void testHanoiTower(String instance, SystemConfig cfg) throws IOException { // TODO should be read by the Alpha instance constructed in buildSolverForRegressionTest, // do not instantiate parsers "free-style"! - InputProgram prog = new ProgramParserImpl().parse( + InputProgram prog = new ASPCore2ProgramParser().parse( Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); Solver solver = buildSolverForRegressionTest(prog, cfg); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java index 63b6ff59b..36f0f1ecc 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java @@ -42,7 +42,7 @@ import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests rule transformations described in the following research paper, and their effects on performance: @@ -246,7 +246,7 @@ private InputProgram constructProgramA_TransformationA(int n) { private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { assertEquals(numberOfRules, strRules.size()); String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - InputProgram parsedProgram = new ProgramParserImpl().parse(strProgram); + InputProgram parsedProgram = new EvologProgramParser().parse(strProgram); assertEquals(numberOfRules, parsedProgram.getRules().size()); return parsedProgram; } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java index 31c67bae2..c481b4a99 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java @@ -41,7 +41,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** @@ -112,7 +112,7 @@ public void testReach_4(SystemConfig cfg) { private void test(String folder, String aspFileName, SystemConfig cfg) throws IOException { @SuppressWarnings("unused") Optional answerSet = buildSolverForRegressionTest( - new ProgramParserImpl().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) + new EvologProgramParser().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) .stream().findFirst(); // System.out.println(answerSet); // TODO: check correctness of answer set diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java index 6bca18e5e..ecdb85095 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** @@ -61,7 +61,7 @@ public void testRacks(SystemConfig cfg) { private void test(SystemConfig cfg) throws IOException { CharStream programInputStream = CharStreams.fromPath( Paths.get("benchmarks", "siemens", "racks", "racks.lp")); - Solver solver = buildSolverForRegressionTest(new ProgramParserImpl().parse(programInputStream), cfg); + Solver solver = buildSolverForRegressionTest(new EvologProgramParser().parse(programInputStream), cfg); @SuppressWarnings("unused") Optional answerSet = solver.stream().findFirst(); // System.out.println(answerSet); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java index 19bf3f7e5..7782b110a 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java @@ -43,7 +43,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; @@ -101,7 +101,7 @@ public void testV300E300(SystemConfig cfg) { } private void testThreeColouring(int nVertices, int nEdges, SystemConfig cfg) { - InputProgram tmpPrg = new ProgramParserImpl().parse( + InputProgram tmpPrg = new ASPCore2ProgramParser().parse( "blue(N) :- v(N), not red(N), not green(N)." + "red(N) :- v(N), not blue(N), not green(N)." + "green(N) :- v(N), not red(N), not blue(N)." + diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java index 9f29deae8..550c34809 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java @@ -46,7 +46,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; @@ -187,7 +187,7 @@ public void testN101(SystemConfig cfg) { } private void testThreeColouring(int n, boolean shuffle, int seed, SystemConfig cfg) { - InputProgram tmpPrg = new ProgramParserImpl() + InputProgram tmpPrg = new ASPCore2ProgramParser() .parse("col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder().accumulate(tmpPrg); prgBuilder.addFacts(createColors("1", "2", "3")); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java index 554b6f8b5..a94f12ae5 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java @@ -44,7 +44,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; @@ -101,7 +101,7 @@ public void testN11(SystemConfig cfg) { } private void testThreeColouring(int n, SystemConfig cfg) { - InputProgram tmpPrg = new ProgramParserImpl().parse( + InputProgram tmpPrg = new ASPCore2ProgramParser().parse( "col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); From 50975873b28276ad29e411c7b7ce6e212029ca1a Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 10 Feb 2022 20:03:20 +0100 Subject: [PATCH 06/59] account for action heads in rewritings and rule translations --- .../transformation/VariableEqualityRemoval.java | 13 +++++++++++-- .../ac/tuwien/kr/alpha/core/rules/AbstractRule.java | 6 +++--- .../ac/tuwien/kr/alpha/core/rules/InternalRule.java | 2 +- .../tuwien/kr/alpha/core/rules/NormalRuleImpl.java | 13 +++---------- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 3d74801a1..0086de1fe 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -42,6 +42,7 @@ import at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.rules.heads.DisjunctiveHead; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; @@ -116,8 +117,16 @@ private Rule findAndReplaceVariableEquality(Rule rule) { if (!rule.isConstraint() && rule.getHead() instanceof DisjunctiveHead) { throw new UnsupportedOperationException("VariableEqualityRemoval cannot be applied to rule with DisjunctiveHead, yet."); } - // TODO handle action heads! - NormalHead rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom()); + + NormalHead head = (NormalHead) rule.getHead(); + NormalHead rewrittenHead; + // TODO can this be done nicer? + if(rule.getHead() instanceof ActionHead) { + ActionHead actHead = (ActionHead) head; + rewrittenHead = Heads.newActionHead(actHead.getAtom(), actHead.getAction(), actHead.getActionInputTerms(), actHead.getActionOutputTerm()); + } else { + rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom()); + } // Use substitution for actual replacement. Unifier replacementSubstitution = new Unifier(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java index dad66bc2d..efa0d5785 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java @@ -27,7 +27,7 @@ public abstract class AbstractRule implements Rule { private final Set bodyLiteralsPositive; private final Set bodyLiteralsNegative; - public AbstractRule(H head, List body) { + public AbstractRule(H head, Set body) { this.head = head; Set positiveBody = new LinkedHashSet<>(); Set negativeBody = new LinkedHashSet<>(); @@ -49,8 +49,8 @@ public AbstractRule(H head, List body) { } } - public AbstractRule(H head, Set body) { - this(head, new ArrayList<>(body)); + public AbstractRule(H head, List body) { + this(head, new LinkedHashSet<>(body)); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java index 0df14b399..8e9e797f5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java @@ -98,7 +98,7 @@ public static void resetIdGenerator() { } public static CompiledRule fromNormalRule(Rule rule) { - return new InternalRule(rule.isConstraint() ? null : Heads.newNormalHead(rule.getHead().getAtom()), new ArrayList<>(rule.getBody())); + return new InternalRule(rule.getHead(), new ArrayList<>(rule.getBody())); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java index 5283a6a6d..6f520bf63 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java @@ -1,6 +1,5 @@ package at.ac.tuwien.kr.alpha.core.rules; -import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -10,8 +9,6 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; -import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; -import at.ac.tuwien.kr.alpha.commons.util.Util; /** * A rule that has a normal head, i.e. just one head atom, no disjunction or choice heads allowed. @@ -30,14 +27,10 @@ public NormalRuleImpl(NormalHead head, Set body) { } public static NormalRuleImpl fromBasicRule(Rule rule) { - BasicAtom headAtom = null; - if (!rule.isConstraint()) { - if (!(rule.getHead() instanceof NormalHead)) { - throw Util.oops("Trying to construct a NormalRule from rule with non-normal head! Head type is: " + rule.getHead().getClass().getSimpleName()); - } - headAtom = ((NormalHead) rule.getHead()).getAtom(); + if(!(rule.getHead() instanceof NormalHead)) { + throw new IllegalArgumentException("Cannot create normal rule for unsupported head type " + rule.getHead().getClass().getSimpleName()); } - return new NormalRuleImpl(headAtom != null ? Heads.newNormalHead(headAtom) : null, new ArrayList<>(rule.getBody())); + return new NormalRuleImpl((NormalHead) rule.getHead(), rule.getBody()); } public boolean isGround() { From b975a9cfb91954f7c5c93a7d14b87567d0016490 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 11 Feb 2022 13:27:16 +0100 Subject: [PATCH 07/59] refactoring: factory methods for rules --- .../tuwien/kr/alpha/api/rules/NormalRule.java | 2 + .../kr/alpha/commons}/rules/AbstractRule.java | 21 ++--- .../kr/alpha/commons}/rules/BasicRule.java | 15 ++-- .../alpha/commons}/rules/NormalRuleImpl.java | 21 +---- .../tuwien/kr/alpha/commons/rules/Rules.java | 46 ++++++++++ .../alpha/core/grounder/BridgedGrounder.java | 6 +- .../core/grounder/RuleGroundingOrderImpl.java | 4 +- .../alpha/core/grounder/bridges/Bridge.java | 4 +- .../LiteralInstantiationResult.java | 4 +- .../aspcore2/ASPCore2ParseTreeVisitor.java | 19 ++-- .../alpha/core/programs/InternalProgram.java | 10 +-- .../core/programs/NormalProgramImpl.java | 10 ++- .../ArithmeticTermsRewriting.java | 13 +-- .../transformation/ChoiceHeadToNormal.java | 14 +-- .../transformation/EnumerationRewriting.java | 8 +- .../IntervalTermToIntervalAtom.java | 8 +- .../transformation/PredicateInternalizer.java | 10 +-- .../VariableEqualityRemoval.java | 21 +++-- .../aggregates/AggregateLiteralSplitting.java | 22 ++--- .../AggregateOperatorNormalization.java | 22 ++--- .../aggregates/AggregateRewriting.java | 7 +- .../encoders/AbstractAggregateEncoder.java | 8 +- .../aggregates/encoders/MinMaxEncoder.java | 12 +-- .../StringtemplateBasedAggregateEncoder.java | 7 +- .../kr/alpha/core/rules/CompiledRule.java | 1 - ...nternalRule.java => CompiledRuleImpl.java} | 90 ++++++++++++++----- .../kr/alpha/core/rules/CompiledRules.java | 27 ++++++ .../ac/tuwien/kr/alpha/core/rules/Rules.java | 28 ------ .../kr/alpha/core/common/ProgramTest.java | 2 +- .../tuwien/kr/alpha/core/common/RuleTest.java | 15 ++-- .../GrounderMockWithBasicProgram.java | 9 +- .../core/grounder/GrounderMockWithChoice.java | 13 ++- .../alpha/core/grounder/SubstitutionTest.java | 6 +- .../RuleGroundingInfoTest.java | 24 ++--- .../alpha/core/solver/AtomCounterTests.java | 6 +- .../alpha/core/solver/ChoiceManagerTests.java | 4 +- .../AlphaHeuristicTestAssumptions.java | 12 +-- .../ac/tuwien/kr/alpha/RuleToStringTest.java | 11 +-- .../kr/alpha/api/impl/AlphaImplTest.java | 9 +- 39 files changed, 327 insertions(+), 244 deletions(-) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/rules/AbstractRule.java (87%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/rules/BasicRule.java (85%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/rules/NormalRuleImpl.java (54%) create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/Rules.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/{InternalRule.java => CompiledRuleImpl.java} (74%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/{grounder => rules}/RuleGroundingInfoTest.java (88%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalRule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalRule.java index 5a5c995c6..fb0bef941 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalRule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalRule.java @@ -12,4 +12,6 @@ public interface NormalRule extends Rule { BasicAtom getHeadAtom(); + boolean isGround(); + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/AbstractRule.java similarity index 87% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/AbstractRule.java index efa0d5785..3431a637a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/AbstractRule.java @@ -1,9 +1,7 @@ -package at.ac.tuwien.kr.alpha.core.rules; +package at.ac.tuwien.kr.alpha.commons.rules; -import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; -import java.util.List; import java.util.Objects; import java.util.Set; @@ -21,13 +19,13 @@ * * Copyright (c) 2017-2019, the Alpha Team. */ -public abstract class AbstractRule implements Rule { +abstract class AbstractRule implements Rule { private final H head; private final Set bodyLiteralsPositive; private final Set bodyLiteralsNegative; - public AbstractRule(H head, Set body) { + AbstractRule(H head, Set body) { this.head = head; Set positiveBody = new LinkedHashSet<>(); Set negativeBody = new LinkedHashSet<>(); @@ -48,10 +46,6 @@ public AbstractRule(H head, Set body) { + "Notice: A rule is considered safe if all variables occurring in negative literals, builtin atoms, and the head of the rule also occur in some positive literal."); } } - - public AbstractRule(H head, List body) { - this(head, new LinkedHashSet<>(body)); - } /** * Checks whether a rule is safe. The actual safety condition may vary over the next improvements. Currently, a rule is @@ -127,13 +121,12 @@ public boolean equals(Object obj) { if (this == obj) { return true; } - if (!(obj instanceof AbstractRule)) { + if (!(obj instanceof Rule)) { return false; } - AbstractRule other = (AbstractRule) obj; - return Objects.equals(this.bodyLiteralsNegative, other.bodyLiteralsNegative) - && Objects.equals(this.bodyLiteralsPositive, other.bodyLiteralsPositive) - && Objects.equals(this.head, other.head); + Rule other = (Rule) obj; + return Objects.equals(this.getBody(), other.getBody()) + && Objects.equals(this.head, other.getHead()); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/BasicRule.java similarity index 85% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/BasicRule.java index bc3076f85..64ee0daa5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/BasicRule.java @@ -25,27 +25,24 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.rules; +package at.ac.tuwien.kr.alpha.commons.rules; -import java.util.Arrays; -import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; /** * Represents a non-ground rule or a constraint. A {@link BasicRule} has a general {@link Head}, meaning both choice heads and disjunctive * heads are permissible. * This implementation represents a rule after being parsed from a given ASP program, but before being transformed into a - * {@link NormalRuleImpl}. + * {@link NormalRule}. */ -public class BasicRule extends AbstractRule { +class BasicRule extends AbstractRule { - public BasicRule(Head head, List body) { + BasicRule(Head head, Set body) { super(head, body); } - public BasicRule(Head head, Literal... body) { - this(head, Arrays.asList(body)); - } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/NormalRuleImpl.java similarity index 54% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/NormalRuleImpl.java index 6f520bf63..6380c4e4a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/NormalRuleImpl.java @@ -1,13 +1,10 @@ -package at.ac.tuwien.kr.alpha.core.rules; +package at.ac.tuwien.kr.alpha.commons.rules; -import java.util.List; import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.rules.NormalRule; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; /** @@ -16,23 +13,13 @@ * * Copyright (c) 2019, the Alpha Team. */ -public class NormalRuleImpl extends AbstractRule implements NormalRule { +class NormalRuleImpl extends AbstractRule implements NormalRule { - public NormalRuleImpl(NormalHead head, List body) { + NormalRuleImpl(NormalHead head, Set body) { super(head, body); } - public NormalRuleImpl(NormalHead head, Set body) { - super(head, body); - } - - public static NormalRuleImpl fromBasicRule(Rule rule) { - if(!(rule.getHead() instanceof NormalHead)) { - throw new IllegalArgumentException("Cannot create normal rule for unsupported head type " + rule.getHead().getClass().getSimpleName()); - } - return new NormalRuleImpl((NormalHead) rule.getHead(), rule.getBody()); - } - + @Override public boolean isGround() { if (!isConstraint() && !this.getHead().isGround()) { return false; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/Rules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/Rules.java new file mode 100644 index 000000000..c86cf9b46 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/Rules.java @@ -0,0 +1,46 @@ +package at.ac.tuwien.kr.alpha.commons.rules; + +import java.util.LinkedHashSet; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.NormalRule; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; + +public final class Rules { + + private Rules() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static Rule newRule(BasicAtom headAtom, Literal... body) { + NormalHead head = Heads.newNormalHead(headAtom); + Set bodyLiterals = new LinkedHashSet<>(); + for (Literal lit : body) { + bodyLiterals.add(lit); + } + return Rules.newRule(head, bodyLiterals); + } + + public static Rule newRule(BasicAtom headAtom, Set body) { + NormalHead head = Heads.newNormalHead(headAtom); + return Rules.newRule(head, body); + } + + public static Rule newRule(Head head, Set body) { + return new BasicRule(head, body); + } + + public static Rule newConstraint(Set body) { + return new BasicRule(null, body); + } + + public static NormalRule newNormalRule(NormalHead head, Set body) { + return new NormalRuleImpl(head, body); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/BridgedGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/BridgedGrounder.java index 406ced3b0..e81b3efef 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/BridgedGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/BridgedGrounder.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRuleImpl; public abstract class BridgedGrounder extends AbstractGrounder { protected final Bridge[] bridges; @@ -23,8 +23,8 @@ protected BridgedGrounder(Bridge... bridges) { this.bridges = bridges; } - protected Set collectExternalRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator) { - Set collectedRules = new HashSet<>(); + protected Set collectExternalRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator) { + Set collectedRules = new HashSet<>(); for (Bridge bridge : bridges) { collectedRules.addAll(bridge.getRules(assignment, atomStore, intIdGenerator)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderImpl.java index bd7c8ffa1..145b66261 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderImpl.java @@ -29,10 +29,10 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRuleImpl; /** - * A grounding order computed by {@link RuleGroundingInfoImpl} for a specific {@link InternalRule} and a specific starting literal. + * A grounding order computed by {@link RuleGroundingInfoImpl} for a specific {@link CompiledRuleImpl} and a specific starting literal. */ public class RuleGroundingOrderImpl implements RuleGroundingOrder{ diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/bridges/Bridge.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/bridges/Bridge.java index 2d0beedb2..f2efd465a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/bridges/Bridge.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/bridges/Bridge.java @@ -3,10 +3,10 @@ import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRuleImpl; import java.util.Collection; public interface Bridge { - Collection getRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator); + Collection getRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationResult.java index 6d2506543..10d733523 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationResult.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationResult.java @@ -35,7 +35,7 @@ import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRuleImpl; /** * Representation of the result of instantiating, i.e. finding ground instances for a literal, as performed by @@ -43,7 +43,7 @@ * * A {@link LiteralInstantiationResult} bundles obtained ground substitutions - or the lack thereof, if none exist for a given literal - * together with status information that can be used by a {@link Grounder} to determine how to proceed when grounding an - * {@link InternalRule}. + * {@link CompiledRuleImpl}. * * Copyright (c) 2020, the Alpha Team. */ diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java index d817b57d2..1bf6d8a1b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java @@ -27,10 +27,9 @@ */ package at.ac.tuwien.kr.alpha.core.parser.aspcore2; -import static java.util.Collections.emptyList; - import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -69,6 +68,7 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; @@ -77,7 +77,6 @@ import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Copyright (c) 2016-2021, the Alpha Team. @@ -188,7 +187,7 @@ public Object visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { programBuilder.addFact(((NormalHead) head).getAtom()); } else { // Treat facts with choice or disjunction in the head like a rule. - programBuilder.addRule(new BasicRule(head, emptyList())); + programBuilder.addRule(Rules.newRule(head, Collections.emptySet())); } return null; } @@ -196,14 +195,14 @@ public Object visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { @Override public Object visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx) { // CONS body DOT - programBuilder.addRule(new BasicRule(null, visitBody(ctx.body()))); + programBuilder.addRule(Rules.newConstraint(visitBody(ctx.body()))); return null; } @Override public Object visitStatement_rule(ASPCore2Parser.Statement_ruleContext ctx) { // head CONS body DOT - programBuilder.addRule(new BasicRule(visitHead(ctx.head()), visitBody(ctx.body()))); + programBuilder.addRule(Rules.newRule(visitHead(ctx.head()), visitBody(ctx.body()))); return null; } @@ -312,13 +311,13 @@ public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationCon } @Override - public List visitBody(ASPCore2Parser.BodyContext ctx) { + public Set visitBody(ASPCore2Parser.BodyContext ctx) { // body : ( naf_literal | aggregate ) (COMMA body)?; if (ctx == null) { - return emptyList(); + return Collections.emptySet(); } - final List literals = new ArrayList<>(); + final Set literals = new LinkedHashSet<>(); do { if (ctx.naf_literal() != null) { literals.add(visitNaf_literal(ctx.naf_literal())); @@ -494,7 +493,7 @@ public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext public List visitTerms(ASPCore2Parser.TermsContext ctx) { // terms : term (COMMA terms)?; if (ctx == null) { - return emptyList(); + return Collections.emptyList(); } final List terms = new ArrayList<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java index bca2f97cc..1cc7517c3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java @@ -18,8 +18,7 @@ import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; import at.ac.tuwien.kr.alpha.core.grounder.FactIntervalEvaluator; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; /** * A program in the internal representation needed for grounder and solver, i.e.: rules must have normal heads, all @@ -50,7 +49,7 @@ static ImmutablePair, List> internalizeRulesAndFacts(No } facts.add(r.getHead().getAtom()); } else { - internalRules.add(InternalRule.fromNormalRule(r)); + internalRules.add(CompiledRules.newCompiledRule(r.getHead(), r.getBody())); } } return new ImmutablePair<>(internalRules, facts); @@ -100,10 +99,7 @@ public Map getRulesById() { } public NormalProgram toNormalProgram() { - List normalRules = new ArrayList<>(); - for (CompiledRule rule : getRules()) { - normalRules.add(new NormalRuleImpl(rule.getHead(), new ArrayList<>(rule.getBody()))); - } + List normalRules = new ArrayList<>(getRules()); return new NormalProgramImpl(normalRules, getFacts(), getInlineDirectives()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java index ad65431e0..e18f72366 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java @@ -3,14 +3,15 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; +import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; /** * A program that only contains NormalRules. @@ -26,7 +27,10 @@ public NormalProgramImpl(List rules, List facts, InlineDirecti public static NormalProgramImpl fromInputProgram(InputProgram inputProgram) { List normalRules = new ArrayList<>(); for (Rule r : inputProgram.getRules()) { - normalRules.add(NormalRuleImpl.fromBasicRule(r)); + if (!r.isConstraint() && !(r.getHead() instanceof NormalHead)) { + throw new IllegalArgumentException("Cannot create normal rule for unsupported head type " + r.getHead().getClass().getSimpleName()); + } + normalRules.add(Rules.newNormalRule((NormalHead) r.getHead(), r.getBody())); } return new NormalProgramImpl(normalRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java index 026cde8c5..1a346527c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java @@ -1,7 +1,9 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -17,12 +19,12 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; /** * Transforms rules such that arithmetic terms only occur in comparison predicates. @@ -64,11 +66,12 @@ public NormalProgram apply(NormalProgram inputProgram) { private NormalRule rewriteRule(NormalRule inputProgramRule) { numArithmeticVariables = 0; // Reset number of introduced variables for each rule. NormalHead rewrittenHead = null; - List rewrittenBodyLiterals = new ArrayList<>(); + Set rewrittenBodyLiterals = new LinkedHashSet<>(); // Rewrite head. if (!inputProgramRule.isConstraint()) { BasicAtom headAtom = inputProgramRule.getHeadAtom(); if (containsArithmeticTermsToRewrite(headAtom)) { + // TODO handle action heads! rewrittenHead = Heads.newNormalHead((BasicAtom) rewriteAtom(headAtom, rewrittenBodyLiterals)); } else { rewrittenHead = inputProgramRule.getHead(); @@ -83,7 +86,7 @@ private NormalRule rewriteRule(NormalRule inputProgramRule) { } rewrittenBodyLiterals.add(rewriteAtom(literal.getAtom(), rewrittenBodyLiterals).toLiteral(!literal.isNegated())); } - return new NormalRuleImpl(rewrittenHead, rewrittenBodyLiterals); + return Rules.newNormalRule(rewrittenHead, rewrittenBodyLiterals); } /** @@ -108,7 +111,7 @@ private boolean containsArithmeticTermsToRewrite(NormalRule inputProgramRule) { return false; } - private Term rewriteArithmeticSubterms(Term term, List bodyLiterals) { + private Term rewriteArithmeticSubterms(Term term, Set bodyLiterals) { // Keep term as-is if it contains no ArithmeticTerm. if (!containsArithmeticTerm(term)) { return term; @@ -132,7 +135,7 @@ private Term rewriteArithmeticSubterms(Term term, List bodyLiterals) { } } - private Atom rewriteAtom(Atom atomToRewrite, List bodyLiterals) { + private Atom rewriteAtom(Atom atomToRewrite, Set bodyLiterals) { if (atomToRewrite instanceof ComparisonAtom) { throw Util.oops("Trying to rewrite ComparisonAtom."); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java index 6c20981d0..7a59afd45 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java @@ -29,7 +29,9 @@ import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; @@ -43,11 +45,11 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Copyright (c) 2017-2021, the Alpha Team. @@ -87,7 +89,7 @@ public InputProgram apply(InputProgram inputProgram) { // Construct common body to both rules. BasicAtom head = choiceElement.getChoiceAtom(); - List ruleBody = new ArrayList<>(rule.getBody()); + Set ruleBody = new LinkedHashSet<>(rule.getBody()); ruleBody.addAll(choiceElement.getConditionLiterals()); if (containsIntervalTerms(head)) { @@ -104,13 +106,13 @@ public InputProgram apply(InputProgram inputProgram) { BasicAtom negHead = Atoms.newBasicAtom(negPredicate, headTerms); // Construct two guessing rules. - List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); + Set guessingRuleBodyWithNegHead = new LinkedHashSet<>(ruleBody); guessingRuleBodyWithNegHead.add(Atoms.newBasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); - additionalRules.add(new BasicRule(Heads.newNormalHead(negHead), guessingRuleBodyWithNegHead)); + additionalRules.add(Rules.newRule(Heads.newNormalHead(negHead), guessingRuleBodyWithNegHead)); - List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); + Set guessingRuleBodyWithHead = new LinkedHashSet<>(ruleBody); guessingRuleBodyWithHead.add(Atoms.newBasicAtom(negPredicate, headTerms).toLiteral(false)); - additionalRules.add(new BasicRule(Heads.newNormalHead(head), guessingRuleBodyWithHead)); + additionalRules.add(Rules.newRule(Heads.newNormalHead(head), guessingRuleBodyWithHead)); // TODO: when cardinality constraints are possible, process the boundaries by adding a constraint with a cardinality check. } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java index f9498270e..8c9e67f1e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java @@ -4,8 +4,10 @@ import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; @@ -18,10 +20,10 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Rewrites the ordinary atom whose name is given in the input program by the enumeration directive #enum_atom_is into @@ -69,7 +71,7 @@ private List> rewriteRules(List> srcRules, Predicate enumP if (rule.getHead() != null && ((NormalHead) rule.getHead()).getAtom().getPredicate().equals(enumPredicate)) { throw oops("Atom declared as enumeration atom by directive occurs in head of the rule: " + rule); } - List modifiedBodyLiterals = new ArrayList<>(rule.getBody()); + Set modifiedBodyLiterals = new LinkedHashSet<>(rule.getBody()); Iterator rit = modifiedBodyLiterals.iterator(); LinkedList rewrittenLiterals = new LinkedList<>(); while (rit.hasNext()) { @@ -89,7 +91,7 @@ private List> rewriteRules(List> srcRules, Predicate enumP rewrittenLiterals.add(new EnumerationAtom(enumIdTerm, valueTerm, indexTerm).toLiteral()); } modifiedBodyLiterals.addAll(rewrittenLiterals); - rewrittenRules.add(new BasicRule(rule.getHead(), modifiedBodyLiterals)); + rewrittenRules.add(Rules.newRule(rule.getHead(), modifiedBodyLiterals)); } return rewrittenRules; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java index fd523432b..e5b0f9abe 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java @@ -29,8 +29,10 @@ import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -43,12 +45,12 @@ import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; /** * Rewrites all interval terms in a rule into a new variable and an IntervalAtom. @@ -68,7 +70,7 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { // Collect all intervals and replace them with variables. Map intervalReplacements = new LinkedHashMap<>(); - List rewrittenBody = new ArrayList<>(); + Set rewrittenBody = new LinkedHashSet<>(); for (Literal literal : rule.getBody()) { Literal rewrittenLiteral = rewriteLiteral(literal, intervalReplacements); @@ -91,7 +93,7 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { for (Map.Entry interval : intervalReplacements.entrySet()) { rewrittenBody.add(new IntervalAtom(interval.getValue(), interval.getKey()).toLiteral()); } - return new NormalRuleImpl(rewrittenHead, rewrittenBody); + return Rules.newNormalRule(rewrittenHead, rewrittenBody); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index 7662edff1..7c2fa2ae5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import java.util.ArrayList; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; @@ -15,9 +15,9 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * @@ -63,7 +63,7 @@ public static Rule makePrefixedPredicatesInternal(Rule rule, String newHead = head; } } - List newBody = new ArrayList<>(); + Set newBody = new LinkedHashSet<>(); for (Literal bodyElement : rule.getBody()) { // Only rewrite BasicAtoms. if (bodyElement instanceof BasicLiteral) { @@ -77,7 +77,7 @@ public static Rule makePrefixedPredicatesInternal(Rule rule, String newBody.add(bodyElement); } } - return new BasicRule(newHead, newBody); + return Rules.newRule(newHead, newBody); } private static BasicAtom makePredicateInternal(BasicAtom atom) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 0086de1fe..79270bddc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -36,6 +36,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -48,10 +49,10 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Removes variable equalities from rules by replacing one variable with the other. @@ -113,19 +114,21 @@ private Rule findAndReplaceVariableEquality(Rule rule) { return rule; } - List rewrittenBody = new ArrayList<>(rule.getBody()); + Set rewrittenBody = new LinkedHashSet<>(rule.getBody()); if (!rule.isConstraint() && rule.getHead() instanceof DisjunctiveHead) { throw new UnsupportedOperationException("VariableEqualityRemoval cannot be applied to rule with DisjunctiveHead, yet."); } NormalHead head = (NormalHead) rule.getHead(); - NormalHead rewrittenHead; + NormalHead rewrittenHead = null; // TODO can this be done nicer? - if(rule.getHead() instanceof ActionHead) { - ActionHead actHead = (ActionHead) head; - rewrittenHead = Heads.newActionHead(actHead.getAtom(), actHead.getAction(), actHead.getActionInputTerms(), actHead.getActionOutputTerm()); - } else { - rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom()); + if (!rule.isConstraint()) { + if (rule.getHead() instanceof ActionHead) { + ActionHead actHead = (ActionHead) head; + rewrittenHead = Heads.newActionHead(actHead.getAtom(), actHead.getAction(), actHead.getActionInputTerms(), actHead.getActionOutputTerm()); + } else { + rewrittenHead = Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom()); + } } // Use substitution for actual replacement. @@ -159,6 +162,6 @@ private Rule findAndReplaceVariableEquality(Rule rule) { headAtom.getTerms().set(i, replaced); } } - return new BasicRule(rewrittenHead, rewrittenBody); + return Rules.newRule(rewrittenHead, rewrittenBody); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java index 457d41daa..2bf7af96e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java @@ -2,7 +2,9 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -14,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; /** * Splits aggregate literals with both "lower" and "upper" bound operators into literals with only one operator each. @@ -53,8 +55,8 @@ public static List> split(Rule sourceRule) { private static List> splitAggregatesInRule(Rule sourceRule) { // Rule contains some aggregates that need splitting. // Aggregates may require splitting in two literals, or in two rules. - List commonBodyLiterals = new ArrayList<>(); - List twoLiteralsSplitAggregates = new ArrayList<>(); + Set commonBodyLiterals = new LinkedHashSet<>(); + Set twoLiteralsSplitAggregates = new LinkedHashSet<>(); List> twoRulesSplitAggregates = new ArrayList<>(); // First, sort literals of the rule and also compute splitting. for (Literal literal : sourceRule.getBody()) { @@ -66,17 +68,17 @@ private static List> splitAggregatesInRule(Rule sourceRule) { } } // Second, compute rule bodies of splitting result. - List commonBody = new ArrayList<>(commonBodyLiterals); + Set commonBody = new LinkedHashSet<>(commonBodyLiterals); commonBody.addAll(twoLiteralsSplitAggregates); - List> rewrittenBodies = new ArrayList<>(); + List> rewrittenBodies = new ArrayList<>(); rewrittenBodies.add(commonBody); // Initialize list of rules with the common body. // For n twoRulesSplitAggregates we need 2^n rules, so // for each of the n pairs in twoRulesSplitAggregates we duplicate the list of rewritten bodies. for (ImmutablePair ruleSplitAggregate : twoRulesSplitAggregates) { int numBodiesBeforeDuplication = rewrittenBodies.size(); for (int i = 0; i < numBodiesBeforeDuplication; i++) { - List originalBody = rewrittenBodies.get(i); - List duplicatedBody = new ArrayList<>(originalBody); + Set originalBody = rewrittenBodies.get(i); + Set duplicatedBody = new LinkedHashSet<>(originalBody); // Extend bodies of original and duplicate with splitting results. originalBody.add(ruleSplitAggregate.left); duplicatedBody.add(ruleSplitAggregate.right); @@ -85,13 +87,13 @@ private static List> splitAggregatesInRule(Rule sourceRule) { } // Third, turn computed bodies into rules again. List> rewrittenRules = new ArrayList<>(); - for (List rewrittenBody : rewrittenBodies) { - rewrittenRules.add(new BasicRule(sourceRule.getHead(), rewrittenBody)); + for (Set rewrittenBody : rewrittenBodies) { + rewrittenRules.add(Rules.newRule(sourceRule.getHead(), rewrittenBody)); } return rewrittenRules; } - private static void splitCombinedAggregateLiteral(Literal literal, List twoLiteralsSplitAggregates, + private static void splitCombinedAggregateLiteral(Literal literal, Set twoLiteralsSplitAggregates, List> twoRulesSplitAggregates) { AggregateLiteral aggLit = (AggregateLiteral) literal; ImmutablePair splitAggregate = splitCombinedAggregateAtom(aggLit.getAtom()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java index 66d93a737..696777364 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java @@ -1,8 +1,8 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; @@ -19,8 +19,8 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Transforms an {@link InputProgram} such that, for all aggregate (body-)literals, only the comparison operators "=" @@ -53,35 +53,35 @@ private AggregateOperatorNormalization() { } public static Rule normalize(Rule rule) { - List rewrittenBody = new ArrayList<>(); + Set rewrittenBody = new LinkedHashSet<>(); for (Literal lit : rule.getBody()) { rewrittenBody.addAll(rewriteLiteral(lit)); } - return new BasicRule(rule.getHead(), rewrittenBody); + return Rules.newRule(rule.getHead(), rewrittenBody); } - private static List rewriteLiteral(Literal lit) { + private static Set rewriteLiteral(Literal lit) { if (lit instanceof AggregateLiteral) { return rewriteAggregateOperator((AggregateLiteral) lit); } else { - return Collections.singletonList(lit); + return Collections.singleton(lit); } } - private static List rewriteAggregateOperator(AggregateLiteral lit) { + private static Set rewriteAggregateOperator(AggregateLiteral lit) { AggregateAtom atom = lit.getAtom(); if (atom.getLowerBoundOperator() == null && atom.getUpperBoundOperator() != null) { return rewriteAggregateOperator(convertToLeftHandComparison(lit)); } if (lit.getAtom().getAggregateFunction() == AggregateFunctionSymbol.MIN || lit.getAtom().getAggregateFunction() == AggregateFunctionSymbol.MAX) { // No operator normalization needed for #min/#max aggregates. - return Collections.singletonList(lit); + return Collections.singleton(lit); } if (atom.getLowerBoundOperator().equals(ComparisonOperators.EQ) || atom.getLowerBoundOperator().equals(ComparisonOperators.LE)) { // Nothing to do for operator "=" or "<=". - return Collections.singletonList(lit); + return Collections.singleton(lit); } else { - List retVal = new ArrayList<>(); + Set retVal = new LinkedHashSet<>(); VariableTerm decrementedBound; ComparisonOperator lowerBoundOp = atom.getLowerBoundOperator(); if (lowerBoundOp.equals(ComparisonOperators.LT)) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java index da9352b3a..bd8761d08 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -16,6 +17,7 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; @@ -23,7 +25,6 @@ import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.CountEncoder; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.MinMaxEncoder; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.SumEncoder; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Rewrites {@link AggregateLiteral}s in programs to semantically equivalent, aggregate-free sub-programs. @@ -138,7 +139,7 @@ private AbstractAggregateEncoder getEncoderForAggregateFunction(AggregateFunctio private static List> rewriteRulesWithAggregates(AggregateRewritingContext ctx) { List> rewrittenRules = new ArrayList<>(); for (Rule rule : ctx.getRulesWithAggregates()) { - List rewrittenBody = new ArrayList<>(); + Set rewrittenBody = new LinkedHashSet<>(); for (Literal lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateInfo aggregateInfo = ctx.getAggregateInfo((AggregateLiteral) lit); @@ -147,7 +148,7 @@ private static List> rewriteRulesWithAggregates(AggregateRewritingCon rewrittenBody.add(lit); } } - rewrittenRules.add(new BasicRule(rule.getHead(), rewrittenBody)); + rewrittenRules.add(Rules.newRule(rule.getHead(), rewrittenBody)); } return rewrittenRules; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java index e609c3984..b09fe9b53 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java @@ -1,10 +1,12 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.apache.commons.collections4.ListUtils; +import org.apache.commons.collections4.SetUtils; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; @@ -19,13 +21,13 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.PredicateInternalizer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Abstract base class for aggregate encoders. An aggregate encoder provides an encoding for a given aggregate literal, @@ -104,8 +106,8 @@ public InputProgram encodeAggregateLiteral(AggregateInfo aggregateToEncode) { */ protected Rule encodeAggregateElement(AggregateInfo aggregateInfo, AggregateElement element) { BasicAtom headAtom = buildElementRuleHead(aggregateInfo.getId(), element, aggregateInfo.getAggregateArguments()); - return new BasicRule(Heads.newNormalHead(headAtom), - ListUtils.union(element.getElementLiterals(), new ArrayList<>(aggregateInfo.getDependencies()))); + return Rules.newRule(Heads.newNormalHead(headAtom), + SetUtils.union(new LinkedHashSet<>(element.getElementLiterals()), aggregateInfo.getDependencies())); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java index 9ecb6f0b2..e78acb4bd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import java.util.ArrayList; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; import org.apache.commons.collections4.SetUtils; import org.stringtemplate.v4.ST; @@ -16,6 +16,8 @@ import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; @@ -23,12 +25,12 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; public class MinMaxEncoder extends AbstractAggregateEncoder { @@ -109,7 +111,7 @@ protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { */ NormalHead resultRuleHead = Heads.newNormalHead( Atoms.newBasicAtom(Predicates.getPredicate(resultName, 2), aggregateToEncode.getAggregateArguments(), atom.getLowerBoundTerm())); - List resultRuleBody = new ArrayList<>(); + Set resultRuleBody = new LinkedHashSet<>(); VariableTerm aggregateValue = Terms.newVariable("_AGG_VAL"); ComparisonLiteral aggregateValueComparison = Literals.fromAtom(Atoms.newComparisonAtom(atom.getLowerBoundTerm(), aggregateValue, cmpOp), true); Literal aggregateResult = Atoms.newBasicAtom(Predicates.getPredicate( @@ -119,7 +121,7 @@ protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { resultRuleBody.add(aggregateValueComparison); resultRuleBody.addAll(aggregateToEncode.getDependencies()); InputProgramImpl.Builder bld = InputProgramImpl.builder(parser.parse(encodingTemplate.render())); - BasicRule resultRule = new BasicRule(resultRuleHead, resultRuleBody); + Rule resultRule = Rules.newRule(resultRuleHead, resultRuleBody); bld.addRule(resultRule); return bld.build(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java index c025a6d55..5c1bbde5b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java @@ -1,6 +1,5 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import java.util.ArrayList; import java.util.Collections; import org.apache.commons.collections4.ListUtils; @@ -16,13 +15,13 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationRewriting; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Abstract base class for aggregate encoders making use of stringtemplates in their rewriting workflow. @@ -96,13 +95,13 @@ private String getBoundPredicateName(String aggregateId) { private Rule buildZeroBoundRule(AggregateInfo aggregateToEncode) { BasicAtom bound = Atoms.newBasicAtom(Predicates.getPredicate(getBoundPredicateName(aggregateToEncode.getId()), 2), aggregateToEncode.getAggregateArguments(), Terms.newConstant(0)); - return new BasicRule(Heads.newNormalHead(bound), new ArrayList<>(aggregateToEncode.getDependencies())); + return Rules.newRule(Heads.newNormalHead(bound), aggregateToEncode.getDependencies()); } private Rule buildBoundRule(AggregateInfo aggregateToEncode) { BasicAtom bound = Atoms.newBasicAtom(Predicates.getPredicate(getBoundPredicateName(aggregateToEncode.getId()), 2), aggregateToEncode.getAggregateArguments(), aggregateToEncode.getLiteral().getAtom().getLowerBoundTerm()); - return new BasicRule(Heads.newNormalHead(bound), new ArrayList<>(aggregateToEncode.getDependencies())); + return Rules.newRule(Heads.newNormalHead(bound), aggregateToEncode.getDependencies()); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRule.java index b15dfbc41..62ffa209b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRule.java @@ -16,5 +16,4 @@ public interface CompiledRule extends NormalRule { CompiledRule renameVariables(String str); - boolean isGround(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java similarity index 74% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java index 8e9e797f5..e12bf7693 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java @@ -28,8 +28,9 @@ package at.ac.tuwien.kr.alpha.core.rules; import java.util.ArrayList; -import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import com.google.common.annotations.VisibleForTesting; @@ -37,9 +38,10 @@ import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; import at.ac.tuwien.kr.alpha.commons.terms.Terms; @@ -50,27 +52,23 @@ * Represents a normal rule or a constraint for the semi-naive grounder. * A normal rule has no head atom if it represents a constraint, otherwise it has one atom in its head. */ -public class InternalRule extends NormalRuleImpl implements CompiledRule { +public class CompiledRuleImpl implements CompiledRule { private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); - private final int ruleId; + private final NormalRule wrappedRule; + private final int ruleId; private final List occurringPredicates; - private final RuleGroundingInfoImpl groundingOrders; - - public InternalRule(NormalHead head, Literal... body) { - this(head, Arrays.asList(body)); - } - public InternalRule(NormalHead head, List body) { - super(head, body); + CompiledRuleImpl(NormalHead head, Set body) { if (body.isEmpty()) { throw new IllegalArgumentException( "Empty bodies are not supported for InternalRule! (Head = " + (head == null ? "NULL" : head.getAtom().toString()) + ")"); } - this.ruleId = InternalRule.ID_GENERATOR.getNextId(); + this.ruleId = CompiledRuleImpl.ID_GENERATOR.getNextId(); + this.wrappedRule = Rules.newNormalRule(head, body); this.occurringPredicates = new ArrayList<>(); if (!isConstraint()) { @@ -84,21 +82,13 @@ public InternalRule(NormalHead head, List body) { this.occurringPredicates.add(literal.getPredicate()); } - // not needed, done in AbstractRule! Leaving it commented out for future reference since this might actually be the - // proper place to put it - // this.checkSafety(); - this.groundingOrders = new RuleGroundingInfoImpl(this); this.groundingOrders.computeGroundingOrders(); } @VisibleForTesting public static void resetIdGenerator() { - InternalRule.ID_GENERATOR.resetGenerator(); - } - - public static CompiledRule fromNormalRule(Rule rule) { - return new InternalRule(rule.getHead(), new ArrayList<>(rule.getBody())); + CompiledRuleImpl.ID_GENERATOR.resetGenerator(); } /** @@ -109,7 +99,7 @@ public static CompiledRule fromNormalRule(Rule rule) { * @return */ @Override - public InternalRule renameVariables(String newVariablePostfix) { + public CompiledRuleImpl renameVariables(String newVariablePostfix) { // TODO handle action heads! List occurringVariables = new ArrayList<>(); BasicAtom headAtom = this.getHeadAtom(); @@ -123,11 +113,13 @@ public InternalRule renameVariables(String newVariablePostfix) { variableReplacement.put(occurringVariable, Terms.newVariable(newVariableName)); } BasicAtom renamedHeadAtom = headAtom.substitute(variableReplacement); - ArrayList renamedBody = new ArrayList<>(this.getBody().size()); + Set renamedBody = new LinkedHashSet<>(this.getBody().size()); for (Literal literal : this.getBody()) { renamedBody.add(literal.substitute(variableReplacement)); } - return new InternalRule(Heads.newNormalHead(renamedHeadAtom), renamedBody); + // TODO action heads! + // TODO we want to pull renameVariables down to atom, term, etc level + return new CompiledRuleImpl(Heads.newNormalHead(renamedHeadAtom), renamedBody); } /** @@ -149,4 +141,54 @@ public int getRuleId() { return this.ruleId; } + @Override + public BasicAtom getHeadAtom() { + return wrappedRule.getHeadAtom(); + } + + @Override + public NormalHead getHead() { + return wrappedRule.getHead(); + } + + @Override + public Set getBody() { + return wrappedRule.getBody(); + } + + @Override + public boolean isConstraint() { + return wrappedRule.isConstraint(); + } + + @Override + public Set getPositiveBody() { + return wrappedRule.getPositiveBody(); + } + + @Override + public Set getNegativeBody() { + return wrappedRule.getNegativeBody(); + } + + @Override + public boolean isGround() { + return wrappedRule.isGround(); + } + + @Override + public String toString() { + return wrappedRule.toString(); + } + + @Override + public boolean equals(Object o) { + return wrappedRule.equals(o); + } + + @Override + public int hashCode() { + return wrappedRule.hashCode(); + } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java new file mode 100644 index 000000000..baf96bfb5 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java @@ -0,0 +1,27 @@ +package at.ac.tuwien.kr.alpha.core.rules; + +import java.util.LinkedHashSet; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; + +public final class CompiledRules { + + private CompiledRules() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static CompiledRule newCompiledRule(NormalHead head, Set body) { + return new CompiledRuleImpl(head, body); + } + + public static CompiledRule newCompiledRule(NormalHead head, Literal... body) { + Set bodySet = new LinkedHashSet<>(); + for (Literal lit : body) { + bodySet.add(lit); + } + return CompiledRules.newCompiledRule(head, bodySet); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java deleted file mode 100644 index 7666ba84a..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java +++ /dev/null @@ -1,28 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.rules; - -import java.util.ArrayList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; -import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; - -public final class Rules { - - private Rules() { - throw new AssertionError("Cannot instantiate utility class!"); - } - - public static Rule newRule(BasicAtom headAtom, Literal... body) { - NormalHead head = Heads.newNormalHead(headAtom); - List bodyLiterals = new ArrayList<>(); - for (Literal lit : body) { - bodyLiterals.add(lit); - } - return new BasicRule(head, bodyLiterals); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java index 0557fe2c4..b102d6fd3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java @@ -40,9 +40,9 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.Rules; public class ProgramTest { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java index 9359bb09c..e63700042 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java @@ -13,11 +13,11 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; +import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; -import at.ac.tuwien.kr.alpha.core.rules.Rules; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; /** * Copyright (c) 2018 - 2021, the Alpha Team. @@ -33,8 +33,8 @@ public void renameVariables() { BasicAtom bodyAtom3 = Atoms.newBasicAtom(Predicates.getPredicate("q", 3), Terms.newVariable("X"), Terms.newFunctionTerm("g", Terms.newVariable("Y")), Terms.newVariable("Z")); BasicAtom bodyAtom4 = Atoms.newBasicAtom(Predicates.getPredicate("dom", 1), Terms.newVariable("A")); - CompiledRule rule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule( - Rules.newRule(headAtom, bodyAtom1.toLiteral(), bodyAtom2.toLiteral(), bodyAtom3.toLiteral(), bodyAtom4.toLiteral()))); + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(headAtom), bodyAtom1.toLiteral(), bodyAtom2.toLiteral(), bodyAtom3.toLiteral(), + bodyAtom4.toLiteral()); // ruleWithRenamedVars := p(X_13, Y_13) :- a, f(Z_13) = 1, q(X_13, g(Y_13), Z_13), dom(A_13). BasicAtom headAtomRenamed = Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X_13"), Terms.newVariable("Y_13")); @@ -44,9 +44,8 @@ public void renameVariables() { BasicAtom bodyAtom3Renamed = Atoms.newBasicAtom(Predicates.getPredicate("q", 3), Terms.newVariable("X_13"), Terms.newFunctionTerm("g", Terms.newVariable("Y_13")), Terms.newVariable("Z_13")); BasicAtom bodyAtom4Renamed = Atoms.newBasicAtom(Predicates.getPredicate("dom", 1), Terms.newVariable("A_13")); - CompiledRule ruleWithRenamedVars = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule( - Rules.newRule(headAtomRenamed, bodyAtom1Renamed.toLiteral(), bodyAtom2Renamed.toLiteral(), bodyAtom3Renamed.toLiteral(), - bodyAtom4Renamed.toLiteral()))); + CompiledRule ruleWithRenamedVars = CompiledRules.newCompiledRule(Heads.newNormalHead(headAtomRenamed), bodyAtom1Renamed.toLiteral(), + bodyAtom2Renamed.toLiteral(), bodyAtom3Renamed.toLiteral(), bodyAtom4Renamed.toLiteral()); assertEquals(ruleWithRenamedVars, rule.renameVariables("_13")); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java index 7950b90dd..20f176924 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java @@ -62,9 +62,8 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.IntIterator; import at.ac.tuwien.kr.alpha.core.common.NoGood; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; /** * Represents a small ASP program {@code { c :- a, b. a. b. }}. @@ -94,8 +93,8 @@ public class GrounderMockWithBasicProgram implements Grounder { private static Atom atomAA = Atoms.newBasicAtom(Predicates.getPredicate("a", 0)); private static Atom atomBB = Atoms.newBasicAtom(Predicates.getPredicate("b", 0)); private static BasicAtom atomCC = Atoms.newBasicAtom(Predicates.getPredicate("c", 0)); - private static BasicRule ruleABC = new BasicRule(Heads.newNormalHead(atomCC), Arrays.asList(atomAA.toLiteral(), atomBB.toLiteral())); - private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(ruleABC)), new BasicSubstitution()); + private static CompiledRule ruleABC = CompiledRules.newCompiledRule(Heads.newNormalHead(atomCC), atomAA.toLiteral(), atomBB.toLiteral()); + private static Atom rule1 = new RuleAtom(ruleABC, new BasicSubstitution()); private Set returnedNogoods = new HashSet<>(); public GrounderMockWithBasicProgram(AtomStore atomStore) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java index bda74f709..f548a1feb 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java @@ -63,9 +63,8 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.IntIterator; import at.ac.tuwien.kr.alpha.core.common.NoGood; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; /** * Represents a small ASP program with choices {@code { aa :- not bb. bb :- not aa. }}. @@ -116,10 +115,10 @@ public class GrounderMockWithChoice implements Grounder { ).collect(entriesToMap()); private static BasicAtom atomAA = Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)); private static BasicAtom atomBB = Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)); - private static BasicRule ruleAA = new BasicRule(Heads.newNormalHead(atomAA), Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false))); - private static BasicRule ruleBB = new BasicRule(Heads.newNormalHead(atomBB), Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)).toLiteral(false))); - private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(ruleAA)), new BasicSubstitution()); - private static Atom rule2 = new RuleAtom(InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(ruleBB)), new BasicSubstitution()); + private static CompiledRule ruleAA = CompiledRules.newCompiledRule(Heads.newNormalHead(atomAA), Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false)); + private static CompiledRule ruleBB = CompiledRules.newCompiledRule(Heads.newNormalHead(atomBB), Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)).toLiteral(false)); + private static Atom rule1 = new RuleAtom(ruleAA, new BasicSubstitution()); + private static Atom rule2 = new RuleAtom(ruleBB, new BasicSubstitution()); private static Atom atomEnBR1 = ChoiceAtom.on(1); private static Atom atomEnBR2 = ChoiceAtom.on(2); private static Atom atomDisBR1 = ChoiceAtom.off(3); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java index 24c2aceea..be0335ed0 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java @@ -50,7 +50,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; import at.ac.tuwien.kr.alpha.core.test.util.SubstitutionTestUtil; import at.ac.tuwien.kr.alpha.core.util.Substitutions; @@ -109,7 +109,7 @@ public void substituteNegativeBasicAtom() { @Test public void groundAndPrintRule() { // rule := x :- p(X,Y), not q(X,Y). - CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("x", 0))), + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("x", 0))), Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(false)); Substitution substitution1 = BasicSubstitution.specializeSubstitution(PX, PA, BasicSubstitution.EMPTY_SUBSTITUTION); @@ -166,7 +166,7 @@ private void groundLiteralToString(boolean negated) { @Test public void substitutionFromString() { // rule := x :- p(X,Y), not q(X,Y). - CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("x", 0))), + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("x", 0))), Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(false)); Substitution substitution1 = BasicSubstitution.specializeSubstitution(PX, PA, BasicSubstitution.EMPTY_SUBSTITUTION); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/rules/RuleGroundingInfoTest.java similarity index 88% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/rules/RuleGroundingInfoTest.java index 4f95d0f2c..32df51f6f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/rules/RuleGroundingInfoTest.java @@ -25,7 +25,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.grounder; +package at.ac.tuwien.kr.alpha.core.rules; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -41,8 +41,8 @@ import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfo; +import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfoImpl; /** * Copyright (c) 2017-2021, the Alpha Team. @@ -52,7 +52,7 @@ public class RuleGroundingInfoTest { @Test public void groundingOrder() { // r1 := h(X,C) :- p(X,Y), q(A,B), r(Y,A), s(C). - CompiledRule r1 = new InternalRule( + CompiledRule r1 = CompiledRules.newCompiledRule( Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 2), Terms.newVariable("X"), Terms.newVariable("C"))), Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("A"), Terms.newVariable("B")).toLiteral(), @@ -63,7 +63,7 @@ public void groundingOrder() { assertEquals(4, rgo1.getStartingLiterals().size()); // r2 := j(A,A,X,Y) :- r1(A,A), r1(X,Y), r1(A,X), r1(A,Y). - CompiledRule r2 = new InternalRule( + CompiledRule r2 = CompiledRules.newCompiledRule( Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("j", 4), Terms.newVariable("A"), Terms.newVariable("A"), Terms.newVariable("X"), Terms.newVariable("Y"))), Atoms.newBasicAtom(Predicates.getPredicate("r1", 2), Terms.newVariable("A"), Terms.newVariable("A")).toLiteral(), @@ -75,7 +75,7 @@ public void groundingOrder() { assertEquals(4, rgo2.getStartingLiterals().size()); // r3 := p(a) :- b = a. - CompiledRule r3 = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a"))), + CompiledRule r3 = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a"))), Atoms.newComparisonAtom(Terms.newSymbolicConstant("b"), Terms.newSymbolicConstant("a"), ComparisonOperators.EQ).toLiteral()); RuleGroundingInfo rgo3 = new RuleGroundingInfoImpl(r3); rgo3.computeGroundingOrders(); @@ -90,7 +90,7 @@ public void groundingOrder() { public void groundingOrderUnsafe() { assertThrows(RuntimeException.class, () -> { // rule := h(X, Z) :- Y = X + 1, X = Z + 1, Z = Y - 2. - CompiledRule rule = new InternalRule( + CompiledRule rule = CompiledRules.newCompiledRule( Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 2), Terms.newVariable("X"), Terms.newVariable("Z"))), Atoms.newComparisonAtom( Terms.newVariable("Y"), @@ -111,7 +111,7 @@ public void groundingOrderUnsafe() { @Test public void testPositionFromWhichAllVarsAreBound_ground() { // rule := a :- b, not c. - CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 0))), + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b", 0)).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("c", 0)).toLiteral(false)); RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(rule); @@ -121,7 +121,7 @@ public void testPositionFromWhichAllVarsAreBound_ground() { @Test public void testPositionFromWhichAllVarsAreBound_simpleNonGround() { // rule := a(X) :- b(X), not c(X). - CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newVariable("X")).toLiteral(false)); RuleGroundingInfo rgo0 = computeGroundingOrdersForRule(rule); @@ -134,7 +134,7 @@ public void testPositionFromWhichAllVarsAreBound_simpleNonGround() { @Test public void testPositionFromWhichAllVarsAreBound_longerSimpleNonGround() { // rule := a(X) :- b(X), c(X), d(X), not e(X). - CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newVariable("X")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newVariable("X")).toLiteral(), @@ -149,7 +149,7 @@ public void testPositionFromWhichAllVarsAreBound_longerSimpleNonGround() { @Test public void testToString_longerSimpleNonGround() { // rule := a(X) :- b(X), c(X), d(X), not e(X). - CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newVariable("X")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newVariable("X")).toLiteral(), @@ -176,7 +176,7 @@ public void testToString_longerSimpleNonGround() { @Test public void testPositionFromWhichAllVarsAreBound_joinedNonGround() { // rule := a(X) :- b(X), c(X, Y), d(X, Z), not e(X). - CompiledRule rule = new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), + CompiledRule rule = CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newVariable("X"))), Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newVariable("X")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("c", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("d", 2), Terms.newVariable("X"), Terms.newVariable("Z")).toLiteral(), diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java index f43a858e8..84f271a58 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java @@ -50,7 +50,7 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; // TODO should this be part of an AtomStoreTest?? public class AtomCounterTests { @@ -124,8 +124,8 @@ private void createChoiceAtom() { private void createRuleAtom() { BasicAtom atomAA = Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)); - CompiledRule ruleAA = new InternalRule(Heads.newNormalHead(atomAA), - Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false))); + CompiledRule ruleAA = CompiledRules.newCompiledRule(Heads.newNormalHead(atomAA), + Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false)); atomStore.putIfAbsent(new RuleAtom(ruleAA, new BasicSubstitution())); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java index 692e6840a..47a149456 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java @@ -45,7 +45,7 @@ import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; public class ChoiceManagerTests { private Grounder grounder; @@ -59,7 +59,7 @@ public void setUp() { * h :- b1, b2, not b3, not b4. */ CompiledProgram program = new InternalProgram(Collections.singletonList( - new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 0))), + CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b1", 0)).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("b2", 0)).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("b3", 0)).toLiteral(false), diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java index 6102ee79f..98f16b08f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java @@ -50,7 +50,7 @@ import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.core.solver.NaiveNoGoodStore; import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; @@ -83,11 +83,11 @@ public void setUp() { */ List facts = Arrays.asList(Atoms.newBasicAtom(Predicates.getPredicate("b1", 0)), Atoms.newBasicAtom(Predicates.getPredicate("b2", 0))); List rules = Arrays.asList( - new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("b3", 0))), Atoms.newBasicAtom(Predicates.getPredicate("nb3", 0)).toLiteral(false)), - new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("nb3", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b3", 0)).toLiteral(false)), - new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("b4", 0))), Atoms.newBasicAtom(Predicates.getPredicate("nb4", 0)).toLiteral(false)), - new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("nb4", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b4", 0)).toLiteral(false)), - new InternalRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 0))), + CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("b3", 0))), Atoms.newBasicAtom(Predicates.getPredicate("nb3", 0)).toLiteral(false)), + CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("nb3", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b3", 0)).toLiteral(false)), + CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("b4", 0))), Atoms.newBasicAtom(Predicates.getPredicate("nb4", 0)).toLiteral(false)), + CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("nb4", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b4", 0)).toLiteral(false)), + CompiledRules.newCompiledRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("h", 0))), Atoms.newBasicAtom(Predicates.getPredicate("b1", 0)).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("b2", 0)).toLiteral(), Atoms.newBasicAtom(Predicates.getPredicate("b3", 0)).toLiteral(false), diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java index 1234baadc..aadbd8588 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java @@ -35,14 +35,14 @@ import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.rules.NormalRuleImpl; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRuleImpl; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; /** - * Tests {@link BasicRule#toString()} and {@link InternalRule#toString()}. + * Tests {@link BasicRule#toString()} and {@link CompiledRuleImpl#toString()}. */ public class RuleToStringTest { private final ProgramParser parser = new EvologProgramParser(); @@ -93,7 +93,8 @@ private void parseSingleRuleAndCheckToString(String rule) { } private void constructNonGroundRuleAndCheckToString(String textualRule) { - CompiledRule nonGroundRule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(parseSingleRule(textualRule))); + Rule parsedRule = parseSingleRule(textualRule); + CompiledRule nonGroundRule = CompiledRules.newCompiledRule((NormalHead) parsedRule.getHead(), parsedRule.getBody()); assertEquals(textualRule, nonGroundRule.toString()); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 4b3920483..668dee7bb 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -44,6 +44,7 @@ import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -64,6 +65,8 @@ import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; import at.ac.tuwien.kr.alpha.commons.Predicates; @@ -72,13 +75,13 @@ import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.externals.MethodPredicateInterpretation; import at.ac.tuwien.kr.alpha.commons.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; // TODO This is a functional test and should not be run with standard unit tests @@ -333,9 +336,9 @@ private static class SubThingy extends Thingy { public void withExternalSubtype() throws Exception { SubThingy thingy = new SubThingy(); - BasicRule rule = new BasicRule( + Rule rule = Rules.newRule( Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newConstant("x"))), - singletonList(Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("thinger", 1), + Collections.singleton(Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("thinger", 1), new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true))); From b2f9c96daf915c8e53473b969e0e74a9a87b95f7 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 17 Feb 2022 15:41:49 +0100 Subject: [PATCH 08/59] actions: file output draft --- .../tuwien/kr/alpha/core/actions/Actions.java | 75 +++++++++++++++++++ .../core/actions/OutputStreamHandle.java | 49 ++++++++++++ .../parser/evolog/EvologParseTreeVisitor.java | 3 + 3 files changed, 127 insertions(+) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java index 5aff462d6..1c2890c4b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java @@ -1,13 +1,22 @@ package at.ac.tuwien.kr.alpha.core.actions; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; public class Actions { + // TODO this needs to be encapsulated and made thread-safe! + private static final IntIdGenerator ID_GEN = new IntIdGenerator(); + public static FunctionTerm printLine(List input) { if (input.size() != 1) { // TODO do properly @@ -18,4 +27,70 @@ public static FunctionTerm printLine(List input) { return Terms.newFunctionTerm("ok"); } + public static FunctionTerm fileOpenOutputStream(List input) { + if (input.size() != 1) { + // TODO do properly + throw new IllegalArgumentException("Incorrect arity!"); + } + Term inTerm = input.get(0); + if (!(inTerm instanceof ConstantTerm)) { + throw new IllegalArgumentException("Input must be a string constant!"); + } + ConstantTerm inConst = (ConstantTerm) inTerm; + if (!(inConst.getObject() instanceof String) || inConst.isSymbolic()) { + throw new IllegalArgumentException("Input must be a string constant!"); + } + String path = (String) inConst.getObject(); + try { + OutputStreamHandle streamHandle = new OutputStreamHandle(ID_GEN.getNextId(), new FileOutputStream(path, true)); + return Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle)); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + @SuppressWarnings("unchecked") + public static FunctionTerm outputStreamWrite(List input) { + if (input.size() != 2) { + // TODO do properly + throw new IllegalArgumentException("Incorrect arity!"); + } + if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof OutputStreamHandle)) { + throw new IllegalArgumentException("First input term must be an output stream handle!"); + } + OutputStreamHandle dstHandle = ((ConstantTerm) input.get(0)).getObject(); + if (!(input.get(1) instanceof ConstantTerm) || !(((ConstantTerm) input.get(1)).getObject() instanceof String) + || ((ConstantTerm) input.get(1)).isSymbolic()) { + throw new IllegalArgumentException("Second input term must be a string constant!"); + } + String str = ((ConstantTerm) input.get(1)).getObject(); + // TODO this needs some built-in conversion function + byte[] data = str.getBytes(); + OutputStream dst = dstHandle.getStream(); + try { + dst.write(data); + return Terms.newFunctionTerm("ok"); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @SuppressWarnings("unchecked") + public static FunctionTerm outputStreamClose(List input) { + if (input.size() != 1) { + // TODO do properly + throw new IllegalArgumentException("Incorrect arity!"); + } + if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof OutputStreamHandle)) { + throw new IllegalArgumentException("First input term must be an output stream handle!"); + } + OutputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); + try { + handle.getStream().close(); + return Terms.newFunctionTerm("ok"); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java new file mode 100644 index 000000000..827403bdb --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java @@ -0,0 +1,49 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.io.OutputStream; + +public class OutputStreamHandle implements Comparable { + + private final int id; + private final OutputStream stream; + + public OutputStreamHandle(int id, OutputStream stream) { + this.id = id; + this.stream = stream; + } + + public int getId() { + return id; + } + + public OutputStream getStream() { + return stream; + } + + @Override + public String toString() { + return "outputStream-" + id; + } + + @Override + public int compareTo(OutputStreamHandle other) { + return this.id - other.id; + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } else if (!(o instanceof OutputStreamHandle)) { + return false; + } + OutputStreamHandle other = (OutputStreamHandle) o; + return this.id == other.id; + } + + @Override + public int hashCode() { + return this.id; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java index bf10553cc..f39c923b7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java @@ -22,6 +22,9 @@ public class EvologParseTreeVisitor extends ASPCore2ParseTreeVisitor { public EvologParseTreeVisitor(Map externals, boolean acceptVariables) { super(externals, acceptVariables); actionRegistry.put("printLine", Actions::printLine); + actionRegistry.put("fileOutputStream", Actions::fileOpenOutputStream); + actionRegistry.put("streamWrite", Actions::outputStreamWrite); + actionRegistry.put("streamClose", Actions::outputStreamClose); } public EvologParseTreeVisitor(Map externals) { From 09e1b7ced8e653bd201c4a94a2392106cb0ad61a Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 17 Feb 2022 22:32:58 +0100 Subject: [PATCH 09/59] actions: file input draft --- .../tuwien/kr/alpha/core/actions/Actions.java | 69 ++++++++++++++++++- .../alpha/core/actions/InputStreamHandle.java | 49 +++++++++++++ .../core/actions/OutputStreamHandle.java | 1 + .../parser/evolog/EvologParseTreeVisitor.java | 7 +- .../transformation/StratifiedEvaluation.java | 12 +--- 5 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java index 1c2890c4b..72a138b8b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java @@ -4,6 +4,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.List; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; @@ -92,5 +94,70 @@ public static FunctionTerm outputStreamClose(List input) { throw new RuntimeException(ex); } } - + + public static FunctionTerm fileOpenInputStream(List input) { + if (input.size() != 1) { + // TODO do properly + throw new IllegalArgumentException("Incorrect arity!"); + } + Term inTerm = input.get(0); + if (!(inTerm instanceof ConstantTerm)) { + throw new IllegalArgumentException("Input must be a string constant!"); + } + ConstantTerm inConst = (ConstantTerm) inTerm; + if (!(inConst.getObject() instanceof String) || inConst.isSymbolic()) { + throw new IllegalArgumentException("Input must be a string constant!"); + } + String path = (String) inConst.getObject(); + try { + InputStreamHandle streamHandle = new InputStreamHandle(ID_GEN.getNextId(), Files.newBufferedReader(Paths.get(path))); + return Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @SuppressWarnings("unchecked") + public static FunctionTerm inputStreamReadLine(List input) { + if (input.size() != 1) { + // TODO do properly + throw new IllegalArgumentException("Incorrect arity!"); + } + if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof InputStreamHandle)) { + throw new IllegalArgumentException("First input term must be an input stream handle!"); + } + InputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); + try { + String line = handle.getStream().readLine(); + ConstantTerm lineTerm; + if (line == null) { + // we reached EOF + lineTerm = Terms.newSymbolicConstant("eof"); + } else { + lineTerm = Terms.newConstant(line); + } + return Terms.newFunctionTerm("ok", lineTerm); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @SuppressWarnings("unchecked") + public static FunctionTerm inputStreamClose(List input) { + if (input.size() != 1) { + // TODO do properly + throw new IllegalArgumentException("Incorrect arity!"); + } + if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof InputStreamHandle)) { + throw new IllegalArgumentException("First input term must be an input stream handle!"); + } + InputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); + try { + handle.getStream().close(); + return Terms.newFunctionTerm("ok"); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java new file mode 100644 index 000000000..ee2805d25 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java @@ -0,0 +1,49 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.io.BufferedReader; + +public class InputStreamHandle implements Comparable { + + private final int id; + private final BufferedReader stream; + + public InputStreamHandle(int id, BufferedReader stream) { + this.id = id; + this.stream = stream; + } + + public int getId() { + return id; + } + + public BufferedReader getStream() { + return stream; + } + + @Override + public String toString() { + return "outputStream-" + id; + } + + @Override + public int compareTo(InputStreamHandle other) { + return this.id - other.id; + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } else if (!(o instanceof InputStreamHandle)) { + return false; + } + InputStreamHandle other = (InputStreamHandle) o; + return this.id == other.id; + } + + @Override + public int hashCode() { + return this.id; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java index 827403bdb..edbb19184 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java @@ -2,6 +2,7 @@ import java.io.OutputStream; +// TODO change this to wrap a PrintStream public class OutputStreamHandle implements Comparable { private final int id; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java index f39c923b7..02c9983a5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java @@ -22,9 +22,14 @@ public class EvologParseTreeVisitor extends ASPCore2ParseTreeVisitor { public EvologParseTreeVisitor(Map externals, boolean acceptVariables) { super(externals, acceptVariables); actionRegistry.put("printLine", Actions::printLine); + actionRegistry.put("fileOutputStream", Actions::fileOpenOutputStream); actionRegistry.put("streamWrite", Actions::outputStreamWrite); - actionRegistry.put("streamClose", Actions::outputStreamClose); + actionRegistry.put("outputStreamClose", Actions::outputStreamClose); + + actionRegistry.put("fileInputStream", Actions::fileOpenInputStream); + actionRegistry.put("streamReadLine", Actions::inputStreamReadLine); + actionRegistry.put("inputStreamClose", Actions::inputStreamClose); } public EvologParseTreeVisitor(Map externals) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 379c86875..34d8047fe 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -341,17 +341,7 @@ public BasicAtom instantiateActionHead(ActionHead head, Substitution substitutio List substitutedInput = new ArrayList<>(); // Substitute all variables in action input so that all input terms are ground. for (Term inputTerm : actionInput) { - // TODO handle variables nested in function terms as well! - if (inputTerm instanceof VariableTerm) { - VariableTerm inputVar = (VariableTerm) inputTerm; - if (!substitution.isVariableSet(inputVar)) { - throw new IllegalStateException( - "No substitute for action input variable " + inputVar.toString() + " in substitution: " + substitution.toString()); - } - substitutedInput.add(inputVar.substitute(substitution)); - } else { - substitutedInput.add(inputTerm); - } + substitutedInput.add(inputTerm.substitute(substitution)); } // Call the actual action. // TODO exception handling (translate EVERY throwable to an error term) From 21664edd79d5b554d13a3dd1e2b06aa1ab4697d9 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 24 Feb 2022 15:21:01 +0100 Subject: [PATCH 10/59] additional actions for input stream handling --- .../commons/externals/AspStandardLibrary.java | 31 +++++++++++++++++++ .../tuwien/kr/alpha/core/actions/Actions.java | 6 ++-- .../alpha/core/actions/InputStreamHandle.java | 2 +- .../transformation/StratifiedEvaluation.java | 1 - 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java index 14142ed62..ee757b46e 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java @@ -211,4 +211,35 @@ public static Set>> stringConcat(String s1, String s2) return Collections.singleton(Terms.asTermList(s1 + s2)); } + /** + * Converts the given string to an integer + */ + @Predicate(name = "string_parse_integer") + public static Set>> stringParseInteger(String str) { + return Collections.singleton(Collections.singletonList(Terms.newConstant(Integer.valueOf(str)))); + } + + @Predicate(name = "string_is_empty") + public static boolean isStringEmpty(String str) { + return str.isEmpty(); + } + + @Predicate(name = "string_substring") + public static Set>> substringOfString(String str, int startIdx, int endIdx) { + return Collections.singleton(Collections.singletonList(Terms.newConstant(str.substring(startIdx, endIdx)))); + } + + @Predicate(name = "str_x_xs") + public static Set>> stringHeadRemainder(String str) { + List> xXs = null; + if (str.isEmpty()) { + return Collections.emptySet(); + } else if (str.length() == 1) { + xXs = List.of(Terms.newConstant(str), Terms.newConstant("")); + } else { + xXs = List.of(Terms.newConstant(str.substring(0, 1)), Terms.newConstant(str.substring(1, str.length()))); + } + return Collections.singleton(xXs); + } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java index 72a138b8b..22643cccf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java @@ -71,7 +71,7 @@ public static FunctionTerm outputStreamWrite(List input) { OutputStream dst = dstHandle.getStream(); try { dst.write(data); - return Terms.newFunctionTerm("ok"); + return Terms.newFunctionTerm("writeResult", Terms.newSymbolicConstant("ok")); } catch (IOException ex) { throw new RuntimeException(ex); } @@ -89,7 +89,7 @@ public static FunctionTerm outputStreamClose(List input) { OutputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); try { handle.getStream().close(); - return Terms.newFunctionTerm("ok"); + return Terms.newFunctionTerm("closeResult", Terms.newSymbolicConstant("ok")); } catch (IOException ex) { throw new RuntimeException(ex); } @@ -154,7 +154,7 @@ public static FunctionTerm inputStreamClose(List input) { InputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); try { handle.getStream().close(); - return Terms.newFunctionTerm("ok"); + return Terms.newFunctionTerm("closeResult", Terms.newSymbolicConstant("ok")); } catch (IOException ex) { throw new RuntimeException(ex); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java index ee2805d25..3064ec249 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java @@ -22,7 +22,7 @@ public BufferedReader getStream() { @Override public String toString() { - return "outputStream-" + id; + return "inputStream-" + id; } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 34d8047fe..87e77df1d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -30,7 +30,6 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; From 4f9de69b95a9c6c30bd394a1bb873713562a40a9 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 8 Mar 2022 21:34:09 +0100 Subject: [PATCH 11/59] actions: draft implementation --- .../kr/alpha/api/rules/heads/ActionHead.java | 3 +- .../commons/rules/heads/ActionHeadImpl.java | 11 +- .../kr/alpha/commons/rules/heads/Heads.java | 5 +- .../kr/alpha/core/actions/ActionContext.java | 12 ++ .../alpha/core/actions/ActionContextImpl.java | 108 ++++++++++++++++++ .../kr/alpha/core/actions/ActionWitness.java | 44 +++++++ .../parser/evolog/EvologParseTreeVisitor.java | 19 +-- .../transformation/PredicateInternalizer.java | 2 +- .../transformation/StratifiedEvaluation.java | 23 ++-- .../VariableEqualityRemoval.java | 2 +- .../kr/alpha/api/impl/AlphaFactory.java | 7 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 9 +- 12 files changed, 201 insertions(+), 44 deletions(-) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContext.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java index 1bc4c2674..d30cb726f 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/heads/ActionHead.java @@ -2,13 +2,12 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; public interface ActionHead extends NormalHead { - Action getAction(); + String getActionName(); List getActionInputTerms(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java index a7310a771..f64ca535b 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java @@ -4,7 +4,6 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.rules.RuleInstantiator; import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; @@ -14,13 +13,13 @@ class ActionHeadImpl implements ActionHead { private final BasicAtom atom; - private final Action action; + private final String actionName; private final List actionInputTerms; private final VariableTerm actionOutputTerm; - ActionHeadImpl(BasicAtom atom, Action action, List actionInputTerms, VariableTerm actionOutputTerm) { + ActionHeadImpl(BasicAtom atom, String actionName, List actionInputTerms, VariableTerm actionOutputTerm) { this.atom = atom; - this.action = action; + this.actionName = actionName; this.actionInputTerms = Collections.unmodifiableList(actionInputTerms); this.actionOutputTerm = actionOutputTerm; } @@ -42,8 +41,8 @@ public BasicAtom instantiate(RuleInstantiator instantiator, Substitution substit } @Override - public Action getAction() { - return action; + public String getActionName() { + return actionName; } @Override diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java index 860ca5ee7..c3df8e6b9 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/Heads.java @@ -3,7 +3,6 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; @@ -33,7 +32,7 @@ public static ChoiceElement newChoiceElement(BasicAtom choiceAtom, List return new ChoiceElementImpl(choiceAtom, conditionLiterals); } - public static ActionHead newActionHead(BasicAtom atom, Action action, List actionInputTerms, VariableTerm actionResult) { - return new ActionHeadImpl(atom, action, actionInputTerms, actionResult); + public static ActionHead newActionHead(BasicAtom atom, String actionName, List actionInputTerms, VariableTerm actionResult) { + return new ActionHeadImpl(atom, actionName, actionInputTerms, actionResult); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContext.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContext.java new file mode 100644 index 000000000..bbcca297e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContext.java @@ -0,0 +1,12 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +public interface ActionContext { + + ActionWitness execute(String actionName, int sourceRuleId, Substitution sourceRuleInstance, List inputTerms); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java new file mode 100644 index 000000000..bfe5cc745 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java @@ -0,0 +1,108 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +public class ActionContextImpl implements ActionContext { + + // TODO initialize from outside + private final Map actions = new HashMap<>(); + private final Map actionRecord = new HashMap<>(); + + public ActionContextImpl() { + actions.put("printLine", Actions::printLine); + actions.put("fileOutputStream", Actions::fileOpenOutputStream); + actions.put("streamWrite", Actions::outputStreamWrite); + actions.put("outputStreamClose", Actions::outputStreamClose); + + actions.put("fileInputStream", Actions::fileOpenInputStream); + actions.put("streamReadLine", Actions::inputStreamReadLine); + actions.put("inputStreamClose", Actions::inputStreamClose); + } + + @Override + public ActionWitness execute(String actionName, int sourceRuleId, Substitution sourceRuleInstance, List inputTerms) { + // TODO maybe we want to stuff the whole action head plus substitution in here and do the whole instantiation here? + ActionInput actInput = new ActionInput(actionName, sourceRuleId, sourceRuleInstance, inputTerms); + return actionRecord.computeIfAbsent(actInput, this::execute); + } + + private ActionWitness execute(ActionInput input) { + Action action = actions.get(input.name); + FunctionTerm result = action.execute(input.inputTerms); + return new ActionWitness(input.sourceRule, input.instance, input.name, input.inputTerms, result); + } + + private static class ActionInput { + + private final String name; + private final int sourceRule; + private final Substitution instance; + private final List inputTerms; + + public ActionInput(String name, int sourceRule, Substitution instance, List inputTerms) { + this.name = name; + this.sourceRule = sourceRule; + this.instance = instance; + this.inputTerms = inputTerms; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((inputTerms == null) ? 0 : inputTerms.hashCode()); + result = prime * result + ((instance == null) ? 0 : instance.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + sourceRule; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ActionInput other = (ActionInput) obj; + if (inputTerms == null) { + if (other.inputTerms != null) { + return false; + } + } else if (!inputTerms.equals(other.inputTerms)) { + return false; + } + if (instance == null) { + if (other.instance != null) { + return false; + } + } else if (!instance.equals(other.instance)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (sourceRule != other.sourceRule) { + return false; + } + return true; + } + + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java new file mode 100644 index 000000000..ffa885726 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java @@ -0,0 +1,44 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +public class ActionWitness { + + private final int ruleId; + private final Substitution groundBody; + private final String actionName; + private final List actionInput; + private final Term actionResult; + + public ActionWitness(int ruleId, Substitution groundBody, String actionName, List actionInput, Term actionResult) { + this.ruleId = ruleId; + this.groundBody = groundBody; + this.actionName = actionName; + this.actionInput = actionInput; + this.actionResult = actionResult; + } + + public int getRuleId() { + return ruleId; + } + + public Substitution getGroundBody() { + return groundBody; + } + + public String getActionName() { + return actionName; + } + + public List getActionInput() { + return actionInput; + } + + public Term getActionResult() { + return actionResult; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java index 02c9983a5..2093d5da1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java @@ -1,35 +1,21 @@ package at.ac.tuwien.kr.alpha.core.parser.evolog; -import java.util.HashMap; import java.util.List; import java.util.Map; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; -import at.ac.tuwien.kr.alpha.core.actions.Actions; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ParseTreeVisitor; public class EvologParseTreeVisitor extends ASPCore2ParseTreeVisitor { - private final Map actionRegistry = new HashMap<>(); - public EvologParseTreeVisitor(Map externals, boolean acceptVariables) { super(externals, acceptVariables); - actionRegistry.put("printLine", Actions::printLine); - - actionRegistry.put("fileOutputStream", Actions::fileOpenOutputStream); - actionRegistry.put("streamWrite", Actions::outputStreamWrite); - actionRegistry.put("outputStreamClose", Actions::outputStreamClose); - - actionRegistry.put("fileInputStream", Actions::fileOpenInputStream); - actionRegistry.put("streamReadLine", Actions::inputStreamReadLine); - actionRegistry.put("inputStreamClose", Actions::inputStreamClose); } public EvologParseTreeVisitor(Map externals) { @@ -41,11 +27,8 @@ public Head visitAction(ASPCore2Parser.ActionContext ctx) { BasicAtom atom = visitClassical_literal(ctx.classical_literal()); VariableTerm actionResultTerm = visitVariable_term(ctx.variable_term()); String actionId = ctx.ID().getText(); - if (!actionRegistry.containsKey(actionId)) { - throw new UnsupportedOperationException("Could not resolve action name " + actionId); - } List actionInputTerms = visitTerms(ctx.terms()); - return Heads.newActionHead(atom, actionRegistry.get(actionId), actionInputTerms, actionResultTerm); + return Heads.newActionHead(atom, actionId, actionInputTerms, actionResultTerm); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index 7c2fa2ae5..f7570c7e0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -54,7 +54,7 @@ public static Rule makePrefixedPredicatesInternal(Rule rule, String // TODO do this nicely (using visitor?) if (head instanceof ActionHead) { ActionHead actionHead = (ActionHead) head; - newHead = Heads.newActionHead(makePredicateInternal(actionHead.getAtom()), actionHead.getAction(), actionHead.getActionInputTerms(), + newHead = Heads.newActionHead(makePredicateInternal(actionHead.getAtom()), actionHead.getActionName(), actionHead.getActionInputTerms(), actionHead.getActionOutputTerm()); } else { newHead = Heads.newNormalHead(makePredicateInternal(head.getAtom())); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 87e77df1d..2e99a7752 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -18,7 +18,6 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -28,11 +27,12 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.rules.heads.InstantiableHead; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; +import at.ac.tuwien.kr.alpha.core.actions.ActionContext; +import at.ac.tuwien.kr.alpha.core.actions.ActionWitness; import at.ac.tuwien.kr.alpha.core.depgraph.StratificationAlgorithm; import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfo; @@ -64,6 +64,11 @@ public class StratifiedEvaluation extends ProgramTransformation solvedRuleIds = new HashSet<>(); // Set of rules that have been completely evaluated. private LiteralInstantiator literalInstantiator; + private ActionContext actionContext; + + public StratifiedEvaluation(ActionContext actionContext) { + this.actionContext = actionContext; + } @Override // Note: ideally this returns a "PartiallyEvaluatedProgram" such that the grounder can directly use the working @@ -312,7 +317,7 @@ private void fireRule(CompiledRule rule, Substitution substitution) { // BasicAtom newAtom = this.instantiate(rule.getHead(), substitution); BasicAtom newAtom; if (rule.getHead() instanceof ActionHead) { - newAtom = instantiateActionHead((ActionHead) rule.getHead(), substitution); + newAtom = instantiateActionHead((ActionHead) rule.getHead(), substitution, rule.getRuleId()); } else { newAtom = instantiateNormalHead(rule.getHead(), substitution); } @@ -334,21 +339,19 @@ public BasicAtom instantiateNormalHead(NormalHead head, Substitution substitutio } // FIXME should be dispatched via visitor pattern - public BasicAtom instantiateActionHead(ActionHead head, Substitution substitution) { - // TODO ensure unique action only gets executed once! + public BasicAtom instantiateActionHead(ActionHead head, Substitution substitution, int ruleId) { List actionInput = head.getActionInputTerms(); List substitutedInput = new ArrayList<>(); // Substitute all variables in action input so that all input terms are ground. for (Term inputTerm : actionInput) { substitutedInput.add(inputTerm.substitute(substitution)); } - // Call the actual action. - // TODO exception handling (translate EVERY throwable to an error term) - Action action = head.getAction(); - FunctionTerm actionResult = action.execute(substitutedInput); + // Delegate action execution to respctive backend. + ActionWitness witness = actionContext.execute(head.getActionName(), ruleId, substitution, substitutedInput); + // TODO if the according debug flag is set, convert witness to atom and add to facts. // We have an action result. Add it to the substitution as the substitute for the variable bound to the action so we're able to obtain the // ground BasicAtom derived by the rule - substitution.put(head.getActionOutputTerm(), actionResult); + substitution.put(head.getActionOutputTerm(), witness.getActionResult()); return head.getAtom().substitute(substitution); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 79270bddc..9ccad4d9f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -125,7 +125,7 @@ private Rule findAndReplaceVariableEquality(Rule rule) { if (!rule.isConstraint()) { if (rule.getHead() instanceof ActionHead) { ActionHead actHead = (ActionHead) head; - rewrittenHead = Heads.newActionHead(actHead.getAtom(), actHead.getAction(), actHead.getActionInputTerms(), actHead.getActionOutputTerm()); + rewrittenHead = Heads.newActionHead(actHead.getAtom(), actHead.getActionName(), actHead.getActionInputTerms(), actHead.getActionOutputTerm()); } else { rewrittenHead = Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom()); } diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index b0e89d72e..e55b55d22 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -8,6 +8,8 @@ import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.core.actions.ActionContext; +import at.ac.tuwien.kr.alpha.core.actions.ActionContextImpl; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; @@ -66,8 +68,11 @@ public static Alpha newAlpha(SystemConfig cfg) { .build()); SolverFactory solverFactory = new SolverFactory(cfg.getSolverName(), cfg.getNogoodStoreName(), solverCfg); + // Create an action context + ActionContext aCtx = new ActionContextImpl(); + // Now that all dependencies are taken care of, build new Alpha instance. - return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, cfg.isEvaluateStratifiedPart(), + return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, aCtx, cfg.isEvaluateStratifiedPart(), cfg.isSortAnswerSets()); } diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index f2106fb5e..121f642c1 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -59,6 +59,7 @@ import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; import at.ac.tuwien.kr.alpha.commons.util.Util; +import at.ac.tuwien.kr.alpha.core.actions.ActionContext; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; @@ -81,17 +82,21 @@ public class AlphaImpl implements Alpha { private final GrounderFactory grounderFactory; private final SolverFactory solverFactory; + private final ActionContext actionContext; + private final boolean enableStratifiedEvaluation; private final boolean sortAnswerSets; AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, GrounderFactory grounderFactory, SolverFactory solverFactory, + ActionContext actionContext, boolean enableStratifiedEvaluation, boolean sortAnswerSets) { this.parserFactory = parserFactory; this.programNormalizationFactory = programNormalizationFactory; this.grounderFactory = grounderFactory; this.solverFactory = solverFactory; + this.actionContext = actionContext; this.enableStratifiedEvaluation = enableStratifiedEvaluation; this.sortAnswerSets = sortAnswerSets; } @@ -158,7 +163,7 @@ InternalProgram performProgramPreprocessing(NormalProgram program) { AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); // TODO as Evolog moves further along, we want to integrate stratified evaluation with grounder and solver. // Therefore, leave it as is and don't make part of factory API for now. - retVal = new StratifiedEvaluation().apply(analyzed); + retVal = new StratifiedEvaluation(actionContext).apply(analyzed); } return retVal; } @@ -246,7 +251,7 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; if (enableStratifiedEvaluation) { - preprocessed = new StratifiedEvaluation().apply(analyzed).toNormalProgram(); + preprocessed = new StratifiedEvaluation(actionContext).apply(analyzed).toNormalProgram(); } else { preprocessed = program; } From 0f2fe31e45b5e967773b905f05feb6b8eb921b17 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 8 Mar 2022 21:59:01 +0100 Subject: [PATCH 12/59] remove useage of non-java-8-api --- .../kr/alpha/commons/externals/AspStandardLibrary.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java index ee757b46e..c88a7d12a 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java @@ -27,6 +27,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -231,13 +232,15 @@ public static Set>> substringOfString(String str, int @Predicate(name = "str_x_xs") public static Set>> stringHeadRemainder(String str) { - List> xXs = null; + List> xXs = new ArrayList<>(); if (str.isEmpty()) { return Collections.emptySet(); } else if (str.length() == 1) { - xXs = List.of(Terms.newConstant(str), Terms.newConstant("")); + xXs.add(Terms.newConstant(str)); + xXs.add(Terms.newConstant("")); } else { - xXs = List.of(Terms.newConstant(str.substring(0, 1)), Terms.newConstant(str.substring(1, str.length()))); + xXs.add(Terms.newConstant(str.substring(0, 1))); + xXs.add(Terms.newConstant(str.substring(1, str.length()))); } return Collections.singleton(xXs); } From 7f8ba4f26e5ceb4356999b8aa47758232e469794 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 10 Mar 2022 10:43:11 +0100 Subject: [PATCH 13/59] unit tests for new standard library externals --- .../commons/externals/AspStandardLibrary.java | 19 +++++++- .../externals/AspStandardLibraryTest.java | 47 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java index c88a7d12a..392eed880 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java @@ -32,6 +32,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import at.ac.tuwien.kr.alpha.api.externals.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; @@ -48,6 +51,8 @@ */ public final class AspStandardLibrary { + private static final Logger LOGGER = LoggerFactory.getLogger(AspStandardLibrary.class); + private AspStandardLibrary() { throw new AssertionError(this.getClass().getSimpleName() + " is a non-instantiable utility class!"); } @@ -217,7 +222,12 @@ public static Set>> stringConcat(String s1, String s2) */ @Predicate(name = "string_parse_integer") public static Set>> stringParseInteger(String str) { - return Collections.singleton(Collections.singletonList(Terms.newConstant(Integer.valueOf(str)))); + try { + return Collections.singleton(Collections.singletonList(Terms.newConstant(Integer.valueOf(str)))); + } catch (NumberFormatException ex) { + LOGGER.warn("Not a valid integer value: {}", str); + return Collections.emptySet(); + } } @Predicate(name = "string_is_empty") @@ -227,7 +237,12 @@ public static boolean isStringEmpty(String str) { @Predicate(name = "string_substring") public static Set>> substringOfString(String str, int startIdx, int endIdx) { - return Collections.singleton(Collections.singletonList(Terms.newConstant(str.substring(startIdx, endIdx)))); + try { + return Collections.singleton(Collections.singletonList(Terms.newConstant(str.substring(startIdx, endIdx)))); + } catch (StringIndexOutOfBoundsException ex) { + LOGGER.warn("Invalid range for substring: {}, start {}, end {}", str, startIdx, endIdx); + return Collections.emptySet(); + } } @Predicate(name = "str_x_xs") diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibraryTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibraryTest.java index 75efaa200..ef11ffd28 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibraryTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibraryTest.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Set; +import java.util.function.Function; import org.junit.jupiter.api.Test; @@ -104,4 +105,50 @@ public void stringConcat() { assertEquals(Terms.newConstant("Foobar"), concat); } + @Test + public void stringParseValidInteger() { + Set>> result = AspStandardLibrary.stringParseInteger("123"); + assertEquals(1, result.size()); + List> intTerms = result.stream().findFirst().get(); + assertEquals(1, intTerms.size()); + Integer value = intTerms.get(0).getObject(); + assertEquals(123, value); + } + + @Test + public void stringParseInvalidInteger() { + assertTrue(AspStandardLibrary.stringParseInteger("bla").isEmpty()); + } + + @Test + public void stringEmpty() { + assertTrue(AspStandardLibrary.isStringEmpty("")); + assertFalse(AspStandardLibrary.isStringEmpty("bla")); + } + + @Test + public void substringValidRange() { + Set>> result = AspStandardLibrary.substringOfString("hahaha", 1, 4); + assertEquals(1, result.size()); + List> terms = result.stream().findFirst().get(); + assertEquals(1, terms.size()); + String substr = terms.get(0).getObject(); + assertEquals("aha", substr); + } + + @Test + public void substringInvalidRange() { + assertTrue(AspStandardLibrary.substringOfString("foo", 1, 0).isEmpty()); + } + + @Test + public void stringGetHead() { + Function>>, String> extractString = (set) -> { + return set.stream().findFirst().get().get(0).getObject(); + }; + assertTrue(AspStandardLibrary.stringHeadRemainder("").isEmpty()); + assertEquals("x", extractString.apply(AspStandardLibrary.stringHeadRemainder("x"))); + assertEquals("x", extractString.apply(AspStandardLibrary.stringHeadRemainder("xy"))); + } + } From 25008a4dd50f4f841b286b1902b70ee50eb167d0 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 10 Mar 2022 13:53:57 +0100 Subject: [PATCH 14/59] adapt AlphaFactory to work with externally supplied action bindings --- .../alpha/core/actions/ActionContextImpl.java | 13 ++--- .../tuwien/kr/alpha/core/actions/Actions.java | 16 ++++++ .../kr/alpha/api/impl/AlphaFactory.java | 47 ++++++++++++----- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 51 +++++++++++++++++++ 4 files changed, 104 insertions(+), 23 deletions(-) create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java index bfe5cc745..2d570cf38 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java @@ -12,18 +12,11 @@ public class ActionContextImpl implements ActionContext { // TODO initialize from outside - private final Map actions = new HashMap<>(); + private final Map actions; private final Map actionRecord = new HashMap<>(); - public ActionContextImpl() { - actions.put("printLine", Actions::printLine); - actions.put("fileOutputStream", Actions::fileOpenOutputStream); - actions.put("streamWrite", Actions::outputStreamWrite); - actions.put("outputStreamClose", Actions::outputStreamClose); - - actions.put("fileInputStream", Actions::fileOpenInputStream); - actions.put("streamReadLine", Actions::inputStreamReadLine); - actions.put("inputStreamClose", Actions::inputStreamClose); + public ActionContextImpl(Map actions) { + this.actions = actions; } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java index 22643cccf..391a6a1b7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java @@ -6,8 +6,11 @@ import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -16,6 +19,19 @@ public class Actions { + public static Map getDefaultActionBindings() { + Map actions = new HashMap<>(); + actions.put("printLine", Actions::printLine); + actions.put("fileOutputStream", Actions::fileOpenOutputStream); + actions.put("streamWrite", Actions::outputStreamWrite); + actions.put("outputStreamClose", Actions::outputStreamClose); + + actions.put("fileInputStream", Actions::fileOpenInputStream); + actions.put("streamReadLine", Actions::inputStreamReadLine); + actions.put("inputStreamClose", Actions::inputStreamClose); + return actions; + } + // TODO this needs to be encapsulated and made thread-safe! private static final IntIdGenerator ID_GEN = new IntIdGenerator(); diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index e55b55d22..5c331c055 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -2,7 +2,10 @@ import java.util.function.Supplier; +import com.google.common.annotations.VisibleForTesting; + import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.config.AggregateRewritingConfig; import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; @@ -10,6 +13,7 @@ import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.core.actions.ActionContext; import at.ac.tuwien.kr.alpha.core.actions.ActionContextImpl; +import at.ac.tuwien.kr.alpha.core.actions.Actions; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; @@ -27,14 +31,12 @@ private AlphaFactory() { throw new AssertionError("Cannot instantiate utility class!"); } - public static Alpha newAlpha(SystemConfig cfg) { - // Parser factory - Supply correct parser dependent on the accepted input language. - Supplier parserFactory = () -> cfg.isAcceptEvologPrograms() ? new EvologProgramParser() : new ASPCore2ProgramParser(); - + static Supplier> newProgramNormalizationFactory(Supplier parserFactory, + AggregateRewritingConfig aggregateCfg) { // AggregateEncoderFactory depends on parser factory since stringtemplate-based aggregate encoders need to use the same parser that's used // for input programs. AggregateEncoderFactory aggregateEncoderFactory = new AggregateEncoderFactory(parserFactory, - cfg.getAggregateRewritingConfig().isUseSortingGridEncoding(), cfg.getAggregateRewritingConfig().isSupportNegativeValuesInSums()); + aggregateCfg.isUseSortingGridEncoding(), aggregateCfg.isSupportNegativeValuesInSums()); // Factory for aggregate rewriting (depends on encoders provided by above factory). Supplier aggregateRewritingFactory = () -> new AggregateRewriting(aggregateEncoderFactory.newCountEqualsEncoder(), @@ -43,18 +45,20 @@ public static Alpha newAlpha(SystemConfig cfg) { // Factory for NormalizeProgramTransformation - needs a supplier for AggregateRewriting due to AggregateRewritings' dependency to encoder // factory. - Supplier> programNormalizationFactory = () -> new NormalizeProgramTransformation( + return () -> new NormalizeProgramTransformation( aggregateRewritingFactory); + } - // GrounderFactory - Since every grounder instance is only good for one program instance, we need a factory. + static GrounderFactory newGrounderFactory(SystemConfig cfg) { GrounderHeuristicsConfiguration grounderHeuristicsCfg = GrounderHeuristicsConfiguration.getInstance(cfg.getGrounderToleranceConstraints(), cfg.getGrounderToleranceRules()); grounderHeuristicsCfg.setAccumulatorEnabled(cfg.isGrounderAccumulatorEnabled()); - GrounderFactory grounderFactory = new GrounderFactory( + return new GrounderFactory( grounderHeuristicsCfg, cfg.isDebugInternalChecks()); + } - // SolverFactory - Same as for GrounderFactory, we need a new Solver for each program. + static SolverFactory newSolverFactory(SystemConfig cfg) { SolverConfig solverCfg = new SolverConfig(); solverCfg.setDisableJustifications(cfg.isDisableJustificationSearch()); solverCfg.setDisableNogoodDeletion(cfg.isDisableNoGoodDeletion()); @@ -66,16 +70,33 @@ public static Alpha newAlpha(SystemConfig cfg) { .setMomsStrategy(cfg.getMomsStrategy()) .setReplayChoices(cfg.getReplayChoices()) .build()); - SolverFactory solverFactory = new SolverFactory(cfg.getSolverName(), cfg.getNogoodStoreName(), solverCfg); + return new SolverFactory(cfg.getSolverName(), cfg.getNogoodStoreName(), solverCfg); + } - // Create an action context - ActionContext aCtx = new ActionContextImpl(); + // TODO lifetime of one ActionContext needs to be exactly runtime ofone program! + @VisibleForTesting + public static Alpha newAlpha(SystemConfig cfg, ActionContext actionContext) { + // Parser factory - Supply correct parser dependent on the accepted input language. + Supplier parserFactory = () -> cfg.isAcceptEvologPrograms() ? new EvologProgramParser() : new ASPCore2ProgramParser(); + Supplier> programNormalizationFactory = newProgramNormalizationFactory(parserFactory, + cfg.getAggregateRewritingConfig()); + // GrounderFactory - Since every grounder instance is only good for one program instance, we need a factory. + GrounderFactory grounderFactory = newGrounderFactory(cfg); + + // SolverFactory - Same as for GrounderFactory, we need a new Solver for each program. + SolverFactory solverFactory = newSolverFactory(cfg); + // Now that all dependencies are taken care of, build new Alpha instance. - return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, aCtx, cfg.isEvaluateStratifiedPart(), + return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, actionContext, cfg.isEvaluateStratifiedPart(), cfg.isSortAnswerSets()); } + public static Alpha newAlpha(SystemConfig cfg) { + return newAlpha(cfg, new ActionContextImpl(Actions.getDefaultActionBindings())); + } + + // Create Alpha instance with default config. public static Alpha newAlpha() { return newAlpha(new SystemConfig()); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java new file mode 100644 index 000000000..09d23b500 --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -0,0 +1,51 @@ +package at.ac.tuwien.kr.alpha; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +public class ActionsTest { + + private static class MockActionBindings { + + /* + Map actions = new HashMap<>(); + actions.put("printLine", Actions::printLine); + actions.put("fileOutputStream", Actions::fileOpenOutputStream); + actions.put("streamWrite", Actions::outputStreamWrite); + actions.put("outputStreamClose", Actions::outputStreamClose); + + actions.put("fileInputStream", Actions::fileOpenInputStream); + actions.put("streamReadLine", Actions::inputStreamReadLine); + actions.put("inputStreamClose", Actions::inputStreamClose); + return actions; + */ + + public FunctionTerm fileOpenOutputStream(List input) { + return null; + } + + public FunctionTerm outputStreamWrite(List input) { + return null; + } + + public FunctionTerm outputStreamClose(List input) { + return null; + } + + public FunctionTerm fileOpenInputStream(List input) { + return null; + } + + public FunctionTerm inputStreamReadLine(List input) { + return null; + } + + public FunctionTerm inputStreamClose(List inputStream) { + return null; + } + + } + +} From da7160d312bef24363c98a1f21ace552386015cf Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 7 Jul 2022 13:33:06 +0200 Subject: [PATCH 15/59] WIP: refine action implementation --- .../kr/alpha/core/actions/IOResult.java | 70 +++++++++++++++++++ .../at/ac/tuwien/kr/alpha/ActionsTest.java | 32 +++++---- 2 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java new file mode 100644 index 000000000..dce13429d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java @@ -0,0 +1,70 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; + +public class IOResult implements FunctionTerm { + + private final Optional value; + private final Optional> error; + + public boolean isSuccess() { + return value.isPresent(); + } + + public boolean isError() { + return error.isPresent(); + } + + @Override + public boolean isGround() { + return true; + } + + @Override + public Set getOccurringVariables() { + return Collections.emptySet(); + } + + @Override + public Term substitute(Substitution substitution) { + return this; + } + + @Override + public Term renameVariables(String renamePrefix) { + return this; + } + + @Override + public Term normalizeVariables(String renamePrefix, RenameCounter counter) { + return this; + } + + @Override + public int compareTo(Term arg0) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public List getTerms() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getSymbol() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index 09d23b500..f4e2a31c4 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -1,28 +1,36 @@ package at.ac.tuwien.kr.alpha; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; public class ActionsTest { - + private static class MockActionBindings { - /* - Map actions = new HashMap<>(); - actions.put("printLine", Actions::printLine); - actions.put("fileOutputStream", Actions::fileOpenOutputStream); - actions.put("streamWrite", Actions::outputStreamWrite); - actions.put("outputStreamClose", Actions::outputStreamClose); + static final Logger LOGGER = LoggerFactory.getLogger(MockActionBindings.class); - actions.put("fileInputStream", Actions::fileOpenInputStream); - actions.put("streamReadLine", Actions::inputStreamReadLine); - actions.put("inputStreamClose", Actions::inputStreamClose); - return actions; - */ + Map, Integer> fileOpenOutputStreamInvocations = new HashMap<>(); + Map, Integer> outputStreamWriteInvocations = new HashMap<>(); + Map, Integer> outputStreamCloseInvocations = new HashMap<>(); + Map, Integer> fileOpenInputStreamInvocations = new HashMap<>(); + Map, Integer> inputStreamReadLineInvocations = new HashMap<>(); + Map, Integer> inputStreamCloseInvocations = new HashMap<>(); public FunctionTerm fileOpenOutputStream(List input) { + if (fileOpenOutputStreamInvocations.containsKey(input)) { + fileOpenOutputStreamInvocations.put(input, fileOpenOutputStreamInvocations.get(input) + 1); + } else { + fileOpenOutputStreamInvocations.put(input, 1); + } + LOGGER.info("Action fileOpenOutputStream({})", StringUtils.join(input, ", ")); return null; } From 625a3d0744e026e4434a57a55dbdf446f09e5b7b Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 25 Aug 2022 09:48:33 +0200 Subject: [PATCH 16/59] add ActionResultTerm interface and implementations --- .../kr/alpha/api/terms/ActionResultTerm.java | 29 ++++++++ .../terms/AbstractActionResultTerm.java | 26 +++++++ .../alpha/commons/terms/ActionErrorTerm.java | 24 +++++++ .../commons/terms/ActionSuccessTerm.java | 25 +++++++ .../alpha/commons/terms/FunctionTermImpl.java | 3 +- .../tuwien/kr/alpha/commons/terms/Terms.java | 9 +++ .../kr/alpha/core/actions/IOResult.java | 70 ------------------- 7 files changed, 115 insertions(+), 71 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ActionResultTerm.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/AbstractActionResultTerm.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionErrorTerm.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionSuccessTerm.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ActionResultTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ActionResultTerm.java new file mode 100644 index 000000000..7f6539bfa --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ActionResultTerm.java @@ -0,0 +1,29 @@ +package at.ac.tuwien.kr.alpha.api.terms; + +/** + * A term representing the result of an evolog action (i.e. result of action function application). + * Action result terms are function terms with symbol "success" or "error" depending on whether the corresponding action was sucessful. + * There is always one argument which is either some term representing the actual function result or an error message, respectively. + */ +public interface ActionResultTerm extends FunctionTerm { + + public static final String SUCCESS_SYMBOL = "success"; + public static final String ERROR_SYMBOL = "error"; + + /** + * True if the action that generated this result was successful (i.e. executed normally). + */ + boolean isSuccess(); + + /** + * True if the action that generated this result failed (i.e. threw an error in execution). + */ + boolean isError(); + + /** + * Gets the actual value wrapped in this result. + * Either a term representing the action return value or a string term representing an error + * message.s + */ + T getValue(); +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/AbstractActionResultTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/AbstractActionResultTerm.java new file mode 100644 index 000000000..4fba074cb --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/AbstractActionResultTerm.java @@ -0,0 +1,26 @@ +package at.ac.tuwien.kr.alpha.commons.terms; + +import java.util.Collections; + +import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +abstract class AbstractActionResultTerm extends FunctionTermImpl implements ActionResultTerm { + + AbstractActionResultTerm(String symbol, T value) { + super(symbol, Collections.singletonList(value)); + } + + public abstract boolean isSuccess(); + + public boolean isError() { + return !isSuccess(); + } + + // Note: Unchecked cast is ok, we permit only instances of T as constructor arguments. + @SuppressWarnings("unchecked") + public T getValue() { + return (T) getTerms().get(0); + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionErrorTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionErrorTerm.java new file mode 100644 index 000000000..7bc4431b0 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionErrorTerm.java @@ -0,0 +1,24 @@ +package at.ac.tuwien.kr.alpha.commons.terms; + +import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.util.Interner; + +class ActionErrorTerm extends AbstractActionResultTerm> { + + private static final Interner INTERNER = new Interner<>(); + + ActionErrorTerm(ConstantTerm value) { + super(ActionResultTerm.ERROR_SYMBOL, value); + } + + public static ActionErrorTerm getInstance(ConstantTerm term) { + return INTERNER.intern(new ActionErrorTerm(term)); + } + + @Override + public boolean isSuccess() { + return false; + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionSuccessTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionSuccessTerm.java new file mode 100644 index 000000000..2502de56f --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ActionSuccessTerm.java @@ -0,0 +1,25 @@ +package at.ac.tuwien.kr.alpha.commons.terms; + +import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.util.Interner; + +class ActionSuccessTerm extends AbstractActionResultTerm { + + private static final Interner> INTERNER = new Interner<>(); + + ActionSuccessTerm(T value) { + super(ActionResultTerm.SUCCESS_SYMBOL, value); + } + + @SuppressWarnings("unchecked") + public static ActionSuccessTerm getInstance(T term) { + return (ActionSuccessTerm) INTERNER.intern(new ActionSuccessTerm<>(term)); + } + + @Override + public boolean isSuccess() { + return true; + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java index 14b8535de..694905e48 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java @@ -18,13 +18,14 @@ * Copyright (c) 2016-2017, the Alpha Team. */ class FunctionTermImpl extends AbstractTerm implements FunctionTerm { + private static final Interner INTERNER = new Interner<>(); private final String symbol; private final List terms; private final boolean ground; - private FunctionTermImpl(String symbol, List terms) { + FunctionTermImpl(String symbol, List terms) { if (symbol == null) { throw new IllegalArgumentException(); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/Terms.java index b02e00c7b..8a361df6f 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/Terms.java @@ -5,6 +5,7 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; import at.ac.tuwien.kr.alpha.api.terms.ArithmeticOperator; import at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; @@ -65,6 +66,14 @@ public static Term newMinusTerm(Term negatedTerm) { return MinusTerm.getInstance(negatedTerm); } + public static ActionResultTerm actionSuccess(T value) { + return ActionSuccessTerm.getInstance(value); + } + + public static ActionResultTerm> actionError(String errMsg) { + return ActionErrorTerm.getInstance(Terms.newConstant(errMsg)); + } + @SafeVarargs public static > List> asTermList(T... values) { List> retVal = new ArrayList<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java deleted file mode 100644 index dce13429d..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/IOResult.java +++ /dev/null @@ -1,70 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.actions; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; - -public class IOResult implements FunctionTerm { - - private final Optional value; - private final Optional> error; - - public boolean isSuccess() { - return value.isPresent(); - } - - public boolean isError() { - return error.isPresent(); - } - - @Override - public boolean isGround() { - return true; - } - - @Override - public Set getOccurringVariables() { - return Collections.emptySet(); - } - - @Override - public Term substitute(Substitution substitution) { - return this; - } - - @Override - public Term renameVariables(String renamePrefix) { - return this; - } - - @Override - public Term normalizeVariables(String renamePrefix, RenameCounter counter) { - return this; - } - - @Override - public int compareTo(Term arg0) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public List getTerms() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getSymbol() { - // TODO Auto-generated method stub - return null; - } - -} From 990da899b52132053552e0f7f6ec2d9ed060613d Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 26 Aug 2022 14:51:42 +0200 Subject: [PATCH 17/59] use ActionResultTerm interface in Action implementations --- .../kr/alpha/api/programs/actions/Action.java | 4 +- .../tuwien/kr/alpha/core/actions/Actions.java | 81 +++++++++---------- .../transformation/StratifiedEvaluation.java | 2 +- .../kr/alpha/api/impl/AlphaFactory.java | 2 +- 4 files changed, 41 insertions(+), 48 deletions(-) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java index 4c4b350b9..5b0ab32e1 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java @@ -2,7 +2,7 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; /** @@ -17,6 +17,6 @@ public interface Action { * @param input a list of (ground) terms constituting the input of the action * @return a function term representing the result of executing the action */ - FunctionTerm execute(List input); + ActionResultTerm execute(List input); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java index 391a6a1b7..a914f8523 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java @@ -11,8 +11,8 @@ import java.util.Map; import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; @@ -35,51 +35,48 @@ public static Map getDefaultActionBindings() { // TODO this needs to be encapsulated and made thread-safe! private static final IntIdGenerator ID_GEN = new IntIdGenerator(); - public static FunctionTerm printLine(List input) { + public static ActionResultTerm> printLine(List input) { if (input.size() != 1) { - // TODO do properly - throw new RuntimeException("Incorrect arity!"); + return Terms.actionError("Incorrect input size!"); } // TODO this should only work on ConstantTerm System.out.println(input.get(0).toString()); - return Terms.newFunctionTerm("ok"); + return Terms.actionSuccess(Terms.newSymbolicConstant("ok")); } - public static FunctionTerm fileOpenOutputStream(List input) { + public static ActionResultTerm fileOpenOutputStream(List input) { if (input.size() != 1) { - // TODO do properly - throw new IllegalArgumentException("Incorrect arity!"); + return Terms.actionError("Incorrect input size!"); } Term inTerm = input.get(0); if (!(inTerm instanceof ConstantTerm)) { - throw new IllegalArgumentException("Input must be a string constant!"); + return Terms.actionError("Input must be a string constant!"); } ConstantTerm inConst = (ConstantTerm) inTerm; if (!(inConst.getObject() instanceof String) || inConst.isSymbolic()) { - throw new IllegalArgumentException("Input must be a string constant!"); + return Terms.actionError("Input must be a string constant!"); } String path = (String) inConst.getObject(); try { OutputStreamHandle streamHandle = new OutputStreamHandle(ID_GEN.getNextId(), new FileOutputStream(path, true)); - return Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle)); + return Terms.actionSuccess(Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle))); } catch (FileNotFoundException e) { - throw new RuntimeException(e); + return Terms.actionError("File not found: " + path); } } @SuppressWarnings("unchecked") - public static FunctionTerm outputStreamWrite(List input) { + public static ActionResultTerm> outputStreamWrite(List input) { if (input.size() != 2) { - // TODO do properly - throw new IllegalArgumentException("Incorrect arity!"); + return Terms.actionError("Incorrect input size!"); } if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof OutputStreamHandle)) { - throw new IllegalArgumentException("First input term must be an output stream handle!"); + return Terms.actionError("First input term must be an output stream handle!"); } OutputStreamHandle dstHandle = ((ConstantTerm) input.get(0)).getObject(); if (!(input.get(1) instanceof ConstantTerm) || !(((ConstantTerm) input.get(1)).getObject() instanceof String) || ((ConstantTerm) input.get(1)).isSymbolic()) { - throw new IllegalArgumentException("Second input term must be a string constant!"); + return Terms.actionError("Second input term must be a string constant!"); } String str = ((ConstantTerm) input.get(1)).getObject(); // TODO this needs some built-in conversion function @@ -87,60 +84,57 @@ public static FunctionTerm outputStreamWrite(List input) { OutputStream dst = dstHandle.getStream(); try { dst.write(data); - return Terms.newFunctionTerm("writeResult", Terms.newSymbolicConstant("ok")); + return Terms.actionSuccess(Terms.newSymbolicConstant("ok")); } catch (IOException ex) { - throw new RuntimeException(ex); + return Terms.actionError("Error writing data: " + ex.getMessage()); } } @SuppressWarnings("unchecked") - public static FunctionTerm outputStreamClose(List input) { + public static ActionResultTerm> outputStreamClose(List input) { if (input.size() != 1) { - // TODO do properly - throw new IllegalArgumentException("Incorrect arity!"); + return Terms.actionError("Incorrect input size!"); } if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof OutputStreamHandle)) { - throw new IllegalArgumentException("First input term must be an output stream handle!"); + return Terms.actionError("First input term must be an output stream handle!"); } OutputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); try { handle.getStream().close(); - return Terms.newFunctionTerm("closeResult", Terms.newSymbolicConstant("ok")); + return Terms.actionSuccess(Terms.newSymbolicConstant("ok")); } catch (IOException ex) { - throw new RuntimeException(ex); + return Terms.actionError("Error closing stream: " + ex.getMessage()); } } - public static FunctionTerm fileOpenInputStream(List input) { + public static ActionResultTerm fileOpenInputStream(List input) { if (input.size() != 1) { - // TODO do properly - throw new IllegalArgumentException("Incorrect arity!"); + return Terms.actionError("Incorrect input size!"); } Term inTerm = input.get(0); if (!(inTerm instanceof ConstantTerm)) { - throw new IllegalArgumentException("Input must be a string constant!"); + return Terms.actionError("Input must be a string constant!"); } ConstantTerm inConst = (ConstantTerm) inTerm; if (!(inConst.getObject() instanceof String) || inConst.isSymbolic()) { - throw new IllegalArgumentException("Input must be a string constant!"); + return Terms.actionError("Input must be a string constant!"); } String path = (String) inConst.getObject(); try { InputStreamHandle streamHandle = new InputStreamHandle(ID_GEN.getNextId(), Files.newBufferedReader(Paths.get(path))); - return Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle)); + return Terms.actionSuccess(Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle))); } catch (IOException ex) { - throw new RuntimeException(ex); + return Terms.actionError("Error opening input stream: " + ex.getMessage()); } } @SuppressWarnings("unchecked") - public static FunctionTerm inputStreamReadLine(List input) { + public static ActionResultTerm inputStreamReadLine(List input) { if (input.size() != 1) { - // TODO do properly - throw new IllegalArgumentException("Incorrect arity!"); + return Terms.actionError("Incorrect input size!"); } if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof InputStreamHandle)) { - throw new IllegalArgumentException("First input term must be an input stream handle!"); + return Terms.actionError("First input term must be an input stream handle!"); } InputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); try { @@ -152,27 +146,26 @@ public static FunctionTerm inputStreamReadLine(List input) { } else { lineTerm = Terms.newConstant(line); } - return Terms.newFunctionTerm("ok", lineTerm); + return Terms.actionSuccess(Terms.newFunctionTerm("line", lineTerm)); } catch (IOException ex) { - throw new RuntimeException(ex); + return Terms.actionError("Error reading data"); } } @SuppressWarnings("unchecked") - public static FunctionTerm inputStreamClose(List input) { + public static ActionResultTerm inputStreamClose(List input) { if (input.size() != 1) { - // TODO do properly - throw new IllegalArgumentException("Incorrect arity!"); + return Terms.actionError("Incorrect input size!"); } if (!(input.get(0) instanceof ConstantTerm) || !(((ConstantTerm) input.get(0)).getObject() instanceof InputStreamHandle)) { - throw new IllegalArgumentException("First input term must be an input stream handle!"); + return Terms.actionError("First input term must be an input stream handle!"); } InputStreamHandle handle = ((ConstantTerm) input.get(0)).getObject(); try { handle.getStream().close(); - return Terms.newFunctionTerm("closeResult", Terms.newSymbolicConstant("ok")); + return Terms.actionSuccess(Terms.newFunctionTerm("closeResult", Terms.newSymbolicConstant("ok"))); } catch (IOException ex) { - throw new RuntimeException(ex); + return Terms.actionError("Error writing data: " + ex.getMessage()); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 2e99a7752..753512151 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -346,7 +346,7 @@ public BasicAtom instantiateActionHead(ActionHead head, Substitution substitutio for (Term inputTerm : actionInput) { substitutedInput.add(inputTerm.substitute(substitution)); } - // Delegate action execution to respctive backend. + // Delegate action execution to respective backend. ActionWitness witness = actionContext.execute(head.getActionName(), ruleId, substitution, substitutedInput); // TODO if the according debug flag is set, convert witness to atom and add to facts. // We have an action result. Add it to the substitution as the substitute for the variable bound to the action so we're able to obtain the diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index 5c331c055..7c214243e 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -73,7 +73,7 @@ static SolverFactory newSolverFactory(SystemConfig cfg) { return new SolverFactory(cfg.getSolverName(), cfg.getNogoodStoreName(), solverCfg); } - // TODO lifetime of one ActionContext needs to be exactly runtime ofone program! + // TODO lifetime of one ActionContext needs to be exactly runtime of one program! @VisibleForTesting public static Alpha newAlpha(SystemConfig cfg, ActionContext actionContext) { // Parser factory - Supply correct parser dependent on the accepted input language. From b8821daab7f15d5ac191b9e882c15e01c9f0fd95 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 29 Aug 2022 11:18:59 +0200 Subject: [PATCH 18/59] add debug option to add action witnesses to answer set --- .../kr/alpha/core/actions/ActionWitness.java | 10 ++-- .../transformation/StratifiedEvaluation.java | 48 ++++++++++++++++--- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 4 +- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java index ffa885726..a81bf4301 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java @@ -8,14 +8,14 @@ public class ActionWitness { private final int ruleId; - private final Substitution groundBody; + private final Substitution groundSubstitution; private final String actionName; private final List actionInput; private final Term actionResult; - public ActionWitness(int ruleId, Substitution groundBody, String actionName, List actionInput, Term actionResult) { + public ActionWitness(int ruleId, Substitution groundSubstitution, String actionName, List actionInput, Term actionResult) { this.ruleId = ruleId; - this.groundBody = groundBody; + this.groundSubstitution = groundSubstitution; this.actionName = actionName; this.actionInput = actionInput; this.actionResult = actionResult; @@ -25,8 +25,8 @@ public int getRuleId() { return ruleId; } - public Substitution getGroundBody() { - return groundBody; + public Substitution getGroundSubstitution() { + return groundSubstitution; } public String getActionName() { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 753512151..cde8a0d87 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -27,10 +27,13 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.rules.heads.InstantiableHead; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.actions.ActionContext; import at.ac.tuwien.kr.alpha.core.actions.ActionWitness; import at.ac.tuwien.kr.alpha.core.depgraph.StratificationAlgorithm; @@ -65,9 +68,11 @@ public class StratifiedEvaluation extends ProgramTransformation(inputProgram.getFacts()); - + // Set up literal instantiator. literalInstantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); @@ -317,7 +322,7 @@ private void fireRule(CompiledRule rule, Substitution substitution) { // BasicAtom newAtom = this.instantiate(rule.getHead(), substitution); BasicAtom newAtom; if (rule.getHead() instanceof ActionHead) { - newAtom = instantiateActionHead((ActionHead) rule.getHead(), substitution, rule.getRuleId()); + newAtom = instantiateActionHead((ActionHead) rule.getHead(), substitution, rule); } else { newAtom = instantiateNormalHead(rule.getHead(), substitution); } @@ -339,7 +344,7 @@ public BasicAtom instantiateNormalHead(NormalHead head, Substitution substitutio } // FIXME should be dispatched via visitor pattern - public BasicAtom instantiateActionHead(ActionHead head, Substitution substitution, int ruleId) { + public BasicAtom instantiateActionHead(ActionHead head, Substitution substitution, CompiledRule rule) { List actionInput = head.getActionInputTerms(); List substitutedInput = new ArrayList<>(); // Substitute all variables in action input so that all input terms are ground. @@ -347,14 +352,45 @@ public BasicAtom instantiateActionHead(ActionHead head, Substitution substitutio substitutedInput.add(inputTerm.substitute(substitution)); } // Delegate action execution to respective backend. - ActionWitness witness = actionContext.execute(head.getActionName(), ruleId, substitution, substitutedInput); - // TODO if the according debug flag is set, convert witness to atom and add to facts. + ActionWitness witness = actionContext.execute(head.getActionName(), rule.getRuleId(), substitution, substitutedInput); + // If the according debug flag is set, convert witness to atom and add to facts. + if (generateActionWitnesses) { + BasicAtom witnessAtom = buildActionWitnessAtom(witness, rule); + // Note that this is a rather "sneaky" side-effect, + // but seems like overkill to do this structurally proper just for a debug feature. + workingMemory.addInstance(witnessAtom, true); + } // We have an action result. Add it to the substitution as the substitute for the variable bound to the action so we're able to obtain the // ground BasicAtom derived by the rule substitution.put(head.getActionOutputTerm(), witness.getActionResult()); return head.getAtom().substitute(substitution); } + private BasicAtom buildActionWitnessAtom(ActionWitness witness, CompiledRule rule) { + // Note that this methods should only ever be used for debugging! + // While action witnesses are used as a semantic concept in the evolog specification, + // they normally only exist implicitly. + + // Construct state term: create function terms from ground body literals. + List functionalizedBody = new ArrayList<>(); + for (Literal lit : rule.getBody()) { + Literal groundLit = lit.substitute(witness.getGroundSubstitution()); + FunctionTerm functionalizedLiteral = Terms.newFunctionTerm(groundLit.getPredicate().getName(), groundLit.getTerms()); + functionalizedBody.add(functionalizedLiteral); + } + FunctionTerm stateTerm = Terms.newFunctionTerm("state", functionalizedBody); + + // Construct input term: wrap action input terms into one function term. + FunctionTerm inputTerm = Terms.newFunctionTerm("input", witness.getActionInput()); + + // Return witness atom: put state and input terms together. + return Atoms.newBasicAtom(Predicates.getPredicate("action_witness", 4), + Terms.newConstant(witness.getActionName()), + stateTerm, + inputTerm, + witness.getActionResult()); + } + private ComponentEvaluationInfo getRulesToEvaluate(ComponentGraph.SCComponent comp) { Set nonRecursiveRules = new HashSet<>(); Set recursiveRules = new HashSet<>(); diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index 121f642c1..f6ba63352 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -163,7 +163,7 @@ InternalProgram performProgramPreprocessing(NormalProgram program) { AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); // TODO as Evolog moves further along, we want to integrate stratified evaluation with grounder and solver. // Therefore, leave it as is and don't make part of factory API for now. - retVal = new StratifiedEvaluation(actionContext).apply(analyzed); + retVal = new StratifiedEvaluation(actionContext, true).apply(analyzed); } return retVal; } @@ -251,7 +251,7 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; if (enableStratifiedEvaluation) { - preprocessed = new StratifiedEvaluation(actionContext).apply(analyzed).toNormalProgram(); + preprocessed = new StratifiedEvaluation(actionContext, true).apply(analyzed).toNormalProgram(); } else { preprocessed = program; } From dc0198d06c9440b83d6b65d46cd9ee7c4e3ef621 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 29 Aug 2022 16:06:02 +0200 Subject: [PATCH 19/59] specification for action implementation provider --- ...AbstractActionImplementationProvider.java} | 108 ++++++++++++------ ...ntext.java => ActionExecutionService.java} | 2 +- ...l.java => ActionExecutionServiceImpl.java} | 12 +- .../actions/ActionImplementationProvider.java | 30 +++++ .../DefaultActionImplementationProvider.java | 32 ++++++ .../transformation/StratifiedEvaluation.java | 6 +- .../MockActionImplementationProvider.java | 40 +++++++ .../kr/alpha/api/impl/AlphaFactory.java | 10 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 6 +- .../kr/alpha/regressiontests/ActionsTest.java | 10 ++ .../util/RegressionTestUtils.java | 4 + .../alpha.java-common-conventions.gradle.kts | 1 + 12 files changed, 209 insertions(+), 52 deletions(-) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/{Actions.java => AbstractActionImplementationProvider.java} (59%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/{ActionContext.java => ActionExecutionService.java} (87%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/{ActionContextImpl.java => ActionExecutionServiceImpl.java} (86%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionImplementationProvider.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java create mode 100644 alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java similarity index 59% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java index a914f8523..8ec02d340 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/Actions.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java @@ -1,15 +1,16 @@ package at.ac.tuwien.kr.alpha.core.actions; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.actions.Action; import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; @@ -17,34 +18,67 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; -public class Actions { +public abstract class AbstractActionImplementationProvider implements ActionImplementationProvider { - public static Map getDefaultActionBindings() { - Map actions = new HashMap<>(); - actions.put("printLine", Actions::printLine); - actions.put("fileOutputStream", Actions::fileOpenOutputStream); - actions.put("streamWrite", Actions::outputStreamWrite); - actions.put("outputStreamClose", Actions::outputStreamClose); + private final IntIdGenerator idGenerator = new IntIdGenerator(); + private final Map supportedActions = new HashMap<>(); - actions.put("fileInputStream", Actions::fileOpenInputStream); - actions.put("streamReadLine", Actions::inputStreamReadLine); - actions.put("inputStreamClose", Actions::inputStreamClose); - return actions; + public AbstractActionImplementationProvider() { + registerAction("fileOutputStream", this::openFileOutputStreamAction); + registerAction("streamWrite", this::outputStreamWriteAction); + registerAction("outputStreamClose", this::outputStreamCloseAction); + registerAction("fileInputStream", this::openFileInputStreamAction); + registerAction("streamReadLine", this::inputStreamReadLineAction); + registerAction("inputStreamClose", this::inputStreamCloseAction); } - // TODO this needs to be encapsulated and made thread-safe! - private static final IntIdGenerator ID_GEN = new IntIdGenerator(); + /** + * Returns a map of all actions supported by this implementation provider. + */ + public final Map getSupportedActions() { + return supportedActions; + } - public static ActionResultTerm> printLine(List input) { - if (input.size() != 1) { - return Terms.actionError("Incorrect input size!"); - } - // TODO this should only work on ConstantTerm - System.out.println(input.get(0).toString()); - return Terms.actionSuccess(Terms.newSymbolicConstant("ok")); + /** + * Returns a predicate interpretation specifying an external that takes no arguments + * and returns a reference to the standard system output stream (stdout). + */ + // TODO we need to reuse this term! (do we?? its interned...) + public final PredicateInterpretation getStdoutTerm() { + return (trms) -> { + if (!trms.isEmpty()) { + throw new IllegalArgumentException("Invalid method call! Expected term list to be empty!"); + } + return Collections.singleton( + Collections.singletonList( + Terms.newConstant( + new OutputStreamHandle(idGenerator.getNextId(), getStdoutStream())))); + }; + } + + /** + * Returns a predicate interpretation specifying an external that takes no arguments + * and returns a reference to the standard system input stream (stdin). + */ + // TODO we need to reuse this term! (do we?? its interned...) + public final PredicateInterpretation getStdinTerm() { + return (trms) -> { + if (!trms.isEmpty()) { + throw new IllegalArgumentException("Invalid method call! Expected term list to be empty!"); + } + return Collections.singleton( + Collections.singletonList( + Terms.newConstant( + new InputStreamHandle(idGenerator.getNextId(), + new BufferedReader(new InputStreamReader(getStdinStream())))))); + }; + } + + protected final void registerAction(String name, Action action) { + supportedActions.put(name, action); } - public static ActionResultTerm fileOpenOutputStream(List input) { + private ActionResultTerm openFileOutputStreamAction(List input) { if (input.size() != 1) { return Terms.actionError("Incorrect input size!"); } @@ -58,15 +92,15 @@ public static ActionResultTerm fileOpenOutputStream(List input) { } String path = (String) inConst.getObject(); try { - OutputStreamHandle streamHandle = new OutputStreamHandle(ID_GEN.getNextId(), new FileOutputStream(path, true)); + OutputStreamHandle streamHandle = new OutputStreamHandle(idGenerator.getNextId(), getFileOutputStream(path)); return Terms.actionSuccess(Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle))); - } catch (FileNotFoundException e) { + } catch (IOException e) { return Terms.actionError("File not found: " + path); } } @SuppressWarnings("unchecked") - public static ActionResultTerm> outputStreamWrite(List input) { + private ActionResultTerm> outputStreamWriteAction(List input) { if (input.size() != 2) { return Terms.actionError("Incorrect input size!"); } @@ -91,7 +125,7 @@ public static ActionResultTerm> outputStreamWrite(List> outputStreamClose(List input) { + private ActionResultTerm> outputStreamCloseAction(List input) { if (input.size() != 1) { return Terms.actionError("Incorrect input size!"); } @@ -107,7 +141,7 @@ public static ActionResultTerm> outputStreamClose(List fileOpenInputStream(List input) { + private ActionResultTerm openFileInputStreamAction(List input) { if (input.size() != 1) { return Terms.actionError("Incorrect input size!"); } @@ -121,7 +155,7 @@ public static ActionResultTerm fileOpenInputStream(List input) { } String path = (String) inConst.getObject(); try { - InputStreamHandle streamHandle = new InputStreamHandle(ID_GEN.getNextId(), Files.newBufferedReader(Paths.get(path))); + InputStreamHandle streamHandle = new InputStreamHandle(idGenerator.getNextId(), new BufferedReader(new InputStreamReader(getInputStream(path)))); return Terms.actionSuccess(Terms.newFunctionTerm("stream", Terms.newConstant(streamHandle))); } catch (IOException ex) { return Terms.actionError("Error opening input stream: " + ex.getMessage()); @@ -129,7 +163,7 @@ public static ActionResultTerm fileOpenInputStream(List input) { } @SuppressWarnings("unchecked") - public static ActionResultTerm inputStreamReadLine(List input) { + private ActionResultTerm inputStreamReadLineAction(List input) { if (input.size() != 1) { return Terms.actionError("Incorrect input size!"); } @@ -153,7 +187,7 @@ public static ActionResultTerm inputStreamReadLine(List input) { } @SuppressWarnings("unchecked") - public static ActionResultTerm inputStreamClose(List input) { + private ActionResultTerm inputStreamCloseAction(List input) { if (input.size() != 1) { return Terms.actionError("Incorrect input size!"); } @@ -169,4 +203,12 @@ public static ActionResultTerm inputStreamClose(List input) { } } + protected abstract OutputStream getStdoutStream(); + + protected abstract InputStream getStdinStream(); + + protected abstract OutputStream getFileOutputStream(String path) throws IOException; + + protected abstract InputStream getInputStream(String path) throws IOException; + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContext.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java similarity index 87% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContext.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java index bbcca297e..5e3949519 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContext.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java @@ -5,7 +5,7 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.terms.Term; -public interface ActionContext { +public interface ActionExecutionService { ActionWitness execute(String actionName, int sourceRuleId, Substitution sourceRuleInstance, List inputTerms); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java similarity index 86% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java index 2d570cf38..2952f7f26 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionContextImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java @@ -9,25 +9,23 @@ import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; -public class ActionContextImpl implements ActionContext { +public class ActionExecutionServiceImpl implements ActionExecutionService { - // TODO initialize from outside - private final Map actions; + private final ActionImplementationProvider actionProvider; private final Map actionRecord = new HashMap<>(); - public ActionContextImpl(Map actions) { - this.actions = actions; + public ActionExecutionServiceImpl(ActionImplementationProvider implementationProvider) { + this.actionProvider = implementationProvider; } @Override public ActionWitness execute(String actionName, int sourceRuleId, Substitution sourceRuleInstance, List inputTerms) { - // TODO maybe we want to stuff the whole action head plus substitution in here and do the whole instantiation here? ActionInput actInput = new ActionInput(actionName, sourceRuleId, sourceRuleInstance, inputTerms); return actionRecord.computeIfAbsent(actInput, this::execute); } private ActionWitness execute(ActionInput input) { - Action action = actions.get(input.name); + Action action = actionProvider.getSupportedActions().get(input.name); FunctionTerm result = action.execute(input.inputTerms); return new ActionWitness(input.sourceRule, input.instance, input.name, input.inputTerms, result); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionImplementationProvider.java new file mode 100644 index 000000000..53157b7da --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionImplementationProvider.java @@ -0,0 +1,30 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.util.Map; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; + +/** + * Interface for types providing action implementations. + */ +public interface ActionImplementationProvider { + + /** + * Returns a map of all actions supported by this implementation provider. + */ + Map getSupportedActions(); + + /** + * Returns a predicate interpretation specifying an external that takes no arguments + * and returns a reference to the standard system output stream (stdout). + */ + PredicateInterpretation getStdoutTerm(); + + /** + * Returns a predicate interpretation specifying an external that takes no arguments + * and returns a reference to the standard system input stream (stdin). + */ + PredicateInterpretation getStdinTerm(); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java new file mode 100644 index 000000000..c6d9a26eb --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java @@ -0,0 +1,32 @@ +package at.ac.tuwien.kr.alpha.core.actions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + +public class DefaultActionImplementationProvider extends AbstractActionImplementationProvider { + + @Override + protected OutputStream getStdoutStream() { + return System.out; + } + + @Override + protected InputStream getStdinStream() { + return System.in; + } + + @Override + protected OutputStream getFileOutputStream(String path) throws IOException { + return Files.newOutputStream(Paths.get(path), StandardOpenOption.APPEND); + } + + @Override + protected InputStream getInputStream(String path) throws IOException { + return Files.newInputStream(Paths.get(path)); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index cde8a0d87..378a19f65 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -34,7 +34,7 @@ import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.actions.ActionContext; +import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; import at.ac.tuwien.kr.alpha.core.actions.ActionWitness; import at.ac.tuwien.kr.alpha.core.depgraph.StratificationAlgorithm; import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; @@ -67,10 +67,10 @@ public class StratifiedEvaluation extends ProgramTransformation solvedRuleIds = new HashSet<>(); // Set of rules that have been completely evaluated. private LiteralInstantiator literalInstantiator; - private ActionContext actionContext; + private ActionExecutionService actionContext; private final boolean generateActionWitnesses; - public StratifiedEvaluation(ActionContext actionContext, boolean generateActionWitnesses) { + public StratifiedEvaluation(ActionExecutionService actionContext, boolean generateActionWitnesses) { this.actionContext = actionContext; this.generateActionWitnesses = generateActionWitnesses; } diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java new file mode 100644 index 000000000..388739675 --- /dev/null +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java @@ -0,0 +1,40 @@ +package at.ac.tuwien.kr.alpha.test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.core.actions.AbstractActionImplementationProvider; + +public class MockActionImplementationProvider extends AbstractActionImplementationProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(MockActionImplementationProvider.class); + + @Override + protected OutputStream getStdoutStream() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected InputStream getStdinStream() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected OutputStream getFileOutputStream(String path) throws IOException { + // TODO Auto-generated method stub + return null; + } + + @Override + protected InputStream getInputStream(String path) throws IOException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index 7c214243e..018173818 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -11,9 +11,9 @@ import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.core.actions.ActionContext; -import at.ac.tuwien.kr.alpha.core.actions.ActionContextImpl; -import at.ac.tuwien.kr.alpha.core.actions.Actions; +import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; +import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionServiceImpl; +import at.ac.tuwien.kr.alpha.core.actions.DefaultActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; @@ -75,7 +75,7 @@ static SolverFactory newSolverFactory(SystemConfig cfg) { // TODO lifetime of one ActionContext needs to be exactly runtime of one program! @VisibleForTesting - public static Alpha newAlpha(SystemConfig cfg, ActionContext actionContext) { + public static Alpha newAlpha(SystemConfig cfg, ActionExecutionService actionContext) { // Parser factory - Supply correct parser dependent on the accepted input language. Supplier parserFactory = () -> cfg.isAcceptEvologPrograms() ? new EvologProgramParser() : new ASPCore2ProgramParser(); Supplier> programNormalizationFactory = newProgramNormalizationFactory(parserFactory, @@ -93,7 +93,7 @@ public static Alpha newAlpha(SystemConfig cfg, ActionContext actionContext) { } public static Alpha newAlpha(SystemConfig cfg) { - return newAlpha(cfg, new ActionContextImpl(Actions.getDefaultActionBindings())); + return newAlpha(cfg, new ActionExecutionServiceImpl(new DefaultActionImplementationProvider())); } diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index f6ba63352..5abf07730 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -59,7 +59,7 @@ import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; import at.ac.tuwien.kr.alpha.commons.util.Util; -import at.ac.tuwien.kr.alpha.core.actions.ActionContext; +import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; @@ -82,7 +82,7 @@ public class AlphaImpl implements Alpha { private final GrounderFactory grounderFactory; private final SolverFactory solverFactory; - private final ActionContext actionContext; + private final ActionExecutionService actionContext; private final boolean enableStratifiedEvaluation; private final boolean sortAnswerSets; @@ -90,7 +90,7 @@ public class AlphaImpl implements Alpha { AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, GrounderFactory grounderFactory, SolverFactory solverFactory, - ActionContext actionContext, + ActionExecutionService actionContext, boolean enableStratifiedEvaluation, boolean sortAnswerSets) { this.parserFactory = parserFactory; this.programNormalizationFactory = programNormalizationFactory; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java new file mode 100644 index 000000000..f27ac93fc --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java @@ -0,0 +1,10 @@ +package at.ac.tuwien.kr.alpha.regressiontests; + +/** + * End-to-end tests covering Evolog action support. + * Note that all tests in this suite depend on stratified evaluation being enabled. + */ +public class ActionsTest { + + +} diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java index 82f2b88df..4e7f4e831 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java @@ -80,4 +80,8 @@ public static void ignoreTestForNonDefaultDomainIndependentHeuristics(SystemConf Assumptions.assumeTrue(cfg.getBranchingHeuristic() == Heuristic.VSIDS); } + public static void ignoreTestForStratifiedEvaluationDisabled(SystemConfig cfg) { + Assumptions.assumeTrue(cfg.isEvaluateStratifiedPart()); + } + } diff --git a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts index deace0036..1ccb2d408 100644 --- a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts @@ -37,6 +37,7 @@ dependencies { testImplementation("org.slf4j:slf4j-simple:1.7.32") testFixturesApi(jupiter("api")) + testFixturesApi("org.slf4j:slf4j-api:1.7.32") } // JUnit 5 From e80c424b3412cd2561d123f829e6c66cc9423efa Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 29 Aug 2022 16:39:41 +0200 Subject: [PATCH 20/59] mock action provider for testing --- .../MockActionImplementationProvider.java | 50 ++++++++++++++++--- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java index 388739675..778107c50 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java @@ -1,8 +1,11 @@ package at.ac.tuwien.kr.alpha.test; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,30 +14,61 @@ public class MockActionImplementationProvider extends AbstractActionImplementationProvider { + @SuppressWarnings("unused") private static final Logger LOGGER = LoggerFactory.getLogger(MockActionImplementationProvider.class); + private ByteArrayOutputStream stdoutMock = new ByteArrayOutputStream(); + private ByteArrayInputStream stdinMock; + private Map mockedFileOutputs; + private Map mockedFileInputs; + + public MockActionImplementationProvider() { + } + @Override protected OutputStream getStdoutStream() { - // TODO Auto-generated method stub - return null; + return stdoutMock; + } + + public String getStdoutContent() { + return stdoutMock.toString(); + } + + public void resetStdoutContent() { + stdoutMock.reset(); + } + + public void setMockInput(String input) { + stdinMock = new ByteArrayInputStream(input.getBytes()); + } + + public void setMockedFileOutputs(Map mockedFileOutputs) { + this.mockedFileOutputs = mockedFileOutputs; + } + + public void setMockedFileInputs(Map mockedFileInputs) { + this.mockedFileInputs = mockedFileInputs; } @Override protected InputStream getStdinStream() { - // TODO Auto-generated method stub - return null; + return stdinMock; } @Override protected OutputStream getFileOutputStream(String path) throws IOException { - // TODO Auto-generated method stub - return null; + if(mockedFileOutputs.containsKey(path)) { + return mockedFileOutputs.get(path); + } + throw new IOException("Path does not exist!"); } @Override protected InputStream getInputStream(String path) throws IOException { - // TODO Auto-generated method stub - return null; + if(mockedFileInputs.containsKey(path)) { + return mockedFileInputs.get(path); + } + throw new IOException("Path does not exist!"); } } From 399ec00a93b7143f884ee2fde59830690d0c1349 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 1 Sep 2022 18:32:15 +0200 Subject: [PATCH 21/59] mock implementation provider and smoke test for actions --- .../AbstractActionImplementationProvider.java | 17 ++-- .../MockActionImplementationProvider.java | 6 +- .../kr/alpha/api/impl/AlphaFactory.java | 8 +- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 82 +++++++------------ .../kr/alpha/regressiontests/ActionsTest.java | 10 --- 5 files changed, 47 insertions(+), 76 deletions(-) delete mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java index 8ec02d340..cda9a2eea 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java @@ -23,6 +23,12 @@ public abstract class AbstractActionImplementationProvider implements ActionImpl private final IntIdGenerator idGenerator = new IntIdGenerator(); private final Map supportedActions = new HashMap<>(); + private final ConstantTerm stdout = Terms.newConstant( + new OutputStreamHandle(idGenerator.getNextId(), getStdoutStream())); + private final ConstantTerm stdin = Terms.newConstant( + new InputStreamHandle(idGenerator.getNextId(), + new BufferedReader(new InputStreamReader(getStdinStream())))); + public AbstractActionImplementationProvider() { registerAction("fileOutputStream", this::openFileOutputStreamAction); registerAction("streamWrite", this::outputStreamWriteAction); @@ -49,10 +55,7 @@ public final PredicateInterpretation getStdoutTerm() { if (!trms.isEmpty()) { throw new IllegalArgumentException("Invalid method call! Expected term list to be empty!"); } - return Collections.singleton( - Collections.singletonList( - Terms.newConstant( - new OutputStreamHandle(idGenerator.getNextId(), getStdoutStream())))); + return Collections.singleton(Collections.singletonList(stdout)); }; } @@ -66,11 +69,7 @@ public final PredicateInterpretation getStdinTerm() { if (!trms.isEmpty()) { throw new IllegalArgumentException("Invalid method call! Expected term list to be empty!"); } - return Collections.singleton( - Collections.singletonList( - Terms.newConstant( - new InputStreamHandle(idGenerator.getNextId(), - new BufferedReader(new InputStreamReader(getStdinStream())))))); + return Collections.singleton(Collections.singletonList(stdin)); }; } diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java index 778107c50..a31173162 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java @@ -57,7 +57,7 @@ protected InputStream getStdinStream() { @Override protected OutputStream getFileOutputStream(String path) throws IOException { - if(mockedFileOutputs.containsKey(path)) { + if (mockedFileOutputs.containsKey(path)) { return mockedFileOutputs.get(path); } throw new IOException("Path does not exist!"); @@ -65,10 +65,10 @@ protected OutputStream getFileOutputStream(String path) throws IOException { @Override protected InputStream getInputStream(String path) throws IOException { - if(mockedFileInputs.containsKey(path)) { + if (mockedFileInputs.containsKey(path)) { return mockedFileInputs.get(path); } throw new IOException("Path does not exist!"); } - + } diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index 018173818..76ed54955 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -76,8 +76,12 @@ static SolverFactory newSolverFactory(SystemConfig cfg) { // TODO lifetime of one ActionContext needs to be exactly runtime of one program! @VisibleForTesting public static Alpha newAlpha(SystemConfig cfg, ActionExecutionService actionContext) { + // Parser factory - Supply correct parser dependent on the accepted input language. Supplier parserFactory = () -> cfg.isAcceptEvologPrograms() ? new EvologProgramParser() : new ASPCore2ProgramParser(); + if (cfg.isAcceptEvologPrograms()) { + + } Supplier> programNormalizationFactory = newProgramNormalizationFactory(parserFactory, cfg.getAggregateRewritingConfig()); @@ -86,17 +90,17 @@ public static Alpha newAlpha(SystemConfig cfg, ActionExecutionService actionCont // SolverFactory - Same as for GrounderFactory, we need a new Solver for each program. SolverFactory solverFactory = newSolverFactory(cfg); - + // Now that all dependencies are taken care of, build new Alpha instance. return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, actionContext, cfg.isEvaluateStratifiedPart(), cfg.isSortAnswerSets()); } + // TODO action stuff should go into system config public static Alpha newAlpha(SystemConfig cfg) { return newAlpha(cfg, new ActionExecutionServiceImpl(new DefaultActionImplementationProvider())); } - // Create Alpha instance with default config. public static Alpha newAlpha() { return newAlpha(new SystemConfig()); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index f4e2a31c4..0b61309b1 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -1,59 +1,37 @@ package at.ac.tuwien.kr.alpha; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; - +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; +import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionServiceImpl; +import at.ac.tuwien.kr.alpha.test.MockActionImplementationProvider; + +/** + * End-to-end tests covering Evolog action support. + * Note that all tests in this suite depend on stratified evaluation being enabled. + */ public class ActionsTest { - private static class MockActionBindings { - - static final Logger LOGGER = LoggerFactory.getLogger(MockActionBindings.class); - - Map, Integer> fileOpenOutputStreamInvocations = new HashMap<>(); - Map, Integer> outputStreamWriteInvocations = new HashMap<>(); - Map, Integer> outputStreamCloseInvocations = new HashMap<>(); - Map, Integer> fileOpenInputStreamInvocations = new HashMap<>(); - Map, Integer> inputStreamReadLineInvocations = new HashMap<>(); - Map, Integer> inputStreamCloseInvocations = new HashMap<>(); - - public FunctionTerm fileOpenOutputStream(List input) { - if (fileOpenOutputStreamInvocations.containsKey(input)) { - fileOpenOutputStreamInvocations.put(input, fileOpenOutputStreamInvocations.get(input) + 1); - } else { - fileOpenOutputStreamInvocations.put(input, 1); - } - LOGGER.info("Action fileOpenOutputStream({})", StringUtils.join(input, ", ")); - return null; - } - - public FunctionTerm outputStreamWrite(List input) { - return null; - } - - public FunctionTerm outputStreamClose(List input) { - return null; - } - - public FunctionTerm fileOpenInputStream(List input) { - return null; - } - - public FunctionTerm inputStreamReadLine(List input) { - return null; - } - - public FunctionTerm inputStreamClose(List inputStream) { - return null; - } - + private static final String HELLO_WORLD = + "hello_result(RES) : @streamWrite[STDOUT, \" World!\"] = RES :- &stdout(STDOUT)."; + + /** + * Simple smoke test which verifies correct behavior of an Evolog "Hello World" program. + */ + @Test + @Disabled // TODO we need to pass stdin/stdout externals into parser + public void helloWorld() { + MockActionImplementationProvider actionMock = new MockActionImplementationProvider(); + ActionExecutionService actionService = new ActionExecutionServiceImpl(actionMock); + Alpha alpha = AlphaFactory.newAlpha(new SystemConfig(), actionService); + InputProgram program = alpha.readProgramString(HELLO_WORLD); + alpha.solve(program); + // TODO check mock for correct output content } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java deleted file mode 100644 index f27ac93fc..000000000 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ActionsTest.java +++ /dev/null @@ -1,10 +0,0 @@ -package at.ac.tuwien.kr.alpha.regressiontests; - -/** - * End-to-end tests covering Evolog action support. - * Note that all tests in this suite depend on stratified evaluation being enabled. - */ -public class ActionsTest { - - -} From 20c2b7305abb21773becd19e50fb9a70efa206a0 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 3 Sep 2022 17:17:21 +0200 Subject: [PATCH 22/59] remove option to switch off stratified evaluation --- .../kr/alpha/api/config/SystemConfig.java | 10 --------- .../kr/alpha/api/impl/AlphaFactory.java | 4 ++-- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 21 +++++-------------- 3 files changed, 7 insertions(+), 28 deletions(-) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java index ec129fbc4..25c79b348 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java @@ -56,7 +56,6 @@ public class SystemConfig { public static final boolean DEFAULT_DEBUG_INTERNAL_CHECKS = false; public static final boolean DEFAULT_SORT_ANSWER_SETS = false; public static final List DEFAULT_REPLAY_CHOICES = Collections.emptyList(); - public static final boolean DEFAULT_STRATIFIED_EVALUATION = true; public static final boolean DEFAULT_DISABLE_NOGOOD_DELETION = false; public static final String DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS = GrounderHeuristicsConfiguration.STRICT_STRING; public static final String DEFAULT_GROUNDER_TOLERANCE_RULES = GrounderHeuristicsConfiguration.STRICT_STRING; @@ -76,7 +75,6 @@ public class SystemConfig { private boolean disableJustificationSearch = DEFAULT_DISABLE_JUSTIFICATION_SEARCH; private boolean sortAnswerSets = DEFAULT_SORT_ANSWER_SETS; private List replayChoices = DEFAULT_REPLAY_CHOICES; - private boolean evaluateStratifiedPart = DEFAULT_STRATIFIED_EVALUATION; private boolean disableNoGoodDeletion = DEFAULT_DISABLE_NOGOOD_DELETION; private String grounderToleranceConstraints = DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS; private String grounderToleranceRules = DEFAULT_GROUNDER_TOLERANCE_RULES; @@ -199,14 +197,6 @@ public void setReplayChoices(String replayChoices) { this.replayChoices = Arrays.stream(replayChoices.split(",")).map(String::trim).map(Integer::valueOf).collect(Collectors.toList()); } - public boolean isEvaluateStratifiedPart() { - return this.evaluateStratifiedPart; - } - - public void setEvaluateStratifiedPart(boolean evaluateStratifiedPart) { - this.evaluateStratifiedPart = evaluateStratifiedPart; - } - public boolean isDisableNoGoodDeletion() { return this.disableNoGoodDeletion; } diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index 76ed54955..56d35fe87 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -79,9 +79,9 @@ public static Alpha newAlpha(SystemConfig cfg, ActionExecutionService actionCont // Parser factory - Supply correct parser dependent on the accepted input language. Supplier parserFactory = () -> cfg.isAcceptEvologPrograms() ? new EvologProgramParser() : new ASPCore2ProgramParser(); - if (cfg.isAcceptEvologPrograms()) { + // if (cfg.isAcceptEvologPrograms()) { - } + // } Supplier> programNormalizationFactory = newProgramNormalizationFactory(parserFactory, cfg.getAggregateRewritingConfig()); diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index 5abf07730..1d3683fda 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -82,22 +82,17 @@ public class AlphaImpl implements Alpha { private final GrounderFactory grounderFactory; private final SolverFactory solverFactory; - private final ActionExecutionService actionContext; - private final boolean enableStratifiedEvaluation; private final boolean sortAnswerSets; AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, GrounderFactory grounderFactory, SolverFactory solverFactory, - ActionExecutionService actionContext, boolean enableStratifiedEvaluation, boolean sortAnswerSets) { this.parserFactory = parserFactory; this.programNormalizationFactory = programNormalizationFactory; this.grounderFactory = grounderFactory; this.solverFactory = solverFactory; - this.actionContext = actionContext; - this.enableStratifiedEvaluation = enableStratifiedEvaluation; this.sortAnswerSets = sortAnswerSets; } @@ -159,12 +154,9 @@ public NormalProgram normalizeProgram(InputProgram program) { InternalProgram performProgramPreprocessing(NormalProgram program) { LOGGER.debug("Preprocessing InternalProgram!"); InternalProgram retVal = InternalProgram.fromNormalProgram(program); - if (enableStratifiedEvaluation) { - AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); - // TODO as Evolog moves further along, we want to integrate stratified evaluation with grounder and solver. - // Therefore, leave it as is and don't make part of factory API for now. - retVal = new StratifiedEvaluation(actionContext, true).apply(analyzed); - } + // TODO get the StratifiedEvaluation from factory + AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); + retVal = new StratifiedEvaluation(actionContext, true).apply(analyzed); return retVal; } @@ -250,11 +242,8 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final ComponentGraph compGraph; final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; - if (enableStratifiedEvaluation) { - preprocessed = new StratifiedEvaluation(actionContext, true).apply(analyzed).toNormalProgram(); - } else { - preprocessed = program; - } + // TODO get the StratifiedEvaluation from factory + preprocessed = new StratifiedEvaluation(actionContext, true).apply(analyzed).toNormalProgram(); depGraph = analyzed.getDependencyGraph(); compGraph = analyzed.getComponentGraph(); final Solver solver = prepareSolverFor(analyzed, filter); From 6b2bba25f4a5e7bfbf65915a09df5350fe785181 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 3 Sep 2022 17:59:51 +0200 Subject: [PATCH 23/59] ensure statelessness of program transformations, reflect this in naming --- ...ng.java => ArithmeticTermTransformer.java} | 18 ++++++--- ...oNormal.java => ChoiceHeadNormalizer.java} | 4 +- ...iting.java => EnumerationTransformer.java} | 4 +- ...Atom.java => IntervalTermTransformer.java} | 5 ++- .../NormalizeProgramTransformation.java | 40 +++++++++++-------- ...formation.java => ProgramTransformer.java} | 4 +- .../transformation/StratifiedEvaluation.java | 4 +- ....java => VariableEqualityTransformer.java} | 4 +- ...writing.java => AggregateTransformer.java} | 10 ++--- .../StringtemplateBasedAggregateEncoder.java | 4 +- .../ProgramTransformationTest.java | 8 ++-- .../kr/alpha/api/impl/AlphaFactory.java | 10 ++--- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 12 +++--- .../alpha/ArithmeticTermsRewritingTest.java | 10 ++--- 14 files changed, 76 insertions(+), 61 deletions(-) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{ArithmeticTermsRewriting.java => ArithmeticTermTransformer.java} (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{ChoiceHeadToNormal.java => ChoiceHeadNormalizer.java} (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{EnumerationRewriting.java => EnumerationTransformer.java} (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{IntervalTermToIntervalAtom.java => IntervalTermTransformer.java} (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{ProgramTransformation.java => ProgramTransformer.java} (56%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{VariableEqualityRemoval.java => VariableEqualityTransformer.java} (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/{AggregateRewriting.java => AggregateTransformer.java} (95%) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermTransformer.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermTransformer.java index 1a346527c..0dc7e5dd7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermTransformer.java @@ -23,6 +23,7 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; @@ -33,12 +34,16 @@ * * Copyright (c) 2020-2021, the Alpha Team. */ -public class ArithmeticTermsRewriting extends ProgramTransformation { - private static final String ARITHMETIC_VARIABLES_PREFIX = "_A"; - private int numArithmeticVariables; +public class ArithmeticTermTransformer extends ProgramTransformer { + + /** + * The prefix with which to begin names of internal variables created by this transformer. + */ + private final String generatedVariablesPrefix = "_A"; + private final IntIdGenerator variableNumberGenerator = new IntIdGenerator(); @Override - public NormalProgram apply(NormalProgram inputProgram) { + public NormalProgram transform(NormalProgram inputProgram) { List rewrittenRules = new ArrayList<>(); boolean didRewrite = false; for (NormalRule inputProgramRule : inputProgram.getRules()) { @@ -64,7 +69,7 @@ public NormalProgram apply(NormalProgram inputProgram) { * @return the rewritten rule. Note that a new {@link NormalRule} is returned for every call of this method. */ private NormalRule rewriteRule(NormalRule inputProgramRule) { - numArithmeticVariables = 0; // Reset number of introduced variables for each rule. + variableNumberGenerator.resetGenerator(); // Reset number of introduced variables for each rule. NormalHead rewrittenHead = null; Set rewrittenBodyLiterals = new LinkedHashSet<>(); // Rewrite head. @@ -118,7 +123,7 @@ private Term rewriteArithmeticSubterms(Term term, Set bodyLiterals) { } // Switch on term type. if (term instanceof ArithmeticTerm) { - VariableTerm replacementVariable = Terms.newVariable(ARITHMETIC_VARIABLES_PREFIX + numArithmeticVariables++); + VariableTerm replacementVariable = Terms.newVariable(generatedVariablesPrefix + variableNumberGenerator.getNextId()); bodyLiterals.add(Atoms.newComparisonAtom(replacementVariable, term, ComparisonOperators.EQ).toLiteral()); return replacementVariable; } else if (term instanceof VariableTerm || term instanceof ConstantTerm) { @@ -179,4 +184,5 @@ private boolean containsArithmeticTerm(Term term) { throw Util.oops("Unexpected term type: " + term.getClass()); } } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadNormalizer.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadNormalizer.java index 7a59afd45..c90cc32cf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadNormalizer.java @@ -55,11 +55,11 @@ * Copyright (c) 2017-2021, the Alpha Team. */ // TODO this could already give NormalProgram as result type -public class ChoiceHeadToNormal extends ProgramTransformation { +public class ChoiceHeadNormalizer extends ProgramTransformer { private final static String PREDICATE_NEGATION_PREFIX = "_n"; @Override - public InputProgram apply(InputProgram inputProgram) { + public InputProgram transform(InputProgram inputProgram) { InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); List> additionalRules = new ArrayList<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationTransformer.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationTransformer.java index 8c9e67f1e..14bd3109a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationTransformer.java @@ -32,10 +32,10 @@ * Copyright (c) 2017-2020, the Alpha Team. */ // TODO this should happen during/after internalization -public class EnumerationRewriting extends ProgramTransformation { +public class EnumerationTransformer extends ProgramTransformer { @Override - public InputProgram apply(InputProgram inputProgram) { + public InputProgram transform(InputProgram inputProgram) { // Read enumeration predicate from directive. String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectivesImpl.DIRECTIVE.enum_predicate_is); if (enumDirective == null) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermTransformer.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermTransformer.java index e5b0f9abe..6b1f3f14c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermTransformer.java @@ -58,7 +58,8 @@ * * Copyright (c) 2017-2021, the Alpha Team. */ -public class IntervalTermToIntervalAtom extends ProgramTransformation { +public class IntervalTermTransformer extends ProgramTransformer { + private static final String INTERVAL_VARIABLE_PREFIX = "_Interval"; /** @@ -169,7 +170,7 @@ private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map rewrittenRules = new ArrayList<>(); for (NormalRule rule : inputProgram.getRules()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java index 341c46eb1..1d075903e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java @@ -1,45 +1,53 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import java.util.function.Supplier; - import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewriting; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateTransformer; /** * Encapsulates all transformations necessary to transform a given program into a @{link NormalProgram} that is understood by Alpha internally * * Copyright (c) 2019-2021, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformation { - - private final Supplier aggregateRewritingFactory; - - public NormalizeProgramTransformation(Supplier aggregateRewritingFactory) { - this.aggregateRewritingFactory = aggregateRewritingFactory; +public class NormalizeProgramTransformation extends ProgramTransformer { + + private final VariableEqualityTransformer equalityTransformer; + private final ChoiceHeadNormalizer choiceHeadNormalizer; + private final AggregateTransformer aggregateTransformer; + private final EnumerationTransformer enumerationTransformer; + private final IntervalTermTransformer intervalTermTransformer; + private final ArithmeticTermTransformer arithmeticTermTransformer; + + public NormalizeProgramTransformation(VariableEqualityTransformer equalityTransformer, ChoiceHeadNormalizer choiceHeadNormalizer, AggregateTransformer aggregateTransformer, EnumerationTransformer enumerationTransformer, IntervalTermTransformer intervalTermTransformer, ArithmeticTermTransformer arithmeticTermTransformer) { + this.equalityTransformer = equalityTransformer; + this.choiceHeadNormalizer = choiceHeadNormalizer; + this.aggregateTransformer = aggregateTransformer; + this.enumerationTransformer = enumerationTransformer; + this.intervalTermTransformer = intervalTermTransformer; + this.arithmeticTermTransformer = arithmeticTermTransformer; } @Override - public NormalProgram apply(InputProgram inputProgram) { + public NormalProgram transform(InputProgram inputProgram) { InputProgram tmpPrg; // Remove variable equalities. - tmpPrg = new VariableEqualityRemoval().apply(inputProgram); + tmpPrg = equalityTransformer.transform(inputProgram); // Transform choice rules. - tmpPrg = new ChoiceHeadToNormal().apply(tmpPrg); + tmpPrg = choiceHeadNormalizer.transform(tmpPrg); // Transform aggregates. - tmpPrg = aggregateRewritingFactory.get().apply(tmpPrg); + tmpPrg = aggregateTransformer.transform(tmpPrg); // Transform enumeration atoms. - tmpPrg = new EnumerationRewriting().apply(tmpPrg); + tmpPrg = enumerationTransformer.transform(tmpPrg); EnumerationAtom.resetEnumerations(); // Construct the normal program. NormalProgram retVal = NormalProgramImpl.fromInputProgram(tmpPrg); // Transform intervals. - retVal = new IntervalTermToIntervalAtom().apply(retVal); + retVal = intervalTermTransformer.transform(retVal); // Rewrite ArithmeticTerms. - retVal = new ArithmeticTermsRewriting().apply(retVal); + retVal = arithmeticTermTransformer.transform(retVal); return retVal; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformer.java similarity index 56% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformer.java index 0b7d4e7f1..dad7f48d9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformer.java @@ -6,8 +6,8 @@ /** * Copyright (c) 2017-2019, the Alpha Team. */ -public abstract class ProgramTransformation>, O extends Program>> { +public abstract class ProgramTransformer>, O extends Program>> { - public abstract O apply(I inputProgram); + public abstract O transform(I inputProgram); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 378a19f65..9e4859e7f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -54,7 +54,7 @@ * * Copyright (c) 2019-2020, the Alpha Team. */ -public class StratifiedEvaluation extends ProgramTransformation implements RuleInstantiator { +public class StratifiedEvaluation extends ProgramTransformer implements RuleInstantiator { private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluation.class); @@ -78,7 +78,7 @@ public StratifiedEvaluation(ActionExecutionService actionContext, boolean genera @Override // Note: ideally this returns a "PartiallyEvaluatedProgram" such that the grounder can directly use the working // memories created here rather than re-initialize everything. - public InternalProgram apply(AnalyzedProgram inputProgram) { + public InternalProgram transform(AnalyzedProgram inputProgram) { // Calculate a stratification and initialize the working memory. ComponentGraph componentGraph = inputProgram.getComponentGraph(); List strata = StratificationAlgorithm.calculateStratification(componentGraph); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityTransformer.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityTransformer.java index 9ccad4d9f..a9bb46a1e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityTransformer.java @@ -59,10 +59,10 @@ * * Copyright (c) 2017-2021, the Alpha Team. */ -public class VariableEqualityRemoval extends ProgramTransformation { +public class VariableEqualityTransformer extends ProgramTransformer { @Override - public InputProgram apply(InputProgram inputProgram) { + public InputProgram transform(InputProgram inputProgram) { List> rewrittenRules = new ArrayList<>(); for (Rule rule : inputProgram.getRules()) { rewrittenRules.add(findAndReplaceVariableEquality(rule)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateTransformer.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateTransformer.java index bd8761d08..b277a635a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateTransformer.java @@ -19,7 +19,7 @@ import at.ac.tuwien.kr.alpha.commons.literals.Literals; import at.ac.tuwien.kr.alpha.commons.rules.Rules; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AbstractAggregateEncoder; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.CountEncoder; @@ -31,7 +31,7 @@ * * Copyright (c) 2020, the Alpha Team. */ -public class AggregateRewriting extends ProgramTransformation { +public class AggregateTransformer extends ProgramTransformer { private final AbstractAggregateEncoder countEqualsEncoder; private final AbstractAggregateEncoder countLessOrEqualEncoder; @@ -41,7 +41,7 @@ public class AggregateRewriting extends ProgramTransformation> outputRules = new ArrayList<>(); for (Rule inputRule : inputProgram.getRules()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java index 5c1bbde5b..a86a660d1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java @@ -20,7 +20,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationRewriting; +import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationTransformer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; /** @@ -81,7 +81,7 @@ protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { String coreEncodingAsp = coreEncodingTemplate.render(); // Create the basic program - InputProgram coreEncoding = new EnumerationRewriting().apply(parser.parse(coreEncodingAsp)); + InputProgram coreEncoding = new EnumerationTransformer().transform(parser.parse(coreEncodingAsp)); // Add the programatically created bound rule and return return new InputProgramImpl(ListUtils.union(coreEncoding.getRules(), Collections.singletonList(boundRule)), coreEncoding.getFacts(), diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index f56f48ccf..1e2566d52 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -29,8 +29,8 @@ public class ProgramTransformationTest { // TODO should this always be an evolog parser? private static final ProgramParser PARSER = new EvologProgramParser(); - private ChoiceHeadToNormal choiceToNormal = new ChoiceHeadToNormal(); - private IntervalTermToIntervalAtom intervalRewriting = new IntervalTermToIntervalAtom(); + private ChoiceHeadNormalizer choiceToNormal = new ChoiceHeadNormalizer(); + private IntervalTermTransformer intervalRewriting = new IntervalTermTransformer(); @SuppressWarnings("resource") private static String readTestResource(String resource) throws IOException { @@ -45,7 +45,7 @@ private static String readTestResource(String resource) throws IOException { return bld.toString(); } - private , O extends Program> void genericTransformationTest(ProgramTransformation transform, + private , O extends Program> void genericTransformationTest(ProgramTransformer transform, Function prepareFunc, String resourceSet) { try { String inputCode = ProgramTransformationTest.readTestResource(resourceSet + ".in"); @@ -53,7 +53,7 @@ private , O extends Program> void genericTransformationT InputProgram inputProg = PARSER.parse(inputCode, Externals.scan(ProgramTransformationTest.class)); I transformInput = prepareFunc.apply(inputProg); String beforeTransformProg = transformInput.toString(); - O transformedProg = transform.apply(transformInput); + O transformedProg = transform.transform(transformInput); assertEquals(expectedResult, transformedProg.toString(), "Transformation result doesn't match expected result"); assertEquals(beforeTransformProg, transformInput.toString(), "Transformation modified source program (breaks immutability!)"); } catch (Exception ex) { diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index 56d35fe87..aeb0fed9e 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -18,8 +18,8 @@ import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewriting; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformer; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateTransformer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AggregateEncoderFactory; import at.ac.tuwien.kr.alpha.core.solver.SolverConfig; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; @@ -31,7 +31,7 @@ private AlphaFactory() { throw new AssertionError("Cannot instantiate utility class!"); } - static Supplier> newProgramNormalizationFactory(Supplier parserFactory, + static Supplier> newProgramNormalizationFactory(Supplier parserFactory, AggregateRewritingConfig aggregateCfg) { // AggregateEncoderFactory depends on parser factory since stringtemplate-based aggregate encoders need to use the same parser that's used // for input programs. @@ -39,7 +39,7 @@ static Supplier> newProgramNo aggregateCfg.isUseSortingGridEncoding(), aggregateCfg.isSupportNegativeValuesInSums()); // Factory for aggregate rewriting (depends on encoders provided by above factory). - Supplier aggregateRewritingFactory = () -> new AggregateRewriting(aggregateEncoderFactory.newCountEqualsEncoder(), + Supplier aggregateRewritingFactory = () -> new AggregateTransformer(aggregateEncoderFactory.newCountEqualsEncoder(), aggregateEncoderFactory.newCountLessOrEqualEncoder(), aggregateEncoderFactory.newSumEqualsEncoder(), aggregateEncoderFactory.newSumLessOrEqualEncoder(), aggregateEncoderFactory.newMinEncoder(), aggregateEncoderFactory.newMaxEncoder()); @@ -82,7 +82,7 @@ public static Alpha newAlpha(SystemConfig cfg, ActionExecutionService actionCont // if (cfg.isAcceptEvologPrograms()) { // } - Supplier> programNormalizationFactory = newProgramNormalizationFactory(parserFactory, + Supplier> programNormalizationFactory = newProgramNormalizationFactory(parserFactory, cfg.getAggregateRewritingConfig()); // GrounderFactory - Since every grounder instance is only good for one program instance, we need a factory. diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index 1d3683fda..5bb5d1621 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -68,7 +68,7 @@ import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformer; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; @@ -77,7 +77,7 @@ public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); private final Supplier parserFactory; - private final Supplier> programNormalizationFactory; + private final Supplier> programNormalizationFactory; private final GrounderFactory grounderFactory; private final SolverFactory solverFactory; @@ -85,7 +85,7 @@ public class AlphaImpl implements Alpha { private final boolean sortAnswerSets; - AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, + AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, GrounderFactory grounderFactory, SolverFactory solverFactory, boolean enableStratifiedEvaluation, boolean sortAnswerSets) { @@ -147,7 +147,7 @@ public InputProgram readProgramString(String aspString) { @Override public NormalProgram normalizeProgram(InputProgram program) { - return programNormalizationFactory.get().apply(program); + return programNormalizationFactory.get().transform(program); } @VisibleForTesting @@ -156,7 +156,7 @@ InternalProgram performProgramPreprocessing(NormalProgram program) { InternalProgram retVal = InternalProgram.fromNormalProgram(program); // TODO get the StratifiedEvaluation from factory AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); - retVal = new StratifiedEvaluation(actionContext, true).apply(analyzed); + retVal = new StratifiedEvaluation(actionContext, true).transform(analyzed); return retVal; } @@ -243,7 +243,7 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; // TODO get the StratifiedEvaluation from factory - preprocessed = new StratifiedEvaluation(actionContext, true).apply(analyzed).toNormalProgram(); + preprocessed = new StratifiedEvaluation(actionContext, true).transform(analyzed).toNormalProgram(); depGraph = analyzed.getDependencyGraph(); compGraph = analyzed.getComponentGraph(); final Solver solver = prepareSolverFor(analyzed, filter); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java index d642e2cf8..637fe75a1 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java @@ -25,7 +25,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermsRewriting; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermTransformer; /** * Copyright (c) 2021, the Alpha Team. @@ -47,8 +47,8 @@ public static Set>> externalForArithmeticTermsRewriti public void rewriteRule() { NormalProgram inputProgram = NormalProgramImpl.fromInputProgram(parser.parse("p(X+1) :- q(Y/2), r(f(X*2),Y), X-2 = Y*3, X = 0..9.")); assertEquals(1, inputProgram.getRules().size()); - ArithmeticTermsRewriting arithmeticTermsRewriting = new ArithmeticTermsRewriting(); - NormalProgram rewrittenProgram = arithmeticTermsRewriting.apply(inputProgram); + ArithmeticTermTransformer arithmeticTermsRewriting = new ArithmeticTermTransformer(); + NormalProgram rewrittenProgram = arithmeticTermsRewriting.transform(inputProgram); // Expect the rewritten program to be one rule with: p(_A0) :- _A0 = X+1, _A1 = Y/2, q(_A1), _A2 = X*2, r(f(_A2),Y), X-2 = Y*3, X = 0..9. assertEquals(1, rewrittenProgram.getRules().size()); NormalRule rewrittenRule = rewrittenProgram.getRules().get(0); @@ -60,8 +60,8 @@ public void rewriteRule() { public void rewriteExternalAtom() { NormalProgram inputProgram = NormalProgramImpl.fromInputProgram(parser.parse("p :- Y = 13, &extArithTest[Y*5](Y-4).")); assertEquals(1, inputProgram.getRules().size()); - ArithmeticTermsRewriting arithmeticTermsRewriting = new ArithmeticTermsRewriting(); - NormalProgram rewrittenProgram = arithmeticTermsRewriting.apply(inputProgram); + ArithmeticTermTransformer arithmeticTermsRewriting = new ArithmeticTermTransformer(); + NormalProgram rewrittenProgram = arithmeticTermsRewriting.transform(inputProgram); assertEquals(1, rewrittenProgram.getRules().size()); NormalRule rewrittenRule = rewrittenProgram.getRules().get(0); assertEquals(4, rewrittenRule.getBody().size()); From 7802ffb1e321d3cea9ecfcfa5f61994b08a86913 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 5 Sep 2022 14:50:38 +0200 Subject: [PATCH 24/59] incorporate action support into AlphaFactory, remove option to disable StratifiedEvaluation --- .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 33 +++- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 2 +- .../alpha/app/config/CommandLineParser.java | 9 -- .../alpha/app/ComponentGraphWriterTest.java | 2 +- .../alpha/app/DependencyGraphWriterTest.java | 2 +- .../app/config/CommandLineParserTest.java | 15 -- .../AnswerSetToWorkbookMapperTest.java | 2 +- .../core/parser/AbstractProgramParser.java | 4 + .../parser/evolog/EvologProgramParser.java | 10 +- .../kr/alpha/core/programs/Programs.java | 26 --- ...sformation.java => ProgramNormalizer.java} | 4 +- .../transformation/StratifiedEvaluation.java | 8 +- .../encoders/AggregateEncoderFactory.java | 44 ----- .../encoders/AggregateEncoders.java | 36 +++++ .../aggregates/encoders/MinMaxEncoder.java | 2 +- .../aggregates/encoders/SumEncoder.java | 4 +- .../alpha/core/parser/EvologParserTest.java | 3 +- .../ProgramTransformationTest.java | 6 +- .../kr/alpha/api/impl/AlphaFactory.java | 91 ++++++----- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 42 +++-- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 2 +- .../alpha/AggregateRewritingContextTest.java | 4 +- .../kr/alpha/AggregateRewritingTest.java | 2 +- .../alpha/ArithmeticTermsRewritingTest.java | 4 +- .../FixedInterpretationLiteralsTest.java | 2 +- .../at/ac/tuwien/kr/alpha/RuleParser.java | 4 +- .../ac/tuwien/kr/alpha/RuleToStringTest.java | 4 +- .../kr/alpha/StratifiedEvaluationTest.java | 26 +-- .../kr/alpha/api/impl/AlphaImplTest.java | 151 ++++++------------ .../HeadBodyTransformationTests.java | 4 +- .../regressiontests/OmigaBenchmarksTest.java | 4 +- .../kr/alpha/regressiontests/RacksTest.java | 4 +- .../StratifiedEvaluationRegressionTest.java | 2 +- .../util/RegressionTestConfigProvider.java | 80 ++++------ .../util/RegressionTestUtils.java | 14 +- 35 files changed, 279 insertions(+), 373 deletions(-) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{NormalizeProgramTransformation.java => ProgramNormalizer.java} (82%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java index 60dd0a236..eae27ca05 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.api; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Path; import java.util.List; import java.util.Map; @@ -60,6 +61,16 @@ public interface Alpha { */ InputProgram readProgramString(String aspString); + /** + * Parses an ASP program from an input stream. + */ + InputProgram readProgramStream(InputStream is) throws IOException; + + /** + * Parses an ASP program from an input stream. + */ + InputProgram readProgramStream(InputStream is, Map externals) throws IOException; + /** * Prepares a {@link DebugSolvingContext} for the given {@link ASPCore2Program} to debug program preprocessing. * @@ -92,6 +103,7 @@ public interface Alpha { /** * Solves the given {@link ASPCore2Program}. + * * @param program an input program * @return a {@link Stream} of {@link AnswerSet}s of the given program */ @@ -99,14 +111,16 @@ public interface Alpha { /** * Solves the given {@link ASPCore2Program}. + * * @param program an input program - * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. + * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Stream} of {@link AnswerSet}s of the given program */ Stream solve(InputProgram program, java.util.function.Predicate filter); /** * Solves the given {@link NormalProgram}. + * * @param program an input program * @return a {@link Stream} of {@link AnswerSet}s of the given program */ @@ -114,34 +128,39 @@ public interface Alpha { /** * Solves the given {@link NormalProgram}. + * * @param program an input program - * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. + * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Stream} of {@link AnswerSet}s of the given program */ Stream solve(NormalProgram program, java.util.function.Predicate filter); /** - * Normalizes a program, i.e. rewrites all syntax constructs not natively supported by Alphas back-end into semantically equivalent ASP code. + * Normalizes a program, i.e. rewrites all syntax constructs not natively supported by Alphas back-end into semantically equivalent ASP + * code. * See {@link NormalProgram}, + * * @param program An {@link ASPCore2Program} to normalize * @return a {@link NormalProgram} that is a semantic equivalent to the given input program */ NormalProgram normalizeProgram(InputProgram program); /** - * Constructs a @{link Solver} pre-loaded with the given {@link ASPCore2Program} from which {@link AnswerSet}s can be obtained via {@link Solver#stream()}. + * Constructs a @{link Solver} pre-loaded with the given {@link ASPCore2Program} from which {@link AnswerSet}s can be obtained via + * {@link Solver#stream()}. * * @param program the program to solve - * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. + * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Solver} pre-loaded withthe given program */ Solver prepareSolverFor(InputProgram program, java.util.function.Predicate filter); /** - * Constructs a @{link Solver} pre-loaded with the given {@link NormalProgram} from which {@link AnswerSet}s can be obtained via {@link Solver#stream()}. + * Constructs a @{link Solver} pre-loaded with the given {@link NormalProgram} from which {@link AnswerSet}s can be obtained via + * {@link Solver#stream()}. * * @param program the program to solve - * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. + * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Solver} pre-loaded withthe given program */ Solver prepareSolverFor(NormalProgram program, java.util.function.Predicate filter); diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java index 4fd32e07e..d94f45969 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java @@ -80,7 +80,7 @@ public static void main(String[] args) { Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); } - Alpha alpha = AlphaFactory.newAlpha(cfg.getSystemConfig()); + Alpha alpha = new AlphaFactory().newAlpha(cfg.getSystemConfig()); InputProgram program = null; try { diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java index 8b68d0dc1..865186191 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java @@ -122,9 +122,6 @@ public class CommandLineParser { private static final Option OPT_AGGREGATES_NO_NEGATIVE_INTEGERS = Option.builder("dni").longOpt("disableNegativeIntegers") .desc("use simplified encodings without netagive integer support for #sum aggregates (default: " + !AggregateRewritingConfig.DEFAULT_SUPPORT_NEGATIVE_INTEGERS + ")") .build(); - private static final Option OPT_NO_EVAL_STRATIFIED = Option.builder("dse").longOpt("disableStratifiedEvaluation") - .desc("Disable stratified evaluation") - .build(); private static final Option OPT_NO_NOGOOD_DELETION = Option.builder("dnd").longOpt("disableNoGoodDeletion") .desc("disable the deletion of (learned, little active) nogoods (default: " + SystemConfig.DEFAULT_DISABLE_NOGOOD_DELETION + ")") @@ -177,7 +174,6 @@ public class CommandLineParser { CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_AGGREGATES_NO_SORTING_GRID); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_AGGREGATES_NO_NEGATIVE_INTEGERS); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NO_EVAL_STRATIFIED); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NO_NOGOOD_DELETION); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER_TOLERANCE_CONSTRAINTS); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER_TOLERANCE_RULES); @@ -232,7 +228,6 @@ private void initializeGlobalOptionHandlers() { this.globalOptionHandlers.put(CommandLineParser.OPT_NO_JUSTIFICATION.getOpt(), this::handleNoJustification); this.globalOptionHandlers.put(CommandLineParser.OPT_AGGREGATES_NO_SORTING_GRID.getOpt(), this::handleDisableSortingGrid); this.globalOptionHandlers.put(CommandLineParser.OPT_AGGREGATES_NO_NEGATIVE_INTEGERS.getOpt(), this::handleDisableNegativeSumElements); - this.globalOptionHandlers.put(CommandLineParser.OPT_NO_EVAL_STRATIFIED.getOpt(), this::handleDisableStratifedEval); this.globalOptionHandlers.put(CommandLineParser.OPT_NO_NOGOOD_DELETION.getOpt(), this::handleNoNoGoodDeletion); this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER_TOLERANCE_CONSTRAINTS.getOpt(), this::handleGrounderToleranceConstraints); this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER_TOLERANCE_RULES.getOpt(), this::handleGrounderToleranceRules); @@ -423,10 +418,6 @@ private void handleDisableNegativeSumElements(Option opt, SystemConfig cfg) { cfg.getAggregateRewritingConfig().setSupportNegativeValuesInSums(false); } - private void handleDisableStratifedEval(Option opt, SystemConfig cfg) { - cfg.setEvaluateStratifiedPart(false); - } - private void handleDebugPreprocessing(Option opt, InputConfig cfg) { cfg.setDebugPreprocessing(true); } diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java index 23655f106..9c5777159 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java @@ -54,7 +54,7 @@ public void smokeTest() { "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + "n2 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = new AlphaFactory().newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); ComponentGraph compgraph = dbgResult.getComponentGraph(); ComponentGraphWriter writer = new ComponentGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java index 8d5929e80..a738bf3e0 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java @@ -51,7 +51,7 @@ public void smokeTest() { "n6 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + "n6 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = new AlphaFactory().newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); DependencyGraph depgraph = dbgResult.getDependencyGraph(); DependencyGraphWriter writer = new DependencyGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParserTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParserTest.java index f77f6527e..91a2855b9 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParserTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParserTest.java @@ -28,7 +28,6 @@ package at.ac.tuwien.kr.alpha.app.config; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -160,20 +159,6 @@ public void noInstanceRemoval() throws ParseException { assertTrue(alphaConfig.getSystemConfig().isGrounderAccumulatorEnabled()); } - @Test - public void disableStratifiedEval() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig ctx = parser.parseCommandLine(new String[]{"-i", "someFile.asp", "-i", "someOtherFile.asp", "-dse"}); - assertFalse(ctx.getSystemConfig().isEvaluateStratifiedPart()); - } - - @Test - public void disableStratifiedEvalLongOpt() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig ctx = parser.parseCommandLine(new String[]{"-i", "someFile.asp", "-i", "someOtherFile.asp", "--disableStratifiedEvaluation"}); - assertFalse(ctx.getSystemConfig().isEvaluateStratifiedPart()); - } - @Test public void atomSeparator() throws ParseException { CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java index 75a2d7cb6..c272d1ec3 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java @@ -47,7 +47,7 @@ public void solveAndWriteWorkbookTest() { + "p(N) :- p(I), N = I + 1, N <= MX, maxP(MX)." + "q(A, B) :- p(A), p(B)."; //@formatter:on - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = new AlphaFactory().newAlpha(); List answerSets = alpha.solve(alpha.readProgramString(progstr)).collect(Collectors.toList()); assertEquals(1, answerSets.size()); AnswerSet as = answerSets.get(0); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java index 17684b602..2dd9f0f5c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java @@ -36,6 +36,10 @@ public AbstractProgramParser(Map externals) { this.preloadedExternals.putAll(externals); } + protected void registerExternal(String name, PredicateInterpretation interpretation) { + this.preloadedExternals.put(name, interpretation); + } + @Override public InputProgram parse(String s) { return parse(s, Collections.emptyMap()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java index 9f1079922..3b1a9f71c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java @@ -1,18 +1,22 @@ package at.ac.tuwien.kr.alpha.core.parser.evolog; +import java.util.Collections; import java.util.Map; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; public class EvologProgramParser extends AbstractProgramParser { - public EvologProgramParser(Map externals) { + public EvologProgramParser(ActionImplementationProvider actionImplementationProvider, Map externals) { super(externals); + registerExternal("stdin", actionImplementationProvider.getStdinTerm()); + registerExternal("stdout", actionImplementationProvider.getStdoutTerm()); } - public EvologProgramParser() { - super(); + public EvologProgramParser(ActionImplementationProvider actionImplementationProvider) { + this(actionImplementationProvider, Collections.emptyMap()); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java deleted file mode 100644 index 83e9ab9c9..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java +++ /dev/null @@ -1,26 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.programs; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.antlr.v4.runtime.CharStreams; - -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; - -public class Programs { - - private Programs() { - throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); - } - - // TODO integrate this Method into Alpha interface so we have a parser following overall system config - public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { - AbstractProgramParser parser = new EvologProgramParser(); - return parser.parse(CharStreams.fromStream(is), externals); - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramNormalizer.java similarity index 82% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramNormalizer.java index 1d075903e..89498e3da 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramNormalizer.java @@ -11,7 +11,7 @@ * * Copyright (c) 2019-2021, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformer { +public class ProgramNormalizer extends ProgramTransformer { private final VariableEqualityTransformer equalityTransformer; private final ChoiceHeadNormalizer choiceHeadNormalizer; @@ -20,7 +20,7 @@ public class NormalizeProgramTransformation extends ProgramTransformer solvedRuleIds = new HashSet<>(); // Set of rules that have been completely evaluated. private LiteralInstantiator literalInstantiator; - private ActionExecutionService actionContext; + private ActionExecutionService actionExecutionService; private final boolean generateActionWitnesses; - public StratifiedEvaluation(ActionExecutionService actionContext, boolean generateActionWitnesses) { - this.actionContext = actionContext; + public StratifiedEvaluation(ActionExecutionService actionExecutionService, boolean generateActionWitnesses) { + this.actionExecutionService = actionExecutionService; this.generateActionWitnesses = generateActionWitnesses; } @@ -352,7 +352,7 @@ public BasicAtom instantiateActionHead(ActionHead head, Substitution substitutio substitutedInput.add(inputTerm.substitute(substitution)); } // Delegate action execution to respective backend. - ActionWitness witness = actionContext.execute(head.getActionName(), rule.getRuleId(), substitution, substitutedInput); + ActionWitness witness = actionExecutionService.execute(head.getActionName(), rule.getRuleId(), substitution, substitutedInput); // If the according debug flag is set, convert witness to atom and add to facts. if (generateActionWitnesses) { BasicAtom witnessAtom = buildActionWitnessAtom(witness, rule); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java deleted file mode 100644 index c1a6ad17e..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; - -import java.util.function.Supplier; - -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; - -public class AggregateEncoderFactory { - - private final Supplier parserFactory; - private final boolean useSortingGridEncoding; - private final boolean supportNegativeSumElements; - - public AggregateEncoderFactory(Supplier parserFactory, boolean useSortingGridEncoding, boolean supportNegativeSumElements) { - this.parserFactory = parserFactory; - this.useSortingGridEncoding = useSortingGridEncoding; - this.supportNegativeSumElements = supportNegativeSumElements; - } - - public CountEncoder newCountEqualsEncoder() { - return CountEncoder.buildCountEqualsEncoder(parserFactory.get()); - } - - public CountEncoder newCountLessOrEqualEncoder() { - return CountEncoder.buildCountLessOrEqualEncoder(parserFactory.get(), useSortingGridEncoding); - } - - public SumEncoder newSumEqualsEncoder() { - return SumEncoder.buildSumEqualsEncoder(parserFactory.get(), supportNegativeSumElements); - } - - public SumEncoder newSumLessOrEqualEncoder() { - return SumEncoder.buildSumLessOrEqualEncoder(parserFactory.get(), supportNegativeSumElements); - } - - public MinMaxEncoder newMinEncoder() { - return new MinMaxEncoder(parserFactory.get(), AggregateFunctionSymbol.MIN); - } - - public MinMaxEncoder newMaxEncoder() { - return new MinMaxEncoder(parserFactory.get(), AggregateFunctionSymbol.MAX); - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java new file mode 100644 index 000000000..55d6ca6af --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java @@ -0,0 +1,36 @@ +package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; + +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; + +public final class AggregateEncoders { + + private AggregateEncoders() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static CountEncoder newCountEqualsEncoder(ProgramParser parser) { + return CountEncoder.buildCountEqualsEncoder(parser); + } + + public static CountEncoder newCountLessOrEqualEncoder(ProgramParser parser, boolean useSortingGridEncoding) { + return CountEncoder.buildCountLessOrEqualEncoder(parser, useSortingGridEncoding); + } + + public static SumEncoder newSumEqualsEncoder(ProgramParser parser, boolean supportNegativeSumElements) { + return SumEncoder.buildSumEqualsEncoder(parser, supportNegativeSumElements); + } + + public static SumEncoder newSumLessOrEqualEncoder(ProgramParser parser, boolean supportNegativeSumElements) { + return SumEncoder.buildSumLessOrEqualEncoder(parser, supportNegativeSumElements); + } + + public static MinMaxEncoder newMinEncoder(ProgramParser parser) { + return new MinMaxEncoder(parser, AggregateFunctionSymbol.MIN); + } + + public static MinMaxEncoder newMaxEncoder(ProgramParser parser) { + return new MinMaxEncoder(parser, AggregateFunctionSymbol.MAX); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java index e78acb4bd..74b10bb47 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java @@ -62,7 +62,7 @@ public class MinMaxEncoder extends AbstractAggregateEncoder { private final ProgramParser parser; - public MinMaxEncoder(ProgramParser parser, AggregateFunctionSymbol func) { + MinMaxEncoder(ProgramParser parser, AggregateFunctionSymbol func) { super(func, SetUtils.hashSet(ComparisonOperators.operators())); if (!(func == AggregateFunctionSymbol.MAX || func == AggregateFunctionSymbol.MIN)) { throw new IllegalArgumentException("Encoder " + this.getClass().getSimpleName() + " can only encode min/max aggregates!"); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java index 95d9737a3..4a5a9497d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java @@ -37,11 +37,11 @@ private SumEncoder(ProgramParser parser, ComparisonOperator acceptedOperator, ST super(parser, AggregateFunctionSymbol.SUM, acceptedOperator, encodingTemplate); } - public static SumEncoder buildSumLessOrEqualEncoder(ProgramParser parser, boolean supportNegativeIntegers) { + static SumEncoder buildSumLessOrEqualEncoder(ProgramParser parser, boolean supportNegativeIntegers) { return new SumEncoder(parser, ComparisonOperators.LE, supportNegativeIntegers ? SUM_LE_TEMPLATE : NON_NEG_ELEMENTS_SUM_LE_TEMPLATE); } - public static SumEncoder buildSumEqualsEncoder(ProgramParser parser, boolean supportNegativeIntegers) { + static SumEncoder buildSumEqualsEncoder(ProgramParser parser, boolean supportNegativeIntegers) { return new SumEncoder(parser, ComparisonOperators.EQ, supportNegativeIntegers ? SUM_EQ_TEMPLATE : NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java index 5621615cc..69e7eb0b7 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java @@ -1,11 +1,12 @@ package at.ac.tuwien.kr.alpha.core.parser; +import at.ac.tuwien.kr.alpha.core.actions.DefaultActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; public class EvologParserTest extends ParserTest { protected EvologParserTest() { - super(new EvologProgramParser()); + super(new EvologProgramParser(new DefaultActionImplementationProvider())); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index 1e2566d52..db77b46d8 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.externals.Externals; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; // TODO This is a functional test and should not be run with standard unit tests @@ -26,8 +26,8 @@ public class ProgramTransformationTest { private static final String TESTFILES_PATH = "/transform-test/"; - // TODO should this always be an evolog parser? - private static final ProgramParser PARSER = new EvologProgramParser(); + // TODO should this always be an asp core2 parser? + private static final ProgramParser PARSER = new ASPCore2ProgramParser(); private ChoiceHeadNormalizer choiceToNormal = new ChoiceHeadNormalizer(); private IntervalTermTransformer intervalRewriting = new IntervalTermTransformer(); diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index aeb0fed9e..b3c014c13 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -2,8 +2,6 @@ import java.util.function.Supplier; -import com.google.common.annotations.VisibleForTesting; - import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.config.AggregateRewritingConfig; import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; @@ -11,45 +9,51 @@ import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionServiceImpl; +import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.actions.DefaultActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermTransformer; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ChoiceHeadNormalizer; +import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationTransformer; +import at.ac.tuwien.kr.alpha.core.programs.transformation.IntervalTermTransformer; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramNormalizer; import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformer; +import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.VariableEqualityTransformer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateTransformer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AggregateEncoderFactory; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AggregateEncoders; import at.ac.tuwien.kr.alpha.core.solver.SolverConfig; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; -public final class AlphaFactory { - - private AlphaFactory() { - throw new AssertionError("Cannot instantiate utility class!"); - } +public class AlphaFactory { - static Supplier> newProgramNormalizationFactory(Supplier parserFactory, + protected ProgramTransformer newProgramNormalizer(ProgramParser parser, AggregateRewritingConfig aggregateCfg) { - // AggregateEncoderFactory depends on parser factory since stringtemplate-based aggregate encoders need to use the same parser that's used - // for input programs. - AggregateEncoderFactory aggregateEncoderFactory = new AggregateEncoderFactory(parserFactory, - aggregateCfg.isUseSortingGridEncoding(), aggregateCfg.isSupportNegativeValuesInSums()); - - // Factory for aggregate rewriting (depends on encoders provided by above factory). - Supplier aggregateRewritingFactory = () -> new AggregateTransformer(aggregateEncoderFactory.newCountEqualsEncoder(), - aggregateEncoderFactory.newCountLessOrEqualEncoder(), aggregateEncoderFactory.newSumEqualsEncoder(), - aggregateEncoderFactory.newSumLessOrEqualEncoder(), aggregateEncoderFactory.newMinEncoder(), aggregateEncoderFactory.newMaxEncoder()); + return new ProgramNormalizer( + new VariableEqualityTransformer(), + new ChoiceHeadNormalizer(), + new AggregateTransformer( + AggregateEncoders.newCountEqualsEncoder(parser), + AggregateEncoders.newCountLessOrEqualEncoder(parser, aggregateCfg.isUseSortingGridEncoding()), + AggregateEncoders.newSumEqualsEncoder(parser, aggregateCfg.isSupportNegativeValuesInSums()), + AggregateEncoders.newSumLessOrEqualEncoder(parser, aggregateCfg.isSupportNegativeValuesInSums()), + AggregateEncoders.newMinEncoder(parser), + AggregateEncoders.newMaxEncoder(parser)), + new EnumerationTransformer(), + new IntervalTermTransformer(), + new ArithmeticTermTransformer()); + } - // Factory for NormalizeProgramTransformation - needs a supplier for AggregateRewriting due to AggregateRewritings' dependency to encoder - // factory. - return () -> new NormalizeProgramTransformation( - aggregateRewritingFactory); + protected Supplier newStratifiedEvaluationFactory(ActionImplementationProvider actionImplementationProvider, + boolean generateActionWitnesses) { + return () -> new StratifiedEvaluation(new ActionExecutionServiceImpl(actionImplementationProvider), generateActionWitnesses); } - static GrounderFactory newGrounderFactory(SystemConfig cfg) { + protected GrounderFactory newGrounderFactory(SystemConfig cfg) { GrounderHeuristicsConfiguration grounderHeuristicsCfg = GrounderHeuristicsConfiguration.getInstance(cfg.getGrounderToleranceConstraints(), cfg.getGrounderToleranceRules()); grounderHeuristicsCfg.setAccumulatorEnabled(cfg.isGrounderAccumulatorEnabled()); @@ -58,7 +62,7 @@ static GrounderFactory newGrounderFactory(SystemConfig cfg) { cfg.isDebugInternalChecks()); } - static SolverFactory newSolverFactory(SystemConfig cfg) { + protected SolverFactory newSolverFactory(SystemConfig cfg) { SolverConfig solverCfg = new SolverConfig(); solverCfg.setDisableJustifications(cfg.isDisableJustificationSearch()); solverCfg.setDisableNogoodDeletion(cfg.isDisableNoGoodDeletion()); @@ -73,18 +77,25 @@ static SolverFactory newSolverFactory(SystemConfig cfg) { return new SolverFactory(cfg.getSolverName(), cfg.getNogoodStoreName(), solverCfg); } - // TODO lifetime of one ActionContext needs to be exactly runtime of one program! - @VisibleForTesting - public static Alpha newAlpha(SystemConfig cfg, ActionExecutionService actionContext) { - - // Parser factory - Supply correct parser dependent on the accepted input language. - Supplier parserFactory = () -> cfg.isAcceptEvologPrograms() ? new EvologProgramParser() : new ASPCore2ProgramParser(); - // if (cfg.isAcceptEvologPrograms()) { + protected ActionImplementationProvider newActionImplementationProvider() { + return new DefaultActionImplementationProvider(); + } - // } - Supplier> programNormalizationFactory = newProgramNormalizationFactory(parserFactory, + public Alpha newAlpha(SystemConfig cfg) { + ActionImplementationProvider actionImplementationProvider = newActionImplementationProvider(); + ProgramParser parser; + if (cfg.isAcceptEvologPrograms()) { + parser = new EvologProgramParser(actionImplementationProvider); // TODO need to give stdin/stdout definitions to parser (pass in implementation + // provider) + } else { + parser = new ASPCore2ProgramParser(); + } + ProgramTransformer programNormalizer = newProgramNormalizer(parser, cfg.getAggregateRewritingConfig()); + // Stratified evaluation factory - since every instance of stratified evaluation is only good for one program, we need a factory. + Supplier stratifiedEvaluationFactory = newStratifiedEvaluationFactory(actionImplementationProvider, cfg.isDebugInternalChecks()); + // GrounderFactory - Since every grounder instance is only good for one program instance, we need a factory. GrounderFactory grounderFactory = newGrounderFactory(cfg); @@ -92,17 +103,11 @@ public static Alpha newAlpha(SystemConfig cfg, ActionExecutionService actionCont SolverFactory solverFactory = newSolverFactory(cfg); // Now that all dependencies are taken care of, build new Alpha instance. - return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, actionContext, cfg.isEvaluateStratifiedPart(), - cfg.isSortAnswerSets()); - } - - // TODO action stuff should go into system config - public static Alpha newAlpha(SystemConfig cfg) { - return newAlpha(cfg, new ActionExecutionServiceImpl(new DefaultActionImplementationProvider())); + return new AlphaImpl(parser, programNormalizer, stratifiedEvaluationFactory, grounderFactory, solverFactory, cfg.isSortAnswerSets()); } // Create Alpha instance with default config. - public static Alpha newAlpha() { + public Alpha newAlpha() { return newAlpha(new SystemConfig()); } diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index 5bb5d1621..a95276fe7 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -40,12 +40,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import com.google.common.annotations.VisibleForTesting; - import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.annotations.VisibleForTesting; + import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; @@ -59,7 +59,6 @@ import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; import at.ac.tuwien.kr.alpha.commons.util.Util; -import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; @@ -76,21 +75,23 @@ public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); - private final Supplier parserFactory; - private final Supplier> programNormalizationFactory; + private final ProgramParser parser; + private final ProgramTransformer programNormalizer; + private final Supplier stratifiedEvaluationFactory; private final GrounderFactory grounderFactory; private final SolverFactory solverFactory; private final boolean sortAnswerSets; - AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, + AlphaImpl(ProgramParser parser, ProgramTransformer programNormalizer, + Supplier stratifiedEvaluationFactory, GrounderFactory grounderFactory, - SolverFactory solverFactory, - boolean enableStratifiedEvaluation, boolean sortAnswerSets) { - this.parserFactory = parserFactory; - this.programNormalizationFactory = programNormalizationFactory; + SolverFactory solverFactory, boolean sortAnswerSets) { + this.parser = parser; + this.programNormalizer = programNormalizer; + this.stratifiedEvaluationFactory = stratifiedEvaluationFactory; this.grounderFactory = grounderFactory; this.solverFactory = solverFactory; this.sortAnswerSets = sortAnswerSets; @@ -119,7 +120,6 @@ public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - ProgramParser parser = parserFactory.get(); InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); InputProgram tmpProg; for (Path path : paths) { @@ -137,7 +137,7 @@ public InputProgram readProgramFiles(boolean literate, Map externals) { - return parserFactory.get().parse(aspString, externals); + return parser.parse(aspString, externals); } @Override @@ -145,18 +145,27 @@ public InputProgram readProgramString(String aspString) { return readProgramString(aspString, Collections.emptyMap()); } + @Override + public InputProgram readProgramStream(InputStream is) throws IOException { + return parser.parse(is); + } + + @Override + public InputProgram readProgramStream(InputStream is, Map externals) throws IOException { + return parser.parse(is, externals); + } + @Override public NormalProgram normalizeProgram(InputProgram program) { - return programNormalizationFactory.get().transform(program); + return programNormalizer.transform(program); } @VisibleForTesting InternalProgram performProgramPreprocessing(NormalProgram program) { LOGGER.debug("Preprocessing InternalProgram!"); InternalProgram retVal = InternalProgram.fromNormalProgram(program); - // TODO get the StratifiedEvaluation from factory AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); - retVal = new StratifiedEvaluation(actionContext, true).transform(analyzed); + retVal = stratifiedEvaluationFactory.get().transform(analyzed); return retVal; } @@ -242,8 +251,7 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final ComponentGraph compGraph; final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; - // TODO get the StratifiedEvaluation from factory - preprocessed = new StratifiedEvaluation(actionContext, true).transform(analyzed).toNormalProgram(); + preprocessed = stratifiedEvaluationFactory.get().transform(analyzed).toNormalProgram(); depGraph = analyzed.getDependencyGraph(); compGraph = analyzed.getComponentGraph(); final Solver solver = prepareSolverFor(analyzed, filter); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index 0b61309b1..f0a25b778 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -28,7 +28,7 @@ public class ActionsTest { public void helloWorld() { MockActionImplementationProvider actionMock = new MockActionImplementationProvider(); ActionExecutionService actionService = new ActionExecutionServiceImpl(actionMock); - Alpha alpha = AlphaFactory.newAlpha(new SystemConfig(), actionService); + Alpha alpha = new AlphaFactory().newAlpha(new SystemConfig()); InputProgram program = alpha.readProgramString(HELLO_WORLD); alpha.solve(program); // TODO check mock for correct output content diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java index 0acbb173a..4114d032d 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java @@ -18,7 +18,7 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; @@ -60,7 +60,7 @@ public class AggregateRewritingContextTest { //@formatter:on private static final AggregateRewritingContext rewritingContextForAspString(String asp) { - InputProgram program = new EvologProgramParser().parse(asp); + InputProgram program = new ASPCore2ProgramParser().parse(asp); AggregateRewritingContext ctx = new AggregateRewritingContext(); for (Rule rule : program.getRules()) { ctx.registerRule(rule); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java index df015f477..c3e9e3b90 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java @@ -79,7 +79,7 @@ public class AggregateRewritingTest { //@formatter:on // Use an alpha instance with default config for all test cases - private final Alpha alpha = AlphaFactory.newAlpha(); + private final Alpha alpha = new AlphaFactory().newAlpha(); private final Function> solve = (asp) -> { InputProgram prog = alpha.readProgramString(asp); return alpha.solve(prog).collect(Collectors.toList()); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java index 637fe75a1..4df809080 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java @@ -23,7 +23,7 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermTransformer; @@ -34,7 +34,7 @@ public class ArithmeticTermsRewritingTest { private final Map externalsOfThisClass = Externals.scan(ArithmeticTermsRewritingTest.class); - private final ProgramParser parser = new EvologProgramParser(externalsOfThisClass); // Create parser that knows an implementation of external atom &extArithTest[](). + private final ProgramParser parser = new ASPCore2ProgramParser(externalsOfThisClass); // Create parser that knows an implementation of external atom &extArithTest[](). @Predicate(name = "extArithTest") public static Set>> externalForArithmeticTermsRewriting(Integer in) { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java index 0aafb40c7..871b20491 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java @@ -81,7 +81,7 @@ public static Set>> connection(String dummy) { private Map externals; public FixedInterpretationLiteralsTest() { - this.alpha = AlphaFactory.newAlpha(); + this.alpha = new AlphaFactory().newAlpha(); this.externals = new HashMap<>(); this.externals.putAll(Externals.scan(AspStandardLibrary.class)); this.externals.putAll(Externals.scan(FixedInterpretationLiteralsTest.class)); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java index 69982ad45..f379a2a30 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java @@ -4,12 +4,12 @@ import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; public class RuleParser { public static Rule parse(String str) { - ProgramParser parser = new EvologProgramParser(); + ProgramParser parser = new ASPCore2ProgramParser(); InputProgram prog = parser.parse(str); if (!prog.getFacts().isEmpty()) { throw new IllegalArgumentException("Expected exactly one rule and no facts!"); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java index aadbd8588..d2f2e9dfd 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java @@ -36,7 +36,7 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.rules.CompiledRuleImpl; import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; @@ -45,7 +45,7 @@ * Tests {@link BasicRule#toString()} and {@link CompiledRuleImpl#toString()}. */ public class RuleToStringTest { - private final ProgramParser parser = new EvologProgramParser(); + private final ProgramParser parser = new ASPCore2ProgramParser(); @Test public void positiveRuleToString() { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java index 1a53a980f..ff80432b6 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java @@ -27,11 +27,10 @@ */ package at.ac.tuwien.kr.alpha; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; - import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -45,7 +44,6 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; @@ -56,13 +54,12 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.Programs; // TODO This is an integration test and should be run in an extra suite public class StratifiedEvaluationTest { // Alpha instance with default configuration (evolog support and stratified evaluation enabled) - private final Alpha alpha = AlphaFactory.newAlpha(); + private final Alpha alpha = new AlphaFactory().newAlpha(); /** * Verifies that facts are not duplicated by stratified evaluation. @@ -160,7 +157,7 @@ public void testNegatedExternalLiteral() throws Exception { */ @Test public void testPartnerUnitsProblemTopologicalOrder() throws IOException { - InputProgram prg = Programs.fromInputStream( + InputProgram prg = alpha.readProgramStream( StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp"), new HashMap<>()); DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(prg); @@ -184,24 +181,13 @@ public void testNegatedLiteralInRecursiveRule() throws IOException { + "inc_value(4), inc_value(5), inc_value(6), inc_value(7), " + "inc_value(8)"; //@formatter:on - InputProgram prog = Programs.fromInputStream( + InputProgram prog = alpha.readProgramStream( StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), new HashMap<>()); // Run stratified evaluation and solve - SystemConfig cfgWithStratEval = new SystemConfig(); - cfgWithStratEval.setEvaluateStratifiedPart(true); - Alpha alphaStratEval = AlphaFactory.newAlpha(cfgWithStratEval); - DebugSolvingContext dbgWithStratEval = alphaStratEval.prepareDebugSolve(prog); - Set asStrat = dbgWithStratEval.getSolver().collectSet(); - assertAnswerSetsEqual(expectedAnswerSet, asStrat); - - // Solve without stratified evaluation - SystemConfig cfgNoStratEval = new SystemConfig(); - cfgNoStratEval.setEvaluateStratifiedPart(false); - Alpha alphaNoStratEval = AlphaFactory.newAlpha(cfgNoStratEval); - DebugSolvingContext dbgNoStratEval = alphaNoStratEval.prepareDebugSolve(prog); - Set as = dbgNoStratEval.getSolver().collectSet(); + DebugSolvingContext dbg = alpha.prepareDebugSolve(prog); + Set as = dbg.getSolver().collectSet(); assertAnswerSetsEqual(expectedAnswerSet, as); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 668dee7bb..9e365313d 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -38,16 +38,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -58,12 +54,11 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.config.Heuristic; +import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; @@ -79,16 +74,14 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; // TODO This is a functional test and should not be run with standard unit tests public class AlphaImplTest { - + private static final Logger LOGGER = LoggerFactory.getLogger(AspStandardLibrary.class); - + //@formatter:off private static final String STRINGSTUFF_ASP = "string(\"bla\")." @@ -118,7 +111,7 @@ public class AlphaImplTest { //@formatter:on private static int invocations; - + @at.ac.tuwien.kr.alpha.api.externals.Predicate public static boolean isOne(int term) { invocations++; @@ -138,7 +131,7 @@ public static boolean thinger(Thingy thingy) { @Test public void withExternal() throws Exception { - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = new AlphaFactory().newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isOne[1]."); inputCfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram program = alpha.readProgram(inputCfg); @@ -149,7 +142,7 @@ public void withExternal() throws Exception { @Test public void addsFacts() { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); Thingy a = new Thingy(); Thingy b = new Thingy(); List things = asList(a, b); @@ -162,18 +155,18 @@ public void addsFacts() { @Test public void withExternalTypeConflict() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = AlphaFactory.newAlpha(); - InputConfig inputCfg = InputConfig.forString("a :- &isFoo[\"adsfnfdsf\"]."); - inputCfg.addPredicateMethod("isFoo", Externals.processPredicateMethod(this.getClass().getMethod("isFoo", Integer.class))); - Set actual = system.solve(system.readProgram(inputCfg)).collect(Collectors.toSet()); - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); - assertEquals(expected, actual); -}); + Alpha system = new AlphaFactory().newAlpha(); + InputConfig inputCfg = InputConfig.forString("a :- &isFoo[\"adsfnfdsf\"]."); + inputCfg.addPredicateMethod("isFoo", Externals.processPredicateMethod(this.getClass().getMethod("isFoo", Integer.class))); + Set actual = system.solve(system.readProgram(inputCfg)).collect(Collectors.toSet()); + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); + assertEquals(expected, actual); + }); } @Test public void smallGraph() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). node(3). a :- &connected[1,2]."); inputCfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); InputProgram program = system.readProgram(inputCfg); @@ -185,7 +178,7 @@ public void smallGraph() throws Exception { @Test public void filterOutput() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); inputCfg.addPredicateMethod("getLargeGraphEdges", Externals.processPredicate(() -> new HashSet<>(asList(asList(Terms.newConstant(1), Terms.newConstant(2)), @@ -198,7 +191,7 @@ public void filterOutput() throws Exception { @Test public void supplier() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicate(() -> singleton(singletonList(Terms.newConstant(1))))); InputProgram prog = system.readProgram(cfg); @@ -215,7 +208,7 @@ public static Set>> bestNode() { @Test public void noInput() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicateMethod(this.getClass().getMethod("bestNode"))); InputProgram prog = system.readProgram(cfg); @@ -228,12 +221,12 @@ public void noInput() throws Exception { @Test public void smallGraphWithWrongType() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = AlphaFactory.newAlpha(); - InputConfig cfg = InputConfig.forString("a :- &connected[\"hello\",2]."); - cfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); - InputProgram prog = system.readProgram(cfg); + Alpha system = new AlphaFactory().newAlpha(); + InputConfig cfg = InputConfig.forString("a :- &connected[\"hello\",2]."); + cfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); + InputProgram prog = system.readProgram(cfg); - system.solve(prog).collect(Collectors.toSet()); + system.solve(prog).collect(Collectors.toSet()); }); } @@ -254,7 +247,7 @@ public static Set>> coolNode(int node) { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphNoNeighbors() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("noNeighbors(2) :- not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); InputProgram prog = system.readProgram(cfg); @@ -266,7 +259,7 @@ public void smallGraphNoNeighbors() throws Exception { @Test public void smallGraphCoolNode() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("node(1..2). in(X) :- node(X), &coolNode[X]."); cfg.addPredicateMethod("coolNode", Externals.processPredicateMethod(this.getClass().getMethod("coolNode", int.class))); InputProgram prog = system.readProgram(cfg); @@ -278,7 +271,7 @@ public void smallGraphCoolNode() throws Exception { @Test public void smallGraphSingleNeighbor() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("node(1..3). in(1,X) :- &neighbors[1](X), node(X)."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); InputProgram prog = system.readProgram(cfg); @@ -291,7 +284,7 @@ public void smallGraphSingleNeighbor() throws Exception { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphSingleNeighborNoTerm() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("success :- &neighbors[1], not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); InputProgram prog = system.readProgram(cfg); @@ -317,7 +310,7 @@ public boolean equals(Object o) { if (o == null) { return false; } - if (!(o instanceof Thingy)) { + if (!(o instanceof Thingy)) { return false; } return true; @@ -342,7 +335,7 @@ public void withExternalSubtype() throws Exception { new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true))); - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputProgram prog = new InputProgramImpl(singletonList(rule), emptyList(), new InlineDirectivesImpl()); @@ -353,7 +346,7 @@ public void withExternalSubtype() throws Exception { @Test public void withExternalViaAnnotation() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1]."); cfg.addPredicateMethods(Externals.scan(this.getClass())); InputProgram prog = system.readProgram(cfg); @@ -371,15 +364,15 @@ public void withExternalViaAnnotation() throws Exception { @Test public void errorDuplicateExternal() { assertThrows(IllegalArgumentException.class, () -> { - InputConfig cfg = InputConfig.forString("someString."); - cfg.addPredicateMethods(Externals.scan(this.getClass())); - cfg.addPredicateMethods(Externals.scan(this.getClass())); -}); + InputConfig cfg = InputConfig.forString("someString."); + cfg.addPredicateMethods(Externals.scan(this.getClass())); + cfg.addPredicateMethods(Externals.scan(this.getClass())); + }); } @Test public void withNativeExternal() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isTwo[2]."); cfg.addPredicateMethod("isTwo", Externals.processPredicate((Integer t) -> t == 2)); InputProgram prog = system.readProgram(cfg); @@ -392,7 +385,7 @@ public void withNativeExternal() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted1() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], &isOne[1]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram prog = system.readProgram(cfg); @@ -410,7 +403,7 @@ public void withExternalInvocationCounted1() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted2() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a. b :- &isOne[1], &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram prog = system.readProgram(cfg); @@ -428,7 +421,7 @@ public void withExternalInvocationCounted2() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted3() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], not &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram prog = system.readProgram(cfg); @@ -442,11 +435,11 @@ public void withExternalInvocationCounted3() throws Exception { Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); assertEquals(expected, actual); } - + @Test @SuppressWarnings("unchecked") public void programWithExternalStringStuff() throws IOException { - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = new AlphaFactory().newAlpha(); InputProgram prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); // Verify every result string has length 6 and contains "foo" @@ -462,7 +455,7 @@ public void programWithExternalStringStuff() throws IOException { @Test @SuppressWarnings("unchecked") public void withNegatedExternal() throws IOException { - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = new AlphaFactory().newAlpha(); InputProgram prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); assertEquals(31, answerSets.size()); @@ -479,7 +472,7 @@ public void withNegatedExternal() throws IOException { @Test public void basicUsage() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(a)."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").symbolicInstance("a").build())); assertEquals(expected, actual); @@ -487,7 +480,7 @@ public void basicUsage() throws Exception { @Test public void basicUsageWithString() throws Exception { - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(\"a\")."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("a").build())); assertEquals(expected, actual); @@ -499,7 +492,7 @@ public void basicUsageWithString() throws Exception { @Test public void filterTest() { String progstr = "a. b. c. d :- c. e(a, b) :- d."; - Alpha system = AlphaFactory.newAlpha(); + Alpha system = new AlphaFactory().newAlpha(); InputProgram prog = system.readProgramString(progstr); Set actual = system.solve(prog, (p) -> p.equals(Predicates.getPredicate("a", 0)) || p.equals(Predicates.getPredicate("e", 2))) .collect(Collectors.toSet()); @@ -508,34 +501,18 @@ public void filterTest() { } /** - * Verifies that no stratified evaluation is performed up-front when disabled in config. - */ - @Test - public void disableStratifiedEvalTest() { - // Note: This might be cleaner if the test used the debugSolve method from the interface - String progstr = "p(a). q(X) :- p(X)."; - SystemConfig cfg = new SystemConfig(); - cfg.setEvaluateStratifiedPart(false); - AlphaImpl system = (AlphaImpl) AlphaFactory.newAlpha(cfg); - InputProgram input = system.readProgramString(progstr); - NormalProgram normal = system.normalizeProgram(input); - CompiledProgram preprocessed = system.performProgramPreprocessing(normal); - assertFalse(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), - "Preprocessed program contains fact derived from stratifiable rule, but should not!"); - } - - /** - * Verifies that stratified evaluation is performed up-front if not otherwise configured. + * Verifies that stratified evaluation is performed. + * Note: This test case is something of a bit of legacy code since there is no way to disable stratified evaluation anymore. */ @Test public void enableStratifiedEvalTest() { - // Note: This might be cleaner if the test used the debugSolve method from the interface String progstr = "p(a). q(X) :- p(X)."; SystemConfig cfg = new SystemConfig(); - AlphaImpl system = (AlphaImpl) AlphaFactory.newAlpha(cfg); + Alpha system = new AlphaFactory().newAlpha(cfg); InputProgram input = system.readProgramString(progstr); NormalProgram normal = system.normalizeProgram(input); - CompiledProgram preprocessed = system.performProgramPreprocessing(normal); + DebugSolvingContext dbg = system.prepareDebugSolve(normal); + NormalProgram preprocessed = dbg.getPreprocessedProgram(); assertTrue(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), "Preprocessed program does not contain fact derived from stratifiable rule, but should!"); } @@ -592,7 +569,7 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(1119718541727902L); - final Alpha system = AlphaFactory.newAlpha(cfg); + final Alpha system = new AlphaFactory().newAlpha(cfg); final Path path = Paths.get("src", "test", "resources", "PreviouslyProblematic").resolve("3col-20-38.txt"); InputConfig inputCfg = new InputConfig(); @@ -611,7 +588,7 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(seed); - final Alpha system = AlphaFactory.newAlpha(cfg); + final Alpha system = new AlphaFactory().newAlpha(cfg); InputConfig inputCfg = new InputConfig(); List files = new ArrayList<>(); files.add(base.resolve(program).toString()); @@ -619,31 +596,5 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep InputProgram prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).limit(limit).collect(Collectors.toList()).isEmpty()); } - - // Detailed reproduction test-case for github issue #239. - @Test - public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { - final ProgramParser parser = new ASPCore2ProgramParser(); - InputProgramImpl.Builder bld = InputProgramImpl.builder(); - bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), StandardOpenOption.READ))); - bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"), StandardOpenOption.READ))); - InputProgram parsedProgram = bld.build(); - - SystemConfig config = new SystemConfig(); - config.setSolverName("default"); - config.setNogoodStoreName("alpharoaming"); - config.setSeed(0); - config.setBranchingHeuristic(Heuristic.valueOf("VSIDS")); - config.setDebugInternalChecks(true); - config.setDisableJustificationSearch(false); - config.setEvaluateStratifiedPart(false); - config.setReplayChoices(Arrays.asList(21, 26, 36, 56, 91, 96, 285, 166, 101, 290, 106, 451, 445, 439, 448, - 433, 427, 442, 421, 415, 436, 409, 430, 397, 391, 424, 385, 379, - 418, 373, 412, 406, 394, 388, 382, 245, 232, 208 - )); - Alpha alpha = AlphaFactory.newAlpha(config); - Optional answerSet = alpha.solve(parsedProgram).findFirst(); - assertTrue(answerSet.isPresent()); - } - + } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java index 36f0f1ecc..da9238e66 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java @@ -42,7 +42,7 @@ import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests rule transformations described in the following research paper, and their effects on performance: @@ -246,7 +246,7 @@ private InputProgram constructProgramA_TransformationA(int n) { private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { assertEquals(numberOfRules, strRules.size()); String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - InputProgram parsedProgram = new EvologProgramParser().parse(strProgram); + InputProgram parsedProgram = new ASPCore2ProgramParser().parse(strProgram); assertEquals(numberOfRules, parsedProgram.getRules().size()); return parsedProgram; } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java index c481b4a99..a8d9d79d0 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java @@ -41,7 +41,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** @@ -112,7 +112,7 @@ public void testReach_4(SystemConfig cfg) { private void test(String folder, String aspFileName, SystemConfig cfg) throws IOException { @SuppressWarnings("unused") Optional answerSet = buildSolverForRegressionTest( - new EvologProgramParser().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) + new ASPCore2ProgramParser().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) .stream().findFirst(); // System.out.println(answerSet); // TODO: check correctness of answer set diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java index ecdb85095..070177f4e 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** @@ -61,7 +61,7 @@ public void testRacks(SystemConfig cfg) { private void test(SystemConfig cfg) throws IOException { CharStream programInputStream = CharStreams.fromPath( Paths.get("benchmarks", "siemens", "racks", "racks.lp")); - Solver solver = buildSolverForRegressionTest(new EvologProgramParser().parse(programInputStream), cfg); + Solver solver = buildSolverForRegressionTest(new ASPCore2ProgramParser().parse(programInputStream), cfg); @SuppressWarnings("unused") Optional answerSet = solver.stream().findFirst(); // System.out.println(answerSet); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java index 62ba483dd..4884832c2 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java @@ -113,7 +113,7 @@ public void runTest(String aspString, Consumer programVerifier, LOGGER.debug("Testing ASP String {}", aspString); // Parse and pre-evaluate program // Alpha instance with default config, stratified evaluation enabled - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = new AlphaFactory().newAlpha(); InputProgram input = alpha.readProgramString(aspString); DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(input); NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java index 7a5e06633..4d5823aa1 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java @@ -39,7 +39,6 @@ private static List buildConfigs() { String[] gtcValues = new String[]{DEFAULT_GROUNDER_TOLERANCE, "permissive" }; String grounderToleranceRules = DEFAULT_GROUNDER_TOLERANCE; boolean[] grounderAccumulatorValues = ci ? new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL, true } : new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL }; - boolean[] evaluateStratifiedValues = new boolean[]{false, true }; boolean[] enableDebugChecksValues = new boolean[]{DEFAULT_ENABLE_DEBUG_CHECKS, true }; //@formatter:on @@ -58,21 +57,18 @@ private static List buildConfigs() { for (String branchingHeuristicName : heuristics) { for (String grounderToleranceConstraints : gtcValues) { for (boolean grounderAccumulatorEnabled : grounderAccumulatorValues) { - for (boolean evaluateStratified : evaluateStratifiedValues) { - for (boolean enableDebugChecks : enableDebugChecksValues) { - SystemConfig cfg = new SystemConfig(); - cfg.setSolverName(solverName); - cfg.setNogoodStoreName(nogoodStoreName); - cfg.setBranchingHeuristicName(branchingHeuristicName); - cfg.setGrounderToleranceRules(grounderToleranceRules); - cfg.setGrounderToleranceConstraints(grounderToleranceConstraints); - cfg.setGrounderAccumulatorEnabled(grounderAccumulatorEnabled); - cfg.setEvaluateStratifiedPart(evaluateStratified); - cfg.setDebugInternalChecks(enableDebugChecks); - cfg.setSeed(seed); - - configsToTest.add(cfg); - } + for (boolean enableDebugChecks : enableDebugChecksValues) { + SystemConfig cfg = new SystemConfig(); + cfg.setSolverName(solverName); + cfg.setNogoodStoreName(nogoodStoreName); + cfg.setBranchingHeuristicName(branchingHeuristicName); + cfg.setGrounderToleranceRules(grounderToleranceRules); + cfg.setGrounderToleranceConstraints(grounderToleranceConstraints); + cfg.setGrounderAccumulatorEnabled(grounderAccumulatorEnabled); + cfg.setDebugInternalChecks(enableDebugChecks); + cfg.setSeed(seed); + + configsToTest.add(cfg); } } } @@ -92,40 +88,34 @@ private static List buildConfigs() { */ private static List buildConfigsForAggregateTests() { List configsToTest = new ArrayList<>(); - - boolean[] evaluateStratifiedValues = new boolean[] {true, false }; boolean[] useSortingGridValues = new boolean[] {true, false }; boolean[] supportNegativeSumElementsValues = new boolean[] {true, false }; - for (boolean evalStratified : evaluateStratifiedValues) { - for (boolean useSortingGrid : useSortingGridValues) { - for (boolean supportNegativeElements : supportNegativeSumElementsValues) { - // new RegressionTestConfig( - // DEFAULT_SOLVER_NAME, DEFAULT_GROUNDER_NAME, DEFAULT_NOGOOD_STORE, Heuristic.valueOf(DEFAULT_BRANCHING_HEURISTIC), - // 0, DEFAULT_ENABLE_DEBUG_CHECKS, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_DISABLE_INSTANCE_REMOVAL, - // evalStratified, - // useSortingGrid, supportNegativeElements)); - AggregateRewritingConfig aggCfg = new AggregateRewritingConfig(); - aggCfg.setUseSortingGridEncoding(useSortingGrid); - aggCfg.setSupportNegativeValuesInSums(supportNegativeElements); - - SystemConfig cfg = new SystemConfig(); - cfg.setSolverName(DEFAULT_SOLVER_NAME); - cfg.setNogoodStoreName(DEFAULT_NOGOOD_STORE); - cfg.setBranchingHeuristicName(DEFAULT_BRANCHING_HEURISTIC); - cfg.setSeed(0); - cfg.setDebugInternalChecks(DEFAULT_ENABLE_DEBUG_CHECKS); - cfg.setGrounderToleranceRules(DEFAULT_GROUNDER_TOLERANCE); - cfg.setGrounderToleranceConstraints(DEFAULT_GROUNDER_TOLERANCE); - cfg.setGrounderAccumulatorEnabled(DEFAULT_DISABLE_INSTANCE_REMOVAL); - cfg.setEvaluateStratifiedPart(evalStratified); - cfg.setAggregateRewritingConfig(aggCfg); - - configsToTest.add(cfg); - } + for (boolean useSortingGrid : useSortingGridValues) { + for (boolean supportNegativeElements : supportNegativeSumElementsValues) { + // new RegressionTestConfig( + // DEFAULT_SOLVER_NAME, DEFAULT_GROUNDER_NAME, DEFAULT_NOGOOD_STORE, Heuristic.valueOf(DEFAULT_BRANCHING_HEURISTIC), + // 0, DEFAULT_ENABLE_DEBUG_CHECKS, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_DISABLE_INSTANCE_REMOVAL, + // evalStratified, + // useSortingGrid, supportNegativeElements)); + AggregateRewritingConfig aggCfg = new AggregateRewritingConfig(); + aggCfg.setUseSortingGridEncoding(useSortingGrid); + aggCfg.setSupportNegativeValuesInSums(supportNegativeElements); + + SystemConfig cfg = new SystemConfig(); + cfg.setSolverName(DEFAULT_SOLVER_NAME); + cfg.setNogoodStoreName(DEFAULT_NOGOOD_STORE); + cfg.setBranchingHeuristicName(DEFAULT_BRANCHING_HEURISTIC); + cfg.setSeed(0); + cfg.setDebugInternalChecks(DEFAULT_ENABLE_DEBUG_CHECKS); + cfg.setGrounderToleranceRules(DEFAULT_GROUNDER_TOLERANCE); + cfg.setGrounderToleranceConstraints(DEFAULT_GROUNDER_TOLERANCE); + cfg.setGrounderAccumulatorEnabled(DEFAULT_DISABLE_INSTANCE_REMOVAL); + cfg.setAggregateRewritingConfig(aggCfg); + + configsToTest.add(cfg); } } - return configsToTest; } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java index 4e7f4e831..686df4990 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java @@ -32,30 +32,30 @@ public static void runWithTimeout(SystemConfig cfg, long baseTimeout, long timeo } public static Solver buildSolverForRegressionTest(String programString, SystemConfig cfg) { - Alpha alpha = AlphaFactory.newAlpha(cfg); + Alpha alpha = new AlphaFactory().newAlpha(cfg); InputProgram program = alpha.readProgramString(programString); return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); } public static Solver buildSolverForRegressionTest(InputProgram program, SystemConfig cfg) { - Alpha alpha = AlphaFactory.newAlpha(cfg); + Alpha alpha = new AlphaFactory().newAlpha(cfg); return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); } public static Set collectRegressionTestAnswerSets(String program, SystemConfig cfg) { - Alpha alpha = AlphaFactory.newAlpha(cfg); + Alpha alpha = new AlphaFactory().newAlpha(cfg); InputProgram in = alpha.readProgramString(program); return alpha.solve(in).collect(Collectors.toSet()); } public static Set collectRegressionTestAnswerSets(InputProgram program, SystemConfig cfg) { - return AlphaFactory.newAlpha(cfg) + return new AlphaFactory().newAlpha(cfg) .solve(program) .collect(Collectors.toSet()); } private static Set solveForConfig(String programString, SystemConfig cfg) { - Alpha alpha = AlphaFactory.newAlpha(cfg); + Alpha alpha = new AlphaFactory().newAlpha(cfg); InputProgram program = alpha.readProgramString(programString); return alpha.solve(program).collect(Collectors.toSet()); } @@ -80,8 +80,4 @@ public static void ignoreTestForNonDefaultDomainIndependentHeuristics(SystemConf Assumptions.assumeTrue(cfg.getBranchingHeuristic() == Heuristic.VSIDS); } - public static void ignoreTestForStratifiedEvaluationDisabled(SystemConfig cfg) { - Assumptions.assumeTrue(cfg.isEvaluateStratifiedPart()); - } - } From 491390f4cc6c52f386180ad224e391f83f5f2967 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 5 Sep 2022 17:31:35 +0200 Subject: [PATCH 25/59] fix mock implementation for actions --- .../AbstractActionImplementationProvider.java | 20 ++++++++-------- .../MockActionImplementationProvider.java | 13 ++++------- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 12 +++------- .../test/util/MockedActionsAlphaFactory.java | 23 +++++++++++++++++++ .../alpha.java-common-conventions.gradle.kts | 1 + 5 files changed, 43 insertions(+), 26 deletions(-) create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java index cda9a2eea..6079adabe 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java @@ -23,11 +23,8 @@ public abstract class AbstractActionImplementationProvider implements ActionImpl private final IntIdGenerator idGenerator = new IntIdGenerator(); private final Map supportedActions = new HashMap<>(); - private final ConstantTerm stdout = Terms.newConstant( - new OutputStreamHandle(idGenerator.getNextId(), getStdoutStream())); - private final ConstantTerm stdin = Terms.newConstant( - new InputStreamHandle(idGenerator.getNextId(), - new BufferedReader(new InputStreamReader(getStdinStream())))); + private ConstantTerm stdoutHandle; + private ConstantTerm stdinHandle; public AbstractActionImplementationProvider() { registerAction("fileOutputStream", this::openFileOutputStreamAction); @@ -49,13 +46,15 @@ public final Map getSupportedActions() { * Returns a predicate interpretation specifying an external that takes no arguments * and returns a reference to the standard system output stream (stdout). */ - // TODO we need to reuse this term! (do we?? its interned...) public final PredicateInterpretation getStdoutTerm() { + if (stdoutHandle == null) { + stdoutHandle = Terms.newConstant(new OutputStreamHandle(idGenerator.getNextId(), getStdoutStream())); + } return (trms) -> { if (!trms.isEmpty()) { throw new IllegalArgumentException("Invalid method call! Expected term list to be empty!"); } - return Collections.singleton(Collections.singletonList(stdout)); + return Collections.singleton(Collections.singletonList(stdoutHandle)); }; } @@ -63,13 +62,16 @@ public final PredicateInterpretation getStdoutTerm() { * Returns a predicate interpretation specifying an external that takes no arguments * and returns a reference to the standard system input stream (stdin). */ - // TODO we need to reuse this term! (do we?? its interned...) public final PredicateInterpretation getStdinTerm() { + if (stdinHandle == null) { + stdinHandle = Terms.newConstant(new InputStreamHandle(idGenerator.getNextId(), + new BufferedReader(new InputStreamReader(getStdinStream())))); + } return (trms) -> { if (!trms.isEmpty()) { throw new IllegalArgumentException("Invalid method call! Expected term list to be empty!"); } - return Collections.singleton(Collections.singletonList(stdin)); + return Collections.singleton(Collections.singletonList(stdinHandle)); }; } diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java index a31173162..05ea46116 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java @@ -1,12 +1,12 @@ package at.ac.tuwien.kr.alpha.test; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Map; +import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,12 +17,13 @@ public class MockActionImplementationProvider extends AbstractActionImplementati @SuppressWarnings("unused") private static final Logger LOGGER = LoggerFactory.getLogger(MockActionImplementationProvider.class); - private ByteArrayOutputStream stdoutMock = new ByteArrayOutputStream(); - private ByteArrayInputStream stdinMock; + private final ByteArrayOutputStream stdoutMock = new ByteArrayOutputStream(); + private final InputStream stdinMock; private Map mockedFileOutputs; private Map mockedFileInputs; - public MockActionImplementationProvider() { + public MockActionImplementationProvider(String inputBuffer) { + stdinMock = IOUtils.toInputStream(inputBuffer, "UTF-8"); } @Override @@ -38,10 +39,6 @@ public void resetStdoutContent() { stdoutMock.reset(); } - public void setMockInput(String input) { - stdinMock = new ByteArrayInputStream(input.getBytes()); - } - public void setMockedFileOutputs(Map mockedFileOutputs) { this.mockedFileOutputs = mockedFileOutputs; } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index f0a25b778..c17e9dddc 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -1,15 +1,11 @@ package at.ac.tuwien.kr.alpha; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; -import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionServiceImpl; -import at.ac.tuwien.kr.alpha.test.MockActionImplementationProvider; +import at.ac.tuwien.kr.alpha.test.util.MockedActionsAlphaFactory; /** * End-to-end tests covering Evolog action support. @@ -24,11 +20,9 @@ public class ActionsTest { * Simple smoke test which verifies correct behavior of an Evolog "Hello World" program. */ @Test - @Disabled // TODO we need to pass stdin/stdout externals into parser public void helloWorld() { - MockActionImplementationProvider actionMock = new MockActionImplementationProvider(); - ActionExecutionService actionService = new ActionExecutionServiceImpl(actionMock); - Alpha alpha = new AlphaFactory().newAlpha(new SystemConfig()); + MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); + Alpha alpha = alphaFactory.newAlpha(new SystemConfig()); InputProgram program = alpha.readProgramString(HELLO_WORLD); alpha.solve(program); // TODO check mock for correct output content diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java new file mode 100644 index 000000000..82d6863d0 --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java @@ -0,0 +1,23 @@ +package at.ac.tuwien.kr.alpha.test.util; + +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; +import at.ac.tuwien.kr.alpha.test.MockActionImplementationProvider; + +public class MockedActionsAlphaFactory extends AlphaFactory { + + private MockActionImplementationProvider actionImplementationMock = new MockActionImplementationProvider(""); + + public MockActionImplementationProvider getActionImplementationMock() { + return actionImplementationMock; + } + + public void setActionImplementationMock(MockActionImplementationProvider actionImplementationMock) { + this.actionImplementationMock = actionImplementationMock; + } + + protected ActionImplementationProvider newActionImplementationProvider() { + return actionImplementationMock; + } + +} diff --git a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts index 1ccb2d408..423ce31ff 100644 --- a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts @@ -38,6 +38,7 @@ dependencies { testFixturesApi(jupiter("api")) testFixturesApi("org.slf4j:slf4j-api:1.7.32") + testFixturesImplementation("commons-io:commons-io:2.11.0") } // JUnit 5 From efd96e879fd2efe4605513886514f3f11c8c677e Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 6 Sep 2022 13:22:54 +0200 Subject: [PATCH 26/59] fix evolog hello world test --- .../AbstractActionImplementationProvider.java | 3 ++ .../at/ac/tuwien/kr/alpha/ActionsTest.java | 30 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java index 6079adabe..22707f3ed 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java @@ -38,6 +38,7 @@ public AbstractActionImplementationProvider() { /** * Returns a map of all actions supported by this implementation provider. */ + @Override public final Map getSupportedActions() { return supportedActions; } @@ -46,6 +47,7 @@ public final Map getSupportedActions() { * Returns a predicate interpretation specifying an external that takes no arguments * and returns a reference to the standard system output stream (stdout). */ + @Override public final PredicateInterpretation getStdoutTerm() { if (stdoutHandle == null) { stdoutHandle = Terms.newConstant(new OutputStreamHandle(idGenerator.getNextId(), getStdoutStream())); @@ -62,6 +64,7 @@ public final PredicateInterpretation getStdoutTerm() { * Returns a predicate interpretation specifying an external that takes no arguments * and returns a reference to the standard system input stream (stdin). */ + @Override public final PredicateInterpretation getStdinTerm() { if (stdinHandle == null) { stdinHandle = Terms.newConstant(new InputStreamHandle(idGenerator.getNextId(), diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index c17e9dddc..694495ba7 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -1,8 +1,15 @@ package at.ac.tuwien.kr.alpha; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.test.util.MockedActionsAlphaFactory; @@ -14,9 +21,15 @@ public class ActionsTest { private static final String HELLO_WORLD = - "hello_result(RES) : @streamWrite[STDOUT, \" World!\"] = RES :- &stdout(STDOUT)."; + "hello_result(RES) : @streamWrite[STDOUT, \"Hello World!\"] = RES :- &stdout(STDOUT)."; - /** + private static final String WRITE_TO_FILE = + "outfile(\"dummy.file\")." + + "outfile_open_result(F, R) : @fileOutputStream[F] = R :- outfile(F)." + + "outfile_write_result(F, R) : @streamWrite[HD, \"Foo bar!\"] = R :- outfile_open_result(F, success(stream(HD)))." + + "outfile_close_result(F, R) : @outputStreamClose[HD] = R :- outfile_open_result(F, success(stream(HD))), outfile_write_result(F, success(ok))."; + + /** * Simple smoke test which verifies correct behavior of an Evolog "Hello World" program. */ @Test @@ -25,7 +38,18 @@ public void helloWorld() { Alpha alpha = alphaFactory.newAlpha(new SystemConfig()); InputProgram program = alpha.readProgramString(HELLO_WORLD); alpha.solve(program); - // TODO check mock for correct output content + assertEquals("Hello World!", alphaFactory.getActionImplementationMock().getStdoutContent()); + } + + @Test + @Disabled // TODO we need to add our destination file in the mock! + public void writeToFile() { + MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); + Alpha alpha = alphaFactory.newAlpha(new SystemConfig()); + InputProgram program = alpha.readProgramString(WRITE_TO_FILE); + List answerSets = alpha.solve(program).collect(Collectors.toList()); + // TODO check answer set + // TODO check invocation counts } } From 8312dcf9d457a83d0e2c143342bb3adb4558c2ec Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 3 Oct 2022 20:30:09 +0200 Subject: [PATCH 27/59] fix name generation for stream handles --- .../alpha/core/actions/InputStreamHandle.java | 2 +- .../core/actions/OutputStreamHandle.java | 2 +- .../MockActionImplementationProvider.java | 8 ++++ .../at/ac/tuwien/kr/alpha/ActionsTest.java | 42 ++++++++++++------- 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java index 3064ec249..9692e555b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/InputStreamHandle.java @@ -22,7 +22,7 @@ public BufferedReader getStream() { @Override public String toString() { - return "inputStream-" + id; + return "inputStream_" + id; } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java index edbb19184..e6d0d6e92 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/OutputStreamHandle.java @@ -23,7 +23,7 @@ public OutputStream getStream() { @Override public String toString() { - return "outputStream-" + id; + return "outputStream_" + id; } @Override diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java index 05ea46116..d830b6831 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java @@ -47,6 +47,14 @@ public void setMockedFileInputs(Map mockedFileInputs) { this.mockedFileInputs = mockedFileInputs; } + public Map getMockedFileOutputs() { + return mockedFileOutputs; + } + + public Map getMockedFileInputs() { + return mockedFileInputs; + } + @Override protected InputStream getStdinStream() { return stdinMock; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index 694495ba7..4ee979f52 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -1,12 +1,18 @@ package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; -import java.util.List; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; @@ -16,20 +22,19 @@ /** * End-to-end tests covering Evolog action support. - * Note that all tests in this suite depend on stratified evaluation being enabled. */ public class ActionsTest { - private static final String HELLO_WORLD = - "hello_result(RES) : @streamWrite[STDOUT, \"Hello World!\"] = RES :- &stdout(STDOUT)."; + private static final Logger LOGGER = LoggerFactory.getLogger(ActionsTest.class); - private static final String WRITE_TO_FILE = - "outfile(\"dummy.file\")." - + "outfile_open_result(F, R) : @fileOutputStream[F] = R :- outfile(F)." - + "outfile_write_result(F, R) : @streamWrite[HD, \"Foo bar!\"] = R :- outfile_open_result(F, success(stream(HD)))." - + "outfile_close_result(F, R) : @outputStreamClose[HD] = R :- outfile_open_result(F, success(stream(HD))), outfile_write_result(F, success(ok))."; + private static final String HELLO_WORLD = "hello_result(RES) : @streamWrite[STDOUT, \"Hello World!\"] = RES :- &stdout(STDOUT)."; - /** + private static final String WRITE_TO_FILE = "outfile(\"dummy.file\")." + + "outfile_open_result(F, R) : @fileOutputStream[F] = R :- outfile(F)." + + "outfile_write_result(F, R) : @streamWrite[HD, \"Foo bar!\"] = R :- outfile_open_result(F, success(stream(HD)))." + + "outfile_close_result(F, R) : @outputStreamClose[HD] = R :- outfile_open_result(F, success(stream(HD))), outfile_write_result(F, success(ok))."; + + /** * Simple smoke test which verifies correct behavior of an Evolog "Hello World" program. */ @Test @@ -42,14 +47,21 @@ public void helloWorld() { } @Test - @Disabled // TODO we need to add our destination file in the mock! public void writeToFile() { + Map mockedFileOutputs = new HashMap<>(); + ByteArrayOutputStream dummyFileContent = new ByteArrayOutputStream(); + mockedFileOutputs.put("dummy.file", dummyFileContent); MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); + alphaFactory.getActionImplementationMock().setMockedFileOutputs(mockedFileOutputs); Alpha alpha = alphaFactory.newAlpha(new SystemConfig()); InputProgram program = alpha.readProgramString(WRITE_TO_FILE); - List answerSets = alpha.solve(program).collect(Collectors.toList()); - // TODO check answer set - // TODO check invocation counts + Set answerSets = alpha.solve(program).collect(Collectors.toSet()); + LOGGER.debug("Got answer sets: {}", answerSets); + assertAnswerSetsEqual( + "outfile(\"dummy.file\"), outfile_open_result(\"dummy.file\", success(stream(outputStream_2)))," + + " outfile_write_result(\"dummy.file\", success(ok)), outfile_close_result(\"dummy.file\", success(ok))", + answerSets); + assertEquals("Foo bar!", dummyFileContent.toString()); } } From db5544fadb92f0317dbe406d0adc862abf1a5b6f Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 12 Oct 2022 10:14:37 +0200 Subject: [PATCH 28/59] unit tests for actions --- .../src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index 4ee979f52..37c49a1ba 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -10,6 +10,7 @@ import java.util.Set; import java.util.stream.Collectors; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +48,7 @@ public void helloWorld() { } @Test + @Disabled public void writeToFile() { Map mockedFileOutputs = new HashMap<>(); ByteArrayOutputStream dummyFileContent = new ByteArrayOutputStream(); @@ -59,7 +61,7 @@ public void writeToFile() { LOGGER.debug("Got answer sets: {}", answerSets); assertAnswerSetsEqual( "outfile(\"dummy.file\"), outfile_open_result(\"dummy.file\", success(stream(outputStream_2)))," - + " outfile_write_result(\"dummy.file\", success(ok)), outfile_close_result(\"dummy.file\", success(ok))", + + " outfile_write_result(\"dummy.file\", success(ok)), outfile_close_result(\"dummy.file\", success(ok))", answerSets); assertEquals("Foo bar!", dummyFileContent.toString()); } From 782c338ddd859cbbb2084054ac3a820ac737954f Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 1 Dec 2023 15:14:44 +0100 Subject: [PATCH 29/59] fix ParserTest - use updated type name InputProgram instead of ASPCore2Program --- .../test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 05f88a7b1..f900a5047 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -198,7 +198,7 @@ public void testMissingDotNotIgnored() { @Test public void parseEnumerationDirective() { - ASPCore2Program parsedProgram = parser.parse("p(a,1)." + + InputProgram parsedProgram = parser.parse("p(a,1)." + "# enumeration_predicate_is mune." + "r(X) :- p(X), mune(X)." + "p(b,2)."); From c7ec4939b0f8837714fcb58be6706ea01c089962 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sun, 10 Dec 2023 19:40:53 +0100 Subject: [PATCH 30/59] fix FunctionTermImpl#equals s.t. also subtypes can be equal --- .../commons/rules/heads/ActionHeadImpl.java | 5 ++++ .../alpha/commons/terms/FunctionTermImpl.java | 23 +++++++++++-------- .../kr/alpha/commons/terms/TermsTest.java | 12 ++++++++++ .../core/grounder/IndexedInstanceStorage.java | 3 ++- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java index f64ca535b..dd1d5ee3d 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/rules/heads/ActionHeadImpl.java @@ -9,6 +9,7 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import org.apache.commons.lang3.StringUtils; class ActionHeadImpl implements ActionHead { @@ -55,4 +56,8 @@ public VariableTerm getActionOutputTerm() { return actionOutputTerm; } + public String toString() { + return atom.toString() + " : @" + actionName + "(" + StringUtils.join(actionInputTerms, ", ") + ") = " + actionOutputTerm; + } + } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java index 694905e48..a5d605cc8 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java @@ -98,16 +98,19 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (o == null || getClass() != o.getClass()) { + if (o == null) { + return false; + } + if (!(o instanceof FunctionTerm)) { return false; } - FunctionTermImpl that = (FunctionTermImpl) o; + FunctionTerm that = (FunctionTerm) o; - if (!symbol.equals(that.symbol)) { + if (!symbol.equals(that.getSymbol())) { return false; } - return terms.equals(that.terms); + return terms.equals(that.getTerms()); } @Override @@ -121,24 +124,24 @@ public int compareTo(Term o) { return 0; } - if (!(o instanceof FunctionTermImpl)) { + if (!(o instanceof FunctionTerm)) { return super.compareTo(o); } - FunctionTermImpl other = (FunctionTermImpl) o; + FunctionTerm other = (FunctionTerm) o; - if (terms.size() != other.terms.size()) { - return terms.size() - other.terms.size(); + if (terms.size() != other.getTerms().size()) { + return terms.size() - other.getTerms().size(); } - int result = symbol.compareTo(other.symbol); + int result = symbol.compareTo(other.getSymbol()); if (result != 0) { return result; } for (int i = 0; i < terms.size(); i++) { - result = terms.get(i).compareTo(other.terms.get(i)); + result = terms.get(i).compareTo(other.getTerms().get(i)); if (result != 0) { return result; } diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java index 4c4600dc8..cf361a41a 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java @@ -4,6 +4,7 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; @@ -30,4 +31,15 @@ public void stringsAsTermList() { assertEquals("\"blubb\"", terms.get(1).toString()); } + /** + * Reproduction test for an error observed while testing evolog actions. + */ + @Test + public void functionTermVsActionSuccessTermHash() { + FunctionTerm funcTerm = Terms.newFunctionTerm("success", Terms.newFunctionTerm("stream", Terms.newConstant("outputStream_2"))); + FunctionTerm actionSuccessTerm = Terms.actionSuccess(Terms.newFunctionTerm("stream", Terms.newConstant("outputStream_2"))); + assertEquals(funcTerm, actionSuccessTerm); + assertEquals(funcTerm.hashCode(), actionSuccessTerm.hashCode()); + } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorage.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorage.java index 2be5302a5..2fe7b710a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorage.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorage.java @@ -112,7 +112,8 @@ public void removeIndexPosition(int position) { * @return true if the instance is already contained in the storage. */ public boolean containsInstance(Instance instance) { - return instances.contains(instance); + boolean contains = instances.contains(instance); + return contains; // TODO remove extra variable, debugging only } public void addInstance(Instance instance) { From 8d864458343f10771ccc6b2610446f9c0e86f221 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 9 Jan 2024 21:14:51 +0100 Subject: [PATCH 31/59] Fix ActionsTest: check answer set content for answer set of write file program. --- .../tuwien/kr/alpha/commons/AnswerSets.java | 4 ++ .../core/actions/OutputStreamHandle.java | 2 + .../MockActionImplementationProvider.java | 4 +- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 64 +++++++++++++++++-- 4 files changed, 67 insertions(+), 7 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AnswerSets.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AnswerSets.java index 0587e51d8..6b22bbaaf 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AnswerSets.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AnswerSets.java @@ -19,4 +19,8 @@ public static AnswerSet newAnswerSet(SortedSet predicates, Map or some such public class OutputStreamHandle implements Comparable { private final int id; diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java index d830b6831..affe5f555 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/MockActionImplementationProvider.java @@ -61,7 +61,7 @@ protected InputStream getStdinStream() { } @Override - protected OutputStream getFileOutputStream(String path) throws IOException { + public OutputStream getFileOutputStream(String path) throws IOException { if (mockedFileOutputs.containsKey(path)) { return mockedFileOutputs.get(path); } @@ -69,7 +69,7 @@ protected OutputStream getFileOutputStream(String path) throws IOException { } @Override - protected InputStream getInputStream(String path) throws IOException { + public InputStream getInputStream(String path) throws IOException { if (mockedFileInputs.containsKey(path)) { return mockedFileInputs.get(path); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index 37c49a1ba..85cad097d 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -2,14 +2,35 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayOutputStream; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.AnswerSetQuery; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.AnswerSets; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.util.AnswerSetQueryImpl; +import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; +import at.ac.tuwien.kr.alpha.core.actions.OutputStreamHandle; +import at.ac.tuwien.kr.alpha.test.AlphaAssertions; +import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; +import com.ibm.icu.impl.Assert; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -48,21 +69,54 @@ public void helloWorld() { } @Test - @Disabled + //@Disabled + @SuppressWarnings("unchecked") public void writeToFile() { Map mockedFileOutputs = new HashMap<>(); ByteArrayOutputStream dummyFileContent = new ByteArrayOutputStream(); mockedFileOutputs.put("dummy.file", dummyFileContent); MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); alphaFactory.getActionImplementationMock().setMockedFileOutputs(mockedFileOutputs); + ActionImplementationProvider actionProvider = alphaFactory.getActionImplementationMock(); Alpha alpha = alphaFactory.newAlpha(new SystemConfig()); InputProgram program = alpha.readProgramString(WRITE_TO_FILE); Set answerSets = alpha.solve(program).collect(Collectors.toSet()); LOGGER.debug("Got answer sets: {}", answerSets); - assertAnswerSetsEqual( - "outfile(\"dummy.file\"), outfile_open_result(\"dummy.file\", success(stream(outputStream_2)))," - + " outfile_write_result(\"dummy.file\", success(ok)), outfile_close_result(\"dummy.file\", success(ok))", - answerSets); + assertEquals(1, answerSets.size()); + AnswerSet answerSet = answerSets.stream().findFirst().get(); + /* + * Note: We have to check answer set content here because we have no way of constructing an equal instance for + * the outputStreamHandle that is constructed when execution the "fileOutputStream" action. * + */ + assertEquals(1, answerSet.query(AnswerSetQueryImpl.forPredicate(Predicates.getPredicate("outfile_open_result", 2)) + .withFilter(0, term -> term instanceof ConstantTerm && ((ConstantTerm) term).getObject().endsWith("dummy.file")) + .withFunctionTerm(1, "success", 1) + .withFilter(1, (term) -> { + FunctionTerm funcTerm = (FunctionTerm) term; + assertEquals(1, funcTerm.getTerms().size()); + assertTrue(funcTerm.getTerms().get(0) instanceof FunctionTerm && ((FunctionTerm) funcTerm.getTerms().get(0)).getSymbol().equals("stream")); + ConstantTerm streamTerm = (ConstantTerm) ((FunctionTerm) funcTerm.getTerms().get(0)).getTerms().get(0); + return streamTerm.getObject() instanceof OutputStreamHandle; + }) + ).size()); + assertEquals(1, answerSet.query(AnswerSetQueryImpl.forPredicate(Predicates.getPredicate("outfile_write_result", 2)) + .withFilter(0, term -> term instanceof ConstantTerm && ((ConstantTerm) term).getObject().endsWith("dummy.file")) + .withFunctionTerm(1, "success", 1) + .withFilter(1, (term) -> { + FunctionTerm funcTerm = (FunctionTerm) term; + assertEquals(1, funcTerm.getTerms().size()); + return funcTerm.getTerms().get(0) instanceof ConstantTerm && ((ConstantTerm) funcTerm.getTerms().get(0)).getObject().equals("ok"); + }) + ).size()); + assertEquals(1, answerSet.query(AnswerSetQueryImpl.forPredicate(Predicates.getPredicate("outfile_close_result", 2)) + .withFilter(0, term -> term instanceof ConstantTerm && ((ConstantTerm) term).getObject().endsWith("dummy.file")) + .withFunctionTerm(1, "success", 1) + .withFilter(1, (term) -> { + FunctionTerm funcTerm = (FunctionTerm) term; + assertEquals(1, funcTerm.getTerms().size()); + return funcTerm.getTerms().get(0) instanceof ConstantTerm && ((ConstantTerm) funcTerm.getTerms().get(0)).getObject().equals("ok"); + }) + ).size()); assertEquals("Foo bar!", dummyFileContent.toString()); } From 0bb76b19067bf97f21a28f665817514249c8c6bd Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 9 Jan 2024 21:21:48 +0100 Subject: [PATCH 32/59] Fix checkstyle violations --- .../java/at/ac/tuwien/kr/alpha/ActionsTest.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index 85cad097d..1ddfaa7cc 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -1,37 +1,21 @@ package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; -import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayOutputStream; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.api.AnswerSetQuery; -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; -import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.AnswerSets; import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.AnswerSetQueryImpl; import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.actions.OutputStreamHandle; -import at.ac.tuwien.kr.alpha.test.AlphaAssertions; -import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; -import com.ibm.icu.impl.Assert; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; From 01c70382d75197166dabb651faf5bf742219ab47 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 11 Jan 2024 21:39:58 +0100 Subject: [PATCH 33/59] add simple evolog examples --- examples/greet-me.evl | 7 +++++++ examples/write_something.evl | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 examples/greet-me.evl create mode 100644 examples/write_something.evl diff --git a/examples/greet-me.evl b/examples/greet-me.evl new file mode 100644 index 000000000..8bf5bdcda --- /dev/null +++ b/examples/greet-me.evl @@ -0,0 +1,7 @@ +prompt_text("Hello user, what's your name? "). +write_prompt_res(R) : @streamWrite[STDOUT, PROMPT] = R :- prompt_text(PROMPT), &stdout(STDOUT). +usr_input_res(INP) : @streamReadLine[STDIN] = INP :- write_prompt_res(success(_)), &stdin(STDIN). +write_greeting_res(R) : @streamWrite[STDOUT, GREETING] = R :- + usr_input_res(success(line(NAME))), + &stdlib_string_concat["Hello, it is the utmost pleasure to finally greet you from an Evolog program, ", NAME](GREETING), + &stdout(STDOUT). diff --git a/examples/write_something.evl b/examples/write_something.evl new file mode 100644 index 000000000..cb113762b --- /dev/null +++ b/examples/write_something.evl @@ -0,0 +1,9 @@ +outfile("/home/michael/asp_snippets/evolog-actions/hello.out"). + +open_result(PATH, RES) : @fileOutputStream[PATH] = RES :- outfile(PATH). + +write_result(PATH, RES) : @streamWrite[STREAM, "HelloEvologWorld!"] = RES :- open_result(PATH, success(stream(STREAM))), outfile(PATH). + +can_close(PATH, FD) :- write_result(PATH, success(ok)), open_result(PATH, success(stream(FD))), outfile(PATH). + +close_result(PATH, RES) : @outputStreamClose[STREAM] = RES :- write_result(PATH, success(ok)), open_result(PATH, success(stream(STREAM))), outfile(PATH). From 8191e8979a37e1ce5bffa3598420dcd6917ac6a8 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sun, 26 May 2024 17:25:31 +0200 Subject: [PATCH 34/59] WIP: merge action implementation back into state from master --- .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 26 ++--- .../at/ac/tuwien/kr/alpha/api/AnswerSet.java | 2 +- .../alpha/api/programs/ASPCore2Program.java | 21 ---- .../kr/alpha/api/programs/InputProgram.java | 13 ++- .../api/programs/rules/RuleInstantiator.java | 11 ++ .../api/programs/rules/heads/ActionHead.java | 16 +++ .../rules/heads/InstantiableHead.java | 11 ++ .../api/programs/terms/ActionResultTerm.java | 30 +++++ .../alpha/api/programs/tests/Assertion.java | 4 +- .../commons/programs/ASPCore2ProgramImpl.java | 5 +- .../kr/alpha/commons/programs/Programs.java | 22 ++-- .../alpha/commons/programs/rules/Rules.java | 11 +- .../programs/rules/heads/ActionHeadImpl.java | 63 +++++++++++ .../commons/programs/rules/heads/Heads.java | 6 + .../programs/rules/heads/NormalHeadImpl.java | 7 ++ .../terms/AbstractActionResultTerm.java | 26 +++++ .../programs/terms/ActionErrorTerm.java | 24 ++++ .../programs/terms/ActionSuccessTerm.java | 25 +++++ .../alpha/commons/programs/terms/Terms.java | 17 +-- .../ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 | 4 +- ...gramParser.java => ProgramParserImpl.java} | 20 ++-- .../core/programs/rules/InternalRule.java | 106 +++--------------- ...mer.java => ArithmeticTermsRewriting.java} | 20 ++-- ...ormalizer.java => ChoiceHeadToNormal.java} | 5 +- 24 files changed, 320 insertions(+), 175 deletions(-) delete mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{AbstractProgramParser.java => ProgramParserImpl.java} (84%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{ArithmeticTermTransformer.java => ArithmeticTermsRewriting.java} (89%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{ChoiceHeadNormalizer.java => ChoiceHeadToNormal.java} (96%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java index 2cc01b42a..74ef89dac 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java @@ -28,18 +28,18 @@ public interface Alpha { * * @param cfg and {@link InputConfig} specifying program sources (strings, files) as well as config metadata (e.g. literate program, * external atoms, etc) - * @return an {@link ASPCore2Program} representing the parsed ASP code from all sources referenced in the given {@link InputConfig} + * @return an {@link InputProgram} representing the parsed ASP code from all sources referenced in the given {@link InputConfig} * @throws IOException in case one or more program sources (e.g. files) cannot be read, or parsing fails */ InputProgram readProgram(InputConfig cfg) throws IOException; /** - * Reads and parses an {@link ASPCore2Program} from a list of {@link String}s representing paths. + * Reads and parses an {@link InputProgram} from a list of {@link String}s representing paths. * * @param literate flag indicating whether ASP code should be treated as "literate". * @param externals Custom {@link PredicateInterpretation}s for user-defined external atoms * @param paths a list of {@link String}s representing paths containing all sources from which ASP code should be read - * @return an {@link ASPCore2Program} representing the parsed ASP code from all given path strings + * @return an {@link InputProgram} representing the parsed ASP code from all given path strings * @throws IOException in case one or more program sources cannot be read, or parsing fails */ InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException; @@ -50,12 +50,12 @@ public interface Alpha { InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; /** - * Parses a given String into an {@link ASPCore2Program}, using a map of custom {@link PredicateInterpretation}s to resolve external atoms + * Parses a given String into an {@link InputProgram}, using a map of custom {@link PredicateInterpretation}s to resolve external atoms * in ASP code. * * @param aspString a string representing a valid ASP-Core2 program * @param externals a map of custom {@link PredicateInterpretation}s against which external atoms in the given code are resolved - * @return an {@link ASPCore2Program} representing the parsed ASP code + * @return an {@link InputProgram} representing the parsed ASP code */ InputProgram readProgramString(String aspString, Map externals); @@ -75,7 +75,7 @@ public interface Alpha { InputProgram readProgramStream(InputStream is, Map externals) throws IOException; /** - * Prepares a {@link DebugSolvingContext} for the given {@link ASPCore2Program} to debug program preprocessing. + * Prepares a {@link DebugSolvingContext} for the given {@link InputProgram} to debug program preprocessing. * * @return a {@link DebugSolvingContext} holding debug information for the given program */ @@ -89,7 +89,7 @@ public interface Alpha { DebugSolvingContext prepareDebugSolve(final NormalProgram program); /** - * Prepares a {@link DebugSolvingContext} for the given {@link ASPCore2Program} to debug program preprocessing. + * Prepares a {@link DebugSolvingContext} for the given {@link InputProgram} to debug program preprocessing. * * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link DebugSolvingContext} holding debug information for the given program @@ -105,7 +105,7 @@ public interface Alpha { DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.util.function.Predicate filter); /** - * Solves the given {@link ASPCore2Program}. + * Solves the given {@link InputProgram}. * * @param program an input program * @return a {@link Stream} of {@link AnswerSet}s of the given program @@ -113,7 +113,7 @@ public interface Alpha { Stream solve(InputProgram program); /** - * Solves the given {@link ASPCore2Program}. + * Solves the given {@link InputProgram}. * * @param program an input program * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. @@ -143,13 +143,13 @@ public interface Alpha { * code. * See {@link NormalProgram}, * - * @param program An {@link ASPCore2Program} to normalize + * @param program An {@link InputProgram} to normalize * @return a {@link NormalProgram} that is a semantic equivalent to the given input program */ NormalProgram normalizeProgram(InputProgram program); /** - * Constructs a @{link Solver} pre-loaded with the given {@link ASPCore2Program} from which {@link AnswerSet}s can be obtained via + * Constructs a @{link Solver} pre-loaded with the given {@link InputProgram} from which {@link AnswerSet}s can be obtained via * {@link Solver#stream()}. * * @param program the program to solve @@ -174,11 +174,11 @@ public interface Alpha { * @param program an ASP program to reify * @return a set of {@link BasicAtom}s encoding the given program */ - Set reify(ASPCore2Program program); + Set reify(InputProgram program); /** * Runs all test cases of the given program. */ - TestResult test(ASPCore2Program program); + TestResult test(InputProgram program); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java index 1015fb833..8b80fc9ef 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java @@ -32,7 +32,7 @@ public interface AnswerSet extends Comparable { boolean isEmpty(); /** - * List {@link Atom}s in this answer set satisfying the given {@link AnswerSetQuery}. + * List {@link Atom}s in this answer set satisfying the given {@link AtomQuery}. */ List query(AtomQuery query); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java deleted file mode 100644 index fa444b184..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java +++ /dev/null @@ -1,21 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.programs; - -import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; -import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; -import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; - -import java.util.List; - -/** - * A {@link Program} that conforms to Alphas implementation of the ASP-Core2-Standard. - * - * Copyright (c) 2021, the Alpha Team. - */ -public interface ASPCore2Program extends Program> { - - /** - * The test cases associated with this program. - */ - List getTestCases(); - -} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java index c7be5bd2f..f9fe5122f 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java @@ -1,9 +1,16 @@ package at.ac.tuwien.kr.alpha.api.programs; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; + +import java.util.List; -// TODO javadoc public interface InputProgram extends Program> { + /** + * The test cases associated with this program. + */ + List getTestCases(); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java new file mode 100644 index 000000000..74646f00d --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java @@ -0,0 +1,11 @@ +package at.ac.tuwien.kr.alpha.api.programs.rules; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.InstantiableHead; + +public interface RuleInstantiator { + + BasicAtom instantiate(InstantiableHead ruleHead, Substitution substitution); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java new file mode 100644 index 000000000..744531317 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java @@ -0,0 +1,16 @@ +package at.ac.tuwien.kr.alpha.api.programs.rules.heads; + +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; + +import java.util.List; + +public interface ActionHead extends NormalHead { + + String getActionName(); + + List getActionInputTerms(); + + VariableTerm getActionOutputTerm(); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java new file mode 100644 index 000000000..82aa89343 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java @@ -0,0 +1,11 @@ +package at.ac.tuwien.kr.alpha.api.programs.rules.heads; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.programs.rules.RuleInstantiator; + +public interface InstantiableHead extends Head { + + BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java new file mode 100644 index 000000000..28fc53769 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java @@ -0,0 +1,30 @@ +package at.ac.tuwien.kr.alpha.api.programs.terms; + + /** + * A term representing the result of an evolog action (i.e. result of action function application). + * Action result terms are function terms with symbol "success" or "error" depending on whether the corresponding action was sucessful. + * There is always one argument which is either some term representing the actual function result or an error message, respectively. + */ +public interface ActionResultTerm extends FunctionTerm { + + public static final String SUCCESS_SYMBOL = "success"; + public static final String ERROR_SYMBOL = "error"; + + /** + * True if the action that generated this result was successful (i.e. executed normally). + */ + boolean isSuccess(); + + /** + * True if the action that generated this result failed (i.e. threw an error in execution). + */ + boolean isError(); + + /** + * Gets the actual value wrapped in this result. + * Either a term representing the action return value or a string term representing an error + * message.s + */ + T getValue(); + +} \ No newline at end of file diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/tests/Assertion.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/tests/Assertion.java index 70da34ddc..4acf1e5f8 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/tests/Assertion.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/tests/Assertion.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.api.programs.tests; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; public interface Assertion { @@ -23,7 +23,7 @@ public String toString() { Mode getMode(); - ASPCore2Program getVerifier(); + InputProgram getVerifier(); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/ASPCore2ProgramImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/ASPCore2ProgramImpl.java index 32c5ccacf..c67097ed3 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/ASPCore2ProgramImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/ASPCore2ProgramImpl.java @@ -27,8 +27,8 @@ */ package at.ac.tuwien.kr.alpha.commons.programs; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; @@ -43,7 +43,8 @@ *

* Copyright (c) 2017-2019, the Alpha Team. */ -class ASPCore2ProgramImpl extends AbstractProgram> implements ASPCore2Program{ +// TODO rename this to InputProgramImpl or some such +class ASPCore2ProgramImpl extends AbstractProgram> implements InputProgram { static final ASPCore2ProgramImpl EMPTY = new ASPCore2ProgramImpl(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl(), Collections.emptyList()); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java index e42a486fe..460231815 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java @@ -6,6 +6,7 @@ import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; @@ -20,15 +21,17 @@ private Programs() { throw new AssertionError("Cannot instantiate utility class!"); } - public static ASPCore2Program emptyProgram() { + public static InputProgram emptyProgram() { return ASPCore2ProgramImpl.EMPTY; } - public static ASPCore2Program newASPCore2Program(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { + // TODO rename method + public static InputProgram newASPCore2Program(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { return new ASPCore2ProgramImpl(rules, facts, inlineDirectives, testCases); } - public static ASPCore2Program newASPCore2Program(List> rules, List facts, InlineDirectives inlineDirectives) { + // TODO rename method + public static InputProgram newASPCore2Program(List> rules, List facts, InlineDirectives inlineDirectives) { return new ASPCore2ProgramImpl(rules, facts, inlineDirectives, Collections.emptyList()); } @@ -36,7 +39,7 @@ public static ASPCore2ProgramBuilder builder() { return new ASPCore2ProgramBuilder(); } - public static ASPCore2ProgramBuilder builder(ASPCore2Program program) { + public static ASPCore2ProgramBuilder builder(InputProgram program) { return new ASPCore2ProgramBuilder(program); } @@ -44,7 +47,7 @@ public static NormalProgram newNormalProgram(List rules, List return new NormalProgramImpl(rules, facts, inlineDirectives); } - public static NormalProgram toNormalProgram(ASPCore2Program inputProgram) { + public static NormalProgram toNormalProgram(InputProgram inputProgram) { List normalRules = new ArrayList<>(); for (Rule r : inputProgram.getRules()) { normalRules.add(Rules.toNormalRule(r)); @@ -57,8 +60,9 @@ public static InlineDirectives newInlineDirectives() { } /** - * Builder for more complex program construction scenarios, ensuring that an {@link AspCore2ProgramImpl} is immutable + * Builder for more complex program construction scenarios, ensuring that an {@link ASPCore2ProgramImpl} is immutable */ + // TODO maybe rename public static class ASPCore2ProgramBuilder { private List> rules = new ArrayList<>(); @@ -67,7 +71,7 @@ public static class ASPCore2ProgramBuilder { private List testCases = new ArrayList<>(); - public ASPCore2ProgramBuilder(ASPCore2Program prog) { + public ASPCore2ProgramBuilder(InputProgram prog) { this.addRules(prog.getRules()); this.addFacts(prog.getFacts()); this.addInlineDirectives(prog.getInlineDirectives()); @@ -113,11 +117,11 @@ public ASPCore2ProgramBuilder addTestCases(List testCases) { return this; } - public ASPCore2ProgramBuilder accumulate(ASPCore2Program prog) { + public ASPCore2ProgramBuilder accumulate(InputProgram prog) { return this.addRules(prog.getRules()).addFacts(prog.getFacts()).addInlineDirectives(prog.getInlineDirectives()).addTestCases(prog.getTestCases()); } - public ASPCore2Program build() { + public InputProgram build() { return Programs.newASPCore2Program(this.rules, this.facts, this.inlineDirectives, this.testCases); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java index dc0396863..3d04c53f9 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -23,10 +24,7 @@ public static Rule newRule(Head head, List body) { } public static Rule newRule(Head head, Literal... body) { - List bodyLst = new ArrayList<>(); - for (Literal lit : body) { - bodyLst.add(lit); - } + List bodyLst = new ArrayList<>(Arrays.asList(body)); return new BasicRule(head, bodyLst); } @@ -35,10 +33,7 @@ public static NormalRule newNormalRule(NormalHead head, List body) { } public static NormalRule newNormalRule(NormalHead head, Literal... body) { - List bodyLst = new ArrayList<>(); - for (Literal lit : body) { - bodyLst.add(lit); - } + List bodyLst = new ArrayList<>(Arrays.asList(body)); return new NormalRuleImpl(head, bodyLst); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java new file mode 100644 index 000000000..46a598442 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java @@ -0,0 +1,63 @@ +package at.ac.tuwien.kr.alpha.commons.programs.rules.heads; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.programs.rules.RuleInstantiator; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ActionHead; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collections; +import java.util.List; + +class ActionHeadImpl implements ActionHead { + + private final BasicAtom atom; + private final String actionName; + private final List actionInputTerms; + private final VariableTerm actionOutputTerm; + + ActionHeadImpl(BasicAtom atom, String actionName, List actionInputTerms, VariableTerm actionOutputTerm) { + this.atom = atom; + this.actionName = actionName; + this.actionInputTerms = Collections.unmodifiableList(actionInputTerms); + this.actionOutputTerm = actionOutputTerm; + } + + @Override + public BasicAtom getAtom() { + return atom; + } + + @Override + public boolean isGround() { + // TODO: an action head is conceptually a basic one with an (interpreted) function term + return false; + } + + @Override + public BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution) { + return instantiator.instantiate(this, substitution); + } + + @Override + public String getActionName() { + return actionName; + } + + @Override + public List getActionInputTerms() { + return actionInputTerms; + } + + @Override + public VariableTerm getActionOutputTerm() { + return actionOutputTerm; + } + + public String toString() { + return atom.toString() + " : @" + actionName + "(" + StringUtils.join(actionInputTerms, ", ") + ") = " + actionOutputTerm; + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java index 6e7aeebf1..3ebf81b63 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java @@ -5,10 +5,12 @@ import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ChoiceHead; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ChoiceHead.ChoiceElement; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.ChoiceHeadImpl.ChoiceElementImpl; public final class Heads { @@ -29,5 +31,9 @@ public static ChoiceHead newChoiceHead(List choiceElements, Term public static ChoiceElement newChoiceElement(BasicAtom choiceAtom, List conditionLiterals) { return new ChoiceElementImpl(choiceAtom, conditionLiterals); } + + public static ActionHead newActionHead(BasicAtom atom, String actionName, List actionInputTerms, VariableTerm actionResult) { + return new ActionHeadImpl(atom, actionName, actionInputTerms, actionResult); + } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/NormalHeadImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/NormalHeadImpl.java index 7bae74aba..1422d8e75 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/NormalHeadImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/NormalHeadImpl.java @@ -1,6 +1,8 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules.heads; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.api.programs.rules.RuleInstantiator; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; /** @@ -26,6 +28,11 @@ public BasicAtom getAtom() { return atom; } + @Override + public BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution) { + return instantiator.instantiate(this, substitution); + } + @Override public String toString() { return atom.toString(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java new file mode 100644 index 000000000..9a94e942d --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java @@ -0,0 +1,26 @@ +package at.ac.tuwien.kr.alpha.commons.programs.terms; + +import at.ac.tuwien.kr.alpha.api.programs.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; + +import java.util.Collections; + +abstract class AbstractActionResultTerm extends FunctionTermImpl implements ActionResultTerm { + + AbstractActionResultTerm(String symbol, T value) { + super(symbol, Collections.singletonList(value)); + } + + public abstract boolean isSuccess(); + + public boolean isError() { + return !isSuccess(); + } + + // Note: Unchecked cast is ok, we permit only instances of T as constructor arguments. + @SuppressWarnings("unchecked") + public T getValue() { + return (T) getTerms().get(0); + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java new file mode 100644 index 000000000..683b640c1 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java @@ -0,0 +1,24 @@ +package at.ac.tuwien.kr.alpha.commons.programs.terms; + +import at.ac.tuwien.kr.alpha.api.programs.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.util.Interner; + +class ActionErrorTerm extends AbstractActionResultTerm> { + + private static final Interner INTERNER = new Interner<>(); + + ActionErrorTerm(ConstantTerm value) { + super(ActionResultTerm.ERROR_SYMBOL, value); + } + + public static ActionErrorTerm getInstance(ConstantTerm term) { + return INTERNER.intern(new ActionErrorTerm(term)); + } + + @Override + public boolean isSuccess() { + return false; + } + +} \ No newline at end of file diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java new file mode 100644 index 000000000..2c4d7ddfd --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java @@ -0,0 +1,25 @@ +package at.ac.tuwien.kr.alpha.commons.programs.terms; + +import at.ac.tuwien.kr.alpha.api.programs.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.commons.util.Interner; + +class ActionSuccessTerm extends AbstractActionResultTerm { + + private static final Interner> INTERNER = new Interner<>(); + + ActionSuccessTerm(T value) { + super(ActionResultTerm.SUCCESS_SYMBOL, value); + } + + @SuppressWarnings("unchecked") + public static ActionSuccessTerm getInstance(T term) { + return (ActionSuccessTerm) INTERNER.intern(new ActionSuccessTerm<>(term)); + } + + @Override + public boolean isSuccess() { + return true; + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java index d38088b6b..7d0ac9971 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java @@ -5,13 +5,7 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.programs.terms.ArithmeticOperator; -import at.ac.tuwien.kr.alpha.api.programs.terms.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.api.programs.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.api.programs.terms.Term; -import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.*; import at.ac.tuwien.kr.alpha.commons.programs.terms.ArithmeticTermImpl.MinusTerm; import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; @@ -70,6 +64,15 @@ public static IntervalTerm newIntervalTerm(Term lowerBound, Term upperBound) { return IntervalTermImpl.getInstance(lowerBound, upperBound); } + public static ActionResultTerm actionSuccess(T value) { + return ActionSuccessTerm.getInstance(value); + } + + public static ActionResultTerm> actionError(String errMsg) { + return ActionErrorTerm.getInstance(Terms.newConstant(errMsg)); + } + + @SafeVarargs public static > List> asTermList(T... values) { List> retVal = new ArrayList<>(); diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 index 44039084e..bbd952cad 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 @@ -20,7 +20,9 @@ statement : head DOT # statement_fact | WCONS body? DOT SQUARE_OPEN weight_at_level SQUARE_CLOSE # statement_weightConstraint | directive # statement_directive; // NOT Core2 syntax. -head : disjunction | choice; +head : disjunction | choice | action; + +action: classical_literal COLON AT ID SQUARE_OPEN terms SQUARE_CLOSE EQUAL variable_term; // NOT Core2 syntax body : ( naf_literal | aggregate ) (COMMA body)?; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java similarity index 84% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java index cc63f903d..64e36c247 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/AbstractProgramParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; @@ -17,12 +18,9 @@ import org.antlr.v4.runtime.misc.ParseCancellationException; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.programs.Programs; import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; -import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.core.externals.Externals; public class ProgramParserImpl implements ProgramParser { @@ -39,12 +37,12 @@ public ProgramParserImpl(Map externals) { } @Override - public ASPCore2Program parse(String s) { + public InputProgram parse(String s) { return parse(s, Collections.emptyMap()); } @Override - public ASPCore2Program parse(String s, Map externals) { + public InputProgram parse(String s, Map externals) { try { return parse(CharStreams.fromString(s), externals); } catch (RecognitionException | ParseCancellationException e) { @@ -55,11 +53,11 @@ public ASPCore2Program parse(String s, Map exte } } - public ASPCore2Program parse(CharStream stream) { + public InputProgram parse(CharStream stream) { return parse(stream, Collections.emptyMap()); } - public ASPCore2Program parse(CharStream stream, Map externals) { + public InputProgram parse(CharStream stream, Map externals) { //@formatter:off /* * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. @@ -132,17 +130,17 @@ public ASPCore2Program parse(CharStream stream, Map externalPredicateDefinitions) throws IOException { + public InputProgram parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException { return parse(CharStreams.fromStream(programSource), externalPredicateDefinitions); } @Override - public ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions) throws IOException { + public InputProgram parse(Path programPath, Map externalPredicateDefinitions) throws IOException { return parse(CharStreams.fromPath(programPath), externalPredicateDefinitions); } @Override - public ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { + public InputProgram parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { ASPCore2ProgramBuilder bld = Programs.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); @@ -151,7 +149,7 @@ public ASPCore2Program parse(Map externalPredic } @Override - public ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { + public InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { ASPCore2ProgramBuilder bld = Programs.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java index fb998a297..8b57907f2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java @@ -25,37 +25,18 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -<<<<<<<< HEAD:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java -package at.ac.tuwien.kr.alpha.core.rules; - -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import com.google.common.annotations.VisibleForTesting; -======== package at.ac.tuwien.kr.alpha.core.programs.rules; ->>>>>>>> master:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -<<<<<<<< HEAD:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java -import at.ac.tuwien.kr.alpha.api.rules.NormalRule; -import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.rules.Rules; -import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; -======== import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.programs.rules.AbstractRule; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; ->>>>>>>> master:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfoImpl; @@ -70,23 +51,15 @@ * * {@link InternalRule}s are assumed to be uniquely identified by an ID. */ -<<<<<<<< HEAD:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java -public class CompiledRuleImpl implements CompiledRule { -======== public class InternalRule extends AbstractRule implements CompiledRule { ->>>>>>>> master:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); - private final NormalRule wrappedRule; - private final int ruleId; + private final List occurringPredicates; + private final RuleGroundingInfoImpl groundingOrders; -<<<<<<<< HEAD:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java - - CompiledRuleImpl(NormalHead head, Set body) { -======== /** * Creates a new {@link InternalRule} with the given head plus body and a fresh identifier. @@ -96,13 +69,11 @@ public class InternalRule extends AbstractRule implements CompiledRu */ public InternalRule(NormalHead head, List body) { super(head, body); ->>>>>>>> master:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java if (body.isEmpty()) { throw new IllegalArgumentException( "Empty bodies are not supported for InternalRule! (Head = " + (head == null ? "NULL" : head.getAtom().toString()) + ")"); } - this.ruleId = CompiledRuleImpl.ID_GENERATOR.getNextId(); - this.wrappedRule = Rules.newNormalRule(head, body); + this.ruleId = InternalRule.ID_GENERATOR.getNextId(); this.occurringPredicates = new ArrayList<>(); if (!isConstraint()) { @@ -116,24 +87,32 @@ public InternalRule(NormalHead head, List body) { this.occurringPredicates.add(literal.getPredicate()); } + // not needed, done in AbstractRule! Leaving it commented out for future reference since this might actually be the + // proper place to put it + // this.checkSafety(); + this.groundingOrders = new RuleGroundingInfoImpl(this); this.groundingOrders.computeGroundingOrders(); } @VisibleForTesting public static void resetIdGenerator() { - CompiledRuleImpl.ID_GENERATOR.resetGenerator(); + InternalRule.ID_GENERATOR.resetGenerator(); + } + + public static CompiledRule fromNormalRule(Rule rule) { + return new InternalRule(rule.isConstraint() ? null : Heads.newNormalHead(rule.getHead().getAtom()), new ArrayList<>(rule.getBody())); } /** * Returns a new Rule that is equal to this one except that all variables are renamed to have the newVariablePostfix * appended. - * + * * @param newVariablePostfix * @return */ @Override - public CompiledRuleImpl renameVariables(String newVariablePostfix) { + public InternalRule renameVariables(String newVariablePostfix) { // TODO handle action heads! List occurringVariables = new ArrayList<>(); BasicAtom headAtom = this.getHeadAtom(); @@ -147,13 +126,13 @@ public CompiledRuleImpl renameVariables(String newVariablePostfix) { variableReplacement.put(occurringVariable, Terms.newVariable(newVariableName)); } BasicAtom renamedHeadAtom = headAtom.substitute(variableReplacement); - Set renamedBody = new LinkedHashSet<>(this.getBody().size()); + ArrayList renamedBody = new ArrayList<>(this.getBody().size()); for (Literal literal : this.getBody()) { renamedBody.add(literal.substitute(variableReplacement)); } // TODO action heads! // TODO we want to pull renameVariables down to atom, term, etc level - return new CompiledRuleImpl(Heads.newNormalHead(renamedHeadAtom), renamedBody); + return new InternalRule(Heads.newNormalHead(renamedHeadAtom), renamedBody); } /** @@ -175,46 +154,6 @@ public int getRuleId() { return this.ruleId; } - @Override -<<<<<<<< HEAD:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java - public BasicAtom getHeadAtom() { - return wrappedRule.getHeadAtom(); - } - - @Override - public NormalHead getHead() { - return wrappedRule.getHead(); - } - - @Override - public Set getBody() { - return wrappedRule.getBody(); - } - - @Override - public boolean isConstraint() { - return wrappedRule.isConstraint(); - } - - @Override - public Set getPositiveBody() { - return wrappedRule.getPositiveBody(); - } - - @Override - public Set getNegativeBody() { - return wrappedRule.getNegativeBody(); - } - - @Override - public boolean isGround() { - return wrappedRule.isGround(); - } - - @Override - public String toString() { - return wrappedRule.toString(); -======== public boolean isGround() { if (!isConstraint() && !getHead().isGround()) { return false; @@ -225,14 +164,10 @@ public boolean isGround() { } } return true; ->>>>>>>> master:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java } @Override public boolean equals(Object o) { -<<<<<<<< HEAD:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java - return wrappedRule.equals(o); -======== if (this == o) { return true; } @@ -241,17 +176,12 @@ public boolean equals(Object o) { } InternalRule that = (InternalRule) o; return getRuleId() == that.getRuleId(); ->>>>>>>> master:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java } @Override public int hashCode() { -<<<<<<<< HEAD:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRuleImpl.java - return wrappedRule.hashCode(); - } - -======== return Integer.hashCode(getRuleId()); } ->>>>>>>> master:alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java + } + diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermTransformer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java similarity index 89% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermTransformer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java index b556c642a..029123628 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermTransformer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java @@ -22,6 +22,7 @@ import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.commons.util.Util; /** @@ -32,8 +33,12 @@ * Copyright (c) 2020-2021, the Alpha Team. */ public class ArithmeticTermsRewriting extends ProgramTransformation { - private static final String ARITHMETIC_VARIABLES_PREFIX = "_A"; - private int numArithmeticVariables; + /** + private int numArithmeticVariables; + * The prefix with which to begin names of internal variables created by this transformation. + */ + private final String generatedVariablesPrefix = "_A"; + private final IntIdGenerator variableNumberGenerator = new IntIdGenerator(); @Override public NormalProgram apply(NormalProgram inputProgram) { @@ -57,19 +62,20 @@ public NormalProgram apply(NormalProgram inputProgram) { /** * Takes a normal rule and rewrites it such that {@link ArithmeticTerm}s only appear inside - * {@link at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral}s. + * {@link at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral}s. * * @param inputProgramRule the rule to rewrite. * @return the rewritten rule. Note that a new {@link NormalRule} is returned for every call of this method. */ private NormalRule rewriteRule(NormalRule inputProgramRule) { - numArithmeticVariables = 0; // Reset number of introduced variables for each rule. + variableNumberGenerator.resetGenerator(); // Reset number of introduced variables for each rule. NormalHead rewrittenHead = null; List rewrittenBodyLiterals = new ArrayList<>(); // Rewrite head. if (!inputProgramRule.isConstraint()) { BasicAtom headAtom = inputProgramRule.getHeadAtom(); if (containsArithmeticTermsToRewrite(headAtom)) { + // TODO handle action heads rewrittenHead = Heads.newNormalHead((BasicAtom) rewriteAtom(headAtom, rewrittenBodyLiterals)); } else { rewrittenHead = inputProgramRule.getHead(); @@ -89,11 +95,11 @@ private NormalRule rewriteRule(NormalRule inputProgramRule) { /** * Checks whether a normal rule contains an {@link ArithmeticTerm} outside of a - * {@link at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral}. + * {@link at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral}. * * @param inputProgramRule the rule to check for presence of arithmetic terms outside comparison literals. * @return true if the inputProgramRule contains an {@link ArithmeticTerm} outside of a - * {@link at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral}. + * {@link at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral}. */ private boolean containsArithmeticTermsToRewrite(NormalRule inputProgramRule) { if (!inputProgramRule.isConstraint()) { @@ -118,7 +124,7 @@ private Term rewriteArithmeticSubterms(Term term, List bodyLiterals) { } // Switch on term type. if (term instanceof ArithmeticTerm) { - VariableTerm replacementVariable = Terms.newVariable(ARITHMETIC_VARIABLES_PREFIX + numArithmeticVariables++); + VariableTerm replacementVariable = Terms.newVariable(generatedVariablesPrefix + variableNumberGenerator.getNextId()); bodyLiterals.add(Atoms.newComparisonAtom(replacementVariable, term, ComparisonOperators.EQ).toLiteral()); return replacementVariable; } else if (term instanceof VariableTerm || term instanceof ConstantTerm) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadNormalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadNormalizer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java index 5783dd2d9..486c57e12 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadNormalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java @@ -32,6 +32,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -53,11 +54,11 @@ * Copyright (c) 2017-2021, the Alpha Team. */ // TODO this could already give NormalProgram as result type -public class ChoiceHeadToNormal extends ProgramTransformation { +public class ChoiceHeadToNormal extends ProgramTransformation { private final static String PREDICATE_NEGATION_PREFIX = "_n"; @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { + public InputProgram apply(InputProgram inputProgram) { ASPCore2ProgramBuilder programBuilder = Programs.builder(); List> additionalRules = new ArrayList<>(); From 133553ff1d160b9fa5ffd12557cc33f355d25368 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sun, 7 Jul 2024 18:20:24 +0200 Subject: [PATCH 35/59] WIP: fix tests after merging action implementation into latest master state --- .../api/config/AggregateRewritingConfig.java | 2 +- .../kr/alpha/api/programs/InputProgram.java | 8 +- .../kr/alpha/api/programs/actions/Action.java | 6 +- .../alpha/api/programs/rules/NormalRule.java | 2 + .../api/programs/rules/RuleInstantiator.java | 2 +- .../api/programs/rules/heads/ActionHead.java | 6 +- .../rules/heads/InstantiableHead.java | 2 +- .../api/programs/terms/ActionResultTerm.java | 42 +++--- .../kr/alpha/commons/externals/Externals.java | 26 +--- .../PredicateInterpretationImpl.java | 7 +- ...ProgramImpl.java => InputProgramImpl.java} | 6 +- .../kr/alpha/commons/programs/Programs.java | 47 ++++--- .../commons/programs/reification/Reifier.java | 5 +- .../commons/programs/rules/AbstractRule.java | 2 +- .../commons/programs/rules/BasicRule.java | 3 +- .../programs/rules/NormalRuleImpl.java | 16 ++- .../alpha/commons/programs/rules/Rules.java | 14 +- .../commons/programs/tests/AssertionImpl.java | 8 +- .../alpha/commons/programs/tests/Tests.java | 4 +- .../AbstractActionImplementationProvider.java | 22 ++-- .../core/actions/ActionExecutionService.java | 6 +- .../actions/ActionExecutionServiceImpl.java | 4 +- .../kr/alpha/core/actions/ActionWitness.java | 6 +- ...TreeVisitor.java => ParseTreeVisitor.java} | 35 +++-- .../alpha/core/parser/ProgramParserImpl.java | 17 ++- ...PartParser.java => ProgramPartParser.java} | 9 +- .../aspcore2/ASPCore2ProgramParser.java | 23 ---- .../parser/evolog/EvologParseTreeVisitor.java | 34 ----- .../parser/evolog/EvologProgramParser.java | 27 ---- .../alpha/core/programs/InternalProgram.java | 2 +- .../core/programs/rules/InternalRule.java | 8 +- .../ArithmeticTermsRewriting.java | 8 +- .../transformation/ChoiceHeadToNormal.java | 13 +- ...sformer.java => EnumerationRewriting.java} | 17 +-- ...r.java => IntervalTermToIntervalAtom.java} | 7 +- .../NormalizeProgramTransformation.java | 8 +- .../transformation/PredicateInternalizer.java | 18 +-- .../transformation/ProgramNormalizer.java | 54 -------- ...former.java => ProgramTransformation.java} | 4 +- .../transformation/StratifiedEvaluation.java | 122 ++++++++++++++--- ...rmer.java => VariableEqualityRemoval.java} | 20 +-- .../aggregates/AggregateLiteralSplitting.java | 14 +- .../AggregateOperatorNormalization.java | 10 +- ...ansformer.java => AggregateRewriting.java} | 38 +++--- .../aggregates/AggregateRewritingContext.java | 20 +-- .../AggregateRewritingRuleAnalysis.java | 13 +- .../encoders/AbstractAggregateEncoder.java | 33 ++--- .../encoders/AggregateEncoders.java | 24 ++-- .../aggregates/encoders/CountEncoder.java | 12 +- .../aggregates/encoders/MinMaxEncoder.java | 12 +- .../StringtemplateBasedAggregateEncoder.java | 24 ++-- .../aggregates/encoders/SumEncoder.java | 12 +- .../kr/alpha/core/rules/CompiledRules.java | 6 +- .../kr/alpha/core/solver/TrailAssignment.java | 3 +- .../tuwien/kr/alpha/core/common/RuleTest.java | 8 +- .../core/grounder/NaiveGrounderTest.java | 38 +++--- .../core/grounder/NoGoodGeneratorTest.java | 4 +- .../kr/alpha/core/grounder/UnifierTest.java | 4 +- .../alpha/core/parser/AspCore2ParserTest.java | 4 +- .../kr/alpha/core/parser/ParserTest.java | 32 ++--- .../alpha/core/programs/atoms/AtomsTest.java | 30 ++--- .../ProgramTransformationTest.java | 6 +- .../StratifiedEvaluationRegressionTest.java | 4 +- .../alpha/core/solver/ChoiceManagerTests.java | 4 +- .../tuwien/kr/alpha/test/AlphaAssertions.java | 13 +- .../kr/alpha/api/impl/AlphaFactory.java | 52 +++----- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 124 +++++++++--------- .../tuwien/kr/alpha/api/impl/TestRunner.java | 6 +- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 39 +++--- .../alpha/AggregateRewritingContextTest.java | 4 +- .../kr/alpha/AggregateRewritingTest.java | 4 +- .../at/ac/tuwien/kr/alpha/RuleParser.java | 4 +- .../ac/tuwien/kr/alpha/RuleToStringTest.java | 4 +- .../kr/alpha/StratifiedEvaluationTest.java | 6 +- .../kr/alpha/api/impl/AlphaImplTest.java | 108 +++++++-------- .../alpha/regressiontests/HanoiTowerTest.java | 8 +- .../HeadBodyTransformationTests.java | 4 +- .../regressiontests/OmigaBenchmarksTest.java | 4 +- .../kr/alpha/regressiontests/RacksTest.java | 4 +- .../kr/alpha/regressiontests/SolverTests.java | 4 +- .../ThreeColouringRandomGraphTest.java | 12 +- .../ThreeColouringTestWithRandom.java | 10 +- .../ThreeColouringWheelTest.java | 12 +- 83 files changed, 680 insertions(+), 769 deletions(-) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/{ASPCore2ProgramImpl.java => InputProgramImpl.java} (86%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{aspcore2/ASPCore2ParseTreeVisitor.java => ParseTreeVisitor.java} (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{aspcore2/ASPCore2ProgramPartParser.java => ProgramPartParser.java} (88%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{EnumerationTransformer.java => EnumerationRewriting.java} (87%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{IntervalTermTransformer.java => IntervalTermToIntervalAtom.java} (98%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramNormalizer.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{ProgramTransformer.java => ProgramTransformation.java} (57%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/{VariableEqualityTransformer.java => VariableEqualityRemoval.java} (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/{AggregateTransformer.java => AggregateRewriting.java} (84%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/AggregateRewritingConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/AggregateRewritingConfig.java index 6c72fbe62..908b2b3cb 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/AggregateRewritingConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/AggregateRewritingConfig.java @@ -5,7 +5,7 @@ /** * Configuration structure controlling how {@link AggregateLiteral}s are compiled during program normalization in - * {@link Alpha#normalizeProgram(at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program)}. + * {@link Alpha#normalizeProgram(at.ac.tuwien.kr.alpha.api.programs.InputProgram)}. * * Copyright (c) 2021, the Alpha Team. */ diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java index f9fe5122f..7c3df5bf8 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java @@ -8,9 +8,9 @@ public interface InputProgram extends Program> { - /** - * The test cases associated with this program. - */ - List getTestCases(); + /** + * The test cases associated with this program. + */ + List getTestCases(); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java index 5b0ab32e1..240a3b232 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/actions/Action.java @@ -1,9 +1,9 @@ package at.ac.tuwien.kr.alpha.api.programs.actions; -import java.util.List; +import at.ac.tuwien.kr.alpha.api.programs.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; -import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; +import java.util.List; /** * An action that gets executed as part of an action rule in an evolog program firing. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/NormalRule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/NormalRule.java index 8f2d8ebc8..92bdc6776 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/NormalRule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/NormalRule.java @@ -14,4 +14,6 @@ default BasicAtom getHeadAtom() { return this.isConstraint() ? null : this.getHead().getAtom(); } + boolean isGround(); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java index 74646f00d..7a36f19db 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/RuleInstantiator.java @@ -6,6 +6,6 @@ public interface RuleInstantiator { - BasicAtom instantiate(InstantiableHead ruleHead, Substitution substitution); + BasicAtom instantiate(InstantiableHead ruleHead, Substitution substitution); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java index 744531317..9956ccee8 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java @@ -7,10 +7,10 @@ public interface ActionHead extends NormalHead { - String getActionName(); + String getActionName(); - List getActionInputTerms(); + List getActionInputTerms(); - VariableTerm getActionOutputTerm(); + VariableTerm getActionOutputTerm(); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java index 82aa89343..32dcca689 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/InstantiableHead.java @@ -6,6 +6,6 @@ public interface InstantiableHead extends Head { - BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution); + BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java index 28fc53769..5436abf0f 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/terms/ActionResultTerm.java @@ -1,30 +1,30 @@ package at.ac.tuwien.kr.alpha.api.programs.terms; - /** - * A term representing the result of an evolog action (i.e. result of action function application). - * Action result terms are function terms with symbol "success" or "error" depending on whether the corresponding action was sucessful. - * There is always one argument which is either some term representing the actual function result or an error message, respectively. - */ +/** + * A term representing the result of an evolog action (i.e. result of action function application). + * Action result terms are function terms with symbol "success" or "error" depending on whether the corresponding action was sucessful. + * There is always one argument which is either some term representing the actual function result or an error message, respectively. + */ public interface ActionResultTerm extends FunctionTerm { - public static final String SUCCESS_SYMBOL = "success"; - public static final String ERROR_SYMBOL = "error"; + public static final String SUCCESS_SYMBOL = "success"; + public static final String ERROR_SYMBOL = "error"; - /** - * True if the action that generated this result was successful (i.e. executed normally). - */ - boolean isSuccess(); + /** + * True if the action that generated this result was successful (i.e. executed normally). + */ + boolean isSuccess(); - /** - * True if the action that generated this result failed (i.e. threw an error in execution). - */ - boolean isError(); + /** + * True if the action that generated this result failed (i.e. threw an error in execution). + */ + boolean isError(); - /** - * Gets the actual value wrapped in this result. - * Either a term representing the action return value or a string term representing an error - * message.s - */ - T getValue(); + /** + * Gets the actual value wrapped in this result. + * Either a term representing the action return value or a string term representing an error + * message.s + */ + T getValue(); } \ No newline at end of file diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java index aa9153e95..52066fd09 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java @@ -23,19 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.externals; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.reflections.Reflections; -import org.reflections.scanners.MethodAnnotationsScanner; +package at.ac.tuwien.kr.alpha.commons.externals; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.externals.Predicate; @@ -44,13 +32,11 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BinaryPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BindingMethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.IntPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.LongPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.MethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.SuppliedPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.UnaryPredicateInterpretation; +import org.reflections.Reflections; +import org.reflections.scanners.MethodAnnotationsScanner; + +import java.lang.reflect.Method; +import java.util.*; public final class Externals { diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java index 8e52bfacb..5ff6c5cfe 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java @@ -1,11 +1,12 @@ package at.ac.tuwien.kr.alpha.commons.externals; +import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; + import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; // TODO this looks like a duplicate public interface PredicateInterpretationImpl extends PredicateInterpretation { diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/ASPCore2ProgramImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/InputProgramImpl.java similarity index 86% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/ASPCore2ProgramImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/InputProgramImpl.java index c67097ed3..64c3c5a3c 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/ASPCore2ProgramImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/InputProgramImpl.java @@ -44,13 +44,13 @@ * Copyright (c) 2017-2019, the Alpha Team. */ // TODO rename this to InputProgramImpl or some such -class ASPCore2ProgramImpl extends AbstractProgram> implements InputProgram { +class InputProgramImpl extends AbstractProgram> implements InputProgram { - static final ASPCore2ProgramImpl EMPTY = new ASPCore2ProgramImpl(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl(), Collections.emptyList()); + static final InputProgramImpl EMPTY = new InputProgramImpl(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl(), Collections.emptyList()); private final List testCases; - ASPCore2ProgramImpl(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { + InputProgramImpl(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { super(rules, facts, inlineDirectives); this.testCases = testCases; } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java index 460231815..0a10b61d7 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java @@ -4,9 +4,8 @@ import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; @@ -22,25 +21,25 @@ private Programs() { } public static InputProgram emptyProgram() { - return ASPCore2ProgramImpl.EMPTY; + return InputProgramImpl.EMPTY; } // TODO rename method - public static InputProgram newASPCore2Program(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { - return new ASPCore2ProgramImpl(rules, facts, inlineDirectives, testCases); + public static InputProgram newInputProgram(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { + return new InputProgramImpl(rules, facts, inlineDirectives, testCases); } // TODO rename method - public static InputProgram newASPCore2Program(List> rules, List facts, InlineDirectives inlineDirectives) { - return new ASPCore2ProgramImpl(rules, facts, inlineDirectives, Collections.emptyList()); + public static InputProgram newInputProgram(List> rules, List facts, InlineDirectives inlineDirectives) { + return new InputProgramImpl(rules, facts, inlineDirectives, Collections.emptyList()); } - public static ASPCore2ProgramBuilder builder() { - return new ASPCore2ProgramBuilder(); + public static InputProgramBuilder builder() { + return new InputProgramBuilder(); } - public static ASPCore2ProgramBuilder builder(InputProgram program) { - return new ASPCore2ProgramBuilder(program); + public static InputProgramBuilder builder(InputProgram program) { + return new InputProgramBuilder(program); } public static NormalProgram newNormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { @@ -60,10 +59,10 @@ public static InlineDirectives newInlineDirectives() { } /** - * Builder for more complex program construction scenarios, ensuring that an {@link ASPCore2ProgramImpl} is immutable + * Builder for more complex program construction scenarios, ensuring that an {@link InputProgramImpl} is immutable */ // TODO maybe rename - public static class ASPCore2ProgramBuilder { + public static class InputProgramBuilder { private List> rules = new ArrayList<>(); private List facts = new ArrayList<>(); @@ -71,58 +70,58 @@ public static class ASPCore2ProgramBuilder { private List testCases = new ArrayList<>(); - public ASPCore2ProgramBuilder(InputProgram prog) { + public InputProgramBuilder(InputProgram prog) { this.addRules(prog.getRules()); this.addFacts(prog.getFacts()); this.addInlineDirectives(prog.getInlineDirectives()); this.addTestCases(prog.getTestCases()); } - public ASPCore2ProgramBuilder() { + public InputProgramBuilder() { } - public ASPCore2ProgramBuilder addRules(List> rules) { + public InputProgramBuilder addRules(List> rules) { this.rules.addAll(rules); return this; } - public ASPCore2ProgramBuilder addRule(Rule r) { + public InputProgramBuilder addRule(Rule r) { this.rules.add(r); return this; } - public ASPCore2ProgramBuilder addFacts(List facts) { + public InputProgramBuilder addFacts(List facts) { this.facts.addAll(facts); return this; } - public ASPCore2ProgramBuilder addFact(Atom fact) { + public InputProgramBuilder addFact(Atom fact) { this.facts.add(fact); return this; } - public ASPCore2ProgramBuilder addInlineDirectives(InlineDirectives inlineDirectives) { + public InputProgramBuilder addInlineDirectives(InlineDirectives inlineDirectives) { this.inlineDirectives.accumulate(inlineDirectives); return this; } - public ASPCore2ProgramBuilder addTestCase(TestCase testCase) { + public InputProgramBuilder addTestCase(TestCase testCase) { this.testCases.add(testCase); return this; } - public ASPCore2ProgramBuilder addTestCases(List testCases) { + public InputProgramBuilder addTestCases(List testCases) { this.testCases.addAll(testCases); return this; } - public ASPCore2ProgramBuilder accumulate(InputProgram prog) { + public InputProgramBuilder accumulate(InputProgram prog) { return this.addRules(prog.getRules()).addFacts(prog.getFacts()).addInlineDirectives(prog.getInlineDirectives()).addTestCases(prog.getTestCases()); } public InputProgram build() { - return Programs.newASPCore2Program(this.rules, this.facts, this.inlineDirectives, this.testCases); + return Programs.newInputProgram(this.rules, this.facts, this.inlineDirectives, this.testCases); } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/reification/Reifier.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/reification/Reifier.java index dba92f359..c21c7e0cb 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/reification/Reifier.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/reification/Reifier.java @@ -6,8 +6,8 @@ import java.util.function.Supplier; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; @@ -35,6 +35,7 @@ import at.ac.tuwien.kr.alpha.commons.util.IdGenerator; import at.ac.tuwien.kr.alpha.commons.util.Util; +// TODO add support for action rules public class Reifier { // Predicates describing rules. @@ -193,7 +194,7 @@ public Reifier(Supplier>> idGeneratorProvider) { this.idGeneratorProvider = idGeneratorProvider; } - public Set reifyProgram(ASPCore2Program program) { + public Set reifyProgram(InputProgram program) { ReificationContext ctx = new ReificationContext(idGeneratorProvider.get()); reifyDirectives(ctx, program.getInlineDirectives()); for (Atom fact : program.getFacts()) { diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java index 9326cad6b..5b8e4454e 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java @@ -26,7 +26,7 @@ public abstract class AbstractRule implements Rule { private final Set bodyLiteralsPositive; private final Set bodyLiteralsNegative; - public AbstractRule(H head, List body) { + public AbstractRule(H head, Set body) { this.head = head; Set positiveBody = new LinkedHashSet<>(); Set negativeBody = new LinkedHashSet<>(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java index e2bd1e178..13b991506 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java @@ -28,6 +28,7 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; @@ -38,7 +39,7 @@ */ class BasicRule extends AbstractRule { - BasicRule(Head head, List body) { + BasicRule(Head head, Set body) { super(head, body); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java index 828560f6f..80225ef71 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; @@ -14,8 +15,21 @@ */ class NormalRuleImpl extends AbstractRule implements NormalRule { - NormalRuleImpl(NormalHead head, List body) { + NormalRuleImpl(NormalHead head, Set body) { super(head, body); } + @Override + public boolean isGround() { + if (!isConstraint() && !this.getHead().isGround()) { + return false; + } + for (Literal bodyElement : this.getBody()) { + if (!bodyElement.isGround()) { + return false; + } + } + return true; + } + } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java index 3d04c53f9..f0456caba 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java @@ -1,8 +1,6 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -19,21 +17,21 @@ private Rules() { throw new AssertionError("Cannot instantiate utility class!"); } - public static Rule newRule(Head head, List body) { + public static Rule newRule(Head head, Set body) { return new BasicRule(head, body); } public static Rule newRule(Head head, Literal... body) { - List bodyLst = new ArrayList<>(Arrays.asList(body)); + Set bodyLst = new LinkedHashSet<>(Arrays.asList(body)); return new BasicRule(head, bodyLst); } - public static NormalRule newNormalRule(NormalHead head, List body) { + public static NormalRule newNormalRule(NormalHead head, Set body) { return new NormalRuleImpl(head, body); } public static NormalRule newNormalRule(NormalHead head, Literal... body) { - List bodyLst = new ArrayList<>(Arrays.asList(body)); + Set bodyLst = new LinkedHashSet<>(Arrays.asList(body)); return new NormalRuleImpl(head, bodyLst); } @@ -45,7 +43,7 @@ public static NormalRule toNormalRule(Rule rule) { } headAtom = ((NormalHead) rule.getHead()).getAtom(); } - return new NormalRuleImpl(headAtom != null ? Heads.newNormalHead(headAtom) : null, new ArrayList<>(rule.getBody())); + return new NormalRuleImpl(headAtom != null ? Heads.newNormalHead(headAtom) : null, new LinkedHashSet<>(rule.getBody())); } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/AssertionImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/AssertionImpl.java index b7f95a5e6..a62753c8e 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/AssertionImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/AssertionImpl.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.commons.programs.tests; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; class AssertionImpl implements Assertion { private final Mode mode; - private final ASPCore2Program verifier; + private final InputProgram verifier; - AssertionImpl(final Mode mode, final ASPCore2Program verifier) { + AssertionImpl(final Mode mode, final InputProgram verifier) { this.mode = mode; this.verifier = verifier; } @@ -19,7 +19,7 @@ public Mode getMode() { } @Override - public ASPCore2Program getVerifier() { + public InputProgram getVerifier() { return verifier; } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/Tests.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/Tests.java index 3962e5684..a750dc7c4 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/Tests.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/tests/Tests.java @@ -7,7 +7,7 @@ import java.util.function.IntPredicate; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; @@ -24,7 +24,7 @@ public static TestCase newTestCase(final String name, final IntPredicate answerS return new TestCaseImpl(name, answerSetCountVerifier, input, assertions); } - public static Assertion newAssertion(final Assertion.Mode mode, final ASPCore2Program verifier) { + public static Assertion newAssertion(final Assertion.Mode mode, final InputProgram verifier) { return new AssertionImpl(mode, verifier); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java index 22707f3ed..c23352dbd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java @@ -1,23 +1,19 @@ package at.ac.tuwien.kr.alpha.core.actions; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.programs.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; + +import java.io.*; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; -import at.ac.tuwien.kr.alpha.api.terms.ActionResultTerm; -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; - public abstract class AbstractActionImplementationProvider implements ActionImplementationProvider { private final IntIdGenerator idGenerator = new IntIdGenerator(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java index 5e3949519..ef5d8daa6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java @@ -1,9 +1,9 @@ package at.ac.tuwien.kr.alpha.core.actions; -import java.util.List; - +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.terms.Term; + +import java.util.List; public interface ActionExecutionService { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java index 2952f7f26..4067e2182 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java @@ -4,10 +4,10 @@ import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.actions.Action; -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; public class ActionExecutionServiceImpl implements ActionExecutionService { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java index a81bf4301..265780719 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java @@ -1,9 +1,9 @@ package at.ac.tuwien.kr.alpha.core.actions; -import java.util.List; - import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; + +import java.util.List; public class ActionWitness { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index b9e2cc758..610df11ad 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -30,8 +30,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.*; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; @@ -47,7 +47,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.literals.Literals; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; @@ -76,8 +76,8 @@ public class ParseTreeVisitor extends ASPCore2BaseVisitor { * Therefore, have a stack onto which we "park" a program builder for the outer scope (i.e. main program) * while we parse the inner scope (i.e. test verifier). */ - private ASPCore2ProgramBuilder currentLevelProgramBuilder; - private Stack programBuilders = new Stack<>(); + private InputProgramBuilder currentLevelProgramBuilder; + private Stack programBuilders = new Stack<>(); public ParseTreeVisitor(Map externals) { this(externals, true); @@ -95,7 +95,7 @@ private UnsupportedOperationException notSupported(RuleContext ctx) { /** * Translates a program context (referring to a node in an ATN specific to ANTLR) to the internal representation of Alpha. */ - public ASPCore2Program translate(ASPCore2Parser.ProgramContext input) { + public InputProgram translate(ASPCore2Parser.ProgramContext input) { return visitProgram(input); } @@ -145,7 +145,7 @@ public String visitTerminal(TerminalNode node) { } @Override - public ASPCore2Program visitProgram(ASPCore2Parser.ProgramContext ctx) { + public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { // program : statements? query?; if (ctx.query() != null) { throw notSupported(ctx.query()); @@ -178,7 +178,7 @@ public Object visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { currentLevelProgramBuilder.addFact(((NormalHead) head).getAtom()); } else { // Treat facts with choice or disjunction in the head like a rule. - currentLevelProgramBuilder.addRule(Rules.newRule(head, Collections.emptyList())); + currentLevelProgramBuilder.addRule(Rules.newRule(head, Collections.emptySet())); } return null; } @@ -247,6 +247,15 @@ public Head visitChoice(ASPCore2Parser.ChoiceContext ctx) { return Heads.newChoiceHead(visitChoice_elements(ctx.choice_elements()), lt, lop, ut, uop); } + @Override + public Head visitAction(ASPCore2Parser.ActionContext ctx) { + BasicAtom atom = visitClassical_literal(ctx.classical_literal()); + VariableTerm actionResultTerm = visitVariable_term(ctx.variable_term()); + String actionId = ctx.ID().getText(); + List actionInputTerms = visitTerms(ctx.terms()); + return Heads.newActionHead(atom, actionId, actionInputTerms, actionResultTerm); + } + @Override public List visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { // choice_elements : choice_element (SEMICOLON choice_elements)?; @@ -312,13 +321,13 @@ public Object visitDirective_test(ASPCore2Parser.Directive_testContext ctx) { } @Override - public List visitBody(ASPCore2Parser.BodyContext ctx) { + public Set visitBody(ASPCore2Parser.BodyContext ctx) { // body : ( naf_literal | aggregate ) (COMMA body)?; if (ctx == null) { - return Collections.emptyList(); + return Collections.emptySet(); } - final List literals = new ArrayList<>(); + final Set literals = new LinkedHashSet<>(); do { if (ctx.naf_literal() != null) { literals.add(visitNaf_literal(ctx.naf_literal())); @@ -409,7 +418,7 @@ public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { } @Override - public Term visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { + public VariableTerm visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { // variable_term : VARIABLE | ANONYMOUS_VARIABLE; if (ctx.VARIABLE() != null) { return Terms.newVariable(ctx.VARIABLE().getText()); @@ -698,11 +707,11 @@ public Assertion visitTestVerifier(Assertion.Mode assertionMode, ASPCore2Parser. } List stmts = ctx.statement(); programBuilders.push(currentLevelProgramBuilder); - currentLevelProgramBuilder = new ASPCore2ProgramBuilder(); + currentLevelProgramBuilder = new InputProgramBuilder(); for (ASPCore2Parser.StatementContext stmtCtx : stmts) { visit(stmtCtx); } - ASPCore2Program verifier = currentLevelProgramBuilder.build(); + InputProgram verifier = currentLevelProgramBuilder.build(); currentLevelProgramBuilder = programBuilders.pop(); return Tests.newAssertion(assertionMode, verifier); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java index 64e36c247..4c4d418ce 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java @@ -8,6 +8,9 @@ import java.util.Map; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; +import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; +import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; @@ -20,8 +23,8 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; public class ProgramParserImpl implements ProgramParser { @@ -35,6 +38,12 @@ public ProgramParserImpl(Map externals) { this(); this.preloadedExternals.putAll(externals); } + + public ProgramParserImpl(ActionImplementationProvider actionImplementationProvider, Map externals) { + this(externals); + this.preloadedExternals.put("stdin", actionImplementationProvider.getStdinTerm()); + this.preloadedExternals.put("stdout", actionImplementationProvider.getStdoutTerm()); + } @Override public InputProgram parse(String s) { @@ -141,7 +150,7 @@ public InputProgram parse(Path programPath, Map @Override public InputProgram parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { - ASPCore2ProgramBuilder bld = Programs.builder(); + InputProgramBuilder bld = Programs.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); } @@ -150,7 +159,7 @@ public InputProgram parse(Map externalPredicate @Override public InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { - ASPCore2ProgramBuilder bld = Programs.builder(); + InputProgramBuilder bld = Programs.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramPartParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java similarity index 88% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramPartParser.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java index 255a58891..14a5bc1d9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramPartParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.parser.aspcore2; +package at.ac.tuwien.kr.alpha.core.parser; import java.util.Collections; @@ -41,15 +41,14 @@ import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; /** - * A parser that, in contrast to {@link AbstractProgramParser}, does not parse full programs but only program parts like + * A parser that, in contrast to {@link ProgramParser}, does not parse full programs but only program parts like * atoms, terms and such. */ // TODO adapt this and create evolog version -public class ASPCore2ProgramPartParser { - private final ASPCore2ParseTreeVisitor visitor = new ASPCore2ParseTreeVisitor(Collections.emptyMap(), true); +public class ProgramPartParser { + private final ParseTreeVisitor visitor = new ParseTreeVisitor(Collections.emptyMap(), true); public Term parseTerm(String s) { final ASPCore2Parser parser = getASPCore2Parser(s); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java deleted file mode 100644 index c4cd13ea7..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/aspcore2/ASPCore2ProgramParser.java +++ /dev/null @@ -1,23 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.parser.aspcore2; - -import java.util.Map; - -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; - -public class ASPCore2ProgramParser extends AbstractProgramParser { - - public ASPCore2ProgramParser() { - super(); - } - - public ASPCore2ProgramParser(Map externals) { - super(externals); - } - - @Override - protected ASPCore2ParseTreeVisitor createParseTreeVisitor(Map externals) { - return new ASPCore2ParseTreeVisitor(externals); - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java deleted file mode 100644 index 2093d5da1..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologParseTreeVisitor.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.parser.evolog; - -import java.util.List; -import java.util.Map; - -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; -import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ParseTreeVisitor; - -public class EvologParseTreeVisitor extends ASPCore2ParseTreeVisitor { - - public EvologParseTreeVisitor(Map externals, boolean acceptVariables) { - super(externals, acceptVariables); - } - - public EvologParseTreeVisitor(Map externals) { - this(externals, true); - } - - @Override - public Head visitAction(ASPCore2Parser.ActionContext ctx) { - BasicAtom atom = visitClassical_literal(ctx.classical_literal()); - VariableTerm actionResultTerm = visitVariable_term(ctx.variable_term()); - String actionId = ctx.ID().getText(); - List actionInputTerms = visitTerms(ctx.terms()); - return Heads.newActionHead(atom, actionId, actionInputTerms, actionResultTerm); - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java deleted file mode 100644 index 3b1a9f71c..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/evolog/EvologProgramParser.java +++ /dev/null @@ -1,27 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.parser.evolog; - -import java.util.Collections; -import java.util.Map; - -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; -import at.ac.tuwien.kr.alpha.core.parser.AbstractProgramParser; - -public class EvologProgramParser extends AbstractProgramParser { - - public EvologProgramParser(ActionImplementationProvider actionImplementationProvider, Map externals) { - super(externals); - registerExternal("stdin", actionImplementationProvider.getStdinTerm()); - registerExternal("stdout", actionImplementationProvider.getStdoutTerm()); - } - - public EvologProgramParser(ActionImplementationProvider actionImplementationProvider) { - this(actionImplementationProvider, Collections.emptyMap()); - } - - @Override - protected EvologParseTreeVisitor createParseTreeVisitor(Map externals) { - return new EvologParseTreeVisitor(externals); - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java index 43e69b984..afd2236ab 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java @@ -104,7 +104,7 @@ public Map getRulesById() { public NormalProgram toNormalProgram() { List normalRules = new ArrayList<>(); for (CompiledRule rule : getRules()) { - normalRules.add(Rules.newNormalRule(rule.getHead(), new ArrayList<>(rule.getBody()))); + normalRules.add(Rules.newNormalRule(rule.getHead(), new LinkedHashSet<>(rule.getBody()))); } return Programs.newNormalProgram(normalRules, getFacts(), getInlineDirectives()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java index 8b57907f2..1bc31f104 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java @@ -43,7 +43,9 @@ import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; /** * Represents a normal rule or a constraint for the semi-naive grounder. @@ -67,7 +69,7 @@ public class InternalRule extends AbstractRule implements CompiledRu * @param head the head of the rule. * @param body the list of body literals of the rule. */ - public InternalRule(NormalHead head, List body) { + public InternalRule(NormalHead head, Set body) { super(head, body); if (body.isEmpty()) { throw new IllegalArgumentException( @@ -101,7 +103,7 @@ public static void resetIdGenerator() { } public static CompiledRule fromNormalRule(Rule rule) { - return new InternalRule(rule.isConstraint() ? null : Heads.newNormalHead(rule.getHead().getAtom()), new ArrayList<>(rule.getBody())); + return new InternalRule(rule.isConstraint() ? null : Heads.newNormalHead(rule.getHead().getAtom()), new LinkedHashSet<>(rule.getBody())); } /** @@ -126,7 +128,7 @@ public InternalRule renameVariables(String newVariablePostfix) { variableReplacement.put(occurringVariable, Terms.newVariable(newVariableName)); } BasicAtom renamedHeadAtom = headAtom.substitute(variableReplacement); - ArrayList renamedBody = new ArrayList<>(this.getBody().size()); + Set renamedBody = new LinkedHashSet<>(this.getBody().size()); for (Literal literal : this.getBody()) { renamedBody.add(literal.substitute(variableReplacement)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java index 029123628..d7111f098 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java @@ -1,7 +1,9 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -70,7 +72,7 @@ public NormalProgram apply(NormalProgram inputProgram) { private NormalRule rewriteRule(NormalRule inputProgramRule) { variableNumberGenerator.resetGenerator(); // Reset number of introduced variables for each rule. NormalHead rewrittenHead = null; - List rewrittenBodyLiterals = new ArrayList<>(); + Set rewrittenBodyLiterals = new LinkedHashSet<>(); // Rewrite head. if (!inputProgramRule.isConstraint()) { BasicAtom headAtom = inputProgramRule.getHeadAtom(); @@ -117,7 +119,7 @@ private boolean containsArithmeticTermsToRewrite(NormalRule inputProgramRule) { return false; } - private Term rewriteArithmeticSubterms(Term term, List bodyLiterals) { + private Term rewriteArithmeticSubterms(Term term, Set bodyLiterals) { // Keep term as-is if it contains no ArithmeticTerm. if (!containsArithmeticTerm(term)) { return term; @@ -141,7 +143,7 @@ private Term rewriteArithmeticSubterms(Term term, List bodyLiterals) { } } - private Atom rewriteAtom(Atom atomToRewrite, List bodyLiterals) { + private Atom rewriteAtom(Atom atomToRewrite, Set bodyLiterals) { if (atomToRewrite instanceof ComparisonAtom) { throw Util.oops("Trying to rewrite ComparisonAtom."); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java index 486c57e12..3b167ac9f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java @@ -27,11 +27,8 @@ */ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.*; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -44,7 +41,7 @@ import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; @@ -59,7 +56,7 @@ public class ChoiceHeadToNormal extends ProgramTransformation> additionalRules = new ArrayList<>(); List> srcRules = new ArrayList<>(inputProgram.getRules()); @@ -105,11 +102,11 @@ public InputProgram apply(InputProgram inputProgram) { BasicAtom negHead = Atoms.newBasicAtom(negPredicate, headTerms); // Construct two guessing rules. - List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); + Set guessingRuleBodyWithNegHead = new LinkedHashSet<>(ruleBody); guessingRuleBodyWithNegHead.add(Atoms.newBasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); additionalRules.add(Rules.newRule(Heads.newNormalHead(negHead), guessingRuleBodyWithNegHead)); - List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); + Set guessingRuleBodyWithHead = new LinkedHashSet<>(ruleBody); guessingRuleBodyWithHead.add(Atoms.newBasicAtom(negPredicate, headTerms).toLiteral(false)); additionalRules.add(Rules.newRule(Heads.newNormalHead(head), guessingRuleBodyWithHead)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationTransformer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java similarity index 87% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationTransformer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java index 9d20fb69f..803af1879 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationTransformer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java @@ -1,12 +1,9 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; +import java.util.*; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral; @@ -18,7 +15,7 @@ import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.programs.atoms.EnumerationAtom; @@ -30,10 +27,10 @@ * Copyright (c) 2017-2020, the Alpha Team. */ // TODO this should happen during/after internalization -public class EnumerationRewriting extends ProgramTransformation { +public class EnumerationRewriting extends ProgramTransformation { @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { + public InputProgram apply(InputProgram inputProgram) { // Read enumeration predicate from directive. String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectives.DIRECTIVE.enum_predicate_is); if (enumDirective == null) { @@ -42,7 +39,7 @@ public ASPCore2Program apply(ASPCore2Program inputProgram) { } Predicate enumPredicate = Predicates.getPredicate(enumDirective, 3); - ASPCore2ProgramBuilder programBuilder = Programs.builder().addInlineDirectives(inputProgram.getInlineDirectives()); + InputProgramBuilder programBuilder = Programs.builder().addInlineDirectives(inputProgram.getInlineDirectives()); checkFactsAreEnumerationFree(inputProgram.getFacts(), enumPredicate); programBuilder.addFacts(inputProgram.getFacts()); @@ -69,7 +66,7 @@ private List> rewriteRules(List> srcRules, Predicate enumP if (rule.getHead() != null && ((NormalHead) rule.getHead()).getAtom().getPredicate().equals(enumPredicate)) { throw Util.oops("Atom declared as enumeration atom by directive occurs in head of the rule: " + rule); } - List modifiedBodyLiterals = new ArrayList<>(rule.getBody()); + Set modifiedBodyLiterals = new LinkedHashSet<>(rule.getBody()); Iterator rit = modifiedBodyLiterals.iterator(); LinkedList rewrittenLiterals = new LinkedList<>(); while (rit.hasNext()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermTransformer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermTransformer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java index 90d532aff..9b1c69143 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermTransformer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java @@ -27,10 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -68,7 +65,7 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { // Collect all intervals and replace them with variables. Map intervalReplacements = new LinkedHashMap<>(); - List rewrittenBody = new ArrayList<>(); + Set rewrittenBody = new LinkedHashSet<>(); for (Literal literal : rule.getBody()) { Literal rewrittenLiteral = rewriteLiteral(literal, intervalReplacements); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java index f8d3303f0..d3b5c9cc8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; import at.ac.tuwien.kr.alpha.api.config.AggregateRewritingConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.commons.programs.Programs; import at.ac.tuwien.kr.alpha.core.programs.atoms.EnumerationAtom; @@ -12,7 +12,7 @@ * * Copyright (c) 2019-2021, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformation { +public class NormalizeProgramTransformation extends ProgramTransformation { private final AggregateRewritingConfig aggregateRewritingCfg; @@ -21,8 +21,8 @@ public NormalizeProgramTransformation(AggregateRewritingConfig aggregateCfg) { } @Override - public NormalProgram apply(ASPCore2Program inputProgram) { - ASPCore2Program tmpPrg; + public NormalProgram apply(InputProgram inputProgram) { + InputProgram tmpPrg; // Remove variable equalities. tmpPrg = new VariableEqualityRemoval().apply(inputProgram); // Transform choice rules. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index 23b47bc83..d33962805 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -1,9 +1,6 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import java.util.ArrayList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -14,11 +11,16 @@ import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + /** * * Rewrites all predicates of a given Program such that they are internal and hence hidden from answer sets. @@ -27,8 +29,8 @@ */ public class PredicateInternalizer { - public static ASPCore2Program makePrefixedPredicatesInternal(ASPCore2Program program, String prefix) { - ASPCore2ProgramBuilder prgBuilder = Programs.builder(); + public static InputProgram makePrefixedPredicatesInternal(InputProgram program, String prefix) { + InputProgramBuilder prgBuilder = Programs.builder(); for (Atom atom : program.getFacts()) { if (atom.getPredicate().getName().startsWith(prefix)) { prgBuilder.addFact(PredicateInternalizer.makePredicateInternal((BasicAtom) atom)); @@ -56,7 +58,7 @@ public static Rule makePrefixedPredicatesInternal(Rule rule, String newHead = head; } } - List newBody = new ArrayList<>(); + Set newBody = new LinkedHashSet<>(); for (Literal bodyElement : rule.getBody()) { // Only rewrite BasicAtoms. if (bodyElement instanceof BasicLiteral) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramNormalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramNormalizer.java deleted file mode 100644 index 89498e3da..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramNormalizer.java +++ /dev/null @@ -1,54 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation; - -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; -import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateTransformer; - -/** - * Encapsulates all transformations necessary to transform a given program into a @{link NormalProgram} that is understood by Alpha internally - * - * Copyright (c) 2019-2021, the Alpha Team. - */ -public class ProgramNormalizer extends ProgramTransformer { - - private final VariableEqualityTransformer equalityTransformer; - private final ChoiceHeadNormalizer choiceHeadNormalizer; - private final AggregateTransformer aggregateTransformer; - private final EnumerationTransformer enumerationTransformer; - private final IntervalTermTransformer intervalTermTransformer; - private final ArithmeticTermTransformer arithmeticTermTransformer; - - public ProgramNormalizer(VariableEqualityTransformer equalityTransformer, ChoiceHeadNormalizer choiceHeadNormalizer, AggregateTransformer aggregateTransformer, EnumerationTransformer enumerationTransformer, IntervalTermTransformer intervalTermTransformer, ArithmeticTermTransformer arithmeticTermTransformer) { - this.equalityTransformer = equalityTransformer; - this.choiceHeadNormalizer = choiceHeadNormalizer; - this.aggregateTransformer = aggregateTransformer; - this.enumerationTransformer = enumerationTransformer; - this.intervalTermTransformer = intervalTermTransformer; - this.arithmeticTermTransformer = arithmeticTermTransformer; - } - - @Override - public NormalProgram transform(InputProgram inputProgram) { - InputProgram tmpPrg; - // Remove variable equalities. - tmpPrg = equalityTransformer.transform(inputProgram); - // Transform choice rules. - tmpPrg = choiceHeadNormalizer.transform(tmpPrg); - // Transform aggregates. - tmpPrg = aggregateTransformer.transform(tmpPrg); - // Transform enumeration atoms. - tmpPrg = enumerationTransformer.transform(tmpPrg); - EnumerationAtom.resetEnumerations(); - - // Construct the normal program. - NormalProgram retVal = NormalProgramImpl.fromInputProgram(tmpPrg); - // Transform intervals. - retVal = intervalTermTransformer.transform(retVal); - // Rewrite ArithmeticTerms. - retVal = arithmeticTermTransformer.transform(retVal); - return retVal; - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java similarity index 57% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java index 098c10bc8..5fc28c50a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java @@ -6,8 +6,8 @@ /** * Copyright (c) 2017-2019, the Alpha Team. */ -public abstract class ProgramTransformer>, O extends Program>> { +public abstract class ProgramTransformation>, O extends Program>> { - public abstract O transform(I inputProgram); + public abstract O apply(I inputProgram); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 34fed23dc..07bf0036e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -11,6 +11,15 @@ import java.util.Set; import java.util.Stack; +import at.ac.tuwien.kr.alpha.api.programs.rules.RuleInstantiator; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ActionHead; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.InstantiableHead; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; import org.apache.commons.collections4.SetUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.slf4j.Logger; @@ -21,10 +30,13 @@ import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; +import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionService; +import at.ac.tuwien.kr.alpha.core.actions.ActionWitness; import at.ac.tuwien.kr.alpha.core.depgraph.StratificationAlgorithm; import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfo; @@ -36,14 +48,13 @@ import at.ac.tuwien.kr.alpha.core.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy; import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; /** * Evaluates the stratifiable part of a given (analyzed) ASP program. - * + * * Copyright (c) 2019-2020, the Alpha Team. */ -public class StratifiedEvaluation extends ProgramTransformation { +public class StratifiedEvaluation extends ProgramTransformation implements RuleInstantiator { private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluation.class); @@ -52,10 +63,17 @@ public class StratifiedEvaluation extends ProgramTransformation> modifiedInLastEvaluationRun = new HashMap<>(); - private List additionalFacts = new ArrayList<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. + private Set outputFacts = new HashSet<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. private Set solvedRuleIds = new HashSet<>(); // Set of rules that have been completely evaluated. private LiteralInstantiator literalInstantiator; + private ActionExecutionService actionExecutionService; + private final boolean generateActionWitnesses; + + public StratifiedEvaluation(ActionExecutionService actionExecutionService, boolean generateActionWitnesses) { + this.actionExecutionService = actionExecutionService; + this.generateActionWitnesses = generateActionWitnesses; + } @Override // Note: ideally this returns a "PartiallyEvaluatedProgram" such that the grounder can directly use the working @@ -82,6 +100,9 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { workingMemory.reset(); + // Set up set of facts to which we'll add everything derived during stratified evaluation. + outputFacts = new HashSet<>(inputProgram.getFacts()); + // Set up literal instantiator. literalInstantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); @@ -91,13 +112,12 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { } // Build the program resulting from evaluating the stratified part. - additionalFacts.addAll(inputProgram.getFacts()); // Add original input facts to newly derived ones. List outputRules = new ArrayList<>(); inputProgram.getRulesById().entrySet().stream().filter((entry) -> !solvedRuleIds.contains(entry.getKey())) .forEach((entry) -> outputRules.add(entry.getValue())); // NOTE: if InternalProgram requires solved rules, they should be added here. - return new InternalProgram(outputRules, additionalFacts); + return new InternalProgram(outputRules, new ArrayList<>(outputFacts)); } private void evaluateComponent(ComponentGraph.SCComponent comp) { @@ -114,9 +134,7 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { evaluateRules(evaluationInfo.nonRecursiveRules, true); for (IndexedInstanceStorage instanceStorage : workingMemory.modified()) { // Directly record all newly derived instances as additional facts. - for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { - additionalFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } + recordRecentlyAddedInstances(instanceStorage); instanceStorage.markRecentlyAddedInstancesDone(); } } @@ -134,9 +152,7 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { // Since we are stratified we never have to backtrack, therefore just collect the added instances. for (IndexedInstanceStorage instanceStorage : workingMemory.modified()) { // Directly record all newly derived instances as additional facts. - for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { - additionalFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } + recordRecentlyAddedInstances(instanceStorage); modifiedInLastEvaluationRun.putIfAbsent(instanceStorage.getPredicate(), new LinkedHashSet<>()); modifiedInLastEvaluationRun.get(instanceStorage.getPredicate()).addAll(instanceStorage.getRecentlyAddedInstances()); instanceStorage.markRecentlyAddedInstancesDone(); @@ -149,6 +165,12 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { .forEach((rule) -> solvedRuleIds.add(rule.getRuleId())); } + private void recordRecentlyAddedInstances(IndexedInstanceStorage instanceStorage) { + for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { + outputFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); + } + } + private void evaluateRules(Set rules, boolean isInitialRun) { workingMemory.reset(); LOGGER.debug("Starting component evaluation run..."); @@ -225,7 +247,7 @@ private List calculateSatisfyingSubstitutionsForRule(CompiledRule * Use this to find initial substitutions for a starting literal when grounding a rule. * In order to avoid finding the same ground instantiations of rules again, only look at * modifiedInLastEvaluationRun to obtain instances. - * + * * @param lit the literal to substitute. * @return valid ground substitutions for the literal based on the recently added instances (i.e. instances derived in * the last evaluation run). @@ -255,7 +277,7 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde substitutionStack.push((ArrayList) startingSubstitutions); } else { substitutionStack.push(new ArrayList<>(startingSubstitutions)); // Copy startingSubstitutions into ArrayList. Note: mostly happens for empty or - // singleton lists. + // singleton lists. } int currentOrderPosition = 0; List fullSubstitutions = new ArrayList<>(); @@ -280,7 +302,7 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde } // Take one substitution from the top-list of the stack and try extending it. Substitution currentSubstitution = currentSubstitutions.remove(currentSubstitutions.size() - 1); // Work on last element (removing last element is - // O(1) for ArrayList). + // O(1) for ArrayList). LiteralInstantiationResult currentLiteralResult = literalInstantiator.instantiateLiteral(currentLiteral, currentSubstitution); if (currentLiteralResult.getType() == LiteralInstantiationResult.Type.CONTINUE) { // The currentSubstitution could be extended, push the extensions on the stack and continue working on them. @@ -297,7 +319,13 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde } private void fireRule(CompiledRule rule, Substitution substitution) { - Atom newAtom = rule.getHeadAtom().substitute(substitution); + // BasicAtom newAtom = this.instantiate(rule.getHead(), substitution); + BasicAtom newAtom; + if (rule.getHead() instanceof ActionHead) { + newAtom = instantiateActionHead((ActionHead) rule.getHead(), substitution, rule); + } else { + newAtom = instantiateNormalHead(rule.getHead(), substitution); + } if (!newAtom.isGround()) { throw new IllegalStateException("Trying to fire rule " + rule.toString() + " with incompatible substitution " + substitution.toString()); } @@ -305,6 +333,64 @@ private void fireRule(CompiledRule rule, Substitution substitution) { workingMemory.addInstance(newAtom, true); } + @Override + public BasicAtom instantiate(InstantiableHead ruleHead, Substitution substitution) { + return ruleHead.instantiate(this, substitution); + } + + // FIXME should be dispatched via visitor pattern + public BasicAtom instantiateNormalHead(NormalHead head, Substitution substitution) { + return head.getAtom().substitute(substitution); + } + + // FIXME should be dispatched via visitor pattern + public BasicAtom instantiateActionHead(ActionHead head, Substitution substitution, CompiledRule rule) { + List actionInput = head.getActionInputTerms(); + List substitutedInput = new ArrayList<>(); + // Substitute all variables in action input so that all input terms are ground. + for (Term inputTerm : actionInput) { + substitutedInput.add(inputTerm.substitute(substitution)); + } + // Delegate action execution to respective backend. + ActionWitness witness = actionExecutionService.execute(head.getActionName(), rule.getRuleId(), substitution, substitutedInput); + // If the according debug flag is set, convert witness to atom and add to facts. + if (generateActionWitnesses) { + BasicAtom witnessAtom = buildActionWitnessAtom(witness, rule); + // Note that this is a rather "sneaky" side-effect, + // but seems like overkill to do this structurally proper just for a debug feature. + workingMemory.addInstance(witnessAtom, true); + } + // We have an action result. Add it to the substitution as the substitute for the variable bound to the action so we're able to obtain the + // ground BasicAtom derived by the rule + substitution.put(head.getActionOutputTerm(), witness.getActionResult()); + return head.getAtom().substitute(substitution); + } + + private BasicAtom buildActionWitnessAtom(ActionWitness witness, CompiledRule rule) { + // Note that this methods should only ever be used for debugging! + // While action witnesses are used as a semantic concept in the evolog specification, + // they normally only exist implicitly. + + // Construct state term: create function terms from ground body literals. + List functionalizedBody = new ArrayList<>(); + for (Literal lit : rule.getBody()) { + Literal groundLit = lit.substitute(witness.getGroundSubstitution()); + FunctionTerm functionalizedLiteral = Terms.newFunctionTerm(groundLit.getPredicate().getName(), groundLit.getTerms()); + functionalizedBody.add(functionalizedLiteral); + } + FunctionTerm stateTerm = Terms.newFunctionTerm("state", functionalizedBody); + + // Construct input term: wrap action input terms into one function term. + FunctionTerm inputTerm = Terms.newFunctionTerm("input", witness.getActionInput()); + + // Return witness atom: put state and input terms together. + return Atoms.newBasicAtom(Predicates.getPredicate("action_witness", 4), + Terms.newConstant(witness.getActionName()), + stateTerm, + inputTerm, + witness.getActionResult()); + } + private ComponentEvaluationInfo getRulesToEvaluate(ComponentGraph.SCComponent comp) { Set nonRecursiveRules = new HashSet<>(); Set recursiveRules = new HashSet<>(); @@ -348,7 +434,7 @@ private ComponentEvaluationInfo getRulesToEvaluate(ComponentGraph.SCComponent co * dependency chain within that component, and non-recursive rules, i.e. rules where all body predicates occur in lower * strata. The reason for this grouping is that, when evaluating rules within a component, non-recursive rules only need * to be evaluated once, while recursive rules need to be evaluated until a fixed-point has been reached. - * + * * Copyright (c) 2020, the Alpha Team. */ private class ComponentEvaluationInfo { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityTransformer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityTransformer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 3c84b54a0..a08aac2e2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityTransformer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -27,17 +27,9 @@ */ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; +import java.util.*; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -57,15 +49,15 @@ * * Copyright (c) 2017-2021, the Alpha Team. */ -public class VariableEqualityRemoval extends ProgramTransformation { +public class VariableEqualityRemoval extends ProgramTransformation { @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { + public InputProgram apply(InputProgram inputProgram) { List> rewrittenRules = new ArrayList<>(); for (Rule rule : inputProgram.getRules()) { rewrittenRules.add(findAndReplaceVariableEquality(rule)); } - return Programs.newASPCore2Program(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + return Programs.newInputProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); } private Rule findAndReplaceVariableEquality(Rule rule) { @@ -112,7 +104,7 @@ private Rule findAndReplaceVariableEquality(Rule rule) { return rule; } - List rewrittenBody = new ArrayList<>(rule.getBody()); + Set rewrittenBody = new LinkedHashSet<>(rule.getBody()); if (!rule.isConstraint() && rule.getHead() instanceof DisjunctiveHead) { throw new UnsupportedOperationException("VariableEqualityRemoval cannot be applied to rule with DisjunctiveHead, yet."); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java index b959269d2..ed55537b0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateLiteralSplitting.java @@ -1,8 +1,6 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -66,17 +64,17 @@ private static List> splitAggregatesInRule(Rule sourceRule) { } } // Second, compute rule bodies of splitting result. - List commonBody = new ArrayList<>(commonBodyLiterals); + Set commonBody = new LinkedHashSet<>(commonBodyLiterals); commonBody.addAll(twoLiteralsSplitAggregates); - List> rewrittenBodies = new ArrayList<>(); + List> rewrittenBodies = new ArrayList<>(); rewrittenBodies.add(commonBody); // Initialize list of rules with the common body. // For n twoRulesSplitAggregates we need 2^n rules, so // for each of the n pairs in twoRulesSplitAggregates we duplicate the list of rewritten bodies. for (ImmutablePair ruleSplitAggregate : twoRulesSplitAggregates) { int numBodiesBeforeDuplication = rewrittenBodies.size(); for (int i = 0; i < numBodiesBeforeDuplication; i++) { - List originalBody = rewrittenBodies.get(i); - List duplicatedBody = new ArrayList<>(originalBody); + Set originalBody = rewrittenBodies.get(i); + Set duplicatedBody = new LinkedHashSet<>(originalBody); // Extend bodies of original and duplicate with splitting results. originalBody.add(ruleSplitAggregate.left); duplicatedBody.add(ruleSplitAggregate.right); @@ -85,7 +83,7 @@ private static List> splitAggregatesInRule(Rule sourceRule) { } // Third, turn computed bodies into rules again. List> rewrittenRules = new ArrayList<>(); - for (List rewrittenBody : rewrittenBodies) { + for (Set rewrittenBody : rewrittenBodies) { rewrittenRules.add(Rules.newRule(sourceRule.getHead(), rewrittenBody)); } return rewrittenRules; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java index 12e3273b6..8235c1364 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java @@ -1,8 +1,6 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; @@ -22,7 +20,7 @@ import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; /** - * Transforms an {@link AspCore2ProgramImpl} such that, for all aggregate (body-)literals, only the comparison operators "=" + * Transforms an {@link at.ac.tuwien.kr.alpha.api.programs.InputProgram} such that, for all aggregate (body-)literals, only the comparison operators "=" * and "<=" are used. * * Rewriting of "#count" and "#sum" aggregates is done using the following equivalences: @@ -41,7 +39,7 @@ * Note that input programs must only contain aggregate literals of form TERM OP #aggr{...} or #aggr{...} OP TERM, * i.e. with only * a left or right term and operator (but not both). When preprocessing programs, apply this transformation AFTER - * {@link at.ac.tuwien.kr.alpha.grounder.transformation.aggregates.AggregateLiteralSplitting}. + * {@link AggregateLiteralSplitting}. * * Copyright (c) 2020-2021, the Alpha Team. */ @@ -52,7 +50,7 @@ private AggregateOperatorNormalization() { } public static Rule normalize(Rule rule) { - List rewrittenBody = new ArrayList<>(); + Set rewrittenBody = new LinkedHashSet<>(); for (Literal lit : rule.getBody()) { rewrittenBody.addAll(rewriteLiteral(lit)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateTransformer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java similarity index 84% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateTransformer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java index aff59e893..48d4747c9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateTransformer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java @@ -1,14 +1,7 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.tuple.ImmutablePair; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -16,22 +9,23 @@ import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.literals.Literals; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AbstractAggregateEncoder; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.CountEncoder; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.MinMaxEncoder; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.SumEncoder; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AggregateEncoders; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; /** * Rewrites {@link AggregateLiteral}s in programs to semantically equivalent, aggregate-free sub-programs. * * Copyright (c) 2020, the Alpha Team. */ -public class AggregateRewriting extends ProgramTransformation { +public class AggregateRewriting extends ProgramTransformation { private final AbstractAggregateEncoder countEqualsEncoder; private final AbstractAggregateEncoder countLessOrEqualEncoder; @@ -51,12 +45,12 @@ public class AggregateRewriting extends ProgramTransformation> outputRules = new ArrayList<>(); for (Rule inputRule : inputProgram.getRules()) { @@ -89,7 +83,7 @@ public ASPCore2Program apply(ASPCore2Program inputProgram) { } // Substitute AggregateLiterals with generated result literals. outputRules.addAll(rewriteRulesWithAggregates(ctx)); - ASPCore2ProgramBuilder resultBuilder = Programs.builder().addRules(outputRules).addFacts(inputProgram.getFacts()) + InputProgramBuilder resultBuilder = Programs.builder().addRules(outputRules).addFacts(inputProgram.getFacts()) .addInlineDirectives(inputProgram.getInlineDirectives()); // Add sub-programs deriving respective aggregate literals. for (Map.Entry, Set> aggToRewrite : ctx.getAggregateFunctionsToRewrite() @@ -138,7 +132,7 @@ private AbstractAggregateEncoder getEncoderForAggregateFunction(AggregateFunctio private static List> rewriteRulesWithAggregates(AggregateRewritingContext ctx) { List> rewrittenRules = new ArrayList<>(); for (Rule rule : ctx.getRulesWithAggregates()) { - List rewrittenBody = new ArrayList<>(); + Set rewrittenBody = new LinkedHashSet<>(); for (Literal lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateInfo aggregateInfo = ctx.getAggregateInfo((AggregateLiteral) lit); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingContext.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingContext.java index c7e3f2fc2..a1742b71d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingContext.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingContext.java @@ -1,19 +1,5 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; -import static at.ac.tuwien.kr.alpha.commons.util.Util.oops; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.stringtemplate.v4.ST; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; @@ -28,6 +14,12 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.stringtemplate.v4.ST; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.commons.util.Util.oops; /** * Holds all information about aggregate literals that need to be rewritten within a program. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysis.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysis.java index 1433f1665..9647fa444 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysis.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysis.java @@ -1,15 +1,5 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.collections4.SetUtils; - import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -18,6 +8,9 @@ import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; +import org.apache.commons.collections4.SetUtils; + +import java.util.*; /** * Analyses a rule and records occurring aggregates and for each aggregate its global variables and its dependencies on diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java index 4b6c431b1..92a09f658 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java @@ -1,13 +1,7 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.apache.commons.collections4.ListUtils; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; @@ -19,13 +13,20 @@ import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.programs.transformation.PredicateInternalizer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.collections4.SetUtils; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; /** * Abstract base class for aggregate encoders. An aggregate encoder provides an encoding for a given aggregate literal, @@ -49,10 +50,10 @@ protected AbstractAggregateEncoder(AggregateFunctionSymbol aggregateFunctionToEn * Encodes all aggregate literals in the given set of aggregate referenced by the given {@link AggregateInfo}. * * @param aggregatesToEncode the aggregates to encode. - * @return all rules encoding the given aggregates as an {@link AspCore2ProgramImpl}. + * @return all rules encoding the given aggregates as an {@link InputProgram}. */ - public ASPCore2Program encodeAggregateLiterals(Set aggregatesToEncode) { - ASPCore2ProgramBuilder programBuilder = Programs.builder(); + public InputProgram encodeAggregateLiterals(Set aggregatesToEncode) { + InputProgramBuilder programBuilder = Programs.builder(); for (AggregateInfo aggregateInfo : aggregatesToEncode) { programBuilder.accumulate(encodeAggregateLiteral(aggregateInfo)); } @@ -65,7 +66,7 @@ public ASPCore2Program encodeAggregateLiterals(Set aggregatesToEn * @param aggregateToEncode * @return */ - public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { + public InputProgram encodeAggregateLiteral(AggregateInfo aggregateToEncode) { AggregateLiteral literalToEncode = aggregateToEncode.getLiteral(); if (literalToEncode.getAtom().getAggregateFunction() != this.aggregateFunctionToEncode) { throw new IllegalArgumentException( @@ -76,13 +77,13 @@ public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { + literalToEncode.getAtom().getAggregateFunction() + " with operator " + literalToEncode.getAtom().getLowerBoundOperator()); } String aggregateId = aggregateToEncode.getId(); - ASPCore2Program literalEncoding = PredicateInternalizer.makePrefixedPredicatesInternal(encodeAggregateResult(aggregateToEncode), aggregateId); + InputProgram literalEncoding = PredicateInternalizer.makePrefixedPredicatesInternal(encodeAggregateResult(aggregateToEncode), aggregateId); List> elementEncodingRules = new ArrayList<>(); for (AggregateElement elementToEncode : literalToEncode.getAtom().getAggregateElements()) { Rule elementRule = encodeAggregateElement(aggregateToEncode, elementToEncode); elementEncodingRules.add(PredicateInternalizer.makePrefixedPredicatesInternal(elementRule, aggregateId)); } - return Programs.newASPCore2Program(ListUtils.union(literalEncoding.getRules(), elementEncodingRules), literalEncoding.getFacts(), Programs.newInlineDirectives()); + return Programs.newInputProgram(ListUtils.union(literalEncoding.getRules(), elementEncodingRules), literalEncoding.getFacts(), Programs.newInlineDirectives()); } /** @@ -93,7 +94,7 @@ public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { * @param aggregateToEncode * @return */ - protected abstract ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode); + protected abstract InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode); /** * Encodes individual aggregate elements. For each aggregate element, a rule is created that fires for each tuple matching the element. @@ -105,7 +106,7 @@ public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { protected Rule encodeAggregateElement(AggregateInfo aggregateInfo, AggregateElement element) { BasicAtom headAtom = buildElementRuleHead(aggregateInfo.getId(), element, aggregateInfo.getAggregateArguments()); return Rules.newRule(Heads.newNormalHead(headAtom), - ListUtils.union(element.getElementLiterals(), new ArrayList<>(aggregateInfo.getDependencies()))); + SetUtils.union(new LinkedHashSet<>(element.getElementLiterals()), new LinkedHashSet<>(aggregateInfo.getDependencies()))); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java index 55d6ca6af..686fed1f6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java @@ -9,28 +9,28 @@ private AggregateEncoders() { throw new AssertionError("Cannot instantiate utility class!"); } - public static CountEncoder newCountEqualsEncoder(ProgramParser parser) { - return CountEncoder.buildCountEqualsEncoder(parser); + public static CountEncoder newCountEqualsEncoder() { + return CountEncoder.buildCountEqualsEncoder(); } - public static CountEncoder newCountLessOrEqualEncoder(ProgramParser parser, boolean useSortingGridEncoding) { - return CountEncoder.buildCountLessOrEqualEncoder(parser, useSortingGridEncoding); + public static CountEncoder newCountLessOrEqualEncoder(boolean useSortingGridEncoding) { + return CountEncoder.buildCountLessOrEqualEncoder(useSortingGridEncoding); } - public static SumEncoder newSumEqualsEncoder(ProgramParser parser, boolean supportNegativeSumElements) { - return SumEncoder.buildSumEqualsEncoder(parser, supportNegativeSumElements); + public static SumEncoder newSumEqualsEncoder(boolean supportNegativeSumElements) { + return SumEncoder.buildSumEqualsEncoder(supportNegativeSumElements); } - public static SumEncoder newSumLessOrEqualEncoder(ProgramParser parser, boolean supportNegativeSumElements) { - return SumEncoder.buildSumLessOrEqualEncoder(parser, supportNegativeSumElements); + public static SumEncoder newSumLessOrEqualEncoder(boolean supportNegativeSumElements) { + return SumEncoder.buildSumLessOrEqualEncoder(supportNegativeSumElements); } - public static MinMaxEncoder newMinEncoder(ProgramParser parser) { - return new MinMaxEncoder(parser, AggregateFunctionSymbol.MIN); + public static MinMaxEncoder newMinEncoder() { + return new MinMaxEncoder(AggregateFunctionSymbol.MIN); } - public static MinMaxEncoder newMaxEncoder(ProgramParser parser) { - return new MinMaxEncoder(parser, AggregateFunctionSymbol.MAX); + public static MinMaxEncoder newMaxEncoder() { + return new MinMaxEncoder(AggregateFunctionSymbol.MAX); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java index be64efabd..44a10a5a3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java @@ -18,16 +18,16 @@ public final class CountEncoder extends StringtemplateBasedAggregateEncoder { private static final ST CNT_EQ_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_eq"); private static final ST CNT_LE_COUNTING_GRID_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_le_counting_grid"); - private CountEncoder(ProgramParser parser, ComparisonOperator acceptedOperator, ST encodingTemplate) { - super(parser, AggregateFunctionSymbol.COUNT, acceptedOperator, encodingTemplate); + private CountEncoder(ComparisonOperator acceptedOperator, ST encodingTemplate) { + super(AggregateFunctionSymbol.COUNT, acceptedOperator, encodingTemplate); } - static CountEncoder buildCountLessOrEqualEncoder(ProgramParser parser, boolean useSortingGrid) { - return new CountEncoder(parser, ComparisonOperators.LE, useSortingGrid ? CNT_LE_SORTING_GRID_TEMPLATE : CNT_LE_COUNTING_GRID_TEMPLATE); + static CountEncoder buildCountLessOrEqualEncoder(boolean useSortingGrid) { + return new CountEncoder(ComparisonOperators.LE, useSortingGrid ? CNT_LE_SORTING_GRID_TEMPLATE : CNT_LE_COUNTING_GRID_TEMPLATE); } - static CountEncoder buildCountEqualsEncoder(ProgramParser parser) { - return new CountEncoder(parser, ComparisonOperators.EQ, CNT_EQ_TEMPLATE); + static CountEncoder buildCountEqualsEncoder() { + return new CountEncoder(ComparisonOperators.EQ, CNT_EQ_TEMPLATE); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java index 179014554..242fc7719 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java @@ -1,13 +1,15 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.apache.commons.collections4.SetUtils; import org.stringtemplate.v4.ST; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; @@ -24,7 +26,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.literals.Literals; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; @@ -72,7 +74,7 @@ public MinMaxEncoder(AggregateFunctionSymbol func) { } @Override - protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) { + protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { ST encodingTemplate = null; if (this.getAggregateFunctionToEncode() == AggregateFunctionSymbol.MAX) { encodingTemplate = new ST(MAX_LITERAL_ENCODING); @@ -112,7 +114,7 @@ protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) */ NormalHead resultRuleHead = Heads.newNormalHead( Atoms.newBasicAtom(Predicates.getPredicate(resultName, 2), aggregateToEncode.getAggregateArguments(), atom.getLowerBoundTerm())); - List resultRuleBody = new ArrayList<>(); + Set resultRuleBody = new LinkedHashSet<>(); VariableTerm aggregateValue = Terms.newVariable("_AGG_VAL"); ComparisonLiteral aggregateValueComparison = Literals.fromAtom(Atoms.newComparisonAtom(atom.getLowerBoundTerm(), aggregateValue, cmpOp), true); Literal aggregateResult = Atoms.newBasicAtom(Predicates.getPredicate( @@ -121,7 +123,7 @@ protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) resultRuleBody.add(aggregateResult); resultRuleBody.add(aggregateValueComparison); resultRuleBody.addAll(aggregateToEncode.getDependencies()); - ASPCore2ProgramBuilder bld = Programs.builder(parser.parse(encodingTemplate.render())); + InputProgramBuilder bld = Programs.builder(parser.parse(encodingTemplate.render())); Rule resultRule = Rules.newRule(resultRuleHead, resultRuleBody); bld.addRule(resultRule); return bld.build(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java index 8869c66fe..a7eeb9fab 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java @@ -1,13 +1,7 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import java.util.ArrayList; -import java.util.Collections; - -import org.apache.commons.collections4.ListUtils; -import org.stringtemplate.v4.ST; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -23,6 +17,12 @@ import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationRewriting; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; +import org.apache.commons.collections4.ListUtils; +import org.stringtemplate.v4.ST; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; /** * Abstract base class for aggregate encoders making use of stringtemplates in their rewriting workflow. @@ -53,7 +53,7 @@ protected StringtemplateBasedAggregateEncoder(AggregateFunctionSymbol aggregateF } @Override - protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) { + protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { String aggregateId = aggregateToEncode.getId(); /* @@ -81,10 +81,10 @@ protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) String coreEncodingAsp = coreEncodingTemplate.render(); // Create the basic program - ASPCore2Program coreEncoding = new EnumerationRewriting().apply(parser.parse(coreEncodingAsp)); + InputProgram coreEncoding = new EnumerationRewriting().apply(parser.parse(coreEncodingAsp)); // Add the programatically created bound rule and return - return Programs.newASPCore2Program(ListUtils.union(coreEncoding.getRules(), Collections.singletonList(boundRule)), coreEncoding.getFacts(), + return Programs.newInputProgram(ListUtils.union(coreEncoding.getRules(), Collections.singletonList(boundRule)), coreEncoding.getFacts(), Programs.newInlineDirectives()); } @@ -95,13 +95,13 @@ private String getBoundPredicateName(String aggregateId) { private Rule buildZeroBoundRule(AggregateInfo aggregateToEncode) { BasicAtom bound = Atoms.newBasicAtom(Predicates.getPredicate(getBoundPredicateName(aggregateToEncode.getId()), 2), aggregateToEncode.getAggregateArguments(), Terms.newConstant(0)); - return Rules.newRule(Heads.newNormalHead(bound), new ArrayList<>(aggregateToEncode.getDependencies())); + return Rules.newRule(Heads.newNormalHead(bound), new LinkedHashSet<>(aggregateToEncode.getDependencies())); } private Rule buildBoundRule(AggregateInfo aggregateToEncode) { BasicAtom bound = Atoms.newBasicAtom(Predicates.getPredicate(getBoundPredicateName(aggregateToEncode.getId()), 2), aggregateToEncode.getAggregateArguments(), aggregateToEncode.getLiteral().getAtom().getLowerBoundTerm()); - return Rules.newRule(Heads.newNormalHead(bound), new ArrayList<>(aggregateToEncode.getDependencies())); + return Rules.newRule(Heads.newNormalHead(bound), new LinkedHashSet<>(aggregateToEncode.getDependencies())); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java index 1fee5aab3..0dc4a0358 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java @@ -33,16 +33,16 @@ public final class SumEncoder extends StringtemplateBasedAggregateEncoder { private static final ST NON_NEG_ELEMENTS_SUM_LE_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("sum_le_no_negative_elements"); private static final ST NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("sum_eq_no_negative_elements"); - private SumEncoder(ProgramParser parser, ComparisonOperator acceptedOperator, ST encodingTemplate) { - super(parser, AggregateFunctionSymbol.SUM, acceptedOperator, encodingTemplate); + private SumEncoder(ComparisonOperator acceptedOperator, ST encodingTemplate) { + super(AggregateFunctionSymbol.SUM, acceptedOperator, encodingTemplate); } - static SumEncoder buildSumLessOrEqualEncoder(ProgramParser parser, boolean supportNegativeIntegers) { - return new SumEncoder(parser, ComparisonOperators.LE, supportNegativeIntegers ? SUM_LE_TEMPLATE : NON_NEG_ELEMENTS_SUM_LE_TEMPLATE); + static SumEncoder buildSumLessOrEqualEncoder(boolean supportNegativeIntegers) { + return new SumEncoder(ComparisonOperators.LE, supportNegativeIntegers ? SUM_LE_TEMPLATE : NON_NEG_ELEMENTS_SUM_LE_TEMPLATE); } - static SumEncoder buildSumEqualsEncoder(ProgramParser parser, boolean supportNegativeIntegers) { - return new SumEncoder(parser, ComparisonOperators.EQ, supportNegativeIntegers ? SUM_EQ_TEMPLATE : NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE); + static SumEncoder buildSumEqualsEncoder(boolean supportNegativeIntegers) { + return new SumEncoder(ComparisonOperators.EQ, supportNegativeIntegers ? SUM_EQ_TEMPLATE : NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java index baf96bfb5..a3f81eefa 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/CompiledRules.java @@ -4,7 +4,9 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.core.programs.rules.InternalRule; public final class CompiledRules { @@ -13,7 +15,7 @@ private CompiledRules() { } public static CompiledRule newCompiledRule(NormalHead head, Set body) { - return new CompiledRuleImpl(head, body); + return new InternalRule(head, body); } public static CompiledRule newCompiledRule(NormalHead head, Literal... body) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java index ed7e4b1fb..47e037d87 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java @@ -45,7 +45,6 @@ import static at.ac.tuwien.kr.alpha.core.programs.atoms.Literals.atomOf; import static at.ac.tuwien.kr.alpha.core.programs.atoms.Literals.atomToLiteral; import static at.ac.tuwien.kr.alpha.core.programs.atoms.Literals.isPositive; -import static at.ac.tuwien.kr.alpha.core.solver.Atoms.isAtom; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.FALSE; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; @@ -338,7 +337,7 @@ private boolean assignmentsConsistent(ThriceTruth oldTruth, ThriceTruth value) { } private ConflictCause assignWithTrail(int atom, ThriceTruth value, Antecedent impliedBy) { - if (!isAtom(atom)) { + if (!AtomStore.isAtom(atom)) { throw new IllegalArgumentException("not an atom"); } if (value == null) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java index 349249c17..2f2b41740 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/RuleTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; @@ -35,11 +35,11 @@ public void renameVariables() { @Test public void testRulesEqual() { - ASPCore2Program p1 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); + InputProgram p1 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); Rule r1 = p1.getRules().get(0); - ASPCore2Program p2 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); + InputProgram p2 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); Rule r2 = p2.getRules().get(0); - ASPCore2Program p3 = parser.parse("p(X, Y) :- bla(X), blub(X), foo(X, X), not bar(X)."); + InputProgram p3 = parser.parse("p(X, Y) :- bla(X), blub(X), foo(X, X), not bar(X)."); Rule r3 = p3.getRules().get(0); assertTrue(r1.equals(r2)); assertTrue(r2.equals(r1)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java index 1f1ca1d9b..cdee89727 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java @@ -43,7 +43,7 @@ import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -100,7 +100,7 @@ public void resetRuleIdGenerator() { */ @Test public void groundRuleAlreadyGround() { - ASPCore2Program program = PROGRAM_PARSER.parse("a :- not b. " + InputProgram program = PROGRAM_PARSER.parse("a :- not b. " + "b :- not a. " + "c :- b."); NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); @@ -121,7 +121,7 @@ public void groundRuleAlreadyGround() { */ @Test public void groundRuleWithLongerBodyAlreadyGround() { - ASPCore2Program program = PROGRAM_PARSER.parse("a :- not b. " + InputProgram program = PROGRAM_PARSER.parse("a :- not b. " + "b :- not a. " + "c :- b. " + "d :- b, c. "); @@ -147,7 +147,7 @@ public void groundRuleWithLongerBodyAlreadyGround() { */ @Test public void groundConstraintAlreadyGround() { - ASPCore2Program program = PROGRAM_PARSER.parse("a :- not b. " + InputProgram program = PROGRAM_PARSER.parse("a :- not b. " + "b :- not a. " + ":- b."); NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); @@ -237,7 +237,7 @@ private void testDeadEnd(String predicateNameOfStartingLiteral, RuleGroundingOrd @Test public void testGroundingOfRuleSwitchedOffByFalsePositiveBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X). " + "b(X) :- something(X). "); testIfGrounderGroundsRule(program, 0, litAX, 1, ThriceTruth.FALSE, false); @@ -245,7 +245,7 @@ public void testGroundingOfRuleSwitchedOffByFalsePositiveBody() { @Test public void testGroundingOfRuleNotSwitchedOffByTruePositiveBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X). " + "b(X) :- something(X). "); testIfGrounderGroundsRule(program, 0, litAX, 1, ThriceTruth.TRUE, true); @@ -254,7 +254,7 @@ public void testGroundingOfRuleNotSwitchedOffByTruePositiveBody() { @Test @Disabled("Currently, rule grounding is not switched off by a true negative body atom") public void testGroundingOfRuleSwitchedOffByTrueNegativeBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), not b(X). " + "b(X) :- something(X). "); testIfGrounderGroundsRule(program, 0, litAX, 1, ThriceTruth.TRUE, false); @@ -262,7 +262,7 @@ public void testGroundingOfRuleSwitchedOffByTrueNegativeBody() { @Test public void testGroundingOfRuleNotSwitchedOffByFalseNegativeBody() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), not b(X). " + "b(X) :- something(X). "); @@ -276,7 +276,7 @@ public void testGroundingOfRuleNotSwitchedOffByFalseNegativeBody() { * {@code bTruth}. * It is asserted that ground instantiations are produced if and only if {@code expectNoGoods} is true. */ - private void testIfGrounderGroundsRule(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, ThriceTruth bTruth, + private void testIfGrounderGroundsRule(InputProgram program, int ruleID, Literal startingLiteral, int startingInstance, ThriceTruth bTruth, boolean expectNoGoods) { CompiledProgram internalPrg = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(program)); AtomStore atomStore = new AtomStoreImpl(); @@ -299,7 +299,7 @@ private void testIfGrounderGroundsRule(ASPCore2Program program, int ruleID, Lite @Test public void testPermissiveGrounderHeuristicTolerance_0_reject() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X). " + "b(X) :- something(X)."); testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 0, false, Arrays.asList(1)); @@ -307,7 +307,7 @@ public void testPermissiveGrounderHeuristicTolerance_0_reject() { @Test public void testPermissiveGrounderHeuristicTolerance_1_accept() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X). " + "b(X) :- something(X)."); testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 1, true, Arrays.asList(1)); @@ -315,7 +315,7 @@ public void testPermissiveGrounderHeuristicTolerance_1_accept() { @Test public void testPermissiveGrounderHeuristicTolerance_1_reject() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X), b(X+1). " + "b(X) :- something(X)."); testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 1, false, Arrays.asList(2)); @@ -323,7 +323,7 @@ public void testPermissiveGrounderHeuristicTolerance_1_reject() { @Test public void testPermissiveGrounderHeuristicTolerance_2_accept() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X), b(X+1). " + "b(X) :- something(X)."); testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 2, true, Arrays.asList(2)); @@ -331,7 +331,7 @@ public void testPermissiveGrounderHeuristicTolerance_2_accept() { @Test public void testPermissiveGrounderHeuristicTolerance_1_accept_two_substitutions() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X,Y). " + "b(X,Y) :- something(X,Y)."); testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 1, new ThriceTruth[] {ThriceTruth.TRUE, ThriceTruth.TRUE }, 2, true, @@ -340,7 +340,7 @@ public void testPermissiveGrounderHeuristicTolerance_1_accept_two_substitutions( @Test public void testPermissiveGrounderHeuristicTolerance_1_accept_accept_two_substitutions_with_different_remaining_tolerances() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(1), b(X,Y). " + "b(X,Y) :- something(X,Y)."); testPermissiveGrounderHeuristicTolerance(program, 0, litA1, 1, 1, new ThriceTruth[] {null, null }, 2, true, Arrays.asList(1, 1)); @@ -348,7 +348,7 @@ public void testPermissiveGrounderHeuristicTolerance_1_accept_accept_two_substit @Test public void testPermissiveGrounderHeuristicTolerance_2_reject() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). " + "c(X) :- a(X), b(X), b(X+1), b(X+2). " + "b(X) :- something(X)."); testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 2, false, Arrays.asList(3)); @@ -356,13 +356,13 @@ public void testPermissiveGrounderHeuristicTolerance_2_reject() { @Test public void testPermissiveGrounderHeuristicTolerance_2_accept_multiple_facts_of_same_variable() { - ASPCore2Program program = PROGRAM_PARSER.parse("a(1). b(1). " + InputProgram program = PROGRAM_PARSER.parse("a(1). b(1). " + "c(X) :- a(X), b(X), b(X+1), b(X+2). " + "b(X) :- something(X)."); testPermissiveGrounderHeuristicTolerance(program, 0, litAX, 1, 2, true, Arrays.asList(2)); } - private void testPermissiveGrounderHeuristicTolerance(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, + private void testPermissiveGrounderHeuristicTolerance(InputProgram program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, boolean expectNoGoods, List expectedNumbersOfUnassignedPositiveBodyAtoms) { testPermissiveGrounderHeuristicTolerance(program, ruleID, startingLiteral, startingInstance, tolerance, new ThriceTruth[] {}, 1, expectNoGoods, expectedNumbersOfUnassignedPositiveBodyAtoms); @@ -386,7 +386,7 @@ private void testPermissiveGrounderHeuristicTolerance(ASPCore2Program program, i * If ground instantiations are produced, it is also asserted that the numbers of unassigned positive body atoms * determined by {@code getGroundInstantiations} match those given in {@code expectedNumbersOfUnassignedPositiveBodyAtoms}. */ - private void testPermissiveGrounderHeuristicTolerance(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, + private void testPermissiveGrounderHeuristicTolerance(InputProgram program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, ThriceTruth[] truthsOfB, int arityOfB, boolean expectNoGoods, List expectedNumbersOfUnassignedPositiveBodyAtoms) { CompiledProgram internalPrg = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(program)); AtomStore atomStore = new AtomStoreImpl(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java index 501978758..ef42a9eb7 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java @@ -33,7 +33,7 @@ import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; @@ -71,7 +71,7 @@ public class NoGoodGeneratorTest { */ @Test public void collectNeg_ContainsOnlyPositiveLiterals() { - ASPCore2Program input = PARSER.parse("p(a,b). " + InputProgram input = PARSER.parse("p(a,b). " + "q(a,b) :- not nq(a,b). " + "nq(a,b) :- not q(a,b)."); NormalProgram normal = NORMALIZE_TRANSFORM.apply(input); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java index efae731d9..a59a958d3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -78,7 +78,7 @@ public void mergeUnifierIntoLeft() { private BasicAtom parseAtom(String atom) { ProgramParser programParser = new ProgramParserImpl(); - ASPCore2Program program = programParser.parse(atom + "."); + InputProgram program = programParser.parse(atom + "."); return (BasicAtom) program.getFacts().get(0); } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java index fd40c3db6..7b96f4f92 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java @@ -1,11 +1,11 @@ package at.ac.tuwien.kr.alpha.core.parser; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; public class AspCore2ParserTest extends ParserTest { protected AspCore2ParserTest() { - super(new ASPCore2ProgramParser()); + super(new InputProgramParser()); } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 3c4da3aaa..3557a6fa0 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -46,7 +46,7 @@ import org.antlr.v4.runtime.CharStreams; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -91,7 +91,7 @@ public class ParserTest { @Test public void parseFact() { - ASPCore2Program parsedProgram = parser.parse("p(a,b)."); + InputProgram parsedProgram = parser.parse("p(a,b)."); assertEquals(1, parsedProgram.getFacts().size(), "Program contains one fact."); assertEquals("p", parsedProgram.getFacts().get(0).getPredicate().getName(), "Predicate name of fact is p."); @@ -102,7 +102,7 @@ public void parseFact() { @Test public void parseFactWithFunctionTerms() { - ASPCore2Program parsedProgram = parser.parse("p(f(a),g(h(Y)))."); + InputProgram parsedProgram = parser.parse("p(f(a),g(h(Y)))."); assertEquals(1, parsedProgram.getFacts().size(), "Program contains one fact."); assertEquals("p", parsedProgram.getFacts().get(0).getPredicate().getName(), "Predicate name of fact is p."); @@ -113,7 +113,7 @@ public void parseFactWithFunctionTerms() { @Test public void parseSmallProgram() { - ASPCore2Program parsedProgram = parser.parse( + InputProgram parsedProgram = parser.parse( "a :- b, not d." + System.lineSeparator() + "c(X) :- p(X,a,_), q(Xaa,xaa)." + System.lineSeparator() + ":- f(Y)."); @@ -130,7 +130,7 @@ public void parseBadSyntax() { @Test public void parseBuiltinAtom() { - ASPCore2Program parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); + InputProgram parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); assertEquals(1, parsedProgram.getRules().size()); assertEquals(3, parsedProgram.getRules().get(0).getBody().size()); } @@ -145,7 +145,7 @@ public void parseProgramWithDisjunctionInHead() { @Test public void parseInterval() { - ASPCore2Program parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); + InputProgram parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); IntervalTerm factInterval = (IntervalTerm) parsedProgram.getFacts().get(0).getTerms().get(0); assertTrue(factInterval.equals(Terms.newIntervalTerm(Terms.newConstant(2), Terms.newConstant(5)))); IntervalTerm bodyInterval = (IntervalTerm) parsedProgram.getRules().get(0).getBody().stream().findFirst().get().getTerms().get(1); @@ -154,7 +154,7 @@ public void parseInterval() { @Test public void parseChoiceRule() { - ASPCore2Program parsedProgram = parser.parse("dom(1). dom(2). { a ; b } :- dom(X)."); + InputProgram parsedProgram = parser.parse("dom(1). dom(2). { a ; b } :- dom(X)."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); @@ -165,7 +165,7 @@ public void parseChoiceRule() { @Test public void parseChoiceRuleBounded() { - ASPCore2Program parsedProgram = parser.parse("dom(1). dom(2). 1 < { a: p(v,w), not r; b } <= 13 :- dom(X). foo."); + InputProgram parsedProgram = parser.parse("dom(1). dom(2). 1 < { a: p(v,w), not r; b } <= 13 :- dom(X). foo."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); @@ -215,7 +215,7 @@ public void testMissingDotNotIgnored() { @Test public void parseEnumerationDirective() { - ASPCore2Program parsedProgram = parser.parse("p(a,1)." + + InputProgram parsedProgram = parser.parse("p(a,1)." + "# enumeration_predicate_is mune." + "r(X) :- p(X), mune(X)." + "p(b,2)."); @@ -225,7 +225,7 @@ public void parseEnumerationDirective() { @Test public void cardinalityAggregate() { - ASPCore2Program parsedProgram = parser.parse("num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K)."); + InputProgram parsedProgram = parser.parse("num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K)."); Optional optionalBodyElement = parsedProgram.getRules().get(0).getBody().stream().filter((lit) -> lit instanceof AggregateLiteral).findFirst(); assertTrue(optionalBodyElement.isPresent()); Literal bodyElement = optionalBodyElement.get(); @@ -244,7 +244,7 @@ public void cardinalityAggregate() { @Test public void stringWithEscapedQuotes() throws IOException { CharStream stream = CharStreams.fromStream(ParserTest.class.getResourceAsStream("/escaped_quotes.asp")); - ASPCore2Program prog = parser.parse(stream); + InputProgram prog = parser.parse(stream); assertEquals(1, prog.getFacts().size()); Atom stringAtom = prog.getFacts().get(0); String stringWithQuotes = stringAtom.getTerms().get(0).toString(); @@ -253,7 +253,7 @@ public void stringWithEscapedQuotes() throws IOException { @Test public void unitTestExpectUnsat() { - ASPCore2Program prog = parser.parse(UNIT_TEST_EXPECT_UNSAT); + InputProgram prog = parser.parse(UNIT_TEST_EXPECT_UNSAT); assertEquals(1, prog.getTestCases().size()); TestCase tc = prog.getTestCases().get(0); assertEquals("expected_unsat", tc.getName()); @@ -263,7 +263,7 @@ public void unitTestExpectUnsat() { @Test public void unitTestBasicTest() { - ASPCore2Program prog = parser.parse(UNIT_TEST_BASIC_TEST); + InputProgram prog = parser.parse(UNIT_TEST_BASIC_TEST); assertEquals(1, prog.getTestCases().size()); TestCase tc = prog.getTestCases().get(0); assertEquals("ensure_a", tc.getName()); @@ -274,7 +274,7 @@ public void unitTestBasicTest() { @Test public void unitTestMultipleAsserts() { - ASPCore2Program prog = parser.parse(UNIT_TEST_MORE_ASSERTIONS); + InputProgram prog = parser.parse(UNIT_TEST_MORE_ASSERTIONS); assertEquals(1, prog.getTestCases().size()); TestCase tc = prog.getTestCases().get(0); assertEquals("ensure_a", tc.getName()); @@ -286,7 +286,7 @@ public void unitTestMultipleAsserts() { @Test public void unitTestMoreTCs() { - ASPCore2Program prog = parser.parse(UNIT_TEST_MORE_TCS); + InputProgram prog = parser.parse(UNIT_TEST_MORE_TCS); assertEquals(2, prog.getTestCases().size()); TestCase tc1 = prog.getTestCases().get(0); assertEquals("ensure_a", tc1.getName()); @@ -296,7 +296,7 @@ public void unitTestMoreTCs() { @Test public void unitTestKeywordsAsIds() { - ASPCore2Program prog = parser.parse(UNIT_TEST_KEYWORDS_AS_IDS); + InputProgram prog = parser.parse(UNIT_TEST_KEYWORDS_AS_IDS); assertEquals(1, prog.getTestCases().size()); TestCase tc = prog.getTestCases().get(0); assertEquals("test", tc.getName()); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java index 1c0c26b57..d202e579c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java @@ -15,7 +15,7 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.externals.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -58,35 +58,35 @@ public static final Set>> extWithOutput(int in) { @Test public void testIsBasicAtomGround() { - ASPCore2Program p = parser.parse("bla(blubb, foo(bar))."); + InputProgram p = parser.parse("bla(blubb, foo(bar))."); Atom a = p.getFacts().get(0); assertBasicAtomGround(a, true); - ASPCore2Program p1 = parser.parse("foo(1, 2, 3, \"bar\")."); + InputProgram p1 = parser.parse("foo(1, 2, 3, \"bar\")."); Atom a1 = p1.getFacts().get(0); assertBasicAtomGround(a1, true); - ASPCore2Program p2 = parser.parse("foo(BAR)."); + InputProgram p2 = parser.parse("foo(BAR)."); Atom a2 = p2.getFacts().get(0); assertBasicAtomGround(a2, false); - ASPCore2Program p3 = parser.parse("foo(b, a, r(\"bla\", BLUBB))."); + InputProgram p3 = parser.parse("foo(b, a, r(\"bla\", BLUBB))."); Atom a3 = p3.getFacts().get(0); assertBasicAtomGround(a3, false); } @Test public void testAreBasicAtomsEqual() { - ASPCore2Program p1 = parser.parse("bla(blubb, foo(bar)). bla(blubb, foo(bar))."); + InputProgram p1 = parser.parse("bla(blubb, foo(bar)). bla(blubb, foo(bar))."); Atom a1 = p1.getFacts().get(0); Atom a2 = p1.getFacts().get(1); assertEquals(a1, a2); - ASPCore2Program p2 = parser.parse("foo(1, 2, 3, \"bar\"). foo(1, 2, 3, \"bar\")."); + InputProgram p2 = parser.parse("foo(1, 2, 3, \"bar\"). foo(1, 2, 3, \"bar\")."); Atom a3 = p2.getFacts().get(0); Atom a4 = p2.getFacts().get(1); assertEquals(a3, a4); - ASPCore2Program p3 = parser.parse("foo(BAR). foo(BAR)."); + InputProgram p3 = parser.parse("foo(BAR). foo(BAR)."); Atom a5 = p3.getFacts().get(0); Atom a6 = p3.getFacts().get(1); assertEquals(a5, a6); - ASPCore2Program p4 = parser.parse("foo(b, a, r(\"bla\", BLUBB)). foo(b, a, r(\"bla\", BLUBB))."); + InputProgram p4 = parser.parse("foo(b, a, r(\"bla\", BLUBB)). foo(b, a, r(\"bla\", BLUBB))."); Atom a7 = p4.getFacts().get(0); Atom a8 = p4.getFacts().get(1); assertEquals(a7, a8); @@ -101,13 +101,13 @@ public void testAreBasicAtomsEqual() { @Test public void testIsExternalAtomGround() { - ASPCore2Program p1 = parser.parse("a :- &isFoo[1].", externals); + InputProgram p1 = parser.parse("a :- &isFoo[1].", externals); Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); assertExternalAtomGround(ext1, true); - ASPCore2Program p2 = parser.parse("a :- &isFoo[bar(1)].", externals); + InputProgram p2 = parser.parse("a :- &isFoo[bar(1)].", externals); Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); assertExternalAtomGround(ext2, true); - ASPCore2Program p3 = parser.parse("a :- &isFoo[BLA].", externals); + InputProgram p3 = parser.parse("a :- &isFoo[BLA].", externals); Atom ext3 = p3.getRules().get(0).getBody().stream().findFirst().get().getAtom(); assertExternalAtomGround(ext3, false); } @@ -115,9 +115,9 @@ public void testIsExternalAtomGround() { @Test @SuppressWarnings("unlikely-arg-type") public void testAreExternalAtomsEqual() { - ASPCore2Program p1 = parser.parse("a :- &isFoo[1].", externals); + InputProgram p1 = parser.parse("a :- &isFoo[1].", externals); Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - ASPCore2Program p2 = parser.parse("a :- &isFoo[1].", externals); + InputProgram p2 = parser.parse("a :- &isFoo[1].", externals); Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); assertEquals(ext1, ext2); assertEquals(ext2, ext1); @@ -129,7 +129,7 @@ public void testAreExternalAtomsEqual() { @Test public void testExternalHasOutput() { - ASPCore2Program p = parser.parse("a:- &extWithOutput[1](OUT).", externals); + InputProgram p = parser.parse("a:- &extWithOutput[1](OUT).", externals); Atom ext = p.getRules().get(0).getBody().stream().findFirst().get().getAtom(); assertExternalAtomGround(ext, false); assertTrue(((ExternalAtom) ext).hasOutput()); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index d7ff68a37..79ae8be23 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -12,7 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.programs.Programs; @@ -44,11 +44,11 @@ private static String readTestResource(String resource) throws IOException { } private , O extends Program> void genericTransformationTest(ProgramTransformation transform, - Function prepareFunc, String resourceSet) { + Function prepareFunc, String resourceSet) { try { String inputCode = ProgramTransformationTest.readTestResource(resourceSet + ".in"); String expectedResult = ProgramTransformationTest.readTestResource(resourceSet + ".out"); - ASPCore2Program inputProg = PARSER.parse(inputCode, Externals.scan(ProgramTransformationTest.class)); + InputProgram inputProg = PARSER.parse(inputCode, Externals.scan(ProgramTransformationTest.class)); I transformInput = prepareFunc.apply(inputProg); String beforeTransformProg = transformInput.toString(); O transformedProg = transform.apply(transformInput); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java index 8715675b0..383cf8ac0 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java @@ -18,7 +18,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.Predicates; @@ -105,7 +105,7 @@ public static List params() { public void runTest(String aspString, Consumer programVerifier, Consumer> resultVerifier) { // Parse and pre-evaulate program ProgramParser parser = new ProgramParserImpl(); - ASPCore2Program prog = parser.parse(aspString); + InputProgram prog = parser.parse(aspString); AnalyzedProgram analyzed = AnalyzedProgram .analyzeNormalProgram(new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG).apply(prog)); CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java index fe0bd40b0..23eff4511 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.common.NoGood; @@ -54,7 +54,7 @@ public class ChoiceManagerTests { @BeforeEach public void setUp() { String testProgram = "h :- b1, b2, not b3, not b4."; - ASPCore2Program parsedProgram = new ProgramParserImpl().parse(testProgram); + InputProgram parsedProgram = new ProgramParserImpl().parse(testProgram); CompiledProgram internalProgram = InternalProgram.fromNormalProgram(new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG).apply(parsedProgram)); atomStore = new AtomStoreImpl(); grounder = new NaiveGrounder(internalProgram, atomStore, true); diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java index 7de3ef84d..8c45bf662 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java @@ -1,18 +1,19 @@ package at.ac.tuwien.kr.alpha.test; -import static java.util.Collections.emptySet; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.impl.AnswerSetsParser; +import at.ac.tuwien.kr.alpha.api.programs.Program; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; import java.util.StringJoiner; -import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.programs.Program; -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import static java.util.Collections.emptySet; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class AlphaAssertions { diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index b3c014c13..53d5eb323 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -1,5 +1,6 @@ package at.ac.tuwien.kr.alpha.api.impl; +import java.util.Collections; import java.util.function.Supplier; import at.ac.tuwien.kr.alpha.api.Alpha; @@ -9,43 +10,26 @@ import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.commons.programs.reification.Reifier; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.util.IdGenerator; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.actions.ActionExecutionServiceImpl; import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.actions.DefaultActionImplementationProvider; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermTransformer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ChoiceHeadNormalizer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationTransformer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.IntervalTermTransformer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramNormalizer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformer; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; -import at.ac.tuwien.kr.alpha.core.programs.transformation.VariableEqualityTransformer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateTransformer; -import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AggregateEncoders; import at.ac.tuwien.kr.alpha.core.solver.SolverConfig; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; public class AlphaFactory { - protected ProgramTransformer newProgramNormalizer(ProgramParser parser, - AggregateRewritingConfig aggregateCfg) { - return new ProgramNormalizer( - new VariableEqualityTransformer(), - new ChoiceHeadNormalizer(), - new AggregateTransformer( - AggregateEncoders.newCountEqualsEncoder(parser), - AggregateEncoders.newCountLessOrEqualEncoder(parser, aggregateCfg.isUseSortingGridEncoding()), - AggregateEncoders.newSumEqualsEncoder(parser, aggregateCfg.isSupportNegativeValuesInSums()), - AggregateEncoders.newSumLessOrEqualEncoder(parser, aggregateCfg.isSupportNegativeValuesInSums()), - AggregateEncoders.newMinEncoder(parser), - AggregateEncoders.newMaxEncoder(parser)), - new EnumerationTransformer(), - new IntervalTermTransformer(), - new ArithmeticTermTransformer()); + protected ProgramTransformation newProgramNormalizer(AggregateRewritingConfig aggregateCfg) { + return new NormalizeProgramTransformation(aggregateCfg); } protected Supplier newStratifiedEvaluationFactory(ActionImplementationProvider actionImplementationProvider, @@ -83,15 +67,8 @@ protected ActionImplementationProvider newActionImplementationProvider() { public Alpha newAlpha(SystemConfig cfg) { ActionImplementationProvider actionImplementationProvider = newActionImplementationProvider(); - ProgramParser parser; - if (cfg.isAcceptEvologPrograms()) { - parser = new EvologProgramParser(actionImplementationProvider); // TODO need to give stdin/stdout definitions to parser (pass in implementation - // provider) - } else { - parser = new ASPCore2ProgramParser(); - } - ProgramTransformer programNormalizer = newProgramNormalizer(parser, - cfg.getAggregateRewritingConfig()); + ProgramParser parser = new ProgramParserImpl(actionImplementationProvider, Collections.emptyMap()); + ProgramTransformation programNormalizer = new NormalizeProgramTransformation(cfg.getAggregateRewritingConfig()); // Stratified evaluation factory - since every instance of stratified evaluation is only good for one program, we need a factory. Supplier stratifiedEvaluationFactory = newStratifiedEvaluationFactory(actionImplementationProvider, cfg.isDebugInternalChecks()); @@ -103,7 +80,10 @@ public Alpha newAlpha(SystemConfig cfg) { SolverFactory solverFactory = newSolverFactory(cfg); // Now that all dependencies are taken care of, build new Alpha instance. - return new AlphaImpl(parser, programNormalizer, stratifiedEvaluationFactory, grounderFactory, solverFactory, cfg.isSortAnswerSets()); + return new AlphaImpl(parser, programNormalizer, stratifiedEvaluationFactory, grounderFactory, solverFactory, new Reifier(() -> { + IdGenerator idGen = new IntIdGenerator(0); + return () -> Terms.newConstant(idGen.getNextId()); + }), cfg.isSortAnswerSets()); } // Create Alpha instance with default config. diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index 8534b91b4..78631d11b 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -32,10 +32,8 @@ import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.config.InputConfig; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; @@ -44,21 +42,17 @@ import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.tests.TestResult; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.reification.Reifier; -import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.commons.util.IdGenerator; -import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; import com.google.common.annotations.VisibleForTesting; @@ -76,6 +70,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -83,29 +78,37 @@ public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); - private final SystemConfig config; // Config is initialized with default values. - private final ProgramParser parser = new ProgramParserImpl(); - - private final TestRunner testRunner; - private final Reifier reifier = new Reifier(() -> { - IdGenerator idGen = new IntIdGenerator(0); - return () -> Terms.newConstant(idGen.getNextId()); - }); + private final ProgramParser parser; + private final ProgramTransformation programNormalization; - public AlphaImpl(SystemConfig cfg) { - this.config = cfg; + private final Supplier stratifiedEvaluationFactory; + private final GrounderFactory grounderFactory; + private final SolverFactory solverFactory; + private final TestRunner testRunner; + private final Reifier reifier; + private final boolean sortAnswerSets; + + AlphaImpl(ProgramParser parser, ProgramTransformation programNormalization, + Supplier stratifiedEvaluationFactory, + GrounderFactory grounderFactory, + SolverFactory solverFactory, + Reifier reifier, + boolean sortAnswerSets) { + this.parser = parser; + this.programNormalization = programNormalization; + this.stratifiedEvaluationFactory = stratifiedEvaluationFactory; + this.grounderFactory = grounderFactory; + this.solverFactory = solverFactory; + this.reifier = reifier; this.testRunner = new TestRunner(this); - } - - public AlphaImpl() { - this(new SystemConfig()); + this.sortAnswerSets = sortAnswerSets; } @Override - public ASPCore2Program readProgram(InputConfig cfg) throws IOException { - ASPCore2ProgramBuilder prgBuilder = Programs.builder(); - ASPCore2Program tmpProg; + public InputProgram readProgram(InputConfig cfg) throws IOException { + InputProgramBuilder prgBuilder = Programs.builder(); + InputProgram tmpProg; if (!cfg.getFiles().isEmpty()) { tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); prgBuilder.accumulate(tmpProg); @@ -118,14 +121,14 @@ public ASPCore2Program readProgram(InputConfig cfg) throws IOException { } @Override - public ASPCore2Program readProgramFiles(boolean literate, Map externals, List paths) throws IOException { + public InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException { return readProgramFiles(literate, externals, paths.stream().map(Paths::get).collect(Collectors.toList()).toArray(new Path[] {})); } @Override - public ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - ASPCore2ProgramBuilder prgBuilder = Programs.builder(); - ASPCore2Program tmpProg; + public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { + InputProgramBuilder prgBuilder = Programs.builder(); + InputProgram tmpProg; for (Path path : paths) { InputStream stream; if (!literate) { @@ -140,28 +143,37 @@ public ASPCore2Program readProgramFiles(boolean literate, Map externals) { + public InputProgram readProgramString(String aspString, Map externals) { return parser.parse(aspString, externals); } @Override - public ASPCore2Program readProgramString(String aspString) { + public InputProgram readProgramString(String aspString) { return readProgramString(aspString, Collections.emptyMap()); } @Override - public NormalProgram normalizeProgram(ASPCore2Program program) { - return new NormalizeProgramTransformation(config.getAggregateRewritingConfig()).apply(program); + public InputProgram readProgramStream(InputStream is) throws IOException { + return parser.parse(is); + } + + @Override + public InputProgram readProgramStream(InputStream is, Map externals) throws IOException { + return parser.parse(is, externals); + } + + @Override + public NormalProgram normalizeProgram(InputProgram program) { + return programNormalization.apply(program); } @VisibleForTesting InternalProgram performProgramPreprocessing(NormalProgram program) { + LOGGER.debug("Preprocessing InternalProgram!"); LOGGER.debug("Preprocessing InternalProgram!"); InternalProgram retVal = InternalProgram.fromNormalProgram(program); - if (config.isEvaluateStratifiedPart()) { - AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); - retVal = new StratifiedEvaluation().apply(analyzed); - } + AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); + retVal = stratifiedEvaluationFactory.get().apply(analyzed); return retVal; } @@ -170,7 +182,7 @@ InternalProgram performProgramPreprocessing(NormalProgram program) { * program analysis and normalization aren't of interest. */ @Override - public Stream solve(ASPCore2Program program) { + public Stream solve(InputProgram program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -179,7 +191,7 @@ public Stream solve(ASPCore2Program program) { * details of the program analysis and normalization aren't of interest. */ @Override - public Stream solve(ASPCore2Program program, java.util.function.Predicate filter) { + public Stream solve(InputProgram program, java.util.function.Predicate filter) { NormalProgram normalized = normalizeProgram(program); return solve(normalized, filter); } @@ -203,12 +215,12 @@ public Stream solve(NormalProgram program, java.util.function.Predica * Solves the given program and filters answer sets based on the passed predicate. * * @param program an {@link InternalProgram} to solve - * @param filter {@link Predicate} filtering {@at.ac.tuwien.kr.alpha.common.Predicate}s in the returned answer sets + * @param filter {@link Predicate} filtering {@link at.ac.tuwien.kr.alpha.api.programs.Predicate}s in the returned answer sets * @return a Stream of answer sets representing stable models of the given program */ private Stream solve(CompiledProgram program, java.util.function.Predicate filter) { Stream retVal = prepareSolverFor(program, filter).stream(); - return config.isSortAnswerSets() ? retVal.sorted() : retVal; + return sortAnswerSets ? retVal.sorted() : retVal; } /** @@ -221,21 +233,13 @@ private Stream solve(CompiledProgram program, java.util.function.Pred * @return a solver (and accompanying grounder) instance pre-loaded with the given program. */ private Solver prepareSolverFor(CompiledProgram program, java.util.function.Predicate filter) { - String grounderName = config.getGrounderName(); - boolean doDebugChecks = config.isDebugInternalChecks(); - - GrounderHeuristicsConfiguration grounderHeuristicConfiguration = GrounderHeuristicsConfiguration - .getInstance(config.getGrounderToleranceConstraints(), config.getGrounderToleranceRules()); - grounderHeuristicConfiguration.setAccumulatorEnabled(config.isGrounderAccumulatorEnabled()); - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance(grounderName, program, atomStore, filter, grounderHeuristicConfiguration, doDebugChecks); - - return SolverFactory.getInstance(config, atomStore, grounder); + Grounder grounder = grounderFactory.createGrounder(program, atomStore, filter); + return solverFactory.createSolver(grounder, atomStore); } @Override - public DebugSolvingContext prepareDebugSolve(ASPCore2Program program) { + public DebugSolvingContext prepareDebugSolve(InputProgram program) { return prepareDebugSolve(program, InputConfig.DEFAULT_FILTER); } @@ -245,7 +249,7 @@ public DebugSolvingContext prepareDebugSolve(NormalProgram program) { } @Override - public DebugSolvingContext prepareDebugSolve(final ASPCore2Program program, java.util.function.Predicate filter) { + public DebugSolvingContext prepareDebugSolve(final InputProgram program, java.util.function.Predicate filter) { return prepareDebugSolve(normalizeProgram(program), filter); } @@ -255,11 +259,7 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final ComponentGraph compGraph; final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; - if (this.config.isEvaluateStratifiedPart()) { - preprocessed = new StratifiedEvaluation().apply(analyzed).toNormalProgram(); - } else { - preprocessed = program; - } + preprocessed = stratifiedEvaluationFactory.get().apply(analyzed).toNormalProgram(); depGraph = analyzed.getDependencyGraph(); compGraph = analyzed.getComponentGraph(); final Solver solver = prepareSolverFor(analyzed, filter); @@ -294,7 +294,7 @@ public ComponentGraph getComponentGraph() { } @Override - public Solver prepareSolverFor(ASPCore2Program program, java.util.function.Predicate filter) { + public Solver prepareSolverFor(InputProgram program, java.util.function.Predicate filter) { return prepareSolverFor(normalizeProgram(program), filter); } @@ -304,12 +304,12 @@ public Solver prepareSolverFor(NormalProgram program, java.util.function.Predica } @Override - public Set reify(ASPCore2Program program) { + public Set reify(InputProgram program) { return reifier.reifyProgram(program); } @Override - public TestResult test(ASPCore2Program program) { + public TestResult test(InputProgram program) { return testRunner.test(program); } diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java index 2ac4bce95..1b408270e 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java @@ -2,7 +2,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; @@ -27,7 +27,7 @@ class TestRunner { this.alpha = alpha; } - TestResult test(ASPCore2Program program) { + TestResult test(InputProgram program) { LOGGER.info("Running unit tests.."); NormalProgram programUnderTest = alpha.normalizeProgram(program); List testCaseResults = program.getTestCases().stream() @@ -103,7 +103,7 @@ private List evaluateAssertion(Set answerSets, Assertion asse } private boolean answerSetSatisfiesAssertion(AnswerSet as, Assertion assertion) { - ASPCore2Program verifierWithInput = Programs.builder(assertion.getVerifier()).addFacts(new ArrayList<>(as.asFacts())).build(); + InputProgram verifierWithInput = Programs.builder(assertion.getVerifier()).addFacts(new ArrayList<>(as.asFacts())).build(); return alpha.solve(verifierWithInput).findAny().isPresent(); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index 1ddfaa7cc..c00df590d 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -1,7 +1,19 @@ package at.ac.tuwien.kr.alpha; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; +import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; +import at.ac.tuwien.kr.alpha.core.actions.OutputStreamHandle; +import at.ac.tuwien.kr.alpha.test.util.MockedActionsAlphaFactory; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.OutputStream; @@ -10,21 +22,8 @@ import java.util.Set; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.util.AnswerSetQueryImpl; -import at.ac.tuwien.kr.alpha.core.actions.ActionImplementationProvider; -import at.ac.tuwien.kr.alpha.core.actions.OutputStreamHandle; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.test.util.MockedActionsAlphaFactory; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * End-to-end tests covering Evolog action support. @@ -72,7 +71,7 @@ public void writeToFile() { * Note: We have to check answer set content here because we have no way of constructing an equal instance for * the outputStreamHandle that is constructed when execution the "fileOutputStream" action. * */ - assertEquals(1, answerSet.query(AnswerSetQueryImpl.forPredicate(Predicates.getPredicate("outfile_open_result", 2)) + assertEquals(1, answerSet.query(Atoms.query(Predicates.getPredicate("outfile_open_result", 2)) .withFilter(0, term -> term instanceof ConstantTerm && ((ConstantTerm) term).getObject().endsWith("dummy.file")) .withFunctionTerm(1, "success", 1) .withFilter(1, (term) -> { @@ -83,7 +82,7 @@ public void writeToFile() { return streamTerm.getObject() instanceof OutputStreamHandle; }) ).size()); - assertEquals(1, answerSet.query(AnswerSetQueryImpl.forPredicate(Predicates.getPredicate("outfile_write_result", 2)) + assertEquals(1, answerSet.query(Atoms.query(Predicates.getPredicate("outfile_write_result", 2)) .withFilter(0, term -> term instanceof ConstantTerm && ((ConstantTerm) term).getObject().endsWith("dummy.file")) .withFunctionTerm(1, "success", 1) .withFilter(1, (term) -> { @@ -92,7 +91,7 @@ public void writeToFile() { return funcTerm.getTerms().get(0) instanceof ConstantTerm && ((ConstantTerm) funcTerm.getTerms().get(0)).getObject().equals("ok"); }) ).size()); - assertEquals(1, answerSet.query(AnswerSetQueryImpl.forPredicate(Predicates.getPredicate("outfile_close_result", 2)) + assertEquals(1, answerSet.query(Atoms.query(Predicates.getPredicate("outfile_close_result", 2)) .withFilter(0, term -> term instanceof ConstantTerm && ((ConstantTerm) term).getObject().endsWith("dummy.file")) .withFunctionTerm(1, "success", 1) .withFilter(1, (term) -> { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java index 969f26412..a4805b8b3 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; @@ -58,7 +58,7 @@ public class AggregateRewritingContextTest { //@formatter:on private static final AggregateRewritingContext rewritingContextForAspString(String asp) { - ASPCore2Program program = new ProgramParserImpl().parse(asp); + InputProgram program = new ProgramParserImpl().parse(asp); AggregateRewritingContext ctx = new AggregateRewritingContext(); for (Rule rule : program.getRules()) { ctx.registerRule(rule); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java index 288b52fbd..1d11e89d4 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java @@ -12,7 +12,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; @@ -34,7 +34,7 @@ public class AggregateRewritingTest { private static final ProgramParser PARSER = new ProgramParserImpl(); private static final Function> NORMALIZE_AND_SOLVE = (str) -> { SystemConfig cfg = new SystemConfig(); - ASPCore2Program prog = PARSER.parse(str); + InputProgram prog = PARSER.parse(str); NormalProgram normalized = new NormalizeProgramTransformation(cfg.getAggregateRewritingConfig()).apply(prog); CompiledProgram compiled = InternalProgram.fromNormalProgram(normalized); AtomStore atomStore = new AtomStoreImpl(); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java index 5381de504..ee00c7c4b 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.test.util; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; @@ -10,7 +10,7 @@ public class RuleParser { public static Rule parse(String str) { ProgramParser parser = new ProgramParserImpl(); - ASPCore2Program prog = parser.parse(str); + InputProgram prog = parser.parse(str); if (!prog.getFacts().isEmpty()) { throw new IllegalArgumentException("Expected exactly one rule and no facts!"); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java index 828f6f922..7b075979e 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; @@ -97,7 +97,7 @@ private void constructNonGroundRuleAndCheckToString(String textualRule) { } private Rule parseSingleRule(String rule) { - ASPCore2Program program = parser.parse(rule); + InputProgram program = parser.parse(rule); List> rules = program.getRules(); assertEquals(1, rules.size(), "Number of rules"); return rules.get(0); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java index 2cf6b1337..6c6def131 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java @@ -43,7 +43,7 @@ import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -179,7 +179,7 @@ public void testNegatedExternalLiteral() throws Exception { */ @Test public void testPartnerUnitsProblemTopologicalOrder() throws IOException { - ASPCore2Program prg = parser.parse(StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp")); + InputProgram prg = parser.parse(StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp")); CompiledProgram evaluated = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prg))); assertTrue(evaluated.getRules().isEmpty(), "Not all rules eliminated by stratified evaluation"); assertEquals(57, evaluated.getFacts().size()); @@ -200,7 +200,7 @@ public void testNegatedLiteralInRecursiveRule() throws IOException { + "inc_value(4), inc_value(5), inc_value(6), inc_value(7), " + "inc_value(8)"; //@formatter:on - ASPCore2Program prog = new ProgramParserImpl().parse( + InputProgram prog = new ProgramParserImpl().parse( StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), new HashMap<>()); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 9a774a18b..0e4086ea9 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -32,7 +32,7 @@ import at.ac.tuwien.kr.alpha.api.config.Heuristic; import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -43,16 +43,16 @@ import at.ac.tuwien.kr.alpha.api.programs.tests.TestResult; import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.externals.AspStandardLibrary; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.MethodPredicateInterpretation; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.literals.Literals; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.MethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; -import at.ac.tuwien.kr.alpha.core.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import org.junit.jupiter.api.Disabled; @@ -147,10 +147,10 @@ public static boolean thinger(Thingy thingy) { @Test public void withExternal() throws Exception { - Alpha alpha = new AlphaImpl(); + Alpha alpha = new AlphaFactory().newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isOne[1]."); inputCfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program program = alpha.readProgram(inputCfg); + InputProgram program = alpha.readProgram(inputCfg); Set actual = alpha.solve(program).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); assertEquals(expected, actual); @@ -158,11 +158,11 @@ public void withExternal() throws Exception { @Test public void addsFacts() { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); Thingy a = new Thingy(); Thingy b = new Thingy(); List things = asList(a, b); - ASPCore2Program program = Programs.builder().addFacts(Externals.asFacts(Thingy.class, things)).build(); + InputProgram program = Programs.builder().addFacts(Externals.asFacts(Thingy.class, things)).build(); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("thingy").instance(a).instance(b).build())); assertEquals(expected, actual); @@ -171,7 +171,7 @@ public void addsFacts() { @Test public void withExternalTypeConflict() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isFoo[\"adsfnfdsf\"]."); inputCfg.addPredicateMethod("isFoo", Externals.processPredicateMethod(this.getClass().getMethod("isFoo", Integer.class))); Set actual = system.solve(system.readProgram(inputCfg)).collect(Collectors.toSet()); @@ -182,26 +182,26 @@ public void withExternalTypeConflict() { @Test public void smallGraph() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). node(3). a :- &connected[1,2]."); inputCfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); - ASPCore2Program program = system.readProgram(inputCfg); + InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); - Set expected = AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); + Set expected = at.ac.tuwien.kr.alpha.api.impl.AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); assertEquals(expected, actual); } @Test public void filterOutput() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); inputCfg.addPredicateMethod("getLargeGraphEdges", Externals.processPredicate(() -> new HashSet<>(asList(asList(Terms.newConstant(1), Terms.newConstant(2)), asList(Terms.newConstant(2), Terms.newConstant(1)), asList(Terms.newConstant(13), Terms.newConstant(1)))))); - ASPCore2Program program = system.readProgram(inputCfg); + InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); - Set expected = AnswerSetsParser.parse("{ node(1), node(2), outgoing13(1) }"); + Set expected = at.ac.tuwien.kr.alpha.api.impl.AnswerSetsParser.parse("{ node(1), node(2), outgoing13(1) }"); assertEquals(expected, actual); } @@ -210,7 +210,7 @@ public void supplier() throws Exception { Alpha system = new AlphaImpl(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicate(() -> singleton(singletonList(Terms.newConstant(1))))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ node(1), a }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -227,7 +227,7 @@ public void noInput() throws Exception { Alpha system = new AlphaImpl(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicateMethod(this.getClass().getMethod("bestNode"))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ node(1), a }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -237,10 +237,10 @@ public void noInput() throws Exception { @Test public void smallGraphWithWrongType() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &connected[\"hello\",2]."); cfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); system.solve(prog).collect(Collectors.toSet()); }); @@ -263,10 +263,10 @@ public static Set>> coolNode(int node) { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphNoNeighbors() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("noNeighbors(2) :- not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ noNeighbors(2) }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -275,10 +275,10 @@ public void smallGraphNoNeighbors() throws Exception { @Test public void smallGraphCoolNode() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("node(1..2). in(X) :- node(X), &coolNode[X]."); cfg.addPredicateMethod("coolNode", Externals.processPredicateMethod(this.getClass().getMethod("coolNode", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ in(1), node(1), node(2) }"); @@ -287,10 +287,10 @@ public void smallGraphCoolNode() throws Exception { @Test public void smallGraphSingleNeighbor() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("node(1..3). in(1,X) :- &neighbors[1](X), node(X)."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ in(1,2), in(1,3), node(1), node(2), node(3) }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -300,10 +300,10 @@ public void smallGraphSingleNeighbor() throws Exception { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphSingleNeighborNoTerm() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("success :- &neighbors[1], not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ success }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -335,9 +335,9 @@ public void withExternalSubtype() throws Exception { new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true))); - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); - ASPCore2Program prog = Programs.newASPCore2Program(singletonList(rule), emptyList(), Programs.newInlineDirectives()); + InputProgram prog = Programs.newInputProgram(singletonList(rule), emptyList(), Programs.newInlineDirectives()); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("x").build())); @@ -346,10 +346,10 @@ public void withExternalSubtype() throws Exception { @Test public void withExternalViaAnnotation() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1]."); cfg.addPredicateMethods(Externals.scan(this.getClass())); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); @@ -372,10 +372,10 @@ public void errorDuplicateExternal() { @Test public void withNativeExternal() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isTwo[2]."); cfg.addPredicateMethod("isTwo", Externals.processPredicate((Integer t) -> t == 2)); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); @@ -385,10 +385,10 @@ public void withNativeExternal() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted1() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = new AlphaFactory().newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], &isOne[1]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -406,7 +406,7 @@ public void withExternalInvocationCounted2() throws Exception { Alpha system = new AlphaImpl(); InputConfig cfg = InputConfig.forString("a. b :- &isOne[1], &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -424,7 +424,7 @@ public void withExternalInvocationCounted3() throws Exception { Alpha system = new AlphaImpl(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], not &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -440,7 +440,7 @@ public void withExternalInvocationCounted3() throws Exception { @SuppressWarnings("unchecked") public void programWithExternalStringStuff() throws IOException { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); + InputProgram prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); // Verify every result string has length 6 and contains "foo" for (AnswerSet as : answerSets) { @@ -456,7 +456,7 @@ public void programWithExternalStringStuff() throws IOException { @SuppressWarnings("unchecked") public void withNegatedExternal() throws IOException { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); + InputProgram prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); assertEquals(31, answerSets.size()); // Verify every result string has length 6 and contains "foo" @@ -474,7 +474,7 @@ public void withNegatedExternal() throws IOException { public void reifyInput() { String aspInput = "p(X) :- q(X), not r(X)."; Alpha system = new AlphaImpl(); - ASPCore2Program input = system.readProgramString(aspInput); + InputProgram input = system.readProgramString(aspInput); Set reified = system.reify(input); Set reifiedPredicates = reified.stream() @@ -514,7 +514,7 @@ public void basicUsageWithString() throws Exception { public void filterTest() { String progstr = "a. b. c. d :- c. e(a, b) :- d."; Alpha system = new AlphaImpl(); - ASPCore2Program prog = system.readProgramString(progstr); + InputProgram prog = system.readProgramString(progstr); Set actual = system.solve(prog, (p) -> p.equals(Predicates.getPredicate("a", 0)) || p.equals(Predicates.getPredicate("e", 2))) .collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").predicate("e").symbolicInstance("a", "b").build())); @@ -531,7 +531,7 @@ public void disableStratifiedEvalTest() { SystemConfig cfg = new SystemConfig(); cfg.setEvaluateStratifiedPart(false); AlphaImpl system = new AlphaImpl(cfg); - ASPCore2Program input = system.readProgramString(progstr); + InputProgram input = system.readProgramString(progstr); NormalProgram normal = system.normalizeProgram(input); CompiledProgram preprocessed = system.performProgramPreprocessing(normal); assertFalse(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), @@ -547,7 +547,7 @@ public void enableStratifiedEvalTest() { String progstr = "p(a). q(X) :- p(X)."; SystemConfig cfg = new SystemConfig(); AlphaImpl system = new AlphaImpl(cfg); - ASPCore2Program input = system.readProgramString(progstr); + InputProgram input = system.readProgramString(progstr); NormalProgram normal = system.normalizeProgram(input); CompiledProgram preprocessed = system.performProgramPreprocessing(normal); assertTrue(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), @@ -557,7 +557,7 @@ public void enableStratifiedEvalTest() { @Test public void passingUnitTestExpectUnsat() { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgramString(UNIT_TEST_EXPECT_UNSAT); + InputProgram prog = alpha.readProgramString(UNIT_TEST_EXPECT_UNSAT); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); } @@ -565,7 +565,7 @@ public void passingUnitTestExpectUnsat() { @Test public void passingUnitTestBasicTest() { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgramString(UNIT_TEST_BASIC_TEST); + InputProgram prog = alpha.readProgramString(UNIT_TEST_BASIC_TEST); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); assertEquals(1, testResult.getTestCaseResults().size()); @@ -580,7 +580,7 @@ public void passingUnitTestBasicTest() { @Test public void passingUnitTestMultipleAssertions() { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgramString(UNIT_TEST_MORE_ASSERTIONS); + InputProgram prog = alpha.readProgramString(UNIT_TEST_MORE_ASSERTIONS); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); assertEquals(1, testResult.getTestCaseResults().size()); @@ -595,7 +595,7 @@ public void passingUnitTestMultipleAssertions() { @Test public void passingUnitTestMultipleTestCases() { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgramString(UNIT_TEST_MORE_TCS); + InputProgram prog = alpha.readProgramString(UNIT_TEST_MORE_TCS); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); assertEquals(2, testResult.getTestCaseResults().size()); @@ -604,7 +604,7 @@ public void passingUnitTestMultipleTestCases() { @Test public void failingAssertionUnitTest() { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgramString(UNIT_TEST_FAILING_ASSERTION); + InputProgram prog = alpha.readProgramString(UNIT_TEST_FAILING_ASSERTION); TestResult testResult = alpha.test(prog); assertFalse(testResult.isSuccess()); assertEquals(1, testResult.getTestCaseResults().size()); @@ -619,7 +619,7 @@ public void failingAssertionUnitTest() { @Test public void failingAnswerSetCountUnitTest() { Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgramString(UNIT_TEST_FAILING_COUNT); + InputProgram prog = alpha.readProgramString(UNIT_TEST_FAILING_COUNT); TestResult testResult = alpha.test(prog); assertFalse(testResult.isSuccess()); assertEquals(1, testResult.getTestCaseResults().size()); @@ -690,7 +690,7 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException List files = new ArrayList<>(); files.add(path.toString()); inputCfg.setFiles(files); - ASPCore2Program prog = system.readProgram(inputCfg); + InputProgram prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).sorted().limit(400).collect(Collectors.toList()).isEmpty()); } @@ -708,7 +708,7 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep List files = new ArrayList<>(); files.add(base.resolve(program).toString()); inputCfg.setFiles(files); - ASPCore2Program prog = system.readProgram(inputCfg); + InputProgram prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).limit(limit).collect(Collectors.toList()).isEmpty()); } @@ -716,11 +716,11 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep @Test public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { final ProgramParser parser = new ProgramParserImpl(); - ASPCore2ProgramBuilder bld = Programs.builder(); + InputProgramBuilder bld = Programs.builder(); bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), StandardOpenOption.READ))); bld.accumulate( parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"), StandardOpenOption.READ))); - ASPCore2Program parsedProgram = bld.build(); + InputProgram parsedProgram = bld.build(); SystemConfig config = new SystemConfig(); config.setSolverName("default"); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java index 23457da10..7657b7d40 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; @@ -101,7 +101,7 @@ private void testHanoiTower(int instance, RegressionTestConfig cfg) throws IOExc } private void testHanoiTower(String instance, RegressionTestConfig cfg) throws IOException { - ASPCore2Program prog = new ProgramParserImpl().parse( + InputProgram prog = new ProgramParserImpl().parse( Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); Solver solver = TestUtils.buildSolverForRegressionTest(prog, cfg); @@ -115,7 +115,7 @@ private void testHanoiTower(String instance, RegressionTestConfig cfg) throws IO * for every goal/3 * fact in the input there is a corresponding on/3 atom in the output. */ - private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { + private void checkGoal(InputProgram parsedProgram, AnswerSet answerSet) { Predicate ongoal = Predicates.getPredicate("ongoal", 2); Predicate on = Predicates.getPredicate("on", 3); int steps = getSteps(parsedProgram); @@ -131,7 +131,7 @@ private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { } } - private int getSteps(ASPCore2Program parsedProgram) { + private int getSteps(InputProgram parsedProgram) { Predicate steps = Predicates.getPredicate("steps", 1); for (Atom atom : parsedProgram.getFacts()) { if (atom.getPredicate().getName().equals(steps.getName()) && atom.getPredicate().getArity() == steps.getArity()) { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java index da9238e66..2f2b91204 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java @@ -42,7 +42,7 @@ import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests rule transformations described in the following research paper, and their effects on performance: @@ -246,7 +246,7 @@ private InputProgram constructProgramA_TransformationA(int n) { private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { assertEquals(numberOfRules, strRules.size()); String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - InputProgram parsedProgram = new ASPCore2ProgramParser().parse(strProgram); + InputProgram parsedProgram = new InputProgramParser().parse(strProgram); assertEquals(numberOfRules, parsedProgram.getRules().size()); return parsedProgram; } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java index a8d9d79d0..171e0c514 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java @@ -41,7 +41,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** @@ -112,7 +112,7 @@ public void testReach_4(SystemConfig cfg) { private void test(String folder, String aspFileName, SystemConfig cfg) throws IOException { @SuppressWarnings("unused") Optional answerSet = buildSolverForRegressionTest( - new ASPCore2ProgramParser().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) + new InputProgramParser().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) .stream().findFirst(); // System.out.println(answerSet); // TODO: check correctness of answer set diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java index 070177f4e..6303ec475 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.ASPCore2ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** @@ -61,7 +61,7 @@ public void testRacks(SystemConfig cfg) { private void test(SystemConfig cfg) throws IOException { CharStream programInputStream = CharStreams.fromPath( Paths.get("benchmarks", "siemens", "racks", "racks.lp")); - Solver solver = buildSolverForRegressionTest(new ASPCore2ProgramParser().parse(programInputStream), cfg); + Solver solver = buildSolverForRegressionTest(new InputProgramParser().parse(programInputStream), cfg); @SuppressWarnings("unused") Optional answerSet = solver.stream().findFirst(); // System.out.println(answerSet); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java index c0bfdd991..da84e80a7 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java @@ -44,7 +44,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; @@ -79,7 +79,7 @@ public void testObjectProgram(RegressionTestConfig cfg) { final Atom fact = Atoms.newBasicAtom(Predicates.getPredicate("foo", 1), Terms.newConstant(thingy)); - final ASPCore2Program program = Programs.newASPCore2Program( + final InputProgram program = Programs.newInputProgram( Collections.emptyList(), Collections.singletonList(fact), Programs.newInlineDirectives() diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java index b39232c8c..9c8388297 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java @@ -36,12 +36,12 @@ import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -99,17 +99,17 @@ public void testV300E300(RegressionTestConfig cfg) { } private void testThreeColouring(int nVertices, int nEdges, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl().parse( + InputProgram tmpPrg = new ProgramParserImpl().parse( "blue(N) :- v(N), not red(N), not green(N)." + "red(N) :- v(N), not blue(N), not green(N)." + "green(N) :- v(N), not red(N), not blue(N)." + ":- e(N1,N2), blue(N1), blue(N2)." + ":- e(N1,N2), red(N1), red(N2)." + ":- e(N1,N2), green(N1), green(N2)."); - ASPCore2ProgramBuilder prgBuilder = Programs.builder(tmpPrg); + InputProgramBuilder prgBuilder = Programs.builder(tmpPrg); prgBuilder.addFacts(createVertices(nVertices)); prgBuilder.addFacts(createEdges(nVertices, nEdges)); - ASPCore2Program program = prgBuilder.build(); + InputProgram program = prgBuilder.build(); maybeShuffle(program); @SuppressWarnings("unused") @@ -120,7 +120,7 @@ private void testThreeColouring(int nVertices, int nEdges, RegressionTestConfig } @SuppressWarnings("unused") - private void maybeShuffle(ASPCore2Program program) { + private void maybeShuffle(InputProgram program) { // TODO: switch on if different rule orderings in the encoding are desired (e.g. for benchmarking purposes) // FIXME since InputProgram is immutable this needs to be reworked a bit if used diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java index e0ff335a6..8f0c32c05 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java @@ -38,13 +38,13 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -185,13 +185,13 @@ public void testN101(RegressionTestConfig cfg) { } private void testThreeColouring(int n, boolean shuffle, int seed, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl() + InputProgram tmpPrg = new ProgramParserImpl() .parse("col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); - ASPCore2ProgramBuilder prgBuilder = Programs.builder().accumulate(tmpPrg); + InputProgramBuilder prgBuilder = Programs.builder().accumulate(tmpPrg); prgBuilder.addFacts(createColors("1", "2", "3")); prgBuilder.addFacts(createVertices(n)); prgBuilder.addFacts(createEdges(n, shuffle, seed)); - ASPCore2Program program = prgBuilder.build(); + InputProgram program = prgBuilder.build(); Solver solver = buildSolverForRegressionTest(program, cfg); @SuppressWarnings("unused") diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java index 370e6fbd0..1470708ca 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java @@ -36,13 +36,13 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.commons.programs.Programs.ASPCore2ProgramBuilder; +import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -99,15 +99,15 @@ public void testN11(RegressionTestConfig cfg) { } private void testThreeColouring(int n, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl().parse( + InputProgram tmpPrg = new ProgramParserImpl().parse( "col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); - ASPCore2ProgramBuilder prgBuilder = Programs.builder(tmpPrg); + InputProgramBuilder prgBuilder = Programs.builder(tmpPrg); prgBuilder.addFacts(createColors("red", "blue", "green")); prgBuilder.addFacts(createVertices(n)); prgBuilder.addFacts(createEdges(n)); - ASPCore2Program program = prgBuilder.build(); + InputProgram program = prgBuilder.build(); maybeShuffle(program); @@ -121,7 +121,7 @@ private void testThreeColouring(int n, RegressionTestConfig cfg) { } @SuppressWarnings("unused") - private void maybeShuffle(ASPCore2Program program) { + private void maybeShuffle(InputProgram program) { // FIXME since InputProgram is immutable this needs to be reworked a bit if used // No shuffling here. } From 173f664efacba547864e0716ae450abf6a215e6c Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 22 Jul 2024 13:21:24 +0200 Subject: [PATCH 36/59] Fix tests after merging master --- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 2 +- .../alpha/app/ComponentGraphWriterTest.java | 2 +- .../alpha/app/DependencyGraphWriterTest.java | 2 +- .../AnswerSetToWorkbookMapperTest.java | 2 +- .../alpha/core/parser/ProgramPartParser.java | 2 +- .../tuwien/kr/alpha/test/AlphaAssertions.java | 1 - .../kr/alpha/test/AnswerSetsParser.java | 2 +- .../kr/alpha/api/impl/AlphaFactory.java | 11 +- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 5 +- .../kr/alpha/AggregateRewritingTest.java | 42 +++-- .../alpha/ArithmeticTermsRewritingTest.java | 5 +- .../FixedInterpretationLiteralsTest.java | 9 +- .../kr/alpha/StratifiedEvaluationTest.java | 167 +++++++++--------- .../kr/alpha/api/impl/AlphaImplTest.java | 111 ++++-------- .../kr/alpha/api/impl/ReificationTest.java | 2 +- .../alpha/regressiontests/HanoiTowerTest.java | 31 ++-- .../HeadBodyTransformationTests.java | 4 +- .../regressiontests/OmigaBenchmarksTest.java | 7 +- .../kr/alpha/regressiontests/RacksTest.java | 6 +- .../kr/alpha/regressiontests/SolverTests.java | 160 ++++++++--------- .../StratifiedEvaluationRegressionTest.java | 10 +- .../ThreeColouringRandomGraphTest.java | 26 +-- .../ThreeColouringTestWithRandom.java | 50 +++--- .../ThreeColouringWheelTest.java | 26 +-- .../util/RegressionTestConfigProvider.java | 6 +- .../util/RegressionTestUtils.java | 10 +- 26 files changed, 337 insertions(+), 364 deletions(-) diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java index 9fbaccc39..94a8eb285 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java @@ -86,7 +86,7 @@ public static void main(String[] args) { Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); } - Alpha alpha = new AlphaFactory().newAlpha(cfg.getSystemConfig()); + Alpha alpha = AlphaFactory.newAlpha(cfg.getSystemConfig()); InputProgram program = null; try { diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java index 9c5777159..23655f106 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java @@ -54,7 +54,7 @@ public void smokeTest() { "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + "n2 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = new AlphaFactory().newAlpha(); + Alpha alpha = AlphaFactory.newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); ComponentGraph compgraph = dbgResult.getComponentGraph(); ComponentGraphWriter writer = new ComponentGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java index a738bf3e0..8d5929e80 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java @@ -51,7 +51,7 @@ public void smokeTest() { "n6 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + "n6 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = new AlphaFactory().newAlpha(); + Alpha alpha = AlphaFactory.newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); DependencyGraph depgraph = dbgResult.getDependencyGraph(); DependencyGraphWriter writer = new DependencyGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java index cafb17236..3b156426d 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java @@ -47,7 +47,7 @@ public void solveAndWriteWorkbookTest() { + "p(N) :- p(I), N = I + 1, N <= MX, maxP(MX)." + "q(A, B) :- p(A), p(B)."; //@formatter:on - Alpha alpha = new AlphaFactory().newAlpha(); + Alpha alpha = AlphaFactory.newAlpha(); List answerSets = alpha.solve(alpha.readProgramString(progstr)).collect(Collectors.toList()); assertEquals(1, answerSets.size()); AnswerSet as = answerSets.get(0); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java index 14a5bc1d9..b115e4cd9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java @@ -43,7 +43,7 @@ import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; /** - * A parser that, in contrast to {@link ProgramParser}, does not parse full programs but only program parts like + * A parser that, in contrast to {@link at.ac.tuwien.kr.alpha.api.programs.ProgramParser}, does not parse full programs but only program parts like * atoms, terms and such. */ // TODO adapt this and create evolog version diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java index 8c45bf662..cce21dafa 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java @@ -2,7 +2,6 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.impl.AnswerSetsParser; import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java index 93515666b..34f60e7c5 100644 --- a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha.test; import java.util.Collections; import java.util.Set; diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index 53d5eb323..dcc85fdec 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -65,7 +65,7 @@ protected ActionImplementationProvider newActionImplementationProvider() { return new DefaultActionImplementationProvider(); } - public Alpha newAlpha(SystemConfig cfg) { + protected Alpha buildInstance(SystemConfig cfg) { ActionImplementationProvider actionImplementationProvider = newActionImplementationProvider(); ProgramParser parser = new ProgramParserImpl(actionImplementationProvider, Collections.emptyMap()); ProgramTransformation programNormalizer = new NormalizeProgramTransformation(cfg.getAggregateRewritingConfig()); @@ -87,8 +87,13 @@ public Alpha newAlpha(SystemConfig cfg) { } // Create Alpha instance with default config. - public Alpha newAlpha() { - return newAlpha(new SystemConfig()); + public static Alpha newAlpha() { + return AlphaFactory.newAlpha(new SystemConfig()); + } + + public static Alpha newAlpha(SystemConfig cfg) { + AlphaFactory factory = new AlphaFactory(); + return factory.buildInstance(cfg); } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index c00df590d..b52ab8273 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -3,6 +3,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; @@ -45,7 +46,7 @@ public class ActionsTest { @Test public void helloWorld() { MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); - Alpha alpha = alphaFactory.newAlpha(new SystemConfig()); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram program = alpha.readProgramString(HELLO_WORLD); alpha.solve(program); assertEquals("Hello World!", alphaFactory.getActionImplementationMock().getStdoutContent()); @@ -61,7 +62,7 @@ public void writeToFile() { MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); alphaFactory.getActionImplementationMock().setMockedFileOutputs(mockedFileOutputs); ActionImplementationProvider actionProvider = alphaFactory.getActionImplementationMock(); - Alpha alpha = alphaFactory.newAlpha(new SystemConfig()); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram program = alpha.readProgramString(WRITE_TO_FILE); Set answerSets = alpha.solve(program).collect(Collectors.toSet()); LOGGER.debug("Got answer sets: {}", answerSets); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java index 1d11e89d4..e4ca8acf3 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java @@ -1,11 +1,14 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import java.util.function.Function; +import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -31,18 +34,6 @@ public class AggregateRewritingTest { - private static final ProgramParser PARSER = new ProgramParserImpl(); - private static final Function> NORMALIZE_AND_SOLVE = (str) -> { - SystemConfig cfg = new SystemConfig(); - InputProgram prog = PARSER.parse(str); - NormalProgram normalized = new NormalizeProgramTransformation(cfg.getAggregateRewritingConfig()).apply(prog); - CompiledProgram compiled = InternalProgram.fromNormalProgram(normalized); - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", compiled, atomStore, cfg.isDebugInternalChecks()); - Solver solver = SolverFactory.getInstance(cfg, atomStore, grounder); - return solver.collectList(); - }; - //@formatter:off // Smoke-test case for "X <= #count{...}" aggregate private static final String CNT_LE1_ASP = @@ -99,9 +90,16 @@ public class AggregateRewritingTest { + " Y = #count { X : p( X ) }, 1 <= #count { X : p( X ) }, Z = #max { W : p( W ) }."; //@formatter:on + // Use an alpha instance with default config for all test cases + private final Alpha alpha = AlphaFactory.newAlpha(); + private final Function> solve = (asp) -> { + InputProgram prog = alpha.readProgramString(asp); + return alpha.solve(prog).collect(Collectors.toList()); + }; + @Test public void countLeSortingGridSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_LE1_ASP); + List answerSets = solve.apply(CNT_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -123,7 +121,7 @@ public void countLeSortingGridSimple() { @Test public void countEqSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_EQ1_ASP); + List answerSets = solve.apply(CNT_EQ1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -141,7 +139,7 @@ public void countEqSimple() { @Test public void countLeCountingGridSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_LE1_ASP); + List answerSets = solve.apply(CNT_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -163,7 +161,7 @@ public void countLeCountingGridSimple() { @Test public void countEqGlobalVars() { - List answerSets = NORMALIZE_AND_SOLVE.apply(VERTEX_DEGREE_ASP); + List answerSets = solve.apply(VERTEX_DEGREE_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate vertexDegree = Predicates.getPredicate("graph_vertex_degree", 3); @@ -182,7 +180,7 @@ public void countEqGlobalVars() { @Test // Test "count eq" and "max eq" together with global vars public void graphVerticesOfMaxDegree() { - List answerSets = NORMALIZE_AND_SOLVE.apply(NUM_MAX_DEGREE_VERTICES_ASP); + List answerSets = solve.apply(NUM_MAX_DEGREE_VERTICES_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate maxDegreeVertices = Predicates.getPredicate("graph_max_degree_vertices", 3); @@ -196,7 +194,7 @@ public void graphVerticesOfMaxDegree() { @Test public void greaterMin() { - List answerSets = NORMALIZE_AND_SOLVE.apply(MIN_GT1_ASP); + List answerSets = solve.apply(MIN_GT1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate greaterMin = Predicates.getPredicate("greater_min_acceptable", 1); @@ -210,7 +208,7 @@ public void greaterMin() { @Test public void sumEquals1() { - List answerSets = NORMALIZE_AND_SOLVE.apply(SUM_EQ1_ASP); + List answerSets = solve.apply(SUM_EQ1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate sumThings = Predicates.getPredicate("sum_things", 1); @@ -224,7 +222,7 @@ public void sumEquals1() { @Test public void sumLessOrEqual1() { - List answerSets = NORMALIZE_AND_SOLVE.apply(SUM_LE1_ASP); + List answerSets = solve.apply(SUM_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate boundLe = Predicates.getPredicate("bound_le_sum", 1); @@ -238,7 +236,7 @@ public void sumLessOrEqual1() { @Test @Disabled("Open issue, as dependency analysis includes cyclic output-dependency, which it should not.") public void setComplexEqualityWithGlobals() { - List answerSets = NORMALIZE_AND_SOLVE.apply(COMPLEX_EQUALITY_WITH_GLOBALS); + List answerSets = solve.apply(COMPLEX_EQUALITY_WITH_GLOBALS); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate q = Predicates.getPredicate("q", 0); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java index e92589302..bbcb22734 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation; +package at.ac.tuwien.kr.alpha; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Set; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermsRewriting; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; @@ -23,7 +24,7 @@ import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.programs.Programs; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; /** diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java index 690e39777..9915ef7b0 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -12,6 +12,7 @@ import java.util.Optional; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.Alpha; @@ -23,8 +24,8 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.AspStandardLibrary; public class FixedInterpretationLiteralsTest { @@ -79,7 +80,7 @@ public static Set>> connection(String dummy) { private Map externals; public FixedInterpretationLiteralsTest() { - this.alpha = new AlphaImpl(); + this.alpha = AlphaFactory.newAlpha(); this.externals = new HashMap<>(); this.externals.putAll(Externals.scan(AspStandardLibrary.class)); this.externals.putAll(Externals.scan(FixedInterpretationLiteralsTest.class)); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java index 6c6def131..19ec176cb 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java @@ -25,8 +25,9 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.programs.transformation; +package at.ac.tuwien.kr.alpha; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -36,7 +37,14 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; +import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.AnswerSet; @@ -54,7 +62,7 @@ import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -62,33 +70,24 @@ import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; public class StratifiedEvaluationTest { - private final ProgramParser parser = new ProgramParserImpl(); - private final NormalizeProgramTransformation normalizer = new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - private final StratifiedEvaluation evaluator = new StratifiedEvaluation(); - private final Function parseAndEvaluate = (str) -> { - return evaluator.apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parser.parse(str)))); - }; - - private final Function> solveCompiledProg = (prog) -> { - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, false); - Solver solver = SolverFactory.getInstance(new SystemConfig(), atomStore, grounder); - return solver.collectSet(); - }; + // Alpha instance with default configuration (evolog support and stratified evaluation enabled) + private final Alpha alpha = AlphaFactory.newAlpha(); + /** + * Verifies that facts are not duplicated by stratified evaluation. + */ @Test public void testDuplicateFacts() { String aspStr = "p(a). p(b). q(b). q(X) :- p(X)."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Instance qOfB = new Instance(TestUtils.basicAtomWithSymbolicTerms("q", "b").getTerms()); - Set facts = evaluated.getFactsByPredicate().get(Predicates.getPredicate("q", 1)); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(aspStr)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + BasicAtom qOfB = Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("b")); int numQOfB = 0; - for (Instance at : facts) { - if (at.equals(qOfB)) { + for (Atom fact : evaluated.getFacts()) { + if (fact.equals(qOfB)) { numQOfB++; } } @@ -98,41 +97,39 @@ public void testDuplicateFacts() { @Test public void testEqualityWithConstantTerms() { String aspStr = "equal :- 1 = 1."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Atom equal = TestUtils.basicAtomWithSymbolicTerms("equal"); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(aspStr)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + Atom equal = Atoms.newBasicAtom(Predicates.getPredicate("equal", 0)); assertTrue(evaluated.getFacts().contains(equal)); } @Test public void testEqualityWithVarTerms() { String aspStr = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(aspStr)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); } @Test public void testNonGroundableRule() { String asp = "p(a). q(a, b). s(X, Y) :- p(X), q(X, Y), r(Y)."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("p(a), q(a,b)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("p(a), q(a,b)", answerSets); } + @Test public void testCountAggregate() { String asp = "a. b :- 1 <= #count { 1 : a }."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a, b", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a, b", answerSets); } @Test public void testIntervalFact() { String asp = "a(1..3)."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); } @Test @@ -141,18 +138,18 @@ public void testAggregateSpecial() { + "{ chosenThing(X) : thing(X) }.\n" + "chosenSomething :- chosenThing(X).\n" + ":- not chosenSomething.\n" + ":- chosenThing(X), chosenThing(Y), X != Y.\n" + "allThings :- 3 <= #count{ X : thing(X)}. \n" + "chosenMaxThing :- allThings, chosenThing(3).\n" + ":- not chosenMaxThing."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("allThings"))); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("allThings, thing(1), thing(2), thing(3), chosenMaxThing, chosenSomething, chosenThing(3)", answerSets); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(asp)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("allThings", 0)))); + Set answerSets = dbgInfo.getSolver().collectSet(); + assertAnswerSetsEqual("allThings, thing(1), thing(2), thing(3), chosenMaxThing, chosenSomething, chosenThing(3)", answerSets); } @Test public void testNegatedFixedInterpretationLiteral() { String asp = "stuff(1). stuff(2). smallStuff(X) :- stuff(X), not X > 1."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); } @SuppressWarnings("unused") @@ -161,16 +158,14 @@ public static boolean sayTrue(Object o) { return true; } + @Test public void testNegatedExternalLiteral() throws Exception { String asp = "claimedTruth(bla). truth(X) :- claimedTruth(X), &sayTrue[X]. lie(X) :- claimedTruth(X), not &sayTrue[X]."; Map externals = new HashMap<>(); externals.put("sayTrue", Externals.processPredicateMethod(this.getClass().getMethod("sayTrue", Object.class))); - ProgramParser parserWithExternals = new ProgramParserImpl(); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parserWithExternals.parse(asp, externals))); - CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp, externals)).collect(Collectors.toSet()); + assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); } /** @@ -179,8 +174,11 @@ public void testNegatedExternalLiteral() throws Exception { */ @Test public void testPartnerUnitsProblemTopologicalOrder() throws IOException { - InputProgram prg = parser.parse(StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp")); - CompiledProgram evaluated = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prg))); + InputProgram prg = alpha.readProgramStream( + StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp"), + new HashMap<>()); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(prg); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); assertTrue(evaluated.getRules().isEmpty(), "Not all rules eliminated by stratified evaluation"); assertEquals(57, evaluated.getFacts().size()); } @@ -191,6 +189,12 @@ public void testPartnerUnitsProblemTopologicalOrder() throws IOException { * * @throws IOException */ + /** + * Verifies correct handling of negated basic literals in StratifiedEvaluation. + * For details, see comments in test program + * + * @throws IOException + */ @Test public void testNegatedLiteralInRecursiveRule() throws IOException { //@formatter:off @@ -200,51 +204,48 @@ public void testNegatedLiteralInRecursiveRule() throws IOException { + "inc_value(4), inc_value(5), inc_value(6), inc_value(7), " + "inc_value(8)"; //@formatter:on - InputProgram prog = new ProgramParserImpl().parse( + InputProgram prog = alpha.readProgramStream( StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), new HashMap<>()); // Run stratified evaluation and solve - CompiledProgram inputStratEval = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prog))); - Set asStrat = solveCompiledProg.apply(inputStratEval); - TestUtils.assertAnswerSetsEqual(expectedAnswerSet, asStrat); - - // Solve without stratified evaluation - CompiledProgram inputNoStratEval = InternalProgram.fromNormalProgram(normalizer.apply(prog)); - Set as = solveCompiledProg.apply(inputNoStratEval); - TestUtils.assertAnswerSetsEqual(expectedAnswerSet, as); + DebugSolvingContext dbg = alpha.prepareDebugSolve(prog); + Set as = dbg.getSolver().collectSet(); + assertAnswerSetsEqual(expectedAnswerSet, as); } + @Test public void testRecursiveRanking() { //@formatter:off - String asp = "thing(a).\n" + - "thing(b).\n" + - "thing(c).\n" + - "thing_before(a, b).\n" + - "thing_before(b, c).\n" + - "has_prev_thing(X) :- thing(X), thing_succ(_, X).\n" + - "first_thing(X) :- thing(X), not has_prev_thing(X).\n" + - "thing_not_succ(X, Y) :-\n" + - " thing(X),\n" + - " thing(Y),\n" + - " thing(INTM),\n" + - " thing_before(X, Y),\n" + - " thing_before(X, INTM),\n" + - " thing_before(INTM, X).\n" + - "thing_succ(X, Y) :-\n" + - " thing(X),\n" + - " thing(Y),\n" + - " thing_before(X, Y),\n" + - " not thing_not_succ(X, Y).\n" + - "thing_rank(X, 1) :- first_thing(X).\n" + - "thing_rank(X, R) :-\n" + - " thing(X),\n" + - " thing_succ(Y, X),\n" + - " thing_rank(Y, K),\n" + + String asp = "thing(a).\n" + + "thing(b).\n" + + "thing(c).\n" + + "thing_before(a, b).\n" + + "thing_before(b, c).\n" + + "has_prev_thing(X) :- thing(X), thing_succ(_, X).\n" + + "first_thing(X) :- thing(X), not has_prev_thing(X).\n" + + "thing_not_succ(X, Y) :-\n" + + " thing(X),\n" + + " thing(Y),\n" + + " thing(INTM),\n" + + " thing_before(X, Y),\n" + + " thing_before(X, INTM),\n" + + " thing_before(INTM, X).\n" + + "thing_succ(X, Y) :-\n" + + " thing(X),\n" + + " thing(Y),\n" + + " thing_before(X, Y),\n" + + " not thing_not_succ(X, Y).\n" + + "thing_rank(X, 1) :- first_thing(X).\n" + + "thing_rank(X, R) :-\n" + + " thing(X),\n" + + " thing_succ(Y, X),\n" + + " thing_rank(Y, K),\n" + " R = K + 1."; //@formatter:on - CompiledProgram evaluated = parseAndEvaluate.apply(asp); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(asp)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); Predicate rank = Predicates.getPredicate("thing_rank", 2); BasicAtom rank1 = Atoms.newBasicAtom(rank, Terms.newSymbolicConstant("a"), Terms.newConstant(1)); BasicAtom rank2 = Atoms.newBasicAtom(rank, Terms.newSymbolicConstant("b"), Terms.newConstant(2)); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 0e4086ea9..c26b6c66d 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -33,7 +33,6 @@ import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -54,7 +53,7 @@ import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; +import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -147,7 +146,7 @@ public static boolean thinger(Thingy thingy) { @Test public void withExternal() throws Exception { - Alpha alpha = new AlphaFactory().newAlpha(); + Alpha alpha = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isOne[1]."); inputCfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram program = alpha.readProgram(inputCfg); @@ -158,7 +157,7 @@ public void withExternal() throws Exception { @Test public void addsFacts() { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); Thingy a = new Thingy(); Thingy b = new Thingy(); List things = asList(a, b); @@ -171,7 +170,7 @@ public void addsFacts() { @Test public void withExternalTypeConflict() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isFoo[\"adsfnfdsf\"]."); inputCfg.addPredicateMethod("isFoo", Externals.processPredicateMethod(this.getClass().getMethod("isFoo", Integer.class))); Set actual = system.solve(system.readProgram(inputCfg)).collect(Collectors.toSet()); @@ -182,32 +181,32 @@ public void withExternalTypeConflict() { @Test public void smallGraph() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). node(3). a :- &connected[1,2]."); inputCfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); - Set expected = at.ac.tuwien.kr.alpha.api.impl.AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); + Set expected = AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); assertEquals(expected, actual); } @Test public void filterOutput() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); inputCfg.addPredicateMethod("getLargeGraphEdges", Externals.processPredicate(() -> new HashSet<>(asList(asList(Terms.newConstant(1), Terms.newConstant(2)), asList(Terms.newConstant(2), Terms.newConstant(1)), asList(Terms.newConstant(13), Terms.newConstant(1)))))); InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); - Set expected = at.ac.tuwien.kr.alpha.api.impl.AnswerSetsParser.parse("{ node(1), node(2), outgoing13(1) }"); + Set expected = AnswerSetsParser.parse("{ node(1), node(2), outgoing13(1) }"); assertEquals(expected, actual); } @Test public void supplier() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicate(() -> singleton(singletonList(Terms.newConstant(1))))); InputProgram prog = system.readProgram(cfg); @@ -224,7 +223,7 @@ public static Set>> bestNode() { @Test public void noInput() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicateMethod(this.getClass().getMethod("bestNode"))); InputProgram prog = system.readProgram(cfg); @@ -237,7 +236,7 @@ public void noInput() throws Exception { @Test public void smallGraphWithWrongType() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &connected[\"hello\",2]."); cfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); InputProgram prog = system.readProgram(cfg); @@ -263,7 +262,7 @@ public static Set>> coolNode(int node) { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphNoNeighbors() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("noNeighbors(2) :- not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); InputProgram prog = system.readProgram(cfg); @@ -275,7 +274,7 @@ public void smallGraphNoNeighbors() throws Exception { @Test public void smallGraphCoolNode() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1..2). in(X) :- node(X), &coolNode[X]."); cfg.addPredicateMethod("coolNode", Externals.processPredicateMethod(this.getClass().getMethod("coolNode", int.class))); InputProgram prog = system.readProgram(cfg); @@ -287,7 +286,7 @@ public void smallGraphCoolNode() throws Exception { @Test public void smallGraphSingleNeighbor() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1..3). in(1,X) :- &neighbors[1](X), node(X)."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); InputProgram prog = system.readProgram(cfg); @@ -300,7 +299,7 @@ public void smallGraphSingleNeighbor() throws Exception { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphSingleNeighborNoTerm() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("success :- &neighbors[1], not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); InputProgram prog = system.readProgram(cfg); @@ -331,11 +330,11 @@ public void withExternalSubtype() throws Exception { Rule rule = Rules.newRule( Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newConstant("x"))), - singletonList(Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("thinger", 1), + singleton(Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("thinger", 1), new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true))); - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputProgram prog = Programs.newInputProgram(singletonList(rule), emptyList(), Programs.newInlineDirectives()); @@ -346,7 +345,7 @@ public void withExternalSubtype() throws Exception { @Test public void withExternalViaAnnotation() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1]."); cfg.addPredicateMethods(Externals.scan(this.getClass())); InputProgram prog = system.readProgram(cfg); @@ -372,7 +371,7 @@ public void errorDuplicateExternal() { @Test public void withNativeExternal() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isTwo[2]."); cfg.addPredicateMethod("isTwo", Externals.processPredicate((Integer t) -> t == 2)); InputProgram prog = system.readProgram(cfg); @@ -385,7 +384,7 @@ public void withNativeExternal() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted1() throws Exception { - Alpha system = new AlphaFactory().newAlpha(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], &isOne[1]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram prog = system.readProgram(cfg); @@ -403,7 +402,7 @@ public void withExternalInvocationCounted1() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted2() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a. b :- &isOne[1], &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram prog = system.readProgram(cfg); @@ -421,7 +420,7 @@ public void withExternalInvocationCounted2() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted3() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], not &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); InputProgram prog = system.readProgram(cfg); @@ -439,7 +438,7 @@ public void withExternalInvocationCounted3() throws Exception { @Test @SuppressWarnings("unchecked") public void programWithExternalStringStuff() throws IOException { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); // Verify every result string has length 6 and contains "foo" @@ -455,7 +454,7 @@ public void programWithExternalStringStuff() throws IOException { @Test @SuppressWarnings("unchecked") public void withNegatedExternal() throws IOException { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); assertEquals(31, answerSets.size()); @@ -473,7 +472,7 @@ public void withNegatedExternal() throws IOException { @Test public void reifyInput() { String aspInput = "p(X) :- q(X), not r(X)."; - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputProgram input = system.readProgramString(aspInput); Set reified = system.reify(input); @@ -493,7 +492,7 @@ public void reifyInput() { @Test public void basicUsage() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(a)."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").symbolicInstance("a").build())); assertEquals(expected, actual); @@ -501,7 +500,7 @@ public void basicUsage() throws Exception { @Test public void basicUsageWithString() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(\"a\")."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("a").build())); assertEquals(expected, actual); @@ -513,7 +512,7 @@ public void basicUsageWithString() throws Exception { @Test public void filterTest() { String progstr = "a. b. c. d :- c. e(a, b) :- d."; - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputProgram prog = system.readProgramString(progstr); Set actual = system.solve(prog, (p) -> p.equals(Predicates.getPredicate("a", 0)) || p.equals(Predicates.getPredicate("e", 2))) .collect(Collectors.toSet()); @@ -521,42 +520,9 @@ public void filterTest() { assertEquals(expected, actual); } - /** - * Verifies that no stratified evaluation is performed up-front when disabled in config. - */ - @Test - public void disableStratifiedEvalTest() { - // Note: This might be cleaner if the test used the debugSolve method from the interface - String progstr = "p(a). q(X) :- p(X)."; - SystemConfig cfg = new SystemConfig(); - cfg.setEvaluateStratifiedPart(false); - AlphaImpl system = new AlphaImpl(cfg); - InputProgram input = system.readProgramString(progstr); - NormalProgram normal = system.normalizeProgram(input); - CompiledProgram preprocessed = system.performProgramPreprocessing(normal); - assertFalse(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), - "Preprocessed program contains fact derived from stratifiable rule, but should not!"); - } - - /** - * Verifies that stratified evaluation is performed up-front if not otherwise configured. - */ - @Test - public void enableStratifiedEvalTest() { - // Note: This might be cleaner if the test used the debugSolve method from the interface - String progstr = "p(a). q(X) :- p(X)."; - SystemConfig cfg = new SystemConfig(); - AlphaImpl system = new AlphaImpl(cfg); - InputProgram input = system.readProgramString(progstr); - NormalProgram normal = system.normalizeProgram(input); - CompiledProgram preprocessed = system.performProgramPreprocessing(normal); - assertTrue(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), - "Preprocessed program does not contain fact derived from stratifiable rule, but should!"); - } - @Test public void passingUnitTestExpectUnsat() { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgramString(UNIT_TEST_EXPECT_UNSAT); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); @@ -564,7 +530,7 @@ public void passingUnitTestExpectUnsat() { @Test public void passingUnitTestBasicTest() { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgramString(UNIT_TEST_BASIC_TEST); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); @@ -579,7 +545,7 @@ public void passingUnitTestBasicTest() { @Test public void passingUnitTestMultipleAssertions() { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgramString(UNIT_TEST_MORE_ASSERTIONS); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); @@ -594,7 +560,7 @@ public void passingUnitTestMultipleAssertions() { @Test public void passingUnitTestMultipleTestCases() { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgramString(UNIT_TEST_MORE_TCS); TestResult testResult = alpha.test(prog); assertTrue(testResult.isSuccess()); @@ -603,7 +569,7 @@ public void passingUnitTestMultipleTestCases() { @Test public void failingAssertionUnitTest() { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgramString(UNIT_TEST_FAILING_ASSERTION); TestResult testResult = alpha.test(prog); assertFalse(testResult.isSuccess()); @@ -618,7 +584,7 @@ public void failingAssertionUnitTest() { @Test public void failingAnswerSetCountUnitTest() { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram prog = alpha.readProgramString(UNIT_TEST_FAILING_COUNT); TestResult testResult = alpha.test(prog); assertFalse(testResult.isSuccess()); @@ -678,12 +644,11 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException * -DebugEnableInternalChecks -q -g naive -s default -sort -n 400 -i 3col-20-38.txt */ SystemConfig cfg = new SystemConfig(); - cfg.setGrounderName("naive"); cfg.setSolverName("default"); cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(1119718541727902L); - final Alpha system = new AlphaImpl(cfg); + final Alpha system = AlphaFactory.newAlpha(cfg); final Path path = Paths.get("src", "test", "resources", "PreviouslyProblematic").resolve("3col-20-38.txt"); InputConfig inputCfg = new InputConfig(); @@ -698,12 +663,11 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException private void problematicRun(String program, long seed, int limit) throws IOException { final Path base = Paths.get("src", "test", "resources", "PreviouslyProblematic"); SystemConfig cfg = new SystemConfig(); - cfg.setGrounderName("naive"); cfg.setSolverName("default"); cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(seed); - final Alpha system = new AlphaImpl(cfg); + final Alpha system = AlphaFactory.newAlpha(cfg); InputConfig inputCfg = new InputConfig(); List files = new ArrayList<>(); files.add(base.resolve(program).toString()); @@ -729,11 +693,10 @@ public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOE config.setBranchingHeuristic(Heuristic.valueOf("VSIDS")); config.setDebugInternalChecks(true); config.setDisableJustificationSearch(false); - config.setEvaluateStratifiedPart(false); config.setReplayChoices(Arrays.asList(21, 26, 36, 56, 91, 96, 285, 166, 101, 290, 106, 451, 445, 439, 448, 433, 427, 442, 421, 415, 436, 409, 430, 397, 391, 424, 385, 379, 418, 373, 412, 406, 394, 388, 382, 245, 232, 208)); - Alpha alpha = new AlphaImpl(config); + Alpha alpha = AlphaFactory.newAlpha(config); Optional answerSet = alpha.solve(parsedProgram).findFirst(); assertTrue(answerSet.isPresent()); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ReificationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ReificationTest.java index 4ec2ea622..4131b6f52 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ReificationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ReificationTest.java @@ -33,7 +33,7 @@ */ public class ReificationTest { - private final Alpha alpha = new AlphaImpl(); + private final Alpha alpha = AlphaFactory.newAlpha(); private static final Map> CMP_OP_IDS; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java index 7657b7d40..13021d7c5 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HanoiTowerTest.java @@ -23,9 +23,9 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.*; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; @@ -33,6 +33,8 @@ import java.util.Optional; import java.util.SortedSet; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; import org.junit.jupiter.api.Disabled; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,10 +49,9 @@ import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; /** - * Tests {@link AbstractSolver} using some hanoi tower test cases (see https://en.wikipedia.org/wiki/Tower_of_Hanoi). + * Tests {@link Solver} using some hanoi tower test cases (see Towers of Hanoi). * */ public class HanoiTowerTest { @@ -62,49 +63,49 @@ public class HanoiTowerTest { @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance1(RegressionTestConfig cfg) { + public void testInstance1(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance2(RegressionTestConfig cfg) { + public void testInstance2(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance3(RegressionTestConfig cfg) { + public void testInstance3(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance4(RegressionTestConfig cfg) { + public void testInstance4(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(4, cfg)); } @RegressionTest - public void testSimple(RegressionTestConfig cfg) { - TestUtils.ignoreTestForNaiveSolver(cfg); - TestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); + public void testSimple(SystemConfig cfg) { + ignoreTestForNaiveSolver(cfg); + ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower("simple", cfg)); } - private void testHanoiTower(int instance, RegressionTestConfig cfg) throws IOException { + private void testHanoiTower(int instance, SystemConfig cfg) throws IOException { testHanoiTower(String.valueOf(instance), cfg); } - private void testHanoiTower(String instance, RegressionTestConfig cfg) throws IOException { + private void testHanoiTower(String instance, SystemConfig cfg) throws IOException { InputProgram prog = new ProgramParserImpl().parse( Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); - Solver solver = TestUtils.buildSolverForRegressionTest(prog, cfg); + Solver solver = buildSolverForRegressionTest(prog, cfg); Optional answerSet = solver.stream().findFirst(); assertTrue(answerSet.isPresent()); checkGoal(prog, answerSet.get()); @@ -135,7 +136,7 @@ private int getSteps(InputProgram parsedProgram) { Predicate steps = Predicates.getPredicate("steps", 1); for (Atom atom : parsedProgram.getFacts()) { if (atom.getPredicate().getName().equals(steps.getName()) && atom.getPredicate().getArity() == steps.getArity()) { - return Integer.valueOf(atom.getTerms().get(0).toString()); + return Integer.parseInt(atom.getTerms().get(0).toString()); } } throw new IllegalArgumentException("No steps atom found in input program."); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java index 2f2b91204..07f80ac83 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java @@ -36,13 +36,13 @@ import java.util.Optional; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests rule transformations described in the following research paper, and their effects on performance: @@ -246,7 +246,7 @@ private InputProgram constructProgramA_TransformationA(int n) { private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { assertEquals(numberOfRules, strRules.size()); String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - InputProgram parsedProgram = new InputProgramParser().parse(strProgram); + InputProgram parsedProgram = new ProgramParserImpl().parse(strProgram); assertEquals(numberOfRules, parsedProgram.getRules().size()); return parsedProgram; } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java index 171e0c514..9ae96e5cd 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java @@ -35,17 +35,18 @@ import java.nio.file.Paths; import java.util.Optional; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import org.junit.jupiter.api.Disabled; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** - * Tests {@link AbstractSolver} using Omiga benchmark problems. + * Tests {@link Solver} using Omiga benchmark problems. * */ // TODO This is actually a performance benchmark and should not be run with standard unit tests @@ -112,7 +113,7 @@ public void testReach_4(SystemConfig cfg) { private void test(String folder, String aspFileName, SystemConfig cfg) throws IOException { @SuppressWarnings("unused") Optional answerSet = buildSolverForRegressionTest( - new InputProgramParser().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) + new ProgramParserImpl().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) .stream().findFirst(); // System.out.println(answerSet); // TODO: check correctness of answer set diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java index 6303ec475..7fd811e8a 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java @@ -32,6 +32,7 @@ import java.nio.file.Paths; import java.util.Optional; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.junit.jupiter.api.Disabled; @@ -39,11 +40,10 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** - * Tests {@link AbstractSolver} using a racks configuration problem. + * Tests {@link Solver} using a racks configuration problem. * */ // TODO This is a functional test and should not be run with standard unit tests @@ -61,7 +61,7 @@ public void testRacks(SystemConfig cfg) { private void test(SystemConfig cfg) throws IOException { CharStream programInputStream = CharStreams.fromPath( Paths.get("benchmarks", "siemens", "racks", "racks.lp")); - Solver solver = buildSolverForRegressionTest(new InputProgramParser().parse(programInputStream), cfg); + Solver solver = buildSolverForRegressionTest(new ProgramParserImpl().parse(programInputStream), cfg); @SuppressWarnings("unused") Optional answerSet = solver.stream().findFirst(); // System.out.println(answerSet); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java index da84e80a7..c992ae820 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java @@ -25,16 +25,11 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSet; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSetsWithBase; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.*; import static java.util.Collections.singleton; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.util.Collections; import java.util.HashSet; @@ -44,6 +39,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -55,9 +51,8 @@ import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.ChoiceGrounder; -import at.ac.tuwien.kr.alpha.core.grounder.DummyGrounder; -import at.ac.tuwien.kr.alpha.core.test.util.AnswerSetsParser; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; +import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; public class SolverTests { @@ -74,7 +69,7 @@ public int compareTo(Thingy o) { } @RegressionTest - public void testObjectProgram(RegressionTestConfig cfg) { + public void testObjectProgram(SystemConfig cfg) { final Thingy thingy = new Thingy(); final Atom fact = Atoms.newBasicAtom(Predicates.getPredicate("foo", 1), Terms.newConstant(thingy)); @@ -91,8 +86,8 @@ public void testObjectProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testFactsOnlyProgram(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testFactsOnlyProgram(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(a). p(b). foo(13). foo(16). q(a). q(c).", @@ -101,8 +96,8 @@ public void testFactsOnlyProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testSimpleRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testSimpleRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(a). p(b). r(X) :- p(X).", @@ -111,8 +106,8 @@ public void testSimpleRule(RegressionTestConfig cfg) { } @RegressionTest - public void testSimpleRuleWithGroundPart(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testSimpleRuleWithGroundPart(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(1)." + "p(2)." + @@ -123,8 +118,8 @@ public void testSimpleRuleWithGroundPart(RegressionTestConfig cfg) { } @RegressionTest - public void testProgramZeroArityPredicates(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testProgramZeroArityPredicates(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "a. p(X) :- b, r(X).", @@ -133,7 +128,7 @@ public void testProgramZeroArityPredicates(RegressionTestConfig cfg) { } @RegressionTest - public void testChoiceGroundProgram(RegressionTestConfig cfg) { + public void testChoiceGroundProgram(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not b. b :- not a.", @@ -144,7 +139,7 @@ public void testChoiceGroundProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testChoiceProgramNonGround(RegressionTestConfig cfg) { + public void testChoiceProgramNonGround(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1). dom(2). dom(3)." + @@ -165,7 +160,7 @@ public void testChoiceProgramNonGround(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgram3Way(RegressionTestConfig cfg) { + public void choiceProgram3Way(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not b, not c." + @@ -179,12 +174,12 @@ public void choiceProgram3Way(RegressionTestConfig cfg) { } @RegressionTest - public void emptyProgramYieldsEmptyAnswerSet(RegressionTestConfig cfg) { + public void emptyProgramYieldsEmptyAnswerSet(SystemConfig cfg) { assertRegressionTestAnswerSets(cfg, "", ""); } @RegressionTest - public void chooseMultipleAnswerSets(RegressionTestConfig cfg) { + public void chooseMultipleAnswerSets(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not nota." + @@ -206,8 +201,8 @@ public void chooseMultipleAnswerSets(RegressionTestConfig cfg) { } @RegressionTest - public void builtinAtoms(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void builtinAtoms(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "dom(1). dom(2). dom(3). dom(4). dom(5)." + "p(X) :- dom(X), X = 4." + @@ -218,8 +213,8 @@ public void builtinAtoms(RegressionTestConfig cfg) { } @RegressionTest - public void builtinAtomsGroundRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void builtinAtomsGroundRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "a :- 13 != 4." + "b :- 2 != 3, 2 = 3." + @@ -231,8 +226,8 @@ public void builtinAtomsGroundRule(RegressionTestConfig cfg) { @RegressionTest - public void choiceProgramConstraintSimple(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void choiceProgramConstraintSimple(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "fact(a).\n" + "choice(either, X) :- fact(X), not choice(or, X).\n" + @@ -244,8 +239,8 @@ public void choiceProgramConstraintSimple(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraintSimple2(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void choiceProgramConstraintSimple2(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "fact(a).\n" + "desired(either).\n" + @@ -258,7 +253,7 @@ public void choiceProgramConstraintSimple2(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraint(RegressionTestConfig cfg) { + public void choiceProgramConstraint(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "eq(1,1)." + @@ -284,7 +279,7 @@ public void choiceProgramConstraint(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraintPermutation(RegressionTestConfig cfg) { + public void choiceProgramConstraintPermutation(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "eq(1,1)." + @@ -310,8 +305,8 @@ public void choiceProgramConstraintPermutation(RegressionTestConfig cfg) { } @RegressionTest - public void simpleNoPropagation(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void simpleNoPropagation(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "val(1,1)." + "val(2,2)." + @@ -322,7 +317,7 @@ public void simpleNoPropagation(RegressionTestConfig cfg) { } @RegressionTest - public void choiceAndPropagationAfterwards(RegressionTestConfig cfg) { + public void choiceAndPropagationAfterwards(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "node(a)." + @@ -341,7 +336,7 @@ public void choiceAndPropagationAfterwards(RegressionTestConfig cfg) { } @RegressionTest - public void choiceAndConstraints(RegressionTestConfig cfg) { + public void choiceAndConstraints(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "node(a)." + @@ -360,13 +355,13 @@ public void choiceAndConstraints(RegressionTestConfig cfg) { } @RegressionTest - public void testUnsatisfiableProgram(RegressionTestConfig cfg) { + public void testUnsatisfiableProgram(SystemConfig cfg) { assertRegressionTestAnswerSets(cfg, "p(a). p(b). :- p(a), p(b)."); } @RegressionTest - public void testFunctionTermEquality(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testFunctionTermEquality(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "r1(f(a,b)). r2(f(a,b)). a :- r1(X), r2(Y), X = Y.", @@ -375,7 +370,7 @@ public void testFunctionTermEquality(RegressionTestConfig cfg) { } @RegressionTest - public void builtinInequality(RegressionTestConfig cfg) { + public void builtinInequality(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "location(a1)." + @@ -398,7 +393,7 @@ public void builtinInequality(RegressionTestConfig cfg) { } @RegressionTest - public void choiceConstraintsInequality(RegressionTestConfig cfg) { + public void choiceConstraintsInequality(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "assign(L, R) :- not nassign(L, R), possible(L, R)." + @@ -456,7 +451,7 @@ public void choiceConstraintsInequality(RegressionTestConfig cfg) { } @RegressionTest - public void sameVariableTwiceInAtom(RegressionTestConfig cfg) { + public void sameVariableTwiceInAtom(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(a, a)." + @@ -467,7 +462,7 @@ public void sameVariableTwiceInAtom(RegressionTestConfig cfg) { } @RegressionTest - public void sameVariableTwiceInAtomConstraint(RegressionTestConfig cfg) { + public void sameVariableTwiceInAtomConstraint(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(a, a)." + @@ -476,7 +471,7 @@ public void sameVariableTwiceInAtomConstraint(RegressionTestConfig cfg) { } @RegressionTest - public void noPositiveSelfFounding(RegressionTestConfig cfg) { + public void noPositiveSelfFounding(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- b." + @@ -486,7 +481,7 @@ public void noPositiveSelfFounding(RegressionTestConfig cfg) { } @RegressionTest - public void noPositiveCycleSelfFoundingChoice(RegressionTestConfig cfg) { + public void noPositiveCycleSelfFoundingChoice(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "c :- not d." + @@ -498,8 +493,8 @@ public void noPositiveCycleSelfFoundingChoice(RegressionTestConfig cfg) { } @RegressionTest - public void conflictFromUnaryNoGood(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void conflictFromUnaryNoGood(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "d(b)." + "sel(X) :- not nsel(X), d(X)." + @@ -512,7 +507,7 @@ public void conflictFromUnaryNoGood(RegressionTestConfig cfg) { } @RegressionTest - public void intervalsInFacts(RegressionTestConfig cfg) { + public void intervalsInFacts(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a." + @@ -549,7 +544,7 @@ public void intervalsInFacts(RegressionTestConfig cfg) { } @RegressionTest - public void intervalInRules(RegressionTestConfig cfg) { + public void intervalInRules(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- 3 = 1..4 ." + @@ -570,7 +565,7 @@ public void intervalInRules(RegressionTestConfig cfg) { } @RegressionTest - public void emptyIntervals(RegressionTestConfig cfg) { + public void emptyIntervals(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(3..1)." + @@ -581,7 +576,7 @@ public void emptyIntervals(RegressionTestConfig cfg) { } @RegressionTest - public void intervalInFunctionTermsInRules(RegressionTestConfig cfg) { + public void intervalInFunctionTermsInRules(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- q(f(1..3,g(4..5)))." + @@ -606,8 +601,8 @@ public void intervalInFunctionTermsInRules(RegressionTestConfig cfg) { } @RegressionTest - public void groundAtomInRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void groundAtomInRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p :- dom(X), q, q2." + "dom(1)." + @@ -622,7 +617,7 @@ public void groundAtomInRule(RegressionTestConfig cfg) { } @RegressionTest - public void simpleChoiceRule(RegressionTestConfig cfg) { + public void simpleChoiceRule(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "{ a; b; c} :- d." + @@ -641,7 +636,7 @@ public void simpleChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void conditionalChoiceRule(RegressionTestConfig cfg) { + public void conditionalChoiceRule(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1..3)." + @@ -665,7 +660,7 @@ public void conditionalChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void doubleChoiceRule(RegressionTestConfig cfg) { + public void doubleChoiceRule(SystemConfig cfg) { Solver solver = buildSolverForRegressionTest("{ a }. { a }.", cfg); // Make sure that no superfluous answer sets that only differ on hidden atoms occur. List actual = solver.collectList(); @@ -674,8 +669,8 @@ public void doubleChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void simpleArithmetics(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void simpleArithmetics(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "eight(X) :- X = 4 + 5 - 1." + "three(X) :- X = Z, Y = 1..10, Z = Y / 3, Z > 2, Z < 4.", @@ -684,8 +679,8 @@ public void simpleArithmetics(RegressionTestConfig cfg) { } @RegressionTest - public void arithmeticsMultiplicationBeforeAddition(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void arithmeticsMultiplicationBeforeAddition(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "seven(X) :- 1+2 * 3 = X.", @@ -696,7 +691,7 @@ public void arithmeticsMultiplicationBeforeAddition(RegressionTestConfig cfg) { * Tests the fix for issue #101 */ @RegressionTest - public void involvedUnsatisfiableProgram(RegressionTestConfig cfg) { + public void involvedUnsatisfiableProgram(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "x :- c1, c2, not x." + @@ -711,7 +706,7 @@ public void involvedUnsatisfiableProgram(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationAtom(RegressionTestConfig cfg) { + public void instanceEnumerationAtom(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(1). dom(2). dom(3)." + "p(X) :- dom(X)." + @@ -728,7 +723,7 @@ public void instanceEnumerationAtom(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationArbitraryTerms(RegressionTestConfig cfg) { + public void instanceEnumerationArbitraryTerms(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(a). dom(f(a,b)). dom(d)." + "p(X) :- dom(X)." + @@ -745,7 +740,7 @@ public void instanceEnumerationArbitraryTerms(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationMultipleIdentifiers(RegressionTestConfig cfg) { + public void instanceEnumerationMultipleIdentifiers(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(a). dom(b). dom(c). dom(d)." + "p(X) :- dom(X)." + @@ -765,15 +760,15 @@ public void instanceEnumerationMultipleIdentifiers(RegressionTestConfig cfg) { } private void assertPropositionalPredicateFalse(AnswerSet answerSet, Predicate predicate) { - assertEquals(null, answerSet.getPredicateInstances(predicate)); + assertNull(answerSet.getPredicateInstances(predicate)); } private void assertEnumerationPositions(SortedSet positions, int numPositions) { assertEquals(numPositions, positions.size()); - boolean usedPositions[] = new boolean[numPositions]; + boolean[] usedPositions = new boolean[numPositions]; for (Atom position : positions) { @SuppressWarnings("unchecked") - Integer atomPos = ((ConstantTerm) position.getTerms().get(1)).getObject() - 1; + int atomPos = ((ConstantTerm) position.getTerms().get(1)).getObject() - 1; assertTrue(atomPos < numPositions); usedPositions[atomPos] = true; } @@ -783,7 +778,7 @@ private void assertEnumerationPositions(SortedSet positions, int numPositi } @RegressionTest - public void smallCardinalityAggregate(RegressionTestConfig cfg) { + public void smallCardinalityAggregate(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1..3)." + @@ -804,16 +799,17 @@ public void smallCardinalityAggregate(RegressionTestConfig cfg) { ); } - @RegressionTest - public void dummyGrounder(RegressionTestConfig cfg) { - AtomStore atomStore = new AtomStoreImpl(); - assertEquals(DummyGrounder.EXPECTED, buildSolverForRegressionTest(atomStore, new DummyGrounder(atomStore), cfg).collectSet()); - } - - @RegressionTest - public void choiceGrounder(RegressionTestConfig cfg) { - AtomStore atomStore = new AtomStoreImpl(); - assertEquals(ChoiceGrounder.EXPECTED, buildSolverForRegressionTest(atomStore, new ChoiceGrounder(atomStore), cfg).collectSet()); - } + // TODO these look obsolete - confirm if they can be removed +// @RegressionTest +// public void dummyGrounder(SystemConfig cfg) { +// AtomStore atomStore = new AtomStoreImpl(); +// assertEquals(DummyGrounder.EXPECTED, buildSolverForRegressionTest(atomStore, new DummyGrounder(atomStore), cfg).collectSet()); +// } +// +// @RegressionTest +// public void choiceGrounder(SystemConfig cfg) { +// AtomStore atomStore = new AtomStoreImpl(); +// assertEquals(ChoiceGrounder.EXPECTED, buildSolverForRegressionTest(atomStore, new ChoiceGrounder(atomStore), cfg).collectSet()); +// } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java index 4884832c2..db0f40009 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java @@ -10,6 +10,8 @@ import java.util.Set; import java.util.function.Consumer; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import org.apache.commons.lang3.tuple.ImmutablePair; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -26,8 +28,6 @@ import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; // TODO This is a functional test and should not be run with standard unit tests public class StratifiedEvaluationRegressionTest { @@ -113,7 +113,7 @@ public void runTest(String aspString, Consumer programVerifier, LOGGER.debug("Testing ASP String {}", aspString); // Parse and pre-evaluate program // Alpha instance with default config, stratified evaluation enabled - Alpha alpha = new AlphaFactory().newAlpha(); + Alpha alpha =AlphaFactory.newAlpha(); InputProgram input = alpha.readProgramString(aspString); DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(input); NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); @@ -129,7 +129,7 @@ private static void verifyProgramBasic(NormalProgram evaluated) { assertFactsContainedInProgram(evaluated, Atoms.newBasicAtom(Predicates.getPredicate("a", 0)), Atoms.newBasicAtom(Predicates.getPredicate("b", 0))); assertEquals(2, evaluated.getFacts().size()); - assertTrue(evaluated.getRules().size() == 0); + assertTrue(evaluated.getRules().isEmpty()); } private static void verifyAnswerSetsBasic(Set answerSets) { @@ -140,7 +140,7 @@ private static void verifyProgramBasicMultiInstance(NormalProgram evaluated) { assertFactsContainedInProgram(evaluated, Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a")), Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("b"))); - assertTrue(evaluated.getRules().size() == 0); + assertTrue(evaluated.getRules().isEmpty()); } private static void verifyAnswerSetsBasicMultiInstance(Set answerSets) { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java index 9c8388297..1740d5133 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java @@ -23,16 +23,15 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; - -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +package at.ac.tuwien.kr.alpha.regressiontests; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Random; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; @@ -46,59 +45,62 @@ import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; + public class ThreeColouringRandomGraphTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testV3E3(RegressionTestConfig cfg) { + public void testV3E3(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV10E18(RegressionTestConfig cfg) { + public void testV10E18(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, 18, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV20E38(RegressionTestConfig cfg) { + public void testV20E38(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(20, 38, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV30E48(RegressionTestConfig cfg) { + public void testV30E48(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(30, 48, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV200E300(RegressionTestConfig cfg) { + public void testV200E300(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(200, 300, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV300E200(RegressionTestConfig cfg) { + public void testV300E200(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(300, 200, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV300E300(RegressionTestConfig cfg) { + public void testV300E300(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(300, 300, cfg)); } - private void testThreeColouring(int nVertices, int nEdges, RegressionTestConfig cfg) { + private void testThreeColouring(int nVertices, int nEdges, SystemConfig cfg) { InputProgram tmpPrg = new ProgramParserImpl().parse( "blue(N) :- v(N), not red(N), not green(N)." + "red(N) :- v(N), not blue(N), not green(N)." + diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java index 8f0c32c05..7af25b780 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java @@ -23,10 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; - -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +package at.ac.tuwien.kr.alpha.regressiontests; import java.util.ArrayList; import java.util.Collections; @@ -34,6 +31,8 @@ import java.util.Optional; import java.util.Random; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; @@ -49,8 +48,11 @@ import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; + /** - * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: + * Tests {@link Solver} using some three-coloring test cases, as described in: * Lefèvre, Claire; Béatrix, Christopher; Stéphan, Igor; Garcia, Laurent (2017): * ASPeRiX, a first-order forward chaining approach for answer set computing. * In Theory and Practice of Logic Programming, pp. 1-45. DOI: @@ -61,130 +63,130 @@ public class ThreeColouringTestWithRandom { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN3(RegressionTestConfig cfg) { + public void testN3(SystemConfig cfg) { long timeout = 3000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, false, 0, cfg)); } @RegressionTest - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 4000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(4, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN5(RegressionTestConfig cfg) { + public void testN5(SystemConfig cfg) { long timeout = 5000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(5, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN6(RegressionTestConfig cfg) { + public void testN6(SystemConfig cfg) { long timeout = 6000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(6, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN7(RegressionTestConfig cfg) { + public void testN7(SystemConfig cfg) { long timeout = 7000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(7, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN8(RegressionTestConfig cfg) { + public void testN8(SystemConfig cfg) { long timeout = 8000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(8, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN9(RegressionTestConfig cfg) { + public void testN9(SystemConfig cfg) { long timeout = 9000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(9, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10(RegressionTestConfig cfg) { + public void testN10(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random0(RegressionTestConfig cfg) { + public void testN10Random0(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random1(RegressionTestConfig cfg) { + public void testN10Random1(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random2(RegressionTestConfig cfg) { + public void testN10Random2(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random3(RegressionTestConfig cfg) { + public void testN10Random3(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19(RegressionTestConfig cfg) { + public void testN19(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random0(RegressionTestConfig cfg) { + public void testN19Random0(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random1(RegressionTestConfig cfg) { + public void testN19Random1(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random2(RegressionTestConfig cfg) { + public void testN19Random2(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random3(RegressionTestConfig cfg) { + public void testN19Random3(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN101(RegressionTestConfig cfg) { + public void testN101(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(101, false, 0, cfg)); } - private void testThreeColouring(int n, boolean shuffle, int seed, RegressionTestConfig cfg) { + private void testThreeColouring(int n, boolean shuffle, int seed, SystemConfig cfg) { InputProgram tmpPrg = new ProgramParserImpl() .parse("col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); InputProgramBuilder prgBuilder = Programs.builder().accumulate(tmpPrg); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java index 1470708ca..a3ad1c447 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java @@ -23,15 +23,14 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; - -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +package at.ac.tuwien.kr.alpha.regressiontests; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; @@ -47,8 +46,11 @@ import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; + /** - * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: + * Tests {@link Solver} using some three-coloring test cases, as described in: * Lefèvre, Claire; Béatrix, Christopher; Stéphan, Igor; Garcia, Laurent (2017): * ASPeRiX, a first-order forward chaining approach for answer set computing. * In Theory and Practice of Logic Programming, pp. 1-45. @@ -59,46 +61,46 @@ public class ThreeColouringWheelTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(4, cfg)); } @RegressionTest - public void testN5(RegressionTestConfig cfg) { + public void testN5(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(5, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN6(RegressionTestConfig cfg) { + public void testN6(SystemConfig cfg) { long timeout = 6000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(6, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN3(RegressionTestConfig cfg) { + public void testN3(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN7(RegressionTestConfig cfg) { + public void testN7(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(7, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN11(RegressionTestConfig cfg) { + public void testN11(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(11, cfg)); } - private void testThreeColouring(int n, RegressionTestConfig cfg) { + private void testThreeColouring(int n, SystemConfig cfg) { InputProgram tmpPrg = new ProgramParserImpl().parse( "col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java index 4d5823aa1..93a5e3ad7 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java @@ -21,7 +21,7 @@ public class RegressionTestConfigProvider { private static final boolean DEFAULT_ENABLE_DEBUG_CHECKS = false; /** - * Creates a list of {@link RegressionTestConfig}s with all config combinations that are to be tested im methods tagged using + * Creates a list of {@link SystemConfig}s with all config combinations that are to be tested im methods tagged using * "RegressionTest" annotation. * Exact number of combinations depends on the "CI" environment variable that can be used to signal that a test is being run in a CI * environment. @@ -80,7 +80,7 @@ private static List buildConfigs() { } /** - * Provides {@link RegressionTestConfig}s specifically for tests concerned with AggregateRewriting. + * Provides {@link SystemConfig}s specifically for tests concerned with AggregateRewriting. * All parameters fixed to default values except stratified evaluation, sorting grid encoding for count rewriting * and negative sum element support. * @@ -135,7 +135,7 @@ public static List provideAggregateTestConfigs() { return retVal; } - private static final String[] nonDeprecatedHeuristics() { + private static String[] nonDeprecatedHeuristics() { final List nonDeprecatedHeuristicsNames = new ArrayList<>(); for (Field field : Heuristic.class.getFields()) { if (field.getAnnotation(Deprecated.class) == null) { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java index 686df4990..0629c8be1 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java @@ -32,30 +32,30 @@ public static void runWithTimeout(SystemConfig cfg, long baseTimeout, long timeo } public static Solver buildSolverForRegressionTest(String programString, SystemConfig cfg) { - Alpha alpha = new AlphaFactory().newAlpha(cfg); + Alpha alpha = AlphaFactory.newAlpha(cfg); InputProgram program = alpha.readProgramString(programString); return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); } public static Solver buildSolverForRegressionTest(InputProgram program, SystemConfig cfg) { - Alpha alpha = new AlphaFactory().newAlpha(cfg); + Alpha alpha =AlphaFactory.newAlpha(cfg); return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); } public static Set collectRegressionTestAnswerSets(String program, SystemConfig cfg) { - Alpha alpha = new AlphaFactory().newAlpha(cfg); + Alpha alpha = AlphaFactory.newAlpha(cfg); InputProgram in = alpha.readProgramString(program); return alpha.solve(in).collect(Collectors.toSet()); } public static Set collectRegressionTestAnswerSets(InputProgram program, SystemConfig cfg) { - return new AlphaFactory().newAlpha(cfg) + return AlphaFactory.newAlpha(cfg) .solve(program) .collect(Collectors.toSet()); } private static Set solveForConfig(String programString, SystemConfig cfg) { - Alpha alpha = new AlphaFactory().newAlpha(cfg); + Alpha alpha = AlphaFactory.newAlpha(cfg); InputProgram program = alpha.readProgramString(programString); return alpha.solve(program).collect(Collectors.toSet()); } From aad55207d56caf48ecf5813f545f3af8dc08f303 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 23 Jul 2024 11:01:01 +0200 Subject: [PATCH 37/59] Fix tests after merging changes from master --- .../commons/programs/rules/AbstractRule.java | 14 +- .../commons/programs/rules/BasicRule.java | 5 +- .../programs/rules/NormalRuleImpl.java | 5 +- .../alpha/commons/programs/rules/Rules.java | 15 +- .../programs/rules/heads/ActionHeadImpl.java | 92 +++--- .../commons/programs/rules/heads/Heads.java | 6 +- .../terms/AbstractActionResultTerm.java | 24 +- .../programs/terms/ActionErrorTerm.java | 22 +- .../programs/terms/ActionSuccessTerm.java | 24 +- .../atoms/BasicAtomImplTest.java | 25 +- .../atoms/ExternalAtomImplTest.java | 33 +-- ...LiteralBindingNonBindingVariablesTest.java | 68 ++--- .../commons/programs/terms/TermsTest.java | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 8 +- .../core/programs/rules/InternalRule.java | 2 +- .../IntervalTermToIntervalAtom.java | 1 + .../transformation/PredicateInternalizer.java | 2 - .../VariableEqualityRemoval.java | 12 +- .../encoders/AggregateEncoders.java | 1 - .../aggregates/encoders/CountEncoder.java | 6 +- .../aggregates/encoders/MinMaxEncoder.java | 13 +- .../StringtemplateBasedAggregateEncoder.java | 1 - .../aggregates/encoders/SumEncoder.java | 8 +- .../kr/alpha/core/common/ProgramTest.java | 37 +-- .../GrounderMockWithBasicProgram.java | 51 ++-- .../core/grounder/GrounderMockWithChoice.java | 60 ++-- .../core/grounder/NaiveGrounderTest.java | 41 +-- .../core/grounder/NoGoodGeneratorTest.java | 17 +- .../alpha/core/parser/AspCore2ParserTest.java | 11 - .../alpha/core/parser/EvologParserTest.java | 14 - .../alpha/core/programs/atoms/AtomsTest.java | 26 +- .../core/programs/atoms}/RuleAtomTest.java | 11 +- .../ProgramTransformationTest.java | 2 +- .../StratifiedEvaluationRegressionTest.java | 262 ------------------ .../AggregateRewritingRuleAnalysisTest.java | 2 +- .../core/rules/RuleGroundingInfoTest.java | 9 +- .../alpha/core/solver/AtomCounterTests.java | 2 +- .../AlphaHeuristicTestAssumptions.java | 6 +- .../ac/tuwien/kr/alpha/test}/RuleParser.java | 2 +- .../kr/alpha/api/impl/AlphaFactory.java | 2 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 34 ++- .../at/ac/tuwien/kr/alpha/ActionsTest.java | 7 +- .../alpha/AggregateLiteralSplittingTest.java | 16 +- .../AggregateOperatorNormalizationTest.java | 14 +- .../alpha/AggregateRewritingContextTest.java | 22 +- .../kr/alpha/AggregateRewritingTest.java | 34 +-- .../alpha/ArithmeticTermsRewritingTest.java | 25 +- .../FixedInterpretationLiteralsTest.java | 25 +- .../ac/tuwien/kr/alpha/RuleToStringTest.java | 16 +- .../kr/alpha/StratifiedEvaluationTest.java | 49 ++-- .../kr/alpha/api/impl/AlphaImplTest.java | 3 +- .../kr/alpha/regressiontests/SolverTests.java | 18 +- .../StratifiedEvaluationRegressionTest.java | 2 +- .../util/RegressionTestUtils.java | 23 +- .../test/util/MockedActionsAlphaFactory.java | 2 + 55 files changed, 427 insertions(+), 807 deletions(-) rename alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/{ => programs}/atoms/BasicAtomImplTest.java (85%) rename alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/{ => programs}/atoms/ExternalAtomImplTest.java (82%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms => alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/literals}/LiteralBindingNonBindingVariablesTest.java (82%) delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java rename {alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals => alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms}/RuleAtomTest.java (97%) delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java rename {alpha-solver/src/test/java/at/ac/tuwien/kr/alpha => alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test}/RuleParser.java (94%) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java index 5b8e4454e..c243d840b 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/AbstractRule.java @@ -1,17 +1,15 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import org.apache.commons.collections4.SetUtils; - import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.util.Util; +import org.apache.commons.collections4.SetUtils; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; /** * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java index 13b991506..77aac0ea3 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/BasicRule.java @@ -27,12 +27,11 @@ */ package at.ac.tuwien.kr.alpha.commons.programs.rules; -import java.util.List; -import java.util.Set; - import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; +import java.util.Set; + /** * Represents a non-ground rule or a constraint. A {@link BasicRule} has a general {@link Head}, meaning both choice heads and disjunctive * heads are permissible. diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java index 80225ef71..acd5ee0d5 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/NormalRuleImpl.java @@ -1,12 +1,11 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules; -import java.util.List; -import java.util.Set; - import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; +import java.util.Set; + /** * A rule that has a normal head, i.e. just one head atom, no disjunction or choice heads allowed. * Currently, any constructs such as aggregates, intervals, etc. in the rule body are allowed. diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java index f0456caba..9a19b54bc 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java @@ -1,16 +1,17 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules; -import java.util.*; - import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; -import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.util.Util; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + public final class Rules { private Rules() { @@ -22,7 +23,7 @@ public static Rule newRule(Head head, Set body) { } public static Rule newRule(Head head, Literal... body) { - Set bodyLst = new LinkedHashSet<>(Arrays.asList(body)); + Set bodyLst = new LinkedHashSet<>(Arrays.asList(body)); return new BasicRule(head, bodyLst); } @@ -31,7 +32,7 @@ public static NormalRule newNormalRule(NormalHead head, Set body) { } public static NormalRule newNormalRule(NormalHead head, Literal... body) { - Set bodyLst = new LinkedHashSet<>(Arrays.asList(body)); + Set bodyLst = new LinkedHashSet<>(Arrays.asList(body)); return new NormalRuleImpl(head, bodyLst); } @@ -41,9 +42,9 @@ public static NormalRule toNormalRule(Rule rule) { if (!(rule.getHead() instanceof NormalHead)) { throw Util.oops("Trying to construct a NormalRule from rule with non-normal head! Head type is: " + rule.getHead().getClass().getSimpleName()); } - headAtom = ((NormalHead) rule.getHead()).getAtom(); + } - return new NormalRuleImpl(headAtom != null ? Heads.newNormalHead(headAtom) : null, new LinkedHashSet<>(rule.getBody())); + return newNormalRule(rule.isConstraint() ? null : (NormalHead) rule.getHead(), new LinkedHashSet<>(rule.getBody())); } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java index 46a598442..4d41d044a 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/ActionHeadImpl.java @@ -13,51 +13,51 @@ class ActionHeadImpl implements ActionHead { - private final BasicAtom atom; - private final String actionName; - private final List actionInputTerms; - private final VariableTerm actionOutputTerm; - - ActionHeadImpl(BasicAtom atom, String actionName, List actionInputTerms, VariableTerm actionOutputTerm) { - this.atom = atom; - this.actionName = actionName; - this.actionInputTerms = Collections.unmodifiableList(actionInputTerms); - this.actionOutputTerm = actionOutputTerm; - } - - @Override - public BasicAtom getAtom() { - return atom; - } - - @Override - public boolean isGround() { - // TODO: an action head is conceptually a basic one with an (interpreted) function term - return false; - } - - @Override - public BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution) { - return instantiator.instantiate(this, substitution); - } - - @Override - public String getActionName() { - return actionName; - } - - @Override - public List getActionInputTerms() { - return actionInputTerms; - } - - @Override - public VariableTerm getActionOutputTerm() { - return actionOutputTerm; - } - - public String toString() { - return atom.toString() + " : @" + actionName + "(" + StringUtils.join(actionInputTerms, ", ") + ") = " + actionOutputTerm; - } + private final BasicAtom atom; + private final String actionName; + private final List actionInputTerms; + private final VariableTerm actionOutputTerm; + + ActionHeadImpl(BasicAtom atom, String actionName, List actionInputTerms, VariableTerm actionOutputTerm) { + this.atom = atom; + this.actionName = actionName; + this.actionInputTerms = Collections.unmodifiableList(actionInputTerms); + this.actionOutputTerm = actionOutputTerm; + } + + @Override + public BasicAtom getAtom() { + return atom; + } + + @Override + public boolean isGround() { + // TODO: an action head is conceptually a basic one with an (interpreted) function term + return false; + } + + @Override + public BasicAtom instantiate(RuleInstantiator instantiator, Substitution substitution) { + return instantiator.instantiate(this, substitution); + } + + @Override + public String getActionName() { + return actionName; + } + + @Override + public List getActionInputTerms() { + return actionInputTerms; + } + + @Override + public VariableTerm getActionOutputTerm() { + return actionOutputTerm; + } + + public String toString() { + return atom.toString() + " : @" + actionName + "(" + StringUtils.join(actionInputTerms, ", ") + ") = " + actionOutputTerm; + } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java index 3ebf81b63..d2d271258 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/heads/Heads.java @@ -1,18 +1,18 @@ package at.ac.tuwien.kr.alpha.commons.programs.rules.heads; -import java.util.List; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ChoiceHead; -import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ChoiceHead.ChoiceElement; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.ChoiceHeadImpl.ChoiceElementImpl; +import java.util.List; + public final class Heads { private Heads() { diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java index 9a94e942d..1eacea528 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/AbstractActionResultTerm.java @@ -7,20 +7,20 @@ abstract class AbstractActionResultTerm extends FunctionTermImpl implements ActionResultTerm { - AbstractActionResultTerm(String symbol, T value) { - super(symbol, Collections.singletonList(value)); - } + AbstractActionResultTerm(String symbol, T value) { + super(symbol, Collections.singletonList(value)); + } - public abstract boolean isSuccess(); + public abstract boolean isSuccess(); - public boolean isError() { - return !isSuccess(); - } + public boolean isError() { + return !isSuccess(); + } - // Note: Unchecked cast is ok, we permit only instances of T as constructor arguments. - @SuppressWarnings("unchecked") - public T getValue() { - return (T) getTerms().get(0); - } + // Note: Unchecked cast is ok, we permit only instances of T as constructor arguments. + @SuppressWarnings("unchecked") + public T getValue() { + return (T) getTerms().get(0); + } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java index 683b640c1..40815fe80 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionErrorTerm.java @@ -6,19 +6,19 @@ class ActionErrorTerm extends AbstractActionResultTerm> { - private static final Interner INTERNER = new Interner<>(); + private static final Interner INTERNER = new Interner<>(); - ActionErrorTerm(ConstantTerm value) { - super(ActionResultTerm.ERROR_SYMBOL, value); - } + ActionErrorTerm(ConstantTerm value) { + super(ActionResultTerm.ERROR_SYMBOL, value); + } - public static ActionErrorTerm getInstance(ConstantTerm term) { - return INTERNER.intern(new ActionErrorTerm(term)); - } + public static ActionErrorTerm getInstance(ConstantTerm term) { + return INTERNER.intern(new ActionErrorTerm(term)); + } - @Override - public boolean isSuccess() { - return false; - } + @Override + public boolean isSuccess() { + return false; + } } \ No newline at end of file diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java index 2c4d7ddfd..c5a2fde14 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/ActionSuccessTerm.java @@ -6,20 +6,20 @@ class ActionSuccessTerm extends AbstractActionResultTerm { - private static final Interner> INTERNER = new Interner<>(); + private static final Interner> INTERNER = new Interner<>(); - ActionSuccessTerm(T value) { - super(ActionResultTerm.SUCCESS_SYMBOL, value); - } + ActionSuccessTerm(T value) { + super(ActionResultTerm.SUCCESS_SYMBOL, value); + } - @SuppressWarnings("unchecked") - public static ActionSuccessTerm getInstance(T term) { - return (ActionSuccessTerm) INTERNER.intern(new ActionSuccessTerm<>(term)); - } + @SuppressWarnings("unchecked") + public static ActionSuccessTerm getInstance(T term) { + return (ActionSuccessTerm) INTERNER.intern(new ActionSuccessTerm<>(term)); + } - @Override - public boolean isSuccess() { - return true; - } + @Override + public boolean isSuccess() { + return true; + } } diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImplTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/BasicAtomImplTest.java similarity index 85% rename from alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImplTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/BasicAtomImplTest.java index 275aa413e..a500b850a 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImplTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/BasicAtomImplTest.java @@ -1,14 +1,11 @@ -package at.ac.tuwien.kr.alpha.commons.atoms; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; +package at.ac.tuwien.kr.alpha.commons.programs.atoms; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; /** * Test for basic functionality of various implementations of {@link Atom}. @@ -56,12 +53,12 @@ public void testAreBasicAtomsEqual() { Terms.newFunctionTerm("r", Terms.newConstant("bla"), Terms.newVariable("BLUBB"))); assertEquals(a7, a8); - assertFalse(a1.equals(a3)); - assertFalse(a3.equals(a1)); - assertFalse(a1.equals(a5)); - assertFalse(a5.equals(a1)); - assertFalse(a1.equals(a7)); - assertFalse(a7.equals(a1)); + assertNotEquals(a1, a3); + assertNotEquals(a3, a1); + assertNotEquals(a1, a5); + assertNotEquals(a5, a1); + assertNotEquals(a1, a7); + assertNotEquals(a7, a1); } } diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/ExternalAtomImplTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ExternalAtomImplTest.java similarity index 82% rename from alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/ExternalAtomImplTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ExternalAtomImplTest.java index d762709b5..9365625f6 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/atoms/ExternalAtomImplTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ExternalAtomImplTest.java @@ -1,27 +1,18 @@ -package at.ac.tuwien.kr.alpha.commons.atoms; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.jupiter.api.Test; +package at.ac.tuwien.kr.alpha.commons.programs.atoms; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.externals.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.externals.Externals; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import org.junit.jupiter.api.Test; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; public class ExternalAtomImplTest { @@ -83,9 +74,9 @@ public void testAreExternalAtomsEqual() { assertEquals(ext1, ext2); assertEquals(ext2, ext1); - assertFalse(ext1.equals(null)); - assertFalse(ext1.equals("bla")); - assertTrue(ext1.hashCode() == ext2.hashCode()); + assertNotEquals(null, ext1); + assertNotEquals("bla", ext1); + assertEquals(ext1.hashCode(), ext2.hashCode()); } @Test diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/LiteralBindingNonBindingVariablesTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/literals/LiteralBindingNonBindingVariablesTest.java similarity index 82% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/LiteralBindingNonBindingVariablesTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/literals/LiteralBindingNonBindingVariablesTest.java index 388cfff0b..8bd512135 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/LiteralBindingNonBindingVariablesTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/literals/LiteralBindingNonBindingVariablesTest.java @@ -23,39 +23,25 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -<<<<<<<< HEAD:alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/LiteralBindingNonBindingVariablesTest.java -package at.ac.tuwien.kr.alpha.commons.literals; -======== -package at.ac.tuwien.kr.alpha.core.programs.atoms; ->>>>>>>> master:alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/LiteralBindingNonBindingVariablesTest.java - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; +package at.ac.tuwien.kr.alpha.commons.programs.literals; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -<<<<<<<< HEAD:alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/LiteralBindingNonBindingVariablesTest.java -import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -======== -import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; -import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; ->>>>>>>> master:alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/LiteralBindingNonBindingVariablesTest.java +import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.externals.IntPredicateInterpretation; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; /** * Tests the behaviour of {@link Literal#getBindingVariables()} and {@link Literal#getNonBindingVariables()} @@ -68,7 +54,7 @@ public class LiteralBindingNonBindingVariablesTest { public void testPositiveBasicLiteral() { // literal := q(X, Y) Literal literal = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("q", 2), Terms.newVariable("X"), Terms.newVariable("Y")), true); - assertEquals(false, literal.isNegated()); + assertFalse(literal.isNegated()); expectVariables(literal.getBindingVariables(), "X", "Y"); expectVariables(literal.getNonBindingVariables()); } @@ -77,7 +63,7 @@ public void testPositiveBasicLiteral() { public void testNegativeBasicLiteral() { // literal := not r(X, Y) Literal literal = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("r", 2), Terms.newVariable("X"), Terms.newVariable("Y")), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); } @@ -86,7 +72,7 @@ public void testNegativeBasicLiteral() { public void testPositiveComparisonLiteral_EQ_LeftAssigning() { // literal := Y = 5 Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.EQ), true); - assertEquals(false, literal.isNegated()); + assertFalse(literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); } @@ -95,7 +81,7 @@ public void testPositiveComparisonLiteral_EQ_LeftAssigning() { public void testNegativeComparisonLiteral_EQ_LeftAssigning() { // literal := not Y = 5 Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.EQ), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); } @@ -104,7 +90,7 @@ public void testNegativeComparisonLiteral_EQ_LeftAssigning() { public void testPositiveComparisonLiteral_EQ_RightAssigning() { // literal := 5 = Y Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.EQ), true); - assertEquals(false, literal.isNegated()); + assertFalse(literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); } @@ -113,7 +99,7 @@ public void testPositiveComparisonLiteral_EQ_RightAssigning() { public void testNegativeComparisonLiteral_EQ_RightAssigning() { // literal := 5 = Y Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.EQ), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); } @@ -122,7 +108,7 @@ public void testNegativeComparisonLiteral_EQ_RightAssigning() { public void testNegativeComparisonLiteral_EQ_Bidirectional() { // literal := not X = Y Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("X"), Terms.newVariable("Y"), ComparisonOperators.EQ), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); } @@ -131,7 +117,7 @@ public void testNegativeComparisonLiteral_EQ_Bidirectional() { public void testPositiveComparisonLiteral_NEQ_LeftAssigning() { // literal := Y != 5 Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.NE), true); - assertEquals(false, literal.isNegated()); + assertFalse(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); } @@ -140,7 +126,7 @@ public void testPositiveComparisonLiteral_NEQ_LeftAssigning() { public void testNegativeComparisonLiteral_NEQ_LeftAssigning() { // literal := not Y != 5 Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("Y"), Terms.newConstant(5), ComparisonOperators.NE), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); } @@ -149,7 +135,7 @@ public void testNegativeComparisonLiteral_NEQ_LeftAssigning() { public void testPositiveComparisonLiteral_NEQ_RightAssigning() { // literal := 5 != Y Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.NE), true); - assertEquals(false, literal.isNegated()); + assertFalse(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "Y"); } @@ -158,7 +144,7 @@ public void testPositiveComparisonLiteral_NEQ_RightAssigning() { public void testNegativeComparisonLiteral_NEQ_RightAssigning() { // literal := not 5 != Y Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newConstant(5), Terms.newVariable("Y"), ComparisonOperators.NE), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables(), "Y"); expectVariables(literal.getNonBindingVariables()); } @@ -167,7 +153,7 @@ public void testNegativeComparisonLiteral_NEQ_RightAssigning() { public void testPositiveComparisonLiteral_NEQ_Bidirectional() { // literal := X != Y Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("X"), Terms.newVariable("Y"), ComparisonOperators.NE), true); - assertEquals(false, literal.isNegated()); + assertFalse(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); } @@ -177,7 +163,7 @@ public void testPositiveComparisonLiteral_NEQ_Bidirectional() { public void testNegativeComparisonLiteral_NEQ_Bidirectional() { // literal := not X != Y Literal literal = Literals.fromAtom(Atoms.newComparisonAtom(Terms.newVariable("X"), Terms.newVariable("Y"), ComparisonOperators.NE), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables(), "X", "Y"); expectVariables(literal.getNonBindingVariables()); } @@ -190,7 +176,7 @@ public void testPositiveExternalLiteral() { extInput.add(Terms.newVariable("Y")); extOutput.add(Terms.newVariable("X")); Literal literal = Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("ext", 2), new IntPredicateInterpretation(i -> i > 0), extInput, extOutput), true); - assertEquals(false, literal.isNegated()); + assertFalse(literal.isNegated()); expectVariables(literal.getBindingVariables(), "X"); expectVariables(literal.getNonBindingVariables(), "Y"); } @@ -203,7 +189,7 @@ public void testNegativeExternalLiteral() { extInput.add(Terms.newVariable("Y")); extOutput.add(Terms.newVariable("X")); Literal literal = Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("ext", 2), new IntPredicateInterpretation(i -> i > 0), extInput, extOutput), false); - assertEquals(true, literal.isNegated()); + assertTrue(literal.isNegated()); expectVariables(literal.getBindingVariables()); expectVariables(literal.getNonBindingVariables(), "X", "Y"); } diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java index b6700d2e2..50e5afb51 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java @@ -4,10 +4,10 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.api.terms.FunctionTerm; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; public class TermsTest { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 610df11ad..6bdb979cf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -222,11 +222,15 @@ public Head visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { @Override public Head visitHead(ASPCore2Parser.HeadContext ctx) { - // head : disjunction | choice; + // head : disjunction | choice | action; if (ctx.choice() != null) { return visitChoice(ctx.choice()); + } else if (ctx.action() != null) { + return visitAction(ctx.action()); + } else if (ctx.disjunction() != null) { + return visitDisjunction(ctx.disjunction()); } - return visitDisjunction(ctx.disjunction()); + throw notSupported(ctx); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java index 1bc31f104..c6bbf7239 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/rules/InternalRule.java @@ -103,7 +103,7 @@ public static void resetIdGenerator() { } public static CompiledRule fromNormalRule(Rule rule) { - return new InternalRule(rule.isConstraint() ? null : Heads.newNormalHead(rule.getHead().getAtom()), new LinkedHashSet<>(rule.getBody())); + return new InternalRule(rule.isConstraint() ? null : rule.getHead(), new LinkedHashSet<>(rule.getBody())); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java index 9b1c69143..ef73eec08 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java @@ -75,6 +75,7 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { } // Note that this cast is safe: NormalHead can only have a BasicAtom, so literalizing and getting back the Atom destroys type information, // but should never yield anything other than a BasicAtom + // TODO handle action headS! NormalHead rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead((BasicAtom) rewriteLiteral(rule.getHead().getAtom().toLiteral(), intervalReplacements).getAtom()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index d33962805..5095da814 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -16,9 +16,7 @@ import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; -import java.util.ArrayList; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index a08aac2e2..1ca5eb985 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -34,6 +34,7 @@ import at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ActionHead; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.DisjunctiveHead; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; @@ -108,7 +109,16 @@ private Rule findAndReplaceVariableEquality(Rule rule) { if (!rule.isConstraint() && rule.getHead() instanceof DisjunctiveHead) { throw new UnsupportedOperationException("VariableEqualityRemoval cannot be applied to rule with DisjunctiveHead, yet."); } - NormalHead rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead(((NormalHead)rule.getHead()).getAtom()); + // TODO can this be done nicer? + NormalHead rewrittenHead = null; + if (!rule.isConstraint()) { + if (rule.getHead() instanceof ActionHead) { + ActionHead actHead = (ActionHead) rule.getHead(); + rewrittenHead = Heads.newActionHead(actHead.getAtom(), actHead.getActionName(), actHead.getActionInputTerms(), actHead.getActionOutputTerm()); + } else { + rewrittenHead = Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom()); + } + } // Use substitution for actual replacement. Unifier replacementSubstitution = new Unifier(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java index 686fed1f6..a22ecb65e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoders.java @@ -1,6 +1,5 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; public final class AggregateEncoders { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java index 44a10a5a3..dceca1dcf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java @@ -1,13 +1,11 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import org.stringtemplate.v4.ST; -import org.stringtemplate.v4.STGroup; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.util.Util; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; public final class CountEncoder extends StringtemplateBasedAggregateEncoder { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java index 242fc7719..0f8b5d9da 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java @@ -1,13 +1,5 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.collections4.SetUtils; -import org.stringtemplate.v4.ST; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; @@ -35,6 +27,11 @@ import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; +import org.apache.commons.collections4.SetUtils; +import org.stringtemplate.v4.ST; + +import java.util.LinkedHashSet; +import java.util.Set; public class MinMaxEncoder extends AbstractAggregateEncoder { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java index a7eeb9fab..94fa889c8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java @@ -20,7 +20,6 @@ import org.apache.commons.collections4.ListUtils; import org.stringtemplate.v4.ST; -import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java index 0dc4a0358..c184d2dce 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java @@ -1,21 +1,19 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; -import org.stringtemplate.v4.ST; -import org.stringtemplate.v4.STGroup; - import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; /** * Aggregate encoder handling sum aggregates. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java index b102d6fd3..71b6aef05 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java @@ -25,45 +25,24 @@ */ package at.ac.tuwien.kr.alpha.core.common; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.ArrayList; -import java.util.List; - +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; -import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.literals.Literals; -import at.ac.tuwien.kr.alpha.commons.rules.Rules; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import static org.junit.jupiter.api.Assertions.assertEquals; public class ProgramTest { @Test public void testToString() { - InputProgram program; - // rule := q(X) :- p(X). - List body = new ArrayList<>(); - body.add(Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newVariable("X")), true)); - Rule rule = Rules.newRule( - Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newVariable("X")), - Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newVariable("X")).toLiteral()); - List facts = new ArrayList<>(); - facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a"))); - facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("b"))); - // program := p(a). p(b). q(X) :- p(X). - program = InputProgramImpl.builder().addFacts(facts).addRule(rule).build(); + InputProgram parsedProgram = new ProgramParserImpl().parse( + "p(a)." + System.lineSeparator() + + "q(X) :- p(X)." + System.lineSeparator() + + "p(b)."); assertEquals( "p(a)." + System.lineSeparator() + "p(b)." + System.lineSeparator() + "q(X) :- p(X)." + System.lineSeparator(), - program.toString()); + parsedProgram.toString()); } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java index fe2cb6f8c..a298cb6eb 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithBasicProgram.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2016-2019, the Alpha Team. * All rights reserved. - * + * * Additional changes made by Siemens. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1) Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2) Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -44,6 +44,9 @@ import java.util.TreeSet; import java.util.stream.Stream; +import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; +import at.ac.tuwien.kr.alpha.core.programs.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -51,43 +54,38 @@ import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; -import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; import at.ac.tuwien.kr.alpha.commons.AnswerSets; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; -import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.IntIterator; import at.ac.tuwien.kr.alpha.core.common.NoGood; -import at.ac.tuwien.kr.alpha.core.programs.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.core.programs.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; /** * Represents a small ASP program {@code { c :- a, b. a. b. }}. * * Copyright (c) 2016, the Alpha Team. */ -public class DummyGrounder implements Grounder { +public class GrounderMockWithBasicProgram implements Grounder { public static final Set EXPECTED = new HashSet<>(singletonList(new AnswerSetBuilder() - .predicate("a") - .predicate("b") - .predicate("c") - .build() + .predicate("a") + .predicate("b") + .predicate("c") + .build() )); private static final int FACT_A = 11; // { -a } private static final int FACT_B = 12; // { -b } private static final int RULE_B = 13; // { -_br1, a, b } private static final int RULE_H = 14; // { -c, _br1 } private static final Map NOGOODS = Stream.of( - entry(FACT_A, headFirst(fromOldLiterals(-1))), - entry(FACT_B, headFirst(fromOldLiterals(-2))), - entry(RULE_B, headFirst(fromOldLiterals(-3, 1, 2))), - entry(RULE_H, headFirst(fromOldLiterals(-4, 3))) + entry(FACT_A, headFirst(fromOldLiterals(-1))), + entry(FACT_B, headFirst(fromOldLiterals(-2))), + entry(RULE_B, headFirst(fromOldLiterals(-3, 1, 2))), + entry(RULE_H, headFirst(fromOldLiterals(-4, 3))) ).collect(entriesToMap()); private final AtomStore atomStore; private final java.util.function.Predicate filter; @@ -95,15 +93,15 @@ public class DummyGrounder implements Grounder { private static Atom atomAA = Atoms.newBasicAtom(Predicates.getPredicate("a", 0)); private static Atom atomBB = Atoms.newBasicAtom(Predicates.getPredicate("b", 0)); private static BasicAtom atomCC = Atoms.newBasicAtom(Predicates.getPredicate("c", 0)); - private static Rule ruleABC = Rules.newRule(Heads.newNormalHead(atomCC), Arrays.asList(atomAA.toLiteral(), atomBB.toLiteral())); - private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(Rules.toNormalRule(ruleABC)), new BasicSubstitution()); + private static CompiledRule ruleABC = CompiledRules.newCompiledRule(Heads.newNormalHead(atomCC), atomAA.toLiteral(), atomBB.toLiteral()); + private static Atom rule1 = new RuleAtom(ruleABC, new BasicSubstitution()); private Set returnedNogoods = new HashSet<>(); - public DummyGrounder(AtomStore atomStore) { + public GrounderMockWithBasicProgram(AtomStore atomStore) { this(atomStore, p -> true); } - public DummyGrounder(AtomStore atomStore, java.util.function.Predicate filter) { + public GrounderMockWithBasicProgram(AtomStore atomStore, java.util.function.Predicate filter) { this.atomStore = atomStore; this.filter = filter; Arrays.asList(atomAA, atomBB, rule1, atomCC).forEach(atomStore::putIfAbsent); @@ -172,7 +170,7 @@ public Map getNoGoods(Assignment assignment) { public Pair, Map> getChoiceAtoms() { return new ImmutablePair<>(new HashMap<>(), new HashMap<>()); } - + @Override public Map> getHeadsToBodies() { return Collections.emptyMap(); @@ -191,4 +189,5 @@ private void addNoGoodIfNotAlreadyReturned(Map integerNoGoodMap returnedNogoods.add(idNoGood); } } -} + +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java index 530d54944..d2d22c212 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderMockWithChoice.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2016-2019, the Alpha Team. * All rights reserved. - * + * * Additional changes made by Siemens. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1) Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2) Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -32,6 +32,7 @@ import static at.ac.tuwien.kr.alpha.core.common.NoGood.headFirst; import static at.ac.tuwien.kr.alpha.core.common.NoGoodTest.fromOldLiterals; import static java.util.Arrays.asList; +import static java.util.Collections.singleton; import java.util.Arrays; import java.util.Collections; @@ -43,6 +44,9 @@ import java.util.TreeSet; import java.util.stream.Stream; +import at.ac.tuwien.kr.alpha.core.programs.atoms.ChoiceAtom; +import at.ac.tuwien.kr.alpha.core.programs.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -50,34 +54,30 @@ import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; -import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder; import at.ac.tuwien.kr.alpha.commons.AnswerSets; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.IntIterator; import at.ac.tuwien.kr.alpha.core.common.NoGood; -import at.ac.tuwien.kr.alpha.core.programs.atoms.ChoiceAtom; -import at.ac.tuwien.kr.alpha.core.programs.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.core.programs.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; /** - * Represents a small ASP program with choices {@code { aa :- not bb. bb :- not aa. }}. + * Represents a small ASP program with choices {@code { aa :- not bb. bb :- not aa. }}. */ -public class ChoiceGrounder implements Grounder { +public class GrounderMockWithChoice implements Grounder { public static final Set EXPECTED = new HashSet<>(asList( new AnswerSetBuilder() .predicate("aa") .build(), new AnswerSetBuilder() .predicate("bb") - .build())); + .build() + )); private static final int ATOM_AA = 1; private static final int ATOM_BB = 2; @@ -93,7 +93,7 @@ public class ChoiceGrounder implements Grounder { private static final int BRULE_BB = 14; // { -_br2, -aa } private static final int CHOICE_EN_BR1 = 15; // { -_en_br1 } private static final int CHOICE_EN_BR2 = 16; // { -_en_br2 } - private static final int CHOICE_DIS_BR1 = 17; // { -_dis_br1, bb} + private static final int CHOICE_DIS_BR1 = 17; // { -_dis_br1, bb} private static final int CHOICE_DIS_BR2 = 18; // { -dis_br2, aa } private static final Map NOGOODS = Stream.of( entry(RULE_AA, headFirst(fromOldLiterals(-ATOM_AA, ATOM_BR1))), @@ -103,21 +103,22 @@ public class ChoiceGrounder implements Grounder { entry(CHOICE_EN_BR1, headFirst(fromOldLiterals(-ATOM_EN_BR1))), entry(CHOICE_EN_BR2, headFirst(fromOldLiterals(-ATOM_EN_BR2))), entry(CHOICE_DIS_BR1, headFirst(fromOldLiterals(-ATOM_DIS_BR1, ATOM_BB))), - entry(CHOICE_DIS_BR2, headFirst(fromOldLiterals(-ATOM_DIS_BR2, ATOM_AA)))).collect(entriesToMap()); + entry(CHOICE_DIS_BR2, headFirst(fromOldLiterals(-ATOM_DIS_BR2, ATOM_AA))) + ).collect(entriesToMap()); private static final Map CHOICE_ENABLE = Stream.of( entry(ATOM_BR1, ATOM_EN_BR1), - entry(ATOM_BR2, ATOM_EN_BR2)).collect(entriesToMap()); + entry(ATOM_BR2, ATOM_EN_BR2) + ).collect(entriesToMap()); private static final Map CHOICE_DISABLE = Stream.of( entry(ATOM_BR1, ATOM_DIS_BR1), - entry(ATOM_BR2, ATOM_DIS_BR2)).collect(entriesToMap()); + entry(ATOM_BR2, ATOM_DIS_BR2) + ).collect(entriesToMap()); private static BasicAtom atomAA = Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)); private static BasicAtom atomBB = Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)); - private static Rule ruleAA = Rules.newRule(Heads.newNormalHead(atomAA), - Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false))); - private static Rule ruleBB = Rules.newRule(Heads.newNormalHead(atomBB), - Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)).toLiteral(false))); - private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(Rules.toNormalRule(ruleAA)), new BasicSubstitution()); - private static Atom rule2 = new RuleAtom(InternalRule.fromNormalRule(Rules.toNormalRule(ruleBB)), new BasicSubstitution()); + private static CompiledRule ruleAA = CompiledRules.newCompiledRule(Heads.newNormalHead(atomAA), Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false)); + private static CompiledRule ruleBB = CompiledRules.newCompiledRule(Heads.newNormalHead(atomBB), Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)).toLiteral(false)); + private static Atom rule1 = new RuleAtom(ruleAA, new BasicSubstitution()); + private static Atom rule2 = new RuleAtom(ruleBB, new BasicSubstitution()); private static Atom atomEnBR1 = ChoiceAtom.on(1); private static Atom atomEnBR2 = ChoiceAtom.on(2); private static Atom atomDisBR1 = ChoiceAtom.off(3); @@ -127,11 +128,11 @@ public class ChoiceGrounder implements Grounder { private final java.util.function.Predicate filter; - public ChoiceGrounder(AtomStore atomStore) { + public GrounderMockWithChoice(AtomStore atomStore) { this(atomStore, p -> true); } - public ChoiceGrounder(AtomStore atomStore, java.util.function.Predicate filter) { + public GrounderMockWithChoice(AtomStore atomStore, java.util.function.Predicate filter) { this.atomStore = atomStore; this.filter = filter; Arrays.asList(atomAA, atomBB, rule1, rule2, atomEnBR1, atomEnBR2, atomDisBR1, atomDisBR2).forEach(atomStore::putIfAbsent); @@ -155,11 +156,11 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { Map> predicateInstances = new HashMap<>(); for (Predicate trueAtomPredicate : trueAtomPredicates) { BasicAtom basicAtom = Atoms.newBasicAtom(trueAtomPredicate); - predicateInstances.put(trueAtomPredicate, new TreeSet<>(Collections.singleton(basicAtom))); + predicateInstances.put(trueAtomPredicate, new TreeSet<>(singleton(basicAtom))); } // Note: This grounder only deals with 0-ary predicates, i.e., every atom is a predicate and there is - // only one predicate instance representing 0 terms. + // only one predicate instance representing 0 terms. return AnswerSets.newAnswerSet(trueAtomPredicates, predicateInstances); } @@ -209,4 +210,5 @@ public int register(NoGood noGood) { } return solverDerivedNoGoods.get(noGood); } -} + +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java index cdee89727..74ce484f3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java @@ -25,7 +25,6 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.atom; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -36,6 +35,10 @@ import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -104,10 +107,10 @@ public void groundRuleAlreadyGround() { + "b :- not a. " + "c :- b."); NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); - CompiledProgram prog = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normal)); + CompiledProgram prog = new StratifiedEvaluation(null, false).apply(AnalyzedProgram.analyzeNormalProgram(normal)); AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, true); + Grounder grounder = new GrounderFactory(new GrounderHeuristicsConfiguration(), true).createGrounder(prog, atomStore); Map noGoods = grounder.getNoGoods(new TrailAssignment(atomStore)); int litCNeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("c")), false); int litB = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("b"))); @@ -126,10 +129,10 @@ public void groundRuleWithLongerBodyAlreadyGround() { + "c :- b. " + "d :- b, c. "); NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); - InternalProgram prog = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normal)); + InternalProgram prog = new StratifiedEvaluation(null, false).apply(AnalyzedProgram.analyzeNormalProgram(normal)); AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, true); + Grounder grounder = new GrounderFactory(new GrounderHeuristicsConfiguration(), true).createGrounder(prog, atomStore); Map noGoods = grounder.getNoGoods(new TrailAssignment(atomStore)); int litANeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("a")), false); int litBNeg = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("b")), false); @@ -151,10 +154,10 @@ public void groundConstraintAlreadyGround() { + "b :- not a. " + ":- b."); NormalProgram normal = NORMALIZE_TRANSFORM.apply(program); - InternalProgram prog = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normal)); + InternalProgram prog = new StratifiedEvaluation(null, false).apply(AnalyzedProgram.analyzeNormalProgram(normal)); AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, true); + Grounder grounder = new GrounderFactory(new GrounderHeuristicsConfiguration(), true).createGrounder(prog, atomStore); Map noGoods = grounder.getNoGoods(new TrailAssignment(atomStore)); int litB = Literals.atomToLiteral(atomStore.get(PROGRAM_PART_PARSER.parseBasicAtom("b"))); assertTrue(noGoods.containsValue(NoGood.fromConstraint(Collections.singletonList(litB), Collections.emptyList()))); @@ -189,7 +192,7 @@ public void noDeadEndWithPermissiveGrounderHeuristicForQ1() { } /** - * Tests the method {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)} on a + * Tests the method {@link NaiveGrounder#getGroundInstantiations)} on a * predefined program: * * p1(1). q1(1).
@@ -218,8 +221,7 @@ private void testDeadEnd(String predicateNameOfStartingLiteral, RuleGroundingOrd PROGRAM_PARSER.parse(aspStr))); AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", program, atomStore, p -> true, - GrounderHeuristicsConfiguration.permissive(), true); + NaiveGrounder grounder = (NaiveGrounder) new GrounderFactory(GrounderHeuristicsConfiguration.permissive(), true).createGrounder(program, atomStore, p -> true); CompiledRule nonGroundRule = grounder.getNonGroundRule(0); String strLiteral = "p1".equals(predicateNameOfStartingLiteral) ? "p1(X)" : "p1(Y)"; @@ -270,7 +272,7 @@ public void testGroundingOfRuleNotSwitchedOffByFalseNegativeBody() { } /** - * Tests if {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)} + * Tests if {@link NaiveGrounder#getGroundInstantiations(CompiledRule, RuleGroundingOrder, Substitution, Assignment)} * produces ground instantiations for the rule with ID {@code ruleID} in {@code program} when {@code startingLiteral} * unified with the numeric instance {@code startingInstance} is used as starting literal and {@code b(1)} is assigned * {@code bTruth}. @@ -281,10 +283,9 @@ private void testIfGrounderGroundsRule(InputProgram program, int ruleID, Literal CompiledProgram internalPrg = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(program)); AtomStore atomStore = new AtomStoreImpl(); TrailAssignment currentAssignment = new TrailAssignment(atomStore); - NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", internalPrg, atomStore, p -> true, - GrounderHeuristicsConfiguration.permissive(), true); + NaiveGrounder grounder = (NaiveGrounder) new GrounderFactory(GrounderHeuristicsConfiguration.permissive(), true).createGrounder(internalPrg, atomStore, p -> true); - int b = atomStore.putIfAbsent(atom("b", 1)); + int b = atomStore.putIfAbsent(Atoms.newBasicAtom(Predicates.getPredicate("b", 1), Terms.newConstant(1))); currentAssignment.growForMaxAtomId(); currentAssignment.assign(b, bTruth); @@ -369,7 +370,7 @@ private void testPermissiveGrounderHeuristicTolerance(InputProgram program, int } /** - * Tests if {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)} + * Tests if {@link NaiveGrounder#getGroundInstantiations(CompiledRule, RuleGroundingOrder, Substitution, Assignment)} * produces ground instantiations for the rule with ID {@code ruleID} in {@code program} when {@code startingLiteral} * unified with the numeric instance {@code startingInstance} is used as starting literal and the following * additional conditions are established: @@ -392,7 +393,7 @@ private void testPermissiveGrounderHeuristicTolerance(InputProgram program, int AtomStore atomStore = new AtomStoreImpl(); TrailAssignment currentAssignment = new TrailAssignment(atomStore); GrounderHeuristicsConfiguration heuristicConfiguration = GrounderHeuristicsConfiguration.getInstance(tolerance, tolerance); - NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", internalPrg, atomStore, p -> true, heuristicConfiguration, true); + NaiveGrounder grounder = (NaiveGrounder) new GrounderFactory(heuristicConfiguration, true).createGrounder(internalPrg, atomStore, p -> true); int[] bAtomIDs = new int[truthsOfB.length]; for (int i = 0; i < truthsOfB.length; i++) { @@ -457,4 +458,12 @@ private void assertExistsNoGoodContaining(Collection noGoods, int litera fail("No NoGood exists that contains literal " + literal); } + private static Atom atom(String predicateName, int... termInts) { + Term[] terms = new Term[termInts.length]; + for (int i = 0; i < termInts.length; i++) { + terms[i] = Terms.newConstant(termInts[i]); + } + return Atoms.newBasicAtom(Predicates.getPredicate(predicateName, terms.length), terms); + } + } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java index ef42a9eb7..eb0a06392 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java @@ -25,12 +25,7 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; - -import org.junit.jupiter.api.Test; - +import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; @@ -47,8 +42,12 @@ import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.programs.atoms.Literals; import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.programs.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; /** * Tests {@link NoGoodGenerator} @@ -66,7 +65,7 @@ public class NoGoodGeneratorTest { private static final VariableTerm Y = Terms.newVariable("Y"); /** - * Calls {@link NoGoodGenerator#collectNegLiterals(InternalRule, Substitution)}, which puts the atom occurring + * Calls {@link NoGoodGenerator#collectNegLiterals(CompiledRule, Substitution)}, which puts the atom occurring * negatively in a rule into the atom store. It is then checked whether the atom in the atom store is positive. */ @Test @@ -79,7 +78,7 @@ public void collectNeg_ContainsOnlyPositiveLiterals() { CompiledRule rule = program.getRules().get(1); AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", program, atomStore, true); + Grounder grounder = new GrounderFactory(new GrounderHeuristicsConfiguration(), true).createGrounder(program, atomStore); NoGoodGenerator noGoodGenerator = ((NaiveGrounder) grounder).noGoodGenerator; Substitution substitution = new BasicSubstitution(); substitution.put(X, A); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java deleted file mode 100644 index 7b96f4f92..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/AspCore2ParserTest.java +++ /dev/null @@ -1,11 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.parser; - -import at.ac.tuwien.kr.alpha.core.parser.aspcore2.InputProgramParser; - -public class AspCore2ParserTest extends ParserTest { - - protected AspCore2ParserTest() { - super(new InputProgramParser()); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java deleted file mode 100644 index 69e7eb0b7..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/EvologParserTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.parser; - -import at.ac.tuwien.kr.alpha.core.actions.DefaultActionImplementationProvider; -import at.ac.tuwien.kr.alpha.core.parser.evolog.EvologProgramParser; - -public class EvologParserTest extends ParserTest { - - protected EvologParserTest() { - super(new EvologProgramParser(new DefaultActionImplementationProvider())); - } - - - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java index d202e579c..ac961bebe 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/AtomsTest.java @@ -1,9 +1,5 @@ package at.ac.tuwien.kr.alpha.core.programs.atoms; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -22,9 +18,11 @@ import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import static org.junit.jupiter.api.Assertions.*; + /** * Test for basic functionality of various implementations of {@link Atom}. * @@ -91,12 +89,12 @@ public void testAreBasicAtomsEqual() { Atom a8 = p4.getFacts().get(1); assertEquals(a7, a8); - assertFalse(a1.equals(a3)); - assertFalse(a3.equals(a1)); - assertFalse(a1.equals(a5)); - assertFalse(a5.equals(a1)); - assertFalse(a1.equals(a7)); - assertFalse(a7.equals(a1)); + assertNotEquals(a1, a3); + assertNotEquals(a3, a1); + assertNotEquals(a1, a5); + assertNotEquals(a5, a1); + assertNotEquals(a1, a7); + assertNotEquals(a7, a1); } @Test @@ -122,9 +120,9 @@ public void testAreExternalAtomsEqual() { assertEquals(ext1, ext2); assertEquals(ext2, ext1); - assertFalse(ext1.equals(null)); - assertFalse(ext1.equals("bla")); - assertTrue(ext1.hashCode() == ext2.hashCode()); + assertNotEquals(null, ext1); + assertNotEquals("bla", ext1); + assertEquals(ext1.hashCode(), ext2.hashCode()); } @Test diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/RuleAtomTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/RuleAtomTest.java similarity index 97% rename from alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/RuleAtomTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/RuleAtomTest.java index 56e64c4ef..e89317207 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/literals/RuleAtomTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/atoms/RuleAtomTest.java @@ -1,7 +1,10 @@ -package at.ac.tuwien.kr.alpha.core.atoms; +package at.ac.tuwien.kr.alpha.core.programs.atoms; import static org.junit.jupiter.api.Assertions.assertEquals; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.core.programs.rules.InternalRule; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; @@ -18,17 +21,13 @@ import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.core.programs.rules.InternalRule; /** * Copyright (c) 2022, the Alpha Team. */ public class RuleAtomTest { - private static final ProgramParser PARSER = new ProgramParserImpl(); + private static final ProgramParser PARSER = new ProgramParserImpl(); private static final VariableTerm X = Terms.newVariable("X"); private static final VariableTerm Y = Terms.newVariable("Y"); private static final Predicate PREDICATE = Predicates.getPredicate("p", 1); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index 79ae8be23..345cc41bb 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import at.ac.tuwien.kr.alpha.core.externals.Externals; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; public class ProgramTransformationTest { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java deleted file mode 100644 index 383cf8ac0..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java +++ /dev/null @@ -1,262 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; - -public class StratifiedEvaluationRegressionTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluationRegressionTest.class); - - private static final String STRATIFIED_NEG_ASP = "base(X) :- req(X), not incomp(X).\n" - + "depend_base(X, Y) :- base(X), base(Y).\n" - + "dep_b_hlp(X) :- depend_base(X, _).\n" - + "fallback_base(X) :- base(X), not dep_b_hlp(X).\n" - + "depend_further(X) :- depend_base(_, X).\n" - + "depend_further(X) :- fallback_base(X)."; - - private static final String BASIC_TEST_ASP = "a. b:- a."; - private static final String BASIC_MULTI_INSTANCE_ASP = "p(a). p(b). q(X) :- p(X)."; - private static final String BASIC_NEGATION_ASP = "p(a). q(b). p(c). q(d). r(c). s(X, Y) :- p(X), q(Y), not r(X)."; - private static final String PART_STRATIFIED_ASP = "p(a). q(a). p(b). m(c). n(d).\n" + "r(X) :- p(X), q(X).\n" + "s(X, Y, Z) :- r(X), m(Y), n(Z).\n" - + "t(X, Y) :- p(X), q(X), p(Y), not q(Y).\n" + "either(X) :- t(X, _), not or(X).\n" + "or(X) :- t(X, _), not either(X)."; - private static final String POSITIVE_RECURSION_ASP = "num(0).\n" + "max_num(10).\n" + "num(S) :- num(N), S = N + 1, S <= M, max_num(M)."; - private static final String EMPTY_PROG_ASP = ""; - private static final String FACTS_ONLY_ASP = "a. b. c. p(a). q(b, c). r(c, c, a). s(b)."; - private static final String STRATIFIED_NO_FACTS_ASP = STRATIFIED_NEG_ASP; - private static final String STRATIFIED_W_FACTS_ASP = "req(a). req(b). incomp(b).\n" + STRATIFIED_NEG_ASP; - private static final String EQUALITY_ASP = "equal :- 1 = 1."; - private static final String EQUALITY_WITH_VAR_ASP = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; - - private static final ImmutablePair, Consumer>> BASIC_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasic, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasic); - private static final ImmutablePair, Consumer>> BASIC_MULTI_INSTANCE_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasicMultiInstance, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicMultiInstance); - private static final ImmutablePair, Consumer>> BASIC_NEGATION_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasicNegation, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicNegation); - private static final ImmutablePair, Consumer>> PART_STRATIFIED_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramPartStratified, StratifiedEvaluationRegressionTest::verifyAnswerSetsPartStratified); - private static final ImmutablePair, Consumer>> POSITIVE_RECURSIVE_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramPositiveRecursive, StratifiedEvaluationRegressionTest::verifyAnswerSetsPositiveRecursive); - private static final ImmutablePair, Consumer>> EMPTY_PROG_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEmptyProg, StratifiedEvaluationRegressionTest::verifyAnswerSetsEmptyProg); - private static final ImmutablePair, Consumer>> FACTS_ONLY_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramFactsOnly, StratifiedEvaluationRegressionTest::verifyAnswerSetsFactsOnly); - private static final ImmutablePair, Consumer>> STRATIFIED_NO_FACTS_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramStratNoFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratNoFacts); - private static final ImmutablePair, Consumer>> STRATIFIED_W_FACTS_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramStratWithFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratWithFacts); - private static final ImmutablePair, Consumer>> EQUALITY_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEquality, StratifiedEvaluationRegressionTest::verifyAnswerSetsEquality); - private static final ImmutablePair, Consumer>> EQUALITY_WITH_VAR_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEqualityWithVar, StratifiedEvaluationRegressionTest::verifyAnswerSetsEqualityWithVar); - - public static List params() { - List, Consumer>>>> testCases = new ArrayList<>(); - List paramList = new ArrayList<>(); - testCases.add(new ImmutablePair<>(BASIC_TEST_ASP, BASIC_VERIFIERS)); - testCases.add(new ImmutablePair<>(BASIC_MULTI_INSTANCE_ASP, BASIC_MULTI_INSTANCE_VERIFIERS)); - testCases.add(new ImmutablePair<>(BASIC_NEGATION_ASP, BASIC_NEGATION_VERIFIERS)); - testCases.add(new ImmutablePair<>(PART_STRATIFIED_ASP, PART_STRATIFIED_VERIFIERS)); - testCases.add(new ImmutablePair<>(POSITIVE_RECURSION_ASP, POSITIVE_RECURSIVE_VERIFIERS)); - testCases.add(new ImmutablePair<>(EMPTY_PROG_ASP, EMPTY_PROG_VERIFIERS)); - testCases.add(new ImmutablePair<>(FACTS_ONLY_ASP, FACTS_ONLY_VERIFIERS)); - testCases.add(new ImmutablePair<>(STRATIFIED_NO_FACTS_ASP, STRATIFIED_NO_FACTS_VERIFIERS)); - testCases.add(new ImmutablePair<>(STRATIFIED_W_FACTS_ASP, STRATIFIED_W_FACTS_VERIFIERS)); - testCases.add(new ImmutablePair<>(EQUALITY_ASP, EQUALITY_VERIFIERS)); - testCases.add(new ImmutablePair<>(EQUALITY_WITH_VAR_ASP, EQUALITY_WITH_VAR_VERIFIERS)); - - testCases.forEach((pair) -> paramList.add(Arguments.of(pair.left, pair.right.left, pair.right.right))); - return paramList; - } - - @ParameterizedTest - @MethodSource("at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluationRegressionTest#params") - public void runTest(String aspString, Consumer programVerifier, Consumer> resultVerifier) { - // Parse and pre-evaulate program - ProgramParser parser = new ProgramParserImpl(); - InputProgram prog = parser.parse(aspString); - AnalyzedProgram analyzed = AnalyzedProgram - .analyzeNormalProgram(new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG).apply(prog)); - CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); - // Verify stratified evaluation result - programVerifier.accept(evaluated); - // Solve remaining program - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", evaluated, atomStore, false); - Solver solver = SolverFactory.getInstance(new SystemConfig(), atomStore, grounder); - Set answerSets = solver.collectSet(); - resultVerifier.accept(answerSets); - } - - private static void verifyProgramBasic(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("a"), TestUtils.basicAtomWithSymbolicTerms("b")); - assertEquals(2, evaluated.getFacts().size()); - assertTrue(evaluated.getRules().size() == 0); - } - - private static void verifyAnswerSetsBasic(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a, b", answerSets); - } - - private static void verifyProgramBasicMultiInstance(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("q", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "b")); - assertTrue(evaluated.getRules().size() == 0); - } - - private static void verifyAnswerSetsBasicMultiInstance(Set answerSets) { - TestUtils.assertAnswerSetsEqual("p(a), p(b), q(a), q(b)", answerSets); - } - - private static void verifyProgramBasicNegation(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("s", "a", "b"), - TestUtils.basicAtomWithSymbolicTerms("s", "a", "d")); - assertEquals(7, evaluated.getFacts().size()); - assertEquals(0, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsBasicNegation(Set answerSets) { - TestUtils.assertAnswerSetsEqual("p(a), q(b), p(c), q(d), r(c), s(a,b), s(a,d)", answerSets); - } - - private static void verifyProgramPartStratified(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("p", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "a"), - TestUtils.basicAtomWithSymbolicTerms("p", "b"), - TestUtils.basicAtomWithSymbolicTerms("m", "c"), TestUtils.basicAtomWithSymbolicTerms("n", "d"), TestUtils.basicAtomWithSymbolicTerms("r", "a"), - TestUtils.basicAtomWithSymbolicTerms("s", "a", "c", "d"), - TestUtils.basicAtomWithSymbolicTerms("t", "a", "b")); - LOGGER.debug("part stratified evaluated prog is:\n{}", evaluated.toString()); - assertEquals(2, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsPartStratified(Set answerSets) { - TestUtils.assertAnswerSetsEqual(new String[] {"p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), either(a)", - "p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), or(a)" }, answerSets); - } - - private static void verifyProgramPositiveRecursive(CompiledProgram evaluated) { - Predicate num = Predicates.getPredicate("num", 1); - TestUtils.assertFactsContainedInProgram(evaluated, Atoms.newBasicAtom(Predicates.getPredicate("max_num", 1), Terms.newConstant(10)), - Atoms.newBasicAtom(num, Terms.newConstant(0)), - Atoms.newBasicAtom(num, Terms.newConstant(1)), Atoms.newBasicAtom(num, Terms.newConstant(2)), - Atoms.newBasicAtom(num, Terms.newConstant(3)), Atoms.newBasicAtom(num, Terms.newConstant(4)), - Atoms.newBasicAtom(num, Terms.newConstant(5)), Atoms.newBasicAtom(num, Terms.newConstant(6)), - Atoms.newBasicAtom(num, Terms.newConstant(7)), Atoms.newBasicAtom(num, Terms.newConstant(8)), - Atoms.newBasicAtom(num, Terms.newConstant(9)), Atoms.newBasicAtom(num, Terms.newConstant(10))); - LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); - assertEquals(0, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsPositiveRecursive(Set answerSets) { - TestUtils.assertAnswerSetsEqual("max_num(10), num(0), num(1), num(2), num(3), num(4), num(5), num(6), num(7), num(8), num(9), num(10)", answerSets); - } - - private static void verifyProgramEmptyProg(CompiledProgram evaluated) { - assertTrue(evaluated.getRules().isEmpty()); - assertTrue(evaluated.getRulesById().isEmpty()); - assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - assertTrue(evaluated.getFacts().isEmpty()); - assertTrue(evaluated.getFactsByPredicate().isEmpty()); - } - - private static void verifyAnswerSetsEmptyProg(Set answerSets) { - assertEquals(1, answerSets.size()); - assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramFactsOnly(CompiledProgram evaluated) { - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("b"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("c"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("p", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "b", "c"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("r", "c", "c", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("s", "b"))); - } - - private static void verifyAnswerSetsFactsOnly(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a, b, c, p(a), q(b,c), r(c,c,a), s(b)", answerSets); - } - - private static void verifyProgramStratNoFacts(CompiledProgram evaluated) { - assertTrue(evaluated.getFacts().isEmpty()); - } - - private static void verifyAnswerSetsStratNoFacts(Set answerSets) { - assertEquals(1, answerSets.size()); - assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramStratWithFacts(CompiledProgram evaluated) { - // rules should all be taken care of at this point - assertTrue(evaluated.getRules().isEmpty()); - assertTrue(evaluated.getRulesById().isEmpty()); - assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - - // facts should be the full answer set - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "b"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("incomp", "b"))); - - // below facts from stratified evaluation - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("base", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_base", "a", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("dep_b_hlp", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_further", "a"))); - } - - private static void verifyAnswerSetsStratWithFacts(Set answerSets) { - TestUtils.assertAnswerSetsEqual("req(a), req(b), incomp(b), base(a), depend_base(a,a), dep_b_hlp(a), depend_further(a)", answerSets); - } - - private static void verifyProgramEquality(CompiledProgram evaluated) { - assertEquals(0, evaluated.getRules().size()); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("equal"))); - } - - private static void verifyAnswerSetsEquality(Set answerSets) { - TestUtils.assertAnswerSetsEqual("equal", answerSets); - } - - private static void verifyProgramEqualityWithVar(CompiledProgram evaluated) { - assertEquals(0, evaluated.getRules().size()); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newConstant(1)))); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newConstant(2)))); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newConstant(3)))); - } - - private static void verifyAnswerSetsEqualityWithVar(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java index 96a4c6e11..f4ec2ce48 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingRuleAnalysisTest.java @@ -10,6 +10,7 @@ import java.util.Map; import java.util.Set; +import at.ac.tuwien.kr.alpha.test.RuleParser; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; @@ -24,7 +25,6 @@ import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.literals.Literals; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.test.util.RuleParser; public class AggregateRewritingRuleAnalysisTest { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/rules/RuleGroundingInfoTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/rules/RuleGroundingInfoTest.java index 32df51f6f..6edbd02ed 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/rules/RuleGroundingInfoTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/rules/RuleGroundingInfoTest.java @@ -32,15 +32,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import at.ac.tuwien.kr.alpha.api.programs.terms.ArithmeticOperator; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; -import at.ac.tuwien.kr.alpha.api.terms.ArithmeticOperator; import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; -import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfo; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfoImpl; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java index 96d0e0626..b5d69b652 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java @@ -124,7 +124,7 @@ private void createChoiceAtom() { private void createRuleAtom() { BasicAtom atomAA = Atoms.newBasicAtom(Predicates.getPredicate("aa", 0)); CompiledRule ruleAA = new InternalRule(Heads.newNormalHead(atomAA), - Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false))); + Collections.singleton(Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false))); atomStore.putIfAbsent(new RuleAtom(ruleAA, new BasicSubstitution())); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java index 9edb1fe89..faa380f8e 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java @@ -35,13 +35,14 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; +import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.common.NoGood; @@ -49,7 +50,6 @@ import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.rules.CompiledRules; import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.core.solver.NaiveNoGoodStore; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/RuleParser.java similarity index 94% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java rename to alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/RuleParser.java index ee00c7c4b..d66576a44 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/RuleParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.test.util; +package at.ac.tuwien.kr.alpha.test; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java index dcc85fdec..9905d39f5 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -65,7 +65,7 @@ protected ActionImplementationProvider newActionImplementationProvider() { return new DefaultActionImplementationProvider(); } - protected Alpha buildInstance(SystemConfig cfg) { + public Alpha buildInstance(SystemConfig cfg) { ActionImplementationProvider actionImplementationProvider = newActionImplementationProvider(); ProgramParser parser = new ProgramParserImpl(actionImplementationProvider, Collections.emptyMap()); ProgramTransformation programNormalizer = new NormalizeProgramTransformation(cfg.getAggregateRewritingConfig()); diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index 78631d11b..f24c9df63 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2017-2019, the Alpha Team. * All rights reserved. - * + *

* Additional changes made by Siemens. - * + *

* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + *

* 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * + * list of conditions and the following disclaimer. + *

* 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + *

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -79,9 +79,7 @@ public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); private final ProgramParser parser; - private final ProgramTransformation programNormalization; - private final Supplier stratifiedEvaluationFactory; private final GrounderFactory grounderFactory; private final SolverFactory solverFactory; @@ -90,11 +88,11 @@ public class AlphaImpl implements Alpha { private final boolean sortAnswerSets; AlphaImpl(ProgramParser parser, ProgramTransformation programNormalization, - Supplier stratifiedEvaluationFactory, - GrounderFactory grounderFactory, - SolverFactory solverFactory, - Reifier reifier, - boolean sortAnswerSets) { + Supplier stratifiedEvaluationFactory, + GrounderFactory grounderFactory, + SolverFactory solverFactory, + Reifier reifier, + boolean sortAnswerSets) { this.parser = parser; this.programNormalization = programNormalization; this.stratifiedEvaluationFactory = stratifiedEvaluationFactory; @@ -122,7 +120,7 @@ public InputProgram readProgram(InputConfig cfg) throws IOException { @Override public InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException { - return readProgramFiles(literate, externals, paths.stream().map(Paths::get).collect(Collectors.toList()).toArray(new Path[] {})); + return readProgramFiles(literate, externals, paths.stream().map(Paths::get).collect(Collectors.toList()).toArray(new Path[]{})); } @Override @@ -213,7 +211,7 @@ public Stream solve(NormalProgram program, java.util.function.Predica /** * Solves the given program and filters answer sets based on the passed predicate. - * + * * @param program an {@link InternalProgram} to solve * @param filter {@link Predicate} filtering {@link at.ac.tuwien.kr.alpha.api.programs.Predicate}s in the returned answer sets * @return a Stream of answer sets representing stable models of the given program @@ -226,7 +224,7 @@ private Stream solve(CompiledProgram program, java.util.function.Pred /** * Prepares a solver (and accompanying grounder) instance pre-loaded with the given program. Use this if the * solver is needed after reading answer sets (e.g. for obtaining statistics). - * + * * @param program the program to solve. * @param filter a (java util) predicate that filters (asp-)predicates which should be contained in the answer * set stream from the solver. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index b52ab8273..c954bfb46 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -3,7 +3,6 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; @@ -46,7 +45,7 @@ public class ActionsTest { @Test public void helloWorld() { MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = alphaFactory.buildInstance(new SystemConfig()); InputProgram program = alpha.readProgramString(HELLO_WORLD); alpha.solve(program); assertEquals("Hello World!", alphaFactory.getActionImplementationMock().getStdoutContent()); @@ -62,7 +61,7 @@ public void writeToFile() { MockedActionsAlphaFactory alphaFactory = new MockedActionsAlphaFactory(); alphaFactory.getActionImplementationMock().setMockedFileOutputs(mockedFileOutputs); ActionImplementationProvider actionProvider = alphaFactory.getActionImplementationMock(); - Alpha alpha = AlphaFactory.newAlpha(); + Alpha alpha = alphaFactory.buildInstance(new SystemConfig()); InputProgram program = alpha.readProgramString(WRITE_TO_FILE); Set answerSets = alpha.solve(program).collect(Collectors.toSet()); LOGGER.debug("Got answer sets: {}", answerSets); @@ -70,7 +69,7 @@ public void writeToFile() { AnswerSet answerSet = answerSets.stream().findFirst().get(); /* * Note: We have to check answer set content here because we have no way of constructing an equal instance for - * the outputStreamHandle that is constructed when execution the "fileOutputStream" action. * + * the outputStreamHandle that is constructed when executing the "fileOutputStream" action. * */ assertEquals(1, answerSet.query(Atoms.query(Predicates.getPredicate("outfile_open_result", 2)) .withFilter(0, term -> term instanceof ConstantTerm && ((ConstantTerm) term).getObject().endsWith("dummy.file")) diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java index 13df2386e..9481ebc5f 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java @@ -1,15 +1,15 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; +package at.ac.tuwien.kr.alpha; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateLiteralSplitting; +import at.ac.tuwien.kr.alpha.test.RuleParser; +import org.junit.jupiter.api.Test; import java.util.List; -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; -import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.test.util.RuleParser; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class AggregateLiteralSplittingTest { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java index 3b8870c04..72ecd207b 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java @@ -1,10 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; +package at.ac.tuwien.kr.alpha; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; @@ -17,7 +11,11 @@ import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.test.util.RuleParser; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateOperatorNormalization; +import at.ac.tuwien.kr.alpha.test.RuleParser; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; public class AggregateOperatorNormalizationTest { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java index a4805b8b3..e872f081e 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java @@ -1,14 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Map; -import java.util.Set; -import java.util.function.Predicate; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.jupiter.api.Test; +package at.ac.tuwien.kr.alpha; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; @@ -19,7 +9,17 @@ import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.jupiter.api.Test; + +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class AggregateRewritingContextTest { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java index e4ca8acf3..245304cc5 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java @@ -1,36 +1,22 @@ package at.ac.tuwien.kr.alpha; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; - import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class AggregateRewritingTest { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java index bbcb22734..3c6e195de 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java @@ -1,17 +1,5 @@ package at.ac.tuwien.kr.alpha; -import static java.util.stream.Collectors.toList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermsRewriting; -import org.junit.jupiter.api.Test; - import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.externals.Predicate; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; @@ -22,10 +10,21 @@ import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.programs.Programs; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ArithmeticTermsRewriting; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Copyright (c) 2021, the Alpha Team. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java index 9915ef7b0..530040d78 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java @@ -1,31 +1,22 @@ package at.ac.tuwien.kr.alpha; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; -import org.junit.jupiter.api.Test; - import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.externals.AspStandardLibrary; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.commons.externals.Externals; -import at.ac.tuwien.kr.alpha.commons.externals.AspStandardLibrary; +import org.junit.jupiter.api.Test; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; public class FixedInterpretationLiteralsTest { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java index 7b075979e..f099fb724 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java @@ -23,13 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.grounder; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; - -import org.junit.jupiter.api.Test; +package at.ac.tuwien.kr.alpha; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; @@ -39,10 +33,12 @@ import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.programs.rules.InternalRule; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; -/** - * Tests {@link BasicRule#toString()} and {@link InternalRule#toString()}. - */ public class RuleToStringTest { private final ProgramParser parser = new ProgramParserImpl(); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java index 19ec176cb..7c6c5fdae 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java @@ -27,49 +27,32 @@ */ package at.ac.tuwien.kr.alpha; -import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; -import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; -import org.junit.jupiter.api.Test; - import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.commons.externals.Externals; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class StratifiedEvaluationTest { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index c26b6c66d..9b25373ec 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -163,7 +163,7 @@ public void addsFacts() { List things = asList(a, b); InputProgram program = Programs.builder().addFacts(Externals.asFacts(Thingy.class, things)).build(); Set actual = system.solve(program).collect(Collectors.toSet()); - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("thingy").instance(a).instance(b).build())); + Set expected = Set.of(new AnswerSetBuilder().predicate("thingy").instance(a).instance(b).build()); assertEquals(expected, actual); } @@ -678,6 +678,7 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep // Detailed reproduction test-case for github issue #239. @Test + @Disabled("This test relies on stratified evaluation being disabled, which is not supported anymore.") public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { final ProgramParser parser = new ProgramParserImpl(); InputProgramBuilder bld = Programs.builder(); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java index c992ae820..65556fc3e 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java @@ -27,16 +27,6 @@ */ package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.*; -import static java.util.Collections.singleton; -import static org.junit.jupiter.api.Assertions.*; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; - import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; @@ -49,11 +39,15 @@ import at.ac.tuwien.kr.alpha.commons.programs.Programs; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; +import java.util.*; + +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.*; +import static java.util.Collections.singleton; +import static org.junit.jupiter.api.Assertions.*; + public class SolverTests { private static class Thingy implements Comparable { diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java index db0f40009..ada29162d 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java @@ -113,7 +113,7 @@ public void runTest(String aspString, Consumer programVerifier, LOGGER.debug("Testing ASP String {}", aspString); // Parse and pre-evaluate program // Alpha instance with default config, stratified evaluation enabled - Alpha alpha =AlphaFactory.newAlpha(); + Alpha alpha = AlphaFactory.newAlpha(); InputProgram input = alpha.readProgramString(aspString); DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(input); NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java index 0629c8be1..c4301385b 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java @@ -1,16 +1,5 @@ package at.ac.tuwien.kr.alpha.regressiontests.util; -import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; -import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqualWithBase; -import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; - -import java.time.Duration; -import java.util.Set; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Assumptions; -import org.junit.jupiter.api.function.Executable; - import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; @@ -19,6 +8,16 @@ import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.function.Executable; + +import java.time.Duration; +import java.util.Set; +import java.util.stream.Collectors; + +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqualWithBase; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; public final class RegressionTestUtils { @@ -38,7 +37,7 @@ public static Solver buildSolverForRegressionTest(String programString, SystemCo } public static Solver buildSolverForRegressionTest(InputProgram program, SystemConfig cfg) { - Alpha alpha =AlphaFactory.newAlpha(cfg); + Alpha alpha = AlphaFactory.newAlpha(cfg); return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java index 82d6863d0..fffd0cd20 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/MockedActionsAlphaFactory.java @@ -8,6 +8,7 @@ public class MockedActionsAlphaFactory extends AlphaFactory { private MockActionImplementationProvider actionImplementationMock = new MockActionImplementationProvider(""); + public MockActionImplementationProvider getActionImplementationMock() { return actionImplementationMock; } @@ -16,6 +17,7 @@ public void setActionImplementationMock(MockActionImplementationProvider actionI this.actionImplementationMock = actionImplementationMock; } + @Override protected ActionImplementationProvider newActionImplementationProvider() { return actionImplementationMock; } From fd9f6a7fbf076e1dd3a4ccd5f42f82019c9d9d83 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 24 Jul 2024 10:19:05 +0200 Subject: [PATCH 38/59] Evolog Modules: Parsing of module definitions --- .../kr/alpha/api/programs/InputProgram.java | 3 + .../kr/alpha/api/programs/modules/Module.java | 18 +++++ .../commons/programs/InputProgramImpl.java | 11 ++- .../kr/alpha/commons/programs/Programs.java | 24 +++++-- .../literals/ExternalLiteralImpl.java | 13 ++-- .../commons/programs/modules/ModuleImpl.java | 43 +++++++++++ .../commons/programs/modules/Modules.java | 19 +++++ .../ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 | 11 ++- .../ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 | 3 + .../instantiation/LiteralInstantiator.java | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 60 ++++++++++++++-- .../kr/alpha/core/parser/ParserTest.java | 72 +++++++++++++++++-- 12 files changed, 254 insertions(+), 25 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java index 7c3df5bf8..54f697292 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java @@ -1,5 +1,6 @@ package at.ac.tuwien.kr.alpha.api.programs; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; @@ -13,4 +14,6 @@ public interface InputProgram extends Program> { */ List getTestCases(); + List getModules(); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java new file mode 100644 index 000000000..d43bdce6c --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java @@ -0,0 +1,18 @@ +package at.ac.tuwien.kr.alpha.api.programs.modules; + +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; + +import java.util.Set; + +public interface Module { + + String getName(); + + Predicate getInputSpec(); + + Set getOutputSpec(); + + InputProgram getImplementation(); + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/InputProgramImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/InputProgramImpl.java index 64c3c5a3c..fdf4d0021 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/InputProgramImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/InputProgramImpl.java @@ -33,6 +33,7 @@ import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; import at.ac.tuwien.kr.alpha.commons.util.Util; import java.util.Collections; @@ -46,13 +47,15 @@ // TODO rename this to InputProgramImpl or some such class InputProgramImpl extends AbstractProgram> implements InputProgram { - static final InputProgramImpl EMPTY = new InputProgramImpl(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl(), Collections.emptyList()); + static final InputProgramImpl EMPTY = new InputProgramImpl(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl(), Collections.emptyList(), Collections.emptyList()); private final List testCases; + private final List modules; - InputProgramImpl(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { + InputProgramImpl(List> rules, List facts, InlineDirectives inlineDirectives, List testCases, List modules) { super(rules, facts, inlineDirectives); this.testCases = testCases; + this.modules = modules; } @Override @@ -60,6 +63,10 @@ public List getTestCases() { return testCases; } + public List getModules() { + return modules; + } + @Override public String toString() { String ls = System.lineSeparator(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java index 0a10b61d7..1885842e9 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java @@ -8,6 +8,7 @@ import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; @@ -24,14 +25,18 @@ public static InputProgram emptyProgram() { return InputProgramImpl.EMPTY; } + public static InputProgram newInputProgram(List> rules, List facts, InlineDirectives inlineDirectives, List testCases, List modules) { + return new InputProgramImpl(rules, facts, inlineDirectives, testCases, modules); + } + // TODO rename method public static InputProgram newInputProgram(List> rules, List facts, InlineDirectives inlineDirectives, List testCases) { - return new InputProgramImpl(rules, facts, inlineDirectives, testCases); + return new InputProgramImpl(rules, facts, inlineDirectives, testCases, Collections.emptyList()); } // TODO rename method public static InputProgram newInputProgram(List> rules, List facts, InlineDirectives inlineDirectives) { - return new InputProgramImpl(rules, facts, inlineDirectives, Collections.emptyList()); + return new InputProgramImpl(rules, facts, inlineDirectives, Collections.emptyList(), Collections.emptyList()); } public static InputProgramBuilder builder() { @@ -69,6 +74,7 @@ public static class InputProgramBuilder { private InlineDirectives inlineDirectives = new InlineDirectivesImpl(); private List testCases = new ArrayList<>(); + private List modules = new ArrayList<>(); public InputProgramBuilder(InputProgram prog) { this.addRules(prog.getRules()); @@ -116,12 +122,22 @@ public InputProgramBuilder addTestCases(List testCases) { return this; } + public InputProgramBuilder addModule(Module module) { + this.modules.add(module); + return this; + } + + public InputProgramBuilder addModules(List modules) { + this.modules.addAll(modules); + return this; + } + public InputProgramBuilder accumulate(InputProgram prog) { - return this.addRules(prog.getRules()).addFacts(prog.getFacts()).addInlineDirectives(prog.getInlineDirectives()).addTestCases(prog.getTestCases()); + return this.addRules(prog.getRules()).addFacts(prog.getFacts()).addInlineDirectives(prog.getInlineDirectives()).addTestCases(prog.getTestCases()).addModules(prog.getModules()); } public InputProgram build() { - return Programs.newInputProgram(this.rules, this.facts, this.inlineDirectives, this.testCases); + return Programs.newInputProgram(this.rules, this.facts, this.inlineDirectives, this.testCases, this.modules); } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java index c2d87b3e6..276ebd5ce 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java @@ -27,12 +27,6 @@ */ package at.ac.tuwien.kr.alpha.commons.programs.literals; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.ExternalLiteral; @@ -40,11 +34,12 @@ import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.programs.atoms.AbstractAtom; import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; +import java.util.*; + /** - * Contains a potentially negated {@link ExternalAtomImpl}. + * Contains a potentially negated {@link ExternalAtom}. */ class ExternalLiteralImpl extends AbstractLiteral implements ExternalLiteral { @@ -67,7 +62,7 @@ public ExternalLiteralImpl negate() { } /** - * @see AbstractAtom#substitute(BasicSubstitution) + * @see Literal#substitute(Substitution) */ @Override public ExternalLiteralImpl substitute(Substitution substitution) { diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java new file mode 100644 index 000000000..be4fd2d31 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java @@ -0,0 +1,43 @@ +package at.ac.tuwien.kr.alpha.commons.programs.modules; + +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; + +import java.util.Set; + +class ModuleImpl implements Module { + + private final String name; + private final Predicate inputSpec; + private final Set outputSpec; + private final InputProgram implementation; + + ModuleImpl(String name, Predicate inputSpec, Set outputSpec, InputProgram implementation) { + this.name = name; + this.inputSpec = inputSpec; + this.outputSpec = outputSpec; + this.implementation = implementation; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public Predicate getInputSpec() { + return this.inputSpec; + } + + @Override + public Set getOutputSpec() { + return this.outputSpec; + } + + @Override + public InputProgram getImplementation() { + return this.implementation; + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java new file mode 100644 index 000000000..0d8d04e0b --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java @@ -0,0 +1,19 @@ +package at.ac.tuwien.kr.alpha.commons.programs.modules; + +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; + +import java.util.Set; + +public final class Modules { + + private Modules() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static Module newModule(final String name, final Predicate inputSpec, final Set outputSpec, final InputProgram implementation) { + return new ModuleImpl(name, inputSpec, outputSpec, implementation); + } + +} diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 index bbd952cad..caa9147fd 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 @@ -56,6 +56,10 @@ classical_literal : MINUS? basic_atom; builtin_atom : term binop term; +predicate_spec: id '/' NUMBER; + +predicate_specs: predicate_spec (COMMA predicate_specs)?; + binop : EQUAL | UNEQUAL | LESS | GREATER | LESS_OR_EQ | GREATER_OR_EQ; terms : term (COMMA terms)?; @@ -83,13 +87,16 @@ interval_bound : numeral | VARIABLE; external_atom : MINUS? AMPERSAND id (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; // NOT Core2 syntax. -directive : directive_enumeration | directive_test; // NOT Core2 syntax, allows solver specific directives. Further directives shall be added here. +directive : directive_enumeration | directive_test | directive_module; // NOT Core2 syntax, allows solver specific directives. Further directives shall be added here. directive_enumeration : SHARP DIRECTIVE_ENUM id DOT; // NOT Core2 syntax, used for aggregate translation. // Alpha-specific language extension: Unit Tests (-> https://github.com/alpha-asp/Alpha/issues/237) directive_test : SHARP DIRECTIVE_TEST id PAREN_OPEN test_satisfiability_condition PAREN_CLOSE CURLY_OPEN test_input test_assert* CURLY_CLOSE; +// Alpha-specific language extension: Program Modularization (-> https://github.com/madmike200590/evolog-thesis) +directive_module: SHARP DIRECTIVE_MODULE id PAREN_OPEN module_signature PAREN_CLOSE CURLY_OPEN statements CURLY_CLOSE; + basic_terms : basic_term (COMMA basic_terms)? ; basic_term : ground_term | variable_term; @@ -112,3 +119,5 @@ test_assert_all : TEST_ASSERT_ALL CURLY_OPEN statements? CURLY_CLOSE; test_assert_some : TEST_ASSERT_SOME CURLY_OPEN statements? CURLY_CLOSE; +module_signature : predicate_spec ARROW CURLY_OPEN ('*' | predicate_specs) CURLY_CLOSE; + diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 index 1e5582d82..b0641ab1d 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 @@ -28,6 +28,7 @@ SQUARE_OPEN : '['; SQUARE_CLOSE : ']'; CURLY_OPEN : '{'; CURLY_CLOSE : '}'; +ARROW : '=>'; EQUAL : '='; UNEQUAL : '<>' | '!='; LESS : '<'; @@ -49,6 +50,8 @@ TEST_GIVEN : 'given'; TEST_ASSERT_ALL : 'assertForAll'; TEST_ASSERT_SOME : 'assertForSome'; +DIRECTIVE_MODULE : 'module'; + ID : ('a'..'z') ( 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' )*; VARIABLE : ('A'..'Z') ( 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' )*; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiator.java index 68d3839fc..ef9b4d5a4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiator.java @@ -112,7 +112,7 @@ private LiteralInstantiationResult instantiateFixedInterpretationLiteral(FixedIn } /** - * Calculates a substitution that adds an enumeration index (see {@link EnumerationLiteral#addEnumerationIndexToSubstitution(BasicSubstitution)}) + * Calculates a substitution that adds an enumeration index (see {@link EnumerationLiteral#addEnumerationIndexToSubstitution(Substitution)}) * to the given partial substitution. Due to the special nature of enumeration literals, this method will always return * {@link LiteralInstantiationResult.Type#CONTINUE} as its result type. This method assumes that the partial substitution has * not been applied to the passed literal. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 6bdb979cf..6d90d99eb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -50,6 +50,7 @@ import at.ac.tuwien.kr.alpha.commons.programs.Programs.InputProgramBuilder; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.programs.modules.Modules; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; import at.ac.tuwien.kr.alpha.commons.programs.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; @@ -58,6 +59,7 @@ import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.tree.TerminalNode; +import org.apache.commons.lang3.tuple.ImmutablePair; import java.util.*; import java.util.function.IntPredicate; @@ -306,6 +308,9 @@ public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationCon @Override public Object visitDirective_test(ASPCore2Parser.Directive_testContext ctx) { + if (!programBuilders.empty()) { + throw new IllegalStateException("Test directives are not allowed in nested programs!"); + } // directive_test : DIRECTIVE_TEST id PAREN_OPEN test_satisfiability_condition PAREN_CLOSE CURLY_OPEN test_input test_assert* CURLY_CLOSE; String name = visitId(ctx.id()); IntPredicate answerSetCountVerifier = visitTest_satisfiability_condition(ctx.test_satisfiability_condition()); @@ -324,6 +329,44 @@ public Object visitDirective_test(ASPCore2Parser.Directive_testContext ctx) { return null; } + public Object visitDirective_module(ASPCore2Parser.Directive_moduleContext ctx) { + if (!programBuilders.empty()) { + throw new IllegalStateException("Module directives are not allowed in nested programs!"); + } + // directive_module: SHARP DIRECTIVE_MODULE id PAREN_OPEN module_signature PAREN_CLOSE CURLY_OPEN statements CURLY_CLOSE; + String name = visitId(ctx.id()); + ImmutablePair> moduleSignature = visitModule_signature(ctx.module_signature()); + startNestedProgram(); + visitStatements(ctx.statements()); + InputProgram moduleImplementation = endNestedProgram(); + currentLevelProgramBuilder.addModule(Modules.newModule(name, moduleSignature.getLeft(), moduleSignature.getRight(), moduleImplementation)); + return null; + } + + public ImmutablePair> visitModule_signature(ASPCore2Parser.Module_signatureContext ctx) { + Predicate inputPredicate = visitPredicate_spec(ctx.predicate_spec()); + Set outputPredicates = ctx.predicate_specs() != null ? visitPredicate_specs(ctx.predicate_specs()) : Collections.emptySet(); + return ImmutablePair.of(inputPredicate, outputPredicates); + } + + @Override + public Set visitPredicate_specs(ASPCore2Parser.Predicate_specsContext ctx) { + // predicate_specs : predicate_spec (COMMA predicate_specs)?; + Set result = new LinkedHashSet<>(); + result.add(visitPredicate_spec(ctx.predicate_spec())); + if (ctx.predicate_specs() != null) { + result.addAll(visitPredicate_specs(ctx.predicate_specs())); + } + return result; + } + + @Override + public Predicate visitPredicate_spec(ASPCore2Parser.Predicate_specContext ctx) { + String symbol = visitId(ctx.id()); + int arity = Integer.parseInt(ctx.NUMBER().getText()); + return Predicates.getPredicate(symbol, arity); + } + @Override public Set visitBody(ASPCore2Parser.BodyContext ctx) { // body : ( naf_literal | aggregate ) (COMMA body)?; @@ -710,14 +753,23 @@ public Assertion visitTestVerifier(Assertion.Mode assertionMode, ASPCore2Parser. return Tests.newAssertion(assertionMode, Programs.emptyProgram()); } List stmts = ctx.statement(); - programBuilders.push(currentLevelProgramBuilder); - currentLevelProgramBuilder = new InputProgramBuilder(); + startNestedProgram(); for (ASPCore2Parser.StatementContext stmtCtx : stmts) { visit(stmtCtx); } - InputProgram verifier = currentLevelProgramBuilder.build(); - currentLevelProgramBuilder = programBuilders.pop(); + InputProgram verifier = endNestedProgram(); return Tests.newAssertion(assertionMode, verifier); } + private void startNestedProgram() { + programBuilders.push(currentLevelProgramBuilder); + currentLevelProgramBuilder = new InputProgramBuilder(); + } + + private InputProgram endNestedProgram() { + InputProgram result = currentLevelProgramBuilder.build(); + currentLevelProgramBuilder = programBuilders.pop(); + return result; + } + } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 3557a6fa0..8feb5bc04 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -34,12 +34,11 @@ import java.io.IOException; import java.nio.channels.ReadableByteChannel; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Stream; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; import org.antlr.v4.runtime.CharStream; @@ -87,6 +86,12 @@ public class ParserTest { private static final String UNIT_TEST_KEYWORDS_AS_IDS = "assert(a) :- given(b). # test test(expect: 1) { given { given(b). } assertForAll { :- not assert(a). :- assertForSome(b).}}"; + private static final String MODULE_SIMPLE = "#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + + private static final String MODULE_OUTPUT_ALL = "#module mod(in/1 => {*}) { a(X). b(X) :- a(X).}"; + + private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private final ProgramParserImpl parser = new ProgramParserImpl(); @Test @@ -305,4 +310,63 @@ public void unitTestKeywordsAsIds() { assertEquals(Assertion.Mode.FOR_ALL, tc.getAssertions().get(0).getMode()); } + @Test + public void simpleModule() { + InputProgram prog = parser.parse(MODULE_SIMPLE); + List modules = prog.getModules(); + assertFalse(modules.isEmpty()); + assertEquals(1, modules.size()); + Module module = modules.get(0); + assertEquals("aSimpleModule", module.getName()); + Predicate inputSpec = module.getInputSpec(); + assertEquals("input", inputSpec.getName()); + assertEquals(1, inputSpec.getArity()); + Set outputSpec = module.getOutputSpec(); + assertEquals(2, outputSpec.size()); + assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); + assertTrue(outputSpec.contains(Predicates.getPredicate("out2", 3))); + InputProgram implementation = module.getImplementation(); + assertEquals(2, implementation.getFacts().size()); + assertEquals(1, implementation.getRules().size()); + } + + @Test + public void moduleOutputAll() { + InputProgram prog = parser.parse(MODULE_OUTPUT_ALL); + List modules = prog.getModules(); + assertFalse(modules.isEmpty()); + assertEquals(1, modules.size()); + Module module = modules.get(0); + assertEquals("mod", module.getName()); + Predicate inputSpec = module.getInputSpec(); + assertEquals("in", inputSpec.getName()); + assertEquals(1, inputSpec.getArity()); + assertTrue(module.getOutputSpec().isEmpty()); + InputProgram implementation = module.getImplementation(); + assertEquals(1, implementation.getFacts().size()); + assertEquals(1, implementation.getRules().size()); + } + + @Test + public void moduleAndRegularStmts() { + InputProgram prog = parser.parse(MODULE_WITH_REGULAR_STMTS); + assertEquals(2, prog.getFacts().size()); + assertEquals(1, prog.getRules().size()); + List modules = prog.getModules(); + assertFalse(modules.isEmpty()); + assertEquals(1, modules.size()); + Module module = modules.get(0); + assertEquals("aSimpleModule", module.getName()); + Predicate inputSpec = module.getInputSpec(); + assertEquals("input", inputSpec.getName()); + assertEquals(1, inputSpec.getArity()); + Set outputSpec = module.getOutputSpec(); + assertEquals(2, outputSpec.size()); + assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); + assertTrue(outputSpec.contains(Predicates.getPredicate("out2", 3))); + InputProgram implementation = module.getImplementation(); + assertEquals(2, implementation.getFacts().size()); + assertEquals(1, implementation.getRules().size()); + } + } From 2b4f19dddfafc21a48c899c748b660ae6b376d7b Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 24 Jul 2024 11:28:16 +0200 Subject: [PATCH 39/59] Improvement: End2End-Tests using ASP unit tests --- .../kr/alpha/core/parser/ParserTest.java | 25 +++++++ .../kr/alpha/e2etests/End2EndTests.java | 74 +++++++++++++++++++ .../src/test/resources/e2e-tests/3col.asp | 66 +++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java create mode 100644 alpha-solver/src/test/resources/e2e-tests/3col.asp diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 8feb5bc04..5bd5de0fa 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -92,6 +92,8 @@ public class ParserTest { private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private final ProgramParserImpl parser = new ProgramParserImpl(); @Test @@ -369,4 +371,27 @@ public void moduleAndRegularStmts() { assertEquals(1, implementation.getRules().size()); } + @Test + public void multipleModuleDefinitions() { + InputProgram prog = parser.parse(MODULE_MULTIPLE_DEFINITIONS); + assertEquals(2, prog.getFacts().size()); + assertEquals(1, prog.getRules().size()); + + List modules = prog.getModules(); + assertFalse(modules.isEmpty()); + assertEquals(2, modules.size()); + } + + @Test + public void invalidNestedModule() { + assertThrows(IllegalStateException.class, () -> + parser.parse("#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). } }")); + } + + @Test + public void invalidNestedTest() { + assertThrows(IllegalStateException.class, () -> + parser.parse("#module mod(foo/1 => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }")); + } + } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java new file mode 100644 index 000000000..23ee7f3ee --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java @@ -0,0 +1,74 @@ +package at.ac.tuwien.kr.alpha.e2etests; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; +import at.ac.tuwien.kr.alpha.api.programs.tests.TestResult; +import at.ac.tuwien.kr.alpha.commons.programs.Programs; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Runs tests written in ASP from a given set of files. + * Dynamic tests generated by this class use Alpha's default configuration. + * A test fails when any ASP test in the corresponding fileset fails. + */ +public class End2EndTests { + + private static final String E2E_TESTS_DIR = "/e2e-tests/"; + + private static void runAspTests(String testName, String... fileset) { + Alpha alpha = AlphaFactory.newAlpha(); + Programs.InputProgramBuilder programBuilder = Programs.builder(); + for (String file : fileset) { + try(InputStream is = End2EndTests.class.getResourceAsStream(file)) { + programBuilder.accumulate(alpha.readProgramStream(is)); + } catch (IOException ex) { + throw new RuntimeException("Failed to read test file: " + file, ex); + } + } + InputProgram program = programBuilder.build(); + TestResult testResult = alpha.test(program); + if (!testResult.isSuccess()) { + StringBuilder msgBuilder = new StringBuilder("Test ").append(testName).append(" failed:").append(System.lineSeparator()); + testResult.getTestCaseResults().stream().filter(Predicate.not(TestResult.TestCaseResult::isSuccess)).forEach(tcResult -> { + msgBuilder.append("Assertion failures for test case ").append(tcResult.getTestCaseName()).append(": ").append(System.lineSeparator()); + if (tcResult.answerSetCountVerificationResult().isPresent()) { + msgBuilder.append(tcResult.answerSetCountVerificationResult().get()).append(System.lineSeparator()); + } + for (Map.Entry> assertionError : tcResult.getAssertionErrors().entrySet()) { + for (String errMsg : assertionError.getValue()) { + msgBuilder.append("Assertion failed: ").append(assertionError.getKey()).append(", error = ").append(errMsg).append(System.lineSeparator()); + } + } + }); + fail(msgBuilder.toString()); + } + } + + private static DynamicTest alphaEnd2EndTest(String testName, String... fileset) { + return DynamicTest.dynamicTest(testName, () -> runAspTests(testName, fileset)); + } + + @TestFactory + Stream alphaEnd2EndTests() { + return Stream.of( + alphaEnd2EndTest("3-Coloring", E2E_TESTS_DIR + "3col.asp") + ); + } + + + +} diff --git a/alpha-solver/src/test/resources/e2e-tests/3col.asp b/alpha-solver/src/test/resources/e2e-tests/3col.asp new file mode 100644 index 000000000..8b7620cde --- /dev/null +++ b/alpha-solver/src/test/resources/e2e-tests/3col.asp @@ -0,0 +1,66 @@ +%%% Basic Encoding of the Graph 3-Coloring Problem %%% +% Graphs are interpreted as having undirected edges. + +% Edges are undirected +edge(Y, X) :- edge(X, Y). + +% Guess color for each vertex +red(V) :- vertex(V), not green(V), not blue(V). +green(V) :- vertex(V), not red(V), not blue(V). +blue(V) :- vertex(V), not red(V), not green(V). + +% Check for invalid colorings +:- vertex(V1), vertex(V2), edge(V1, V2), red(V1), red(V2). +:- vertex(V1), vertex(V2), edge(V1, V2), green(V1), green(V2). +:- vertex(V1), vertex(V2), edge(V1, V2), blue(V1), blue(V2). + +%% Verify that directed edges are converted to undirected ones. +#test no_asymmetric_edge(expect: >0) { + given { + vertex(a). + vertex(b). + vertex(c). + edge(a, b). + edge(b, c). + edge(c, a). + } + assertForAll { + :- edge(A, B), not edge(B, A). + } +} + +#test triangle_colorings(expect: 6) { + given { + vertex(a). + vertex(b). + vertex(c). + edge(a, b). + edge(b, c). + edge(c, a). + } + % Make sure all vertices are colored in all answer sets + assertForAll { + colored(V) :- vertex(V), red(V). + colored(V) :- vertex(V), green(V). + colored(V) :- vertex(V), blue(V). + :- vertex(V), not colored(V). + } + % Make sure we do not have neighboring vertices of same color in any answer set + assertForAll { + :- edge(V1, V2), red(V1), red(V2). + :- edge(V1, V2), green(V1), green(V2). + :- edge(V1, V2), blue(V1), blue(V2). + } + % In at least one answer set, vertex a should be red + assertForSome { + :- not red(a). + } + % In at least one answer set, vertex a should be green + assertForSome { + :- not green(a). + } + % In at least one answer set, vertex a should be blue + assertForSome { + :- not blue(a). + } +} \ No newline at end of file From 49233d97d7a16dee0637c95fd7463c61819fac76 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 24 Jul 2024 16:13:51 +0200 Subject: [PATCH 40/59] Evolog Modules: Parsing of module literals --- .../kr/alpha/api/programs/atoms/Atom.java | 2 +- .../alpha/api/programs/atoms/ModuleAtom.java | 39 +++++ .../alpha/api/programs/literals/Literal.java | 10 +- .../api/programs/literals/ModuleLiteral.java | 17 ++ .../commons/programs/atoms/AbstractAtom.java | 2 +- .../alpha/commons/programs/atoms/Atoms.java | 10 +- .../programs/atoms/ModuleAtomImpl.java | 132 +++++++++++++++ .../commons/programs/literals/Literals.java | 16 +- .../programs/literals/ModuleLiteralImpl.java | 84 +++++++++ .../ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 | 4 +- .../alpha/core/parser/ParseTreeVisitor.java | 21 ++- .../kr/alpha/core/parser/ParserTest.java | 159 +++++++++++++++--- .../kr/alpha/e2etests/End2EndTests.java | 4 +- 13 files changed, 446 insertions(+), 54 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ModuleLiteral.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ModuleLiteralImpl.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/Atom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/Atom.java index 8d014fd04..d8c8095df 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/Atom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/Atom.java @@ -42,7 +42,7 @@ default Literal toLiteral() { Set getOccurringVariables(); - Atom substitute(Substitution substitution); // Introduce parameterized interface Substituable to get atom types right? + Atom substitute(Substitution substitution); // Introduce parameterized interface Substitutable to get atom types right? Atom renameVariables(String newVariablePrefix); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java new file mode 100644 index 000000000..17cabfc4a --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java @@ -0,0 +1,39 @@ +package at.ac.tuwien.kr.alpha.api.programs.atoms; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; + +import java.util.List; +import java.util.Optional; + +/** + * An atom that is implemented using an additional ASP program (i.e. a module). + * Note that a module atom itself can not be instantiated, but needs to be compiled + * into some kind of instantiable atom by linking it to an ASP program that implements + * the referenced module. + */ +public interface ModuleAtom extends Atom { + + String getModuleName(); + + List getInput(); + + List getOutput(); + + ModuleInstantiationMode getInstantiationMode(); + + @Override + ModuleAtom substitute(Substitution substitution); + + interface ModuleInstantiationMode { + Optional requestedAnswerSets(); + + ModuleInstantiationMode ALL = Optional::empty; + + static ModuleInstantiationMode forNumAnswerSets(int answerSets) { + return () -> Optional.of(answerSets); + } + + } + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/Literal.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/Literal.java index 4824480e9..074c36205 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/Literal.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/Literal.java @@ -1,18 +1,18 @@ package at.ac.tuwien.kr.alpha.api.programs.literals; -import java.util.List; -import java.util.Set; - import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; +import java.util.List; +import java.util.Set; + /** - * A literal according to the ASP Core 2 Standard. + *

A literal according to the ASP Core 2 Standard. * Wraps an {@link Atom} that may or may not be negated. - * + *

* Copyright (c) 2017-2021, the Alpha Team. */ // TODO go through implementations and pull out stuff that can be default-implemented here diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ModuleLiteral.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ModuleLiteral.java new file mode 100644 index 000000000..98bc092f0 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/literals/ModuleLiteral.java @@ -0,0 +1,17 @@ +package at.ac.tuwien.kr.alpha.api.programs.literals; + +import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; + +public interface ModuleLiteral extends Literal{ + + @Override + ModuleAtom getAtom(); + + @Override + ModuleLiteral negate(); + + @Override + ModuleLiteral substitute(Substitution substitution); + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java index 4a54b90f4..f014fe1e2 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java @@ -79,7 +79,7 @@ public Set getOccurringVariables() { /** * Returns whether this atom is ground, i.e., variable-free. * - * @return true iff the terms of this atom contain no {@link VariableTermImpl}. + * @return true iff the terms of this atom contain no {@link VariableTerm}. */ @Override public abstract boolean isGround(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java index 8658c58d1..d11e77e49 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java @@ -7,13 +7,9 @@ import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.*; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; -import at.ac.tuwien.kr.alpha.api.programs.atoms.AtomQuery; -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.programs.atoms.AggregateAtomImpl.AggregateElementImpl; @@ -63,6 +59,10 @@ public static ExternalAtom newExternalAtom(Predicate predicate, PredicateInterpr return new ExternalAtomImpl(predicate, interpretation, input, output); } + public static ModuleAtom newModuleAtom(String moduleName, ModuleAtom.ModuleInstantiationMode instantiationMode, List input, List output) { + return new ModuleAtomImpl(moduleName, input, output, instantiationMode); + } + public static AtomQuery query(Predicate predicate) { return AtomQueryImpl.forPredicate(predicate); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java new file mode 100644 index 000000000..a971214c4 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java @@ -0,0 +1,132 @@ +package at.ac.tuwien.kr.alpha.commons.programs.atoms; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; +import at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.programs.literals.Literals; +import at.ac.tuwien.kr.alpha.commons.util.Util; +import org.apache.commons.collections4.ListUtils; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +class ModuleAtomImpl extends AbstractAtom implements ModuleAtom { + + private final String moduleName; + private final List input; + private final List output; + private final ModuleInstantiationMode instantiationMode; + + ModuleAtomImpl(String moduleName, List input, List output, ModuleInstantiationMode instantiationMode) { + this.moduleName = Objects.requireNonNull(moduleName); + this.input = Objects.requireNonNull(input); + this.output = Objects.requireNonNull(output); + this.instantiationMode = Objects.requireNonNull(instantiationMode); + } + + @Override + public String getModuleName() { + return moduleName; + } + + @Override + public List getInput() { + return input; + } + + @Override + public List getOutput() { + return output; + } + + @Override + public ModuleInstantiationMode getInstantiationMode() { + return instantiationMode; + } + + @Override + public Atom withTerms(List terms) { + if (terms.size() != this.input.size() + this.output.size()) { + throw new IllegalArgumentException( + "Cannot apply term list " + terms + " to module atom " + this + ", terms has invalid size!"); + } + List newInput = terms.subList(0, this.input.size()); + List newOutput = terms.subList(this.input.size(), terms.size()); + return new ModuleAtomImpl(this.moduleName, newInput, newOutput, this.instantiationMode); + } + + @Override + public ModuleAtom substitute(Substitution substitution) { + List substitutedInput = this.input.stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); + List substitutedOutput = this.output.stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); + return new ModuleAtomImpl(this.moduleName, substitutedInput, substitutedOutput, this.instantiationMode); + } + + @Override + public List getTerms() { + return ListUtils.union(input, output); + } + + @Override + public Predicate getPredicate() { + return Predicates.getPredicate(moduleName, output.size()); + } + + @Override + public boolean isGround() { + for (Term t : input) { + if (!t.isGround()) { + return false; + } + } + for (Term t : output) { + if (!t.isGround()) { + return false; + } + } + return true; + } + + @Override + public ModuleLiteral toLiteral(boolean positive) { + return Literals.fromAtom(this, positive); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ModuleAtomImpl that = (ModuleAtomImpl) o; + return Objects.equals(moduleName, that.moduleName) + && Objects.equals(input, that.input) + && Objects.equals(output, that.output) + && Objects.equals(instantiationMode, that.instantiationMode); + } + + @Override + public int hashCode() { + return Objects.hash(moduleName, input, output, instantiationMode); + } + + @Override + public String toString() { + String result = "#" + moduleName; + if (!input.isEmpty()) { + result += Util.join("[", input, "]"); + } + if (!output.isEmpty()) { + result += Util.join("(", output, ")"); + } + return result; + } + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/Literals.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/Literals.java index 82b91f24b..afdbe1934 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/Literals.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/Literals.java @@ -1,13 +1,7 @@ package at.ac.tuwien.kr.alpha.commons.programs.literals; -import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; -import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; -import at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral; -import at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.api.programs.literals.ExternalLiteral; +import at.ac.tuwien.kr.alpha.api.programs.atoms.*; +import at.ac.tuwien.kr.alpha.api.programs.literals.*; public final class Literals { @@ -30,7 +24,11 @@ public static ComparisonLiteral fromAtom(ComparisonAtom atom, boolean positive) public static ExternalLiteral fromAtom(ExternalAtom atom, boolean positive) { return new ExternalLiteralImpl(atom, positive); } - + + public static ModuleLiteral fromAtom(ModuleAtom atom, boolean positive) { + return new ModuleLiteralImpl(atom, positive); + } + public static ComparisonLiteral newComparisonLiteral(ComparisonAtom atom, boolean positive) { return new ComparisonLiteralImpl(atom, positive); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ModuleLiteralImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ModuleLiteralImpl.java new file mode 100644 index 000000000..2b30d8640 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ModuleLiteralImpl.java @@ -0,0 +1,84 @@ +package at.ac.tuwien.kr.alpha.commons.programs.literals; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; +import at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class ModuleLiteralImpl extends AbstractLiteral implements ModuleLiteral { + + ModuleLiteralImpl(ModuleAtom atom, boolean positive) { + super(atom, positive); + } + + @Override + public ModuleAtom getAtom() { + return (ModuleAtom) atom; + } + + @Override + public ModuleLiteral negate() { + return new ModuleLiteralImpl(getAtom(), isNegated()); + } + + @Override + public ModuleLiteral substitute(Substitution substitution) { + return new ModuleLiteralImpl(getAtom().substitute(substitution), positive); + } + + // TODO introduce common abstract supertype for external an module literals to avoid code duplication (same goes for atoms!) + @Override + public Set getBindingVariables() { + // If the external atom is negative, then all variables of input and output are non-binding + // and there are no binding variables (like for ordinary atoms). + // If the external atom is positive, then variables of output are binding. + + if (this.isNegated()) { + return Collections.emptySet(); + } + + List output = getAtom().getOutput(); + + Set binding = new HashSet<>(output.size()); + + for (Term out : output) { + if (out instanceof VariableTerm) { + binding.add((VariableTerm) out); + } + } + + return binding; + } + + @Override + public Set getNonBindingVariables() { + List input = getAtom().getInput(); + List output = getAtom().getOutput(); + + // External atoms have their input always non-binding, since they cannot + // be queried without some concrete input. + Set nonbindingVariables = new HashSet<>(); + for (Term term : input) { + nonbindingVariables.addAll(term.getOccurringVariables()); + } + + // If the external atom is negative, then all variables of input and output are + // non-binding. + if (this.isNegated()) { + for (Term out : output) { + if (out instanceof VariableTerm) { + nonbindingVariables.add((VariableTerm) out); + } + } + } + + return nonbindingVariables; + } + +} diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 index caa9147fd..876c4e190 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 @@ -46,7 +46,7 @@ weight_at_level : term (AT term)? (COMMA terms)?; naf_literals : naf_literal (COMMA naf_literals)?; -naf_literal : NAF? (external_atom | classical_literal | builtin_atom); +naf_literal : NAF? (external_atom | module_atom | classical_literal | builtin_atom); id : ID | TEST_EXPECT | TEST_UNSAT | TEST_GIVEN | TEST_ASSERT_ALL | TEST_ASSERT_SOME | DIRECTIVE_ENUM | DIRECTIVE_TEST; @@ -87,6 +87,8 @@ interval_bound : numeral | VARIABLE; external_atom : MINUS? AMPERSAND id (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; // NOT Core2 syntax. +module_atom : SHARP id (CURLY_OPEN NUMBER CURLY_CLOSE)? (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; // NOT Core2 syntax. + directive : directive_enumeration | directive_test | directive_module; // NOT Core2 syntax, allows solver specific directives. Further directives shall be added here. directive_enumeration : SHARP DIRECTIVE_ENUM id DOT; // NOT Core2 syntax, used for aggregate translation. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 6d90d99eb..16226a168 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -529,6 +529,8 @@ public Literal visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { return Literals.fromAtom(visitClassical_literal(ctx.classical_literal()), !isCurrentLiteralNegated); } else if (ctx.external_atom() != null) { return Literals.fromAtom(visitExternal_atom(ctx.external_atom()), !isCurrentLiteralNegated); + } else if (ctx.module_atom() != null) { + return Literals.fromAtom(visitModule_atom(ctx.module_atom()), !isCurrentLiteralNegated); } throw notSupported(ctx); } @@ -579,7 +581,7 @@ public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext public Integer visitNumeral(ASPCore2Parser.NumeralContext ctx) { // numeral : MINUS? NUMBER; - int absValue = Integer.valueOf(ctx.NUMBER().getText()); + int absValue = Integer.parseInt(ctx.NUMBER().getText()); return ctx.MINUS() != null ? -1 * absValue : absValue; } @@ -644,6 +646,21 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) outputTerms); } + @Override + public ModuleAtom visitModule_atom(ASPCore2Parser.Module_atomContext ctx) { + // module_atom : SHARP id (CURLY_OPEN NUMBER CURLY_CLOSE)? (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; + String moduleName = visitId(ctx.id()); + ModuleAtom.ModuleInstantiationMode instantiationMode; + if (ctx.NUMBER() != null) { + instantiationMode = ModuleAtom.ModuleInstantiationMode.forNumAnswerSets(Integer.parseInt(ctx.NUMBER().getText())); + } else { + instantiationMode = ModuleAtom.ModuleInstantiationMode.ALL; + } + List inputTerms = visitTerms(ctx.input); + List outputTerms = visitTerms(ctx.output); + return Atoms.newModuleAtom(moduleName, instantiationMode, inputTerms, outputTerms); + } + @Override public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) { // interval : lower = interval_bound DOT DOT upper = interval_bound; @@ -704,7 +721,7 @@ public IntPredicate visitTest_satisfiability_condition(ASPCore2Parser.Test_satis return Tests.newIsUnsatCondition(); } else { // binop? NUMBER - int num = Integer.valueOf(ctx.NUMBER().getText()); + int num = Integer.parseInt(ctx.NUMBER().getText()); if (ctx.binop() == null) { return Tests.newAnswerSetCountCondition(ComparisonOperators.EQ, num); } else { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 5bd5de0fa..684f448af 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -27,40 +27,40 @@ */ package at.ac.tuwien.kr.alpha.core.parser; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.nio.channels.ReadableByteChannel; -import java.util.*; -import java.util.stream.Stream; - -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.modules.Module; -import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; -import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.jupiter.api.Test; - -import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; +import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.ChoiceHead; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head; import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.api.programs.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; +import at.ac.tuwien.kr.alpha.api.programs.tests.TestCase; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.channels.ReadableByteChannel; +import java.util.*; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; /** * Copyright (c) 2016, the Alpha Team. @@ -94,6 +94,18 @@ public class ParserTest { private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private static final String MODULE_LITERAL = "p(a). q(b). r(X) :- p(X), q(Y), #mod[X, Y](X)."; + + private static final String MODULE_LITERAL_WITH_NUM_ANSWER_SETS = ":- r(1), q(B, 1). r(X) :- p(X), q(Y), #mod{4}[X, Y](X)."; + + private static final String MODULE_LITERAL_NO_INPUT = "a(X) :- #something(X)."; + + private static final String MODULE_LITERAL_NO_INPUT_WITH_NUM_ANSWER_SETS = "a(X) :- #something{4}(X)."; + + private static final String MODULE_LITERAL_NO_OUTPUT = "a(X) :- #something[X]."; + + private static final String MODULE_LITERAL_NO_OUTPUT_WITH_NUM_ANSWER_SETS = "a(X) :- #something{4}[X]."; + private final ProgramParserImpl parser = new ProgramParserImpl(); @Test @@ -154,9 +166,9 @@ public void parseProgramWithDisjunctionInHead() { public void parseInterval() { InputProgram parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); IntervalTerm factInterval = (IntervalTerm) parsedProgram.getFacts().get(0).getTerms().get(0); - assertTrue(factInterval.equals(Terms.newIntervalTerm(Terms.newConstant(2), Terms.newConstant(5)))); + assertEquals(factInterval, Terms.newIntervalTerm(Terms.newConstant(2), Terms.newConstant(5))); IntervalTerm bodyInterval = (IntervalTerm) parsedProgram.getRules().get(0).getBody().stream().findFirst().get().getTerms().get(1); - assertTrue(bodyInterval.equals(Terms.newIntervalTerm(Terms.newConstant(3), Terms.newVariable("X")))); + assertEquals(bodyInterval, Terms.newIntervalTerm(Terms.newConstant(3), Terms.newVariable("X"))); } @Test @@ -164,10 +176,10 @@ public void parseChoiceRule() { InputProgram parsedProgram = parser.parse("dom(1). dom(2). { a ; b } :- dom(X)."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); - assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); - assertTrue(choiceHead.getChoiceElements().get(1).getChoiceAtom().toString().equals("b")); - assertEquals(null, choiceHead.getLowerBound()); - assertEquals(null, choiceHead.getUpperBound()); + assertEquals("a", choiceHead.getChoiceElements().get(0).getChoiceAtom().toString()); + assertEquals("b", choiceHead.getChoiceElements().get(1).getChoiceAtom().toString()); + assertNull(choiceHead.getLowerBound()); + assertNull(choiceHead.getUpperBound()); } @Test @@ -175,8 +187,8 @@ public void parseChoiceRuleBounded() { InputProgram parsedProgram = parser.parse("dom(1). dom(2). 1 < { a: p(v,w), not r; b } <= 13 :- dom(X). foo."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); - assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); - assertTrue(choiceHead.getChoiceElements().get(1).getChoiceAtom().toString().equals("b")); + assertEquals("a", choiceHead.getChoiceElements().get(0).getChoiceAtom().toString()); + assertEquals("b", choiceHead.getChoiceElements().get(1).getChoiceAtom().toString()); List conditionalLiterals = choiceHead.getChoiceElements().get(0).getConditionLiterals(); assertEquals(2, conditionalLiterals.size()); assertFalse(conditionalLiterals.get(0).isNegated()); @@ -394,4 +406,97 @@ public void invalidNestedTest() { parser.parse("#module mod(foo/1 => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }")); } + @Test + public void moduleLiteral() { + InputProgram prog = parser.parse(MODULE_LITERAL); + assertEquals(2, prog.getFacts().size()); + assertEquals(1, prog.getRules().size()); + Rule rule = prog.getRules().get(0); + assertEquals(3, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).count()); + ModuleLiteral moduleLiteral = (ModuleLiteral) rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).findFirst().get(); + assertEquals("mod", moduleLiteral.getAtom().getModuleName()); + assertEquals(2, moduleLiteral.getAtom().getInput().size()); + assertEquals(1, moduleLiteral.getAtom().getOutput().size()); + assertEquals(ModuleAtom.ModuleInstantiationMode.ALL, moduleLiteral.getAtom().getInstantiationMode()); + } + + @Test + public void moduleLiteralWithNumAnswerSets() { + InputProgram prog = parser.parse(MODULE_LITERAL_WITH_NUM_ANSWER_SETS); + assertEquals(2, prog.getRules().size()); + Optional> ruleWithModuleLiteral = prog.getRules().stream().filter(rule -> rule.getBody().stream().anyMatch(lit -> lit instanceof ModuleLiteral)).findFirst(); + assertTrue(ruleWithModuleLiteral.isPresent()); + Rule rule = ruleWithModuleLiteral.get(); + assertEquals(3, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).count()); + Optional optModuleLiteral = rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).findFirst(); + assertTrue(optModuleLiteral.isPresent()); + ModuleLiteral moduleLiteral = (ModuleLiteral) optModuleLiteral.get(); + assertEquals("mod", moduleLiteral.getAtom().getModuleName()); + assertEquals(2, moduleLiteral.getAtom().getInput().size()); + assertEquals(1, moduleLiteral.getAtom().getOutput().size()); + assertTrue(moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().isPresent()); + assertEquals(4, moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().get()); + } + + @Test + public void moduleLiteralNoInput() { + InputProgram prog = parser.parse(MODULE_LITERAL_NO_INPUT); + assertEquals(1, prog.getRules().size()); + Rule rule = prog.getRules().get(0); + assertEquals(1, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).count()); + ModuleLiteral moduleLiteral = (ModuleLiteral) rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).findFirst().get(); + assertEquals("something", moduleLiteral.getAtom().getModuleName()); + assertTrue(moduleLiteral.getAtom().getInput().isEmpty()); + assertEquals(1, moduleLiteral.getAtom().getOutput().size()); + assertEquals(ModuleAtom.ModuleInstantiationMode.ALL, moduleLiteral.getAtom().getInstantiationMode()); + } + + @Test + public void moduleLiteralNoInputWithNumAnswerSets() { + InputProgram prog = parser.parse(MODULE_LITERAL_NO_INPUT_WITH_NUM_ANSWER_SETS); + assertEquals(1, prog.getRules().size()); + Rule rule = prog.getRules().get(0); + assertEquals(1, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).count()); + ModuleLiteral moduleLiteral = (ModuleLiteral) rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).findFirst().get(); + assertEquals("something", moduleLiteral.getAtom().getModuleName()); + assertTrue(moduleLiteral.getAtom().getInput().isEmpty()); + assertEquals(1, moduleLiteral.getAtom().getOutput().size()); + assertTrue(moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().isPresent()); + assertEquals(4, moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().get()); + } + + @Test + public void moduleLiteralNoOutput() { + InputProgram prog = parser.parse(MODULE_LITERAL_NO_OUTPUT); + assertEquals(1, prog.getRules().size()); + Rule rule = prog.getRules().get(0); + assertEquals(1, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).count()); + ModuleLiteral moduleLiteral = (ModuleLiteral) rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).findFirst().get(); + assertEquals("something", moduleLiteral.getAtom().getModuleName()); + assertEquals(1, moduleLiteral.getAtom().getInput().size()); + assertTrue(moduleLiteral.getAtom().getOutput().isEmpty()); + assertFalse(moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().isPresent()); + assertEquals(ModuleAtom.ModuleInstantiationMode.ALL, moduleLiteral.getAtom().getInstantiationMode()); + } + + @Test + public void moduleLiteralNoOutputWithNumAnswerSets() { + InputProgram prog = parser.parse(MODULE_LITERAL_NO_OUTPUT_WITH_NUM_ANSWER_SETS); + assertEquals(1, prog.getRules().size()); + Rule rule = prog.getRules().get(0); + assertEquals(1, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).count()); + ModuleLiteral moduleLiteral = (ModuleLiteral) rule.getBody().stream().filter(lit -> lit instanceof ModuleLiteral).findFirst().get(); + assertEquals("something", moduleLiteral.getAtom().getModuleName()); + assertEquals(1, moduleLiteral.getAtom().getInput().size()); + assertTrue(moduleLiteral.getAtom().getOutput().isEmpty()); + assertTrue(moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().isPresent()); + assertEquals(4, moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().get()); + } + } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java index 23ee7f3ee..bc21144ef 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java @@ -6,7 +6,6 @@ import at.ac.tuwien.kr.alpha.api.programs.tests.Assertion; import at.ac.tuwien.kr.alpha.api.programs.tests.TestResult; import at.ac.tuwien.kr.alpha.commons.programs.Programs; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; @@ -17,7 +16,6 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; /** @@ -33,7 +31,7 @@ private static void runAspTests(String testName, String... fileset) { Alpha alpha = AlphaFactory.newAlpha(); Programs.InputProgramBuilder programBuilder = Programs.builder(); for (String file : fileset) { - try(InputStream is = End2EndTests.class.getResourceAsStream(file)) { + try (InputStream is = End2EndTests.class.getResourceAsStream(file)) { programBuilder.accumulate(alpha.readProgramStream(is)); } catch (IOException ex) { throw new RuntimeException("Failed to read test file: " + file, ex); From 90d3faf66862d189faaca4ac3899139e82fc2de5 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 24 Jul 2024 17:13:18 +0200 Subject: [PATCH 41/59] Evolog Modules: Unit test for ModuleAtomImpl --- .../alpha/api/programs/atoms/ModuleAtom.java | 23 +++++- .../programs/atoms/ModuleAtomImpl.java | 3 +- .../programs/atoms/ModuleAtomImplTest.java | 74 +++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImplTest.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java index 17cabfc4a..42fedae92 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ModuleAtom.java @@ -25,13 +25,34 @@ public interface ModuleAtom extends Atom { @Override ModuleAtom substitute(Substitution substitution); + @Override + ModuleAtom withTerms(List terms); + interface ModuleInstantiationMode { Optional requestedAnswerSets(); ModuleInstantiationMode ALL = Optional::empty; static ModuleInstantiationMode forNumAnswerSets(int answerSets) { - return () -> Optional.of(answerSets); + return new ModuleInstantiationMode() { + @Override + public Optional requestedAnswerSets() { + return Optional.of(answerSets); + } + + @Override + public int hashCode() { + return answerSets; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ModuleInstantiationMode)) { + return false; + } + return ((ModuleInstantiationMode) obj).requestedAnswerSets().equals(this.requestedAnswerSets()); + } + }; } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java index a971214c4..72178d72b 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImpl.java @@ -2,7 +2,6 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; @@ -50,7 +49,7 @@ public ModuleInstantiationMode getInstantiationMode() { } @Override - public Atom withTerms(List terms) { + public ModuleAtom withTerms(List terms) { if (terms.size() != this.input.size() + this.output.size()) { throw new IllegalArgumentException( "Cannot apply term list " + terms + " to module atom " + this + ", terms has invalid size!"); diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImplTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImplTest.java new file mode 100644 index 000000000..efa2d1353 --- /dev/null +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/ModuleAtomImplTest.java @@ -0,0 +1,74 @@ +package at.ac.tuwien.kr.alpha.commons.programs.atoms; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ModuleAtomImplTest { + + @Test + public void withTerms() { + ModuleAtom moduleAtom = new ModuleAtomImpl("someModule", + List.of(Terms.newVariable("X"), Terms.newVariable("Y")), + List.of(Terms.newVariable("Z")), ModuleAtom.ModuleInstantiationMode.ALL); + ModuleAtom newModuleAtom = moduleAtom.withTerms(List.of(Terms.newConstant(1), Terms.newConstant(2), Terms.newConstant(3))); + // Check correct construction of original atom (also check that withTerms didn't modify the original atom) + assertEquals(moduleAtom.getInput().size(), 2); + assertEquals(moduleAtom.getOutput().size(), 1); + assertEquals(moduleAtom.getModuleName(), "someModule"); + assertEquals(moduleAtom.getInstantiationMode(), ModuleAtom.ModuleInstantiationMode.ALL); + // Check terms of new atom + assertEquals(newModuleAtom.getInput().size(), 2); + assertEquals(newModuleAtom.getOutput().size(), 1); + assertEquals(newModuleAtom.getModuleName(), "someModule"); + assertEquals(newModuleAtom.getInstantiationMode(), ModuleAtom.ModuleInstantiationMode.ALL); + assertEquals(List.of(Terms.newConstant(1), Terms.newConstant(2)), newModuleAtom.getInput()); + assertEquals(List.of(Terms.newConstant(3)), newModuleAtom.getOutput()); + } + + @Test + public void withTermsNewTermsTooLong() { + ModuleAtom moduleAtom = new ModuleAtomImpl("someModule", + List.of(Terms.newVariable("X"), Terms.newVariable("Y")), + List.of(Terms.newVariable("Z")), ModuleAtom.ModuleInstantiationMode.ALL); + assertThrows(IllegalArgumentException.class, + () -> moduleAtom.withTerms( + List.of(Terms.newConstant(1), Terms.newConstant(2), + Terms.newConstant(3), Terms.newConstant(4)))); + } + + @Test + public void withTermsNewTermsTooShort() { + ModuleAtom moduleAtom = new ModuleAtomImpl("someModule", + List.of(Terms.newVariable("X"), Terms.newVariable("Y")), + List.of(Terms.newVariable("Z")), ModuleAtom.ModuleInstantiationMode.ALL); + assertThrows(IllegalArgumentException.class, + () -> moduleAtom.withTerms(List.of(Terms.newConstant(1)))); + } + + @Test + public void moduleAtomsEqual() { + ModuleAtom m1 = new ModuleAtomImpl("someModule", + List.of(Terms.newVariable("X"), Terms.newVariable("Y")), + List.of(Terms.newVariable("Z")), ModuleAtom.ModuleInstantiationMode.ALL); + ModuleAtom m2 = new ModuleAtomImpl("someModule", + List.of(Terms.newVariable("X"), Terms.newVariable("Y")), + List.of(Terms.newVariable("Z")), ModuleAtom.ModuleInstantiationMode.ALL); + assertEquals(m1, m2); + assertEquals(m1.hashCode(), m2.hashCode()); + + ModuleAtom m3 = new ModuleAtomImpl("someModule", + List.of(Terms.newVariable("X"), Terms.newVariable("Y")), + List.of(Terms.newVariable("Z")), ModuleAtom.ModuleInstantiationMode.forNumAnswerSets(3)); + ModuleAtom m4 = new ModuleAtomImpl("someModule", + List.of(Terms.newVariable("X"), Terms.newVariable("Y")), + List.of(Terms.newVariable("Z")), ModuleAtom.ModuleInstantiationMode.forNumAnswerSets(3)); + assertNotEquals(m1, m3); + assertEquals(m3, m4); + } + +} From 761331c6cea8b048b7ac54acbbfedeca409e5ad4 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 24 Jul 2024 18:29:46 +0200 Subject: [PATCH 42/59] Evolog Modules: Permit 0..n input predicates in module definitions. --- .../kr/alpha/api/programs/NormalProgram.java | 5 ++ .../kr/alpha/api/programs/modules/Module.java | 2 +- .../commons/programs/NormalProgramImpl.java | 11 ++- .../kr/alpha/commons/programs/Programs.java | 9 ++- .../commons/programs/modules/ModuleImpl.java | 6 +- .../commons/programs/modules/Modules.java | 2 +- .../alpha/commons/programs/rules/Rules.java | 1 - .../ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 10 +-- .../kr/alpha/core/parser/ParserTest.java | 69 +++++++++++++++---- 10 files changed, 87 insertions(+), 30 deletions(-) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/NormalProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/NormalProgram.java index c6eff6bea..f5a932c52 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/NormalProgram.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/NormalProgram.java @@ -1,7 +1,10 @@ package at.ac.tuwien.kr.alpha.api.programs; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; +import java.util.List; + /** * A {@link Program} consisting only of facts and {@link NormalRule}s, i.e. no disjunctive- or choice-rules, and no aggregates in rule bodies. * @@ -9,4 +12,6 @@ */ public interface NormalProgram extends Program { + List getModules(); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java index d43bdce6c..10b268d10 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java @@ -9,7 +9,7 @@ public interface Module { String getName(); - Predicate getInputSpec(); + Set getInputSpec(); Set getOutputSpec(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/NormalProgramImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/NormalProgramImpl.java index 8bbfc4365..13b5233d2 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/NormalProgramImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/NormalProgramImpl.java @@ -5,6 +5,7 @@ import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; /** @@ -14,8 +15,16 @@ */ class NormalProgramImpl extends AbstractProgram implements NormalProgram { - NormalProgramImpl(List rules, List facts, InlineDirectives inlineDirectives) { + private final List modules; + + NormalProgramImpl(List rules, List facts, InlineDirectives inlineDirectives, List modules) { super(rules, facts, inlineDirectives); + this.modules = modules; + } + + @Override + public List getModules() { + return modules; } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java index 1885842e9..379f75942 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java @@ -48,7 +48,11 @@ public static InputProgramBuilder builder(InputProgram program) { } public static NormalProgram newNormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { - return new NormalProgramImpl(rules, facts, inlineDirectives); + return new NormalProgramImpl(rules, facts, inlineDirectives, Collections.emptyList()); + } + + public static NormalProgram newNormalProgram(List rules, List facts, InlineDirectives inlineDirectives, List modules) { + return new NormalProgramImpl(rules, facts, inlineDirectives, modules); } public static NormalProgram toNormalProgram(InputProgram inputProgram) { @@ -56,7 +60,7 @@ public static NormalProgram toNormalProgram(InputProgram inputProgram) { for (Rule r : inputProgram.getRules()) { normalRules.add(Rules.toNormalRule(r)); } - return new NormalProgramImpl(normalRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + return new NormalProgramImpl(normalRules, inputProgram.getFacts(), inputProgram.getInlineDirectives(), inputProgram.getModules()); } public static InlineDirectives newInlineDirectives() { @@ -81,6 +85,7 @@ public InputProgramBuilder(InputProgram prog) { this.addFacts(prog.getFacts()); this.addInlineDirectives(prog.getInlineDirectives()); this.addTestCases(prog.getTestCases()); + this.addModules(prog.getModules()); } public InputProgramBuilder() { diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java index be4fd2d31..06dbe385f 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java @@ -9,11 +9,11 @@ class ModuleImpl implements Module { private final String name; - private final Predicate inputSpec; + private final Set inputSpec; private final Set outputSpec; private final InputProgram implementation; - ModuleImpl(String name, Predicate inputSpec, Set outputSpec, InputProgram implementation) { + ModuleImpl(String name, Set inputSpec, Set outputSpec, InputProgram implementation) { this.name = name; this.inputSpec = inputSpec; this.outputSpec = outputSpec; @@ -26,7 +26,7 @@ public String getName() { } @Override - public Predicate getInputSpec() { + public Set getInputSpec() { return this.inputSpec; } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java index 0d8d04e0b..57dc7d2ef 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java @@ -12,7 +12,7 @@ private Modules() { throw new AssertionError("Cannot instantiate utility class!"); } - public static Module newModule(final String name, final Predicate inputSpec, final Set outputSpec, final InputProgram implementation) { + public static Module newModule(final String name, final Set inputSpec, final Set outputSpec, final InputProgram implementation) { return new ModuleImpl(name, inputSpec, outputSpec, implementation); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java index 9a19b54bc..ddae7bf49 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/rules/Rules.java @@ -42,7 +42,6 @@ public static NormalRule toNormalRule(Rule rule) { if (!(rule.getHead() instanceof NormalHead)) { throw Util.oops("Trying to construct a NormalRule from rule with non-normal head! Head type is: " + rule.getHead().getClass().getSimpleName()); } - } return newNormalRule(rule.isConstraint() ? null : (NormalHead) rule.getHead(), new LinkedHashSet<>(rule.getBody())); } diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 index 876c4e190..38af994f0 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 @@ -121,5 +121,5 @@ test_assert_all : TEST_ASSERT_ALL CURLY_OPEN statements? CURLY_CLOSE; test_assert_some : TEST_ASSERT_SOME CURLY_OPEN statements? CURLY_CLOSE; -module_signature : predicate_spec ARROW CURLY_OPEN ('*' | predicate_specs) CURLY_CLOSE; +module_signature : CURLY_OPEN predicate_specs? CURLY_CLOSE ARROW CURLY_OPEN ('*' | predicate_specs) CURLY_CLOSE; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 16226a168..4f6e05561 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -335,7 +335,7 @@ public Object visitDirective_module(ASPCore2Parser.Directive_moduleContext ctx) } // directive_module: SHARP DIRECTIVE_MODULE id PAREN_OPEN module_signature PAREN_CLOSE CURLY_OPEN statements CURLY_CLOSE; String name = visitId(ctx.id()); - ImmutablePair> moduleSignature = visitModule_signature(ctx.module_signature()); + ImmutablePair, Set> moduleSignature = visitModule_signature(ctx.module_signature()); startNestedProgram(); visitStatements(ctx.statements()); InputProgram moduleImplementation = endNestedProgram(); @@ -343,10 +343,10 @@ public Object visitDirective_module(ASPCore2Parser.Directive_moduleContext ctx) return null; } - public ImmutablePair> visitModule_signature(ASPCore2Parser.Module_signatureContext ctx) { - Predicate inputPredicate = visitPredicate_spec(ctx.predicate_spec()); - Set outputPredicates = ctx.predicate_specs() != null ? visitPredicate_specs(ctx.predicate_specs()) : Collections.emptySet(); - return ImmutablePair.of(inputPredicate, outputPredicates); + public ImmutablePair, Set> visitModule_signature(ASPCore2Parser.Module_signatureContext ctx) { + Set inputPredicates = ctx.predicate_specs(0) != null ? visitPredicate_specs(ctx.predicate_specs(0)) : Collections.emptySet(); + Set outputPredicates = ctx.predicate_specs(1) != null ? visitPredicate_specs(ctx.predicate_specs(1)) : Collections.emptySet(); + return ImmutablePair.of(inputPredicates, outputPredicates); } @Override diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 684f448af..13e63878c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -86,13 +86,17 @@ public class ParserTest { private static final String UNIT_TEST_KEYWORDS_AS_IDS = "assert(a) :- given(b). # test test(expect: 1) { given { given(b). } assertForAll { :- not assert(a). :- assertForSome(b).}}"; - private static final String MODULE_SIMPLE = "#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private static final String MODULE_SIMPLE = "#module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; - private static final String MODULE_OUTPUT_ALL = "#module mod(in/1 => {*}) { a(X). b(X) :- a(X).}"; + private static final String MODULE_OUTPUT_ALL = "#module mod({in/1} => {*}) { a(X). b(X) :- a(X).}"; - private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; - private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + + private static final String MODULE_EMPTY_INPUT_SPEC = "#module someModule({} => {*}) {p(a).}"; + + private static final String MODULE_MULTIPLE_INPUTS = "#module someModule({input/1, input2/2} => {out1/2}) {p(a).}"; private static final String MODULE_LITERAL = "p(a). q(b). r(X) :- p(X), q(Y), #mod[X, Y](X)."; @@ -332,9 +336,11 @@ public void simpleModule() { assertEquals(1, modules.size()); Module module = modules.get(0); assertEquals("aSimpleModule", module.getName()); - Predicate inputSpec = module.getInputSpec(); - assertEquals("input", inputSpec.getName()); - assertEquals(1, inputSpec.getArity()); + Set inputSpec = module.getInputSpec(); + assertEquals(1, inputSpec.size()); + Predicate inputPredicate = inputSpec.iterator().next(); + assertEquals("input", inputPredicate.getName()); + assertEquals(1, inputPredicate.getArity()); Set outputSpec = module.getOutputSpec(); assertEquals(2, outputSpec.size()); assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); @@ -352,9 +358,11 @@ public void moduleOutputAll() { assertEquals(1, modules.size()); Module module = modules.get(0); assertEquals("mod", module.getName()); - Predicate inputSpec = module.getInputSpec(); - assertEquals("in", inputSpec.getName()); - assertEquals(1, inputSpec.getArity()); + Set inputSpec = module.getInputSpec(); + assertEquals(1, inputSpec.size()); + Predicate inputPredicate = inputSpec.iterator().next(); + assertEquals("in", inputPredicate.getName()); + assertEquals(1, inputPredicate.getArity()); assertTrue(module.getOutputSpec().isEmpty()); InputProgram implementation = module.getImplementation(); assertEquals(1, implementation.getFacts().size()); @@ -371,9 +379,11 @@ public void moduleAndRegularStmts() { assertEquals(1, modules.size()); Module module = modules.get(0); assertEquals("aSimpleModule", module.getName()); - Predicate inputSpec = module.getInputSpec(); - assertEquals("input", inputSpec.getName()); - assertEquals(1, inputSpec.getArity()); + Set inputSpec = module.getInputSpec(); + assertEquals(1, inputSpec.size()); + Predicate inputPredicate = inputSpec.iterator().next(); + assertEquals("input", inputPredicate.getName()); + assertEquals(1, inputPredicate.getArity()); Set outputSpec = module.getOutputSpec(); assertEquals(2, outputSpec.size()); assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); @@ -397,13 +407,42 @@ public void multipleModuleDefinitions() { @Test public void invalidNestedModule() { assertThrows(IllegalStateException.class, () -> - parser.parse("#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). } }")); + parser.parse("#module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). #module anotherModule({input/1} => {out1/2, out2/3}) { p(a). p(b). } }")); } @Test public void invalidNestedTest() { assertThrows(IllegalStateException.class, () -> - parser.parse("#module mod(foo/1 => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }")); + parser.parse("#module mod({foo/1} => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }")); + } + + @Test + public void emptyInputSpec() { + InputProgram prog = parser.parse(MODULE_EMPTY_INPUT_SPEC); + List modules = prog.getModules(); + assertEquals(1, modules.size()); + Module module = modules.get(0); + assertEquals("someModule", module.getName()); + Set inputSpec = module.getInputSpec(); + assertTrue(inputSpec.isEmpty()); + Set outputSpec = module.getOutputSpec(); + assertTrue(outputSpec.isEmpty()); + } + + @Test + public void multipleInputs() { + InputProgram prog = parser.parse(MODULE_MULTIPLE_INPUTS); + List modules = prog.getModules(); + assertEquals(1, modules.size()); + Module module = modules.get(0); + assertEquals("someModule", module.getName()); + Set inputSpec = module.getInputSpec(); + assertEquals(2, inputSpec.size()); + assertTrue(inputSpec.contains(Predicates.getPredicate("input", 1))); + assertTrue(inputSpec.contains(Predicates.getPredicate("input2", 2))); + Set outputSpec = module.getOutputSpec(); + assertEquals(1, outputSpec.size()); + assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); } @Test From 60b819fb8df2c6be3d54fa58e028aea892b9b3db Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 24 Jul 2024 18:37:34 +0200 Subject: [PATCH 43/59] Evolog Modules: Revert to single-predicate module input --- .../kr/alpha/api/programs/modules/Module.java | 2 +- .../commons/programs/modules/ModuleImpl.java | 6 +- .../commons/programs/modules/Modules.java | 2 +- .../ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 10 +-- .../programs/transformation/ModuleLinker.java | 73 ++++++++++++++++++ .../kr/alpha/core/parser/ParserTest.java | 77 +++++-------------- 7 files changed, 103 insertions(+), 69 deletions(-) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java index 10b268d10..d43bdce6c 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java @@ -9,7 +9,7 @@ public interface Module { String getName(); - Set getInputSpec(); + Predicate getInputSpec(); Set getOutputSpec(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java index 06dbe385f..be4fd2d31 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java @@ -9,11 +9,11 @@ class ModuleImpl implements Module { private final String name; - private final Set inputSpec; + private final Predicate inputSpec; private final Set outputSpec; private final InputProgram implementation; - ModuleImpl(String name, Set inputSpec, Set outputSpec, InputProgram implementation) { + ModuleImpl(String name, Predicate inputSpec, Set outputSpec, InputProgram implementation) { this.name = name; this.inputSpec = inputSpec; this.outputSpec = outputSpec; @@ -26,7 +26,7 @@ public String getName() { } @Override - public Set getInputSpec() { + public Predicate getInputSpec() { return this.inputSpec; } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java index 57dc7d2ef..0d8d04e0b 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java @@ -12,7 +12,7 @@ private Modules() { throw new AssertionError("Cannot instantiate utility class!"); } - public static Module newModule(final String name, final Set inputSpec, final Set outputSpec, final InputProgram implementation) { + public static Module newModule(final String name, final Predicate inputSpec, final Set outputSpec, final InputProgram implementation) { return new ModuleImpl(name, inputSpec, outputSpec, implementation); } diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 index 38af994f0..876c4e190 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 @@ -121,5 +121,5 @@ test_assert_all : TEST_ASSERT_ALL CURLY_OPEN statements? CURLY_CLOSE; test_assert_some : TEST_ASSERT_SOME CURLY_OPEN statements? CURLY_CLOSE; -module_signature : CURLY_OPEN predicate_specs? CURLY_CLOSE ARROW CURLY_OPEN ('*' | predicate_specs) CURLY_CLOSE; +module_signature : predicate_spec ARROW CURLY_OPEN ('*' | predicate_specs) CURLY_CLOSE; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 4f6e05561..16226a168 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -335,7 +335,7 @@ public Object visitDirective_module(ASPCore2Parser.Directive_moduleContext ctx) } // directive_module: SHARP DIRECTIVE_MODULE id PAREN_OPEN module_signature PAREN_CLOSE CURLY_OPEN statements CURLY_CLOSE; String name = visitId(ctx.id()); - ImmutablePair, Set> moduleSignature = visitModule_signature(ctx.module_signature()); + ImmutablePair> moduleSignature = visitModule_signature(ctx.module_signature()); startNestedProgram(); visitStatements(ctx.statements()); InputProgram moduleImplementation = endNestedProgram(); @@ -343,10 +343,10 @@ public Object visitDirective_module(ASPCore2Parser.Directive_moduleContext ctx) return null; } - public ImmutablePair, Set> visitModule_signature(ASPCore2Parser.Module_signatureContext ctx) { - Set inputPredicates = ctx.predicate_specs(0) != null ? visitPredicate_specs(ctx.predicate_specs(0)) : Collections.emptySet(); - Set outputPredicates = ctx.predicate_specs(1) != null ? visitPredicate_specs(ctx.predicate_specs(1)) : Collections.emptySet(); - return ImmutablePair.of(inputPredicates, outputPredicates); + public ImmutablePair> visitModule_signature(ASPCore2Parser.Module_signatureContext ctx) { + Predicate inputPredicate = visitPredicate_spec(ctx.predicate_spec()); + Set outputPredicates = ctx.predicate_specs() != null ? visitPredicate_specs(ctx.predicate_specs()) : Collections.emptySet(); + return ImmutablePair.of(inputPredicate, outputPredicates); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java new file mode 100644 index 000000000..8a5e6c867 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java @@ -0,0 +1,73 @@ +package at.ac.tuwien.kr.alpha.core.programs.transformation; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; +import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral; +import at.ac.tuwien.kr.alpha.api.programs.modules.Module; +import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; +import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Program transformation that translates {@link at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral}s into + * {@link at.ac.tuwien.kr.alpha.api.programs.literals.ExternalLiteral}s by constructing {@link at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom}s + * which solve the ASP implementation of the module with the given inputs. + */ +public class ModuleLinker extends ProgramTransformation { + + // Note: References to a standard library of modules that are always available for linking should be member variables of a linker. + + private final Alpha moduleRunner; + + public ModuleLinker(Alpha moduleRunner) { + this.moduleRunner = moduleRunner; + } + + + @Override + public NormalProgram apply(NormalProgram inputProgram) { + Map moduleTable = inputProgram.getModules().stream().collect(Collectors.toMap(Module::getName, Function.identity())); + List transformedRules = inputProgram.getRules().stream() + .map(rule -> containsModuleAtom(rule) ? linkModuleAtoms(rule, moduleTable) : rule) + .collect(Collectors.toList()); + return null; + } + + private NormalRule linkModuleAtoms(NormalRule rule, Map moduleTable) { + NormalHead newHead = rule.getHead(); + Set newBody = rule.getBody().stream() + .map(literal -> { + if (literal instanceof ModuleLiteral) { + ModuleLiteral moduleLiteral = (ModuleLiteral) literal; + return translateModuleAtom(moduleLiteral.getAtom(), moduleTable).toLiteral(!moduleLiteral.isNegated()); + } else { + return literal; + } + }) + .collect(Collectors.toSet()); + return Rules.newNormalRule(newHead, newBody); + } + + private ExternalAtom translateModuleAtom(ModuleAtom moduleAtom, Map moduleTable) { + if (!moduleTable.containsKey(moduleAtom.getModuleName())) { + throw new IllegalArgumentException("Module " + moduleAtom.getModuleName() + " not found in module table."); + } + Module implementationModule = moduleTable.get(moduleAtom.getModuleName()); + //implementationModule. + return null; + } + + private static boolean containsModuleAtom(NormalRule rule) { + return rule.getBody().stream().anyMatch(literal -> literal instanceof ModuleLiteral); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 13e63878c..624658a64 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -69,10 +69,10 @@ public class ParserTest { private static final String UNIT_TEST_EXPECT_UNSAT = "p(1). p(2). " - + ":- p(X), p(Y), X + Y = 3." - + "#test expected_unsat(expect: unsat) {" - + "given {}" - + "}"; + + ":- p(X), p(Y), X + Y = 3." + + "#test expected_unsat(expect: unsat) {" + + "given {}" + + "}"; private static final String UNIT_TEST_BASIC_TEST = "a :- b. #test ensure_a(expect: 1) { given { b. } assertForAll { :- not a. } }"; @@ -86,17 +86,13 @@ public class ParserTest { private static final String UNIT_TEST_KEYWORDS_AS_IDS = "assert(a) :- given(b). # test test(expect: 1) { given { given(b). } assertForAll { :- not assert(a). :- assertForSome(b).}}"; - private static final String MODULE_SIMPLE = "#module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private static final String MODULE_SIMPLE = "#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; - private static final String MODULE_OUTPUT_ALL = "#module mod({in/1} => {*}) { a(X). b(X) :- a(X).}"; + private static final String MODULE_OUTPUT_ALL = "#module mod(in/1 => {*}) { a(X). b(X) :- a(X).}"; - private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; + private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; - private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; - - private static final String MODULE_EMPTY_INPUT_SPEC = "#module someModule({} => {*}) {p(a).}"; - - private static final String MODULE_MULTIPLE_INPUTS = "#module someModule({input/1, input2/2} => {out1/2}) {p(a).}"; + private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }"; private static final String MODULE_LITERAL = "p(a). q(b). r(X) :- p(X), q(Y), #mod[X, Y](X)."; @@ -336,11 +332,9 @@ public void simpleModule() { assertEquals(1, modules.size()); Module module = modules.get(0); assertEquals("aSimpleModule", module.getName()); - Set inputSpec = module.getInputSpec(); - assertEquals(1, inputSpec.size()); - Predicate inputPredicate = inputSpec.iterator().next(); - assertEquals("input", inputPredicate.getName()); - assertEquals(1, inputPredicate.getArity()); + Predicate inputSpec = module.getInputSpec(); + assertEquals("input", inputSpec.getName()); + assertEquals(1, inputSpec.getArity()); Set outputSpec = module.getOutputSpec(); assertEquals(2, outputSpec.size()); assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); @@ -358,11 +352,9 @@ public void moduleOutputAll() { assertEquals(1, modules.size()); Module module = modules.get(0); assertEquals("mod", module.getName()); - Set inputSpec = module.getInputSpec(); - assertEquals(1, inputSpec.size()); - Predicate inputPredicate = inputSpec.iterator().next(); - assertEquals("in", inputPredicate.getName()); - assertEquals(1, inputPredicate.getArity()); + Predicate inputSpec = module.getInputSpec(); + assertEquals("in", inputSpec.getName()); + assertEquals(1, inputSpec.getArity()); assertTrue(module.getOutputSpec().isEmpty()); InputProgram implementation = module.getImplementation(); assertEquals(1, implementation.getFacts().size()); @@ -379,11 +371,9 @@ public void moduleAndRegularStmts() { assertEquals(1, modules.size()); Module module = modules.get(0); assertEquals("aSimpleModule", module.getName()); - Set inputSpec = module.getInputSpec(); - assertEquals(1, inputSpec.size()); - Predicate inputPredicate = inputSpec.iterator().next(); - assertEquals("input", inputPredicate.getName()); - assertEquals(1, inputPredicate.getArity()); + Predicate inputSpec = module.getInputSpec(); + assertEquals("input", inputSpec.getName()); + assertEquals(1, inputSpec.getArity()); Set outputSpec = module.getOutputSpec(); assertEquals(2, outputSpec.size()); assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); @@ -407,42 +397,13 @@ public void multipleModuleDefinitions() { @Test public void invalidNestedModule() { assertThrows(IllegalStateException.class, () -> - parser.parse("#module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). #module anotherModule({input/1} => {out1/2, out2/3}) { p(a). p(b). } }")); + parser.parse("#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). } }")); } @Test public void invalidNestedTest() { assertThrows(IllegalStateException.class, () -> - parser.parse("#module mod({foo/1} => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }")); - } - - @Test - public void emptyInputSpec() { - InputProgram prog = parser.parse(MODULE_EMPTY_INPUT_SPEC); - List modules = prog.getModules(); - assertEquals(1, modules.size()); - Module module = modules.get(0); - assertEquals("someModule", module.getName()); - Set inputSpec = module.getInputSpec(); - assertTrue(inputSpec.isEmpty()); - Set outputSpec = module.getOutputSpec(); - assertTrue(outputSpec.isEmpty()); - } - - @Test - public void multipleInputs() { - InputProgram prog = parser.parse(MODULE_MULTIPLE_INPUTS); - List modules = prog.getModules(); - assertEquals(1, modules.size()); - Module module = modules.get(0); - assertEquals("someModule", module.getName()); - Set inputSpec = module.getInputSpec(); - assertEquals(2, inputSpec.size()); - assertTrue(inputSpec.contains(Predicates.getPredicate("input", 1))); - assertTrue(inputSpec.contains(Predicates.getPredicate("input2", 2))); - Set outputSpec = module.getOutputSpec(); - assertEquals(1, outputSpec.size()); - assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2))); + parser.parse("#module mod(foo/1 => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }")); } @Test From f338eeb9f805abdaa16e24724a28dbff2be5bf2d Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 25 Jul 2024 23:23:42 +0200 Subject: [PATCH 44/59] Evolog Modules: Permit external atom interpretations to return Set> rather than just Set> so we can have module interpretations returning function terms --- .../PredicateInterpretation.java | 7 ++++--- .../BindingMethodPredicateInterpretation.java | 4 ++-- .../kr/alpha/commons/externals/Externals.java | 3 ++- .../NonBindingPredicateInterpretation.java | 2 +- .../externals/PredicateInterpretationImpl.java | 15 --------------- .../SuppliedPredicateInterpretation.java | 7 +++---- .../programs/literals/ExternalLiteralImpl.java | 11 ++++++----- 7 files changed, 18 insertions(+), 31 deletions(-) delete mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/PredicateInterpretation.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/PredicateInterpretation.java index bbe8680bf..5343b4bf4 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/PredicateInterpretation.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/PredicateInterpretation.java @@ -37,10 +37,11 @@ @FunctionalInterface public interface PredicateInterpretation { - Set>> TRUE = singleton(emptyList()); - Set>> FALSE = emptySet(); + + Set> TRUE = singleton(emptyList()); + Set> FALSE = emptySet(); String EVALUATE_RETURN_TYPE_NAME_PREFIX = Set.class.getName() + "<" + List.class.getName() + "<" + ConstantTerm.class.getName(); - Set>> evaluate(List terms); + Set> evaluate(List terms); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BindingMethodPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BindingMethodPredicateInterpretation.java index c10cbdee5..9bf1d25b8 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BindingMethodPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/BindingMethodPredicateInterpretation.java @@ -52,7 +52,7 @@ public BindingMethodPredicateInterpretation(Method method) { @Override @SuppressWarnings("unchecked") - public Set>> evaluate(List terms) { + public Set> evaluate(List terms) { if (terms.size() != method.getParameterCount()) { throw new IllegalArgumentException( "Parameter count mismatch when calling " + method.getName() + ". " + @@ -90,7 +90,7 @@ public Set>> evaluate(List terms) { } try { - return (Set>>) method.invoke(null, arguments); + return (Set>) method.invoke(null, arguments); } catch (IllegalAccessException | InvocationTargetException ex) { throw new RuntimeException("Error invoking method " + method + "with args [" + StringUtils.join(arguments) + "], expection is: " + ex.getMessage()); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java index 52066fd09..cbe65ff16 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/Externals.java @@ -29,6 +29,7 @@ import at.ac.tuwien.kr.alpha.api.externals.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; @@ -114,7 +115,7 @@ public static PredicateInterpretation processPredicate(java.util.function return new BinaryPredicateInterpretation<>(predicate); } - public static PredicateInterpretation processPredicate(java.util.function.Supplier>>> supplier) { + public static PredicateInterpretation processPredicate(java.util.function.Supplier>> supplier) { return new SuppliedPredicateInterpretation(supplier); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/NonBindingPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/NonBindingPredicateInterpretation.java index af7c3c899..6f63d7f3f 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/NonBindingPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/NonBindingPredicateInterpretation.java @@ -51,7 +51,7 @@ public NonBindingPredicateInterpretation() { } @Override - public Set>> evaluate(List terms) { + public Set> evaluate(List terms) { if (terms.size() != arity) { throw new IllegalArgumentException("Exactly " + arity + " term(s) required."); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java deleted file mode 100644 index 5ff6c5cfe..000000000 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/PredicateInterpretationImpl.java +++ /dev/null @@ -1,15 +0,0 @@ -package at.ac.tuwien.kr.alpha.commons.externals; - -import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.terms.Term; - -import java.util.List; -import java.util.Set; - - -// TODO this looks like a duplicate -public interface PredicateInterpretationImpl extends PredicateInterpretation { - @Override - Set>> evaluate(List terms); -} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/SuppliedPredicateInterpretation.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/SuppliedPredicateInterpretation.java index b0da2a4d1..4d46a6186 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/SuppliedPredicateInterpretation.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/SuppliedPredicateInterpretation.java @@ -28,7 +28,6 @@ package at.ac.tuwien.kr.alpha.commons.externals; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.BindingPredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import java.util.List; @@ -36,14 +35,14 @@ import java.util.function.Supplier; public class SuppliedPredicateInterpretation implements BindingPredicateInterpretation { - private final Supplier>>> supplier; + private final Supplier>> supplier; - public SuppliedPredicateInterpretation(Supplier>>> supplier) { + public SuppliedPredicateInterpretation(Supplier>> supplier) { this.supplier = supplier; } @Override - public Set>> evaluate(List terms) { + public Set> evaluate(List terms) { if (!terms.isEmpty()) { throw new IllegalArgumentException("Can only be used without any arguments."); } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java index 276ebd5ce..ea276b14a 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java @@ -127,7 +127,8 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit for (Term t : input) { substitutes.add(t.substitute(partialSubstitution)); } - Set>> results = getAtom().getInterpretation().evaluate(substitutes); + Set> results = getAtom().getInterpretation().evaluate(substitutes); + // TODO verify all results are ground if (results == null) { throw new NullPointerException("Predicate " + getPredicate().getName() + " returned null. It must return a Set."); } @@ -160,10 +161,10 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit * @return true iff no list in externalMethodResult equals the external atom's output term * list as substituted by the grounder, false otherwise */ - private boolean isNegatedLiteralSatisfied(Set>> externalMethodResult) { + private boolean isNegatedLiteralSatisfied(Set> externalMethodResult) { List externalAtomOutTerms = this.getAtom().getOutput(); boolean outputMatches; - for (List> resultTerms : externalMethodResult) { + for (List resultTerms : externalMethodResult) { outputMatches = true; for (int i = 0; i < externalAtomOutTerms.size(); i++) { if (!resultTerms.get(i).equals(externalAtomOutTerms.get(i))) { @@ -182,10 +183,10 @@ private boolean isNegatedLiteralSatisfied(Set>> externalMet return true; } - private List buildSubstitutionsForOutputs(Substitution partialSubstitution, Set>> outputs) { + private List buildSubstitutionsForOutputs(Substitution partialSubstitution, Set> outputs) { List retVal = new ArrayList<>(); List externalAtomOutputTerms = this.getAtom().getOutput(); - for (List> bindings : outputs) { + for (List bindings : outputs) { if (bindings.size() < externalAtomOutputTerms.size()) { throw new RuntimeException( "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() From d410ad1dc660dc9608890d9f6eee0d779e254686 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 25 Jul 2024 23:58:15 +0200 Subject: [PATCH 45/59] Evolog Modules: Draft implementation of ModuleLinker, which constructs interpretations for module literals by wrapping calls to the ASP solver. --- .../api/programs/atoms/ExternalAtom.java | 9 +++ .../literals/ExternalLiteralImpl.java | 5 +- .../programs/transformation/ModuleLinker.java | 65 +++++++++++++++++-- 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ExternalAtom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ExternalAtom.java index d4b2f946c..ef97f8f28 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ExternalAtom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/ExternalAtom.java @@ -4,6 +4,7 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.VariableNormalizableAtom; +import at.ac.tuwien.kr.alpha.api.programs.literals.ExternalLiteral; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; /** @@ -21,4 +22,12 @@ public interface ExternalAtom extends Atom, VariableNormalizableAtom { PredicateInterpretation getInterpretation(); + @Override + default ExternalLiteral toLiteral() { + return toLiteral(true); + } + + @Override + ExternalLiteral toLiteral(boolean positive); + } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java index ea276b14a..9246fa39e 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/literals/ExternalLiteralImpl.java @@ -37,6 +37,7 @@ import at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution; import java.util.*; +import java.util.function.Predicate; /** * Contains a potentially negated {@link ExternalAtom}. @@ -128,10 +129,12 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit substitutes.add(t.substitute(partialSubstitution)); } Set> results = getAtom().getInterpretation().evaluate(substitutes); - // TODO verify all results are ground if (results == null) { throw new NullPointerException("Predicate " + getPredicate().getName() + " returned null. It must return a Set."); } + if (results.stream().anyMatch(trms -> trms.stream().anyMatch(Predicate.not(Term::isGround)))) { + throw new IllegalStateException("Predicate " + getPredicate().getName() + " returned non-ground term."); + } if (this.isNegated()) { return this.isNegatedLiteralSatisfied(results) ? Collections.singletonList(partialSubstitution) : Collections.emptyList(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java index 8a5e6c867..85653f48f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java @@ -1,21 +1,34 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral; import at.ac.tuwien.kr.alpha.api.programs.modules.Module; import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; +import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; +import at.ac.tuwien.kr.alpha.commons.programs.Programs; +import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.collections4.SetUtils; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Program transformation that translates {@link at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral}s into @@ -57,17 +70,57 @@ private NormalRule linkModuleAtoms(NormalRule rule, Map moduleTa return Rules.newNormalRule(newHead, newBody); } - private ExternalAtom translateModuleAtom(ModuleAtom moduleAtom, Map moduleTable) { - if (!moduleTable.containsKey(moduleAtom.getModuleName())) { - throw new IllegalArgumentException("Module " + moduleAtom.getModuleName() + " not found in module table."); + private ExternalAtom translateModuleAtom(ModuleAtom atom, Map moduleTable) { + if (!moduleTable.containsKey(atom.getModuleName())) { + throw new IllegalArgumentException("Module " + atom.getModuleName() + " not found in module table."); } - Module implementationModule = moduleTable.get(moduleAtom.getModuleName()); - //implementationModule. - return null; + Module definition = moduleTable.get(atom.getModuleName()); + // verify inputs + Predicate inputSpec = definition.getInputSpec(); + if (atom.getInput().size() != inputSpec.getArity()) { + throw new IllegalArgumentException("Module " + atom.getModuleName() + " expects " + inputSpec.getArity() + " inputs, but " + atom.getInput().size() + " were given."); + } + NormalProgram normalizedImplementation = moduleRunner.normalizeProgram(definition.getImplementation()); + // verify outputs + Set outputSpec = definition.getOutputSpec(); + int expectedOutputTerms; + if (outputSpec.isEmpty()) { + expectedOutputTerms = calculateOutputPredicates(normalizedImplementation).size(); + } else { + expectedOutputTerms = outputSpec.size(); + } + if (atom.getOutput().size() != expectedOutputTerms) { + throw new IllegalArgumentException("Module " + atom.getModuleName() + " expects " + outputSpec.size() + " outputs, but " + atom.getOutput().size() + " were given."); + } + // create the actual interpretation + PredicateInterpretation interpretation = terms -> { + BasicAtom inputAtom = Atoms.newBasicAtom(inputSpec, terms); + NormalProgram program = Programs.newNormalProgram(normalizedImplementation.getRules(), + ListUtils.union(List.of(inputAtom), normalizedImplementation.getFacts()), normalizedImplementation.getInlineDirectives()); + java.util.function.Predicate filter = outputSpec.isEmpty() ? p -> true : outputSpec::contains; + Stream answerSets = moduleRunner.solve(program, filter); + if (atom.getInstantiationMode().requestedAnswerSets().isPresent()) { + answerSets = answerSets.limit(atom.getInstantiationMode().requestedAnswerSets().get()); + } + return answerSets.map(ModuleLinker::answerSetToTerms).collect(Collectors.toSet()); + }; + return Atoms.newExternalAtom(atom.getPredicate(), interpretation, atom.getInput(), atom.getOutput()); } private static boolean containsModuleAtom(NormalRule rule) { return rule.getBody().stream().anyMatch(literal -> literal instanceof ModuleLiteral); } + private static Set calculateOutputPredicates(NormalProgram program) { + return SetUtils.union(program.getFacts().stream().map(Atom::getPredicate).collect(Collectors.toSet()), + program.getRules().stream() + .filter(java.util.function.Predicate.not(Rule::isConstraint)) + .map(Rule::getHead).map(NormalHead::getAtom).map(Atom::getPredicate) + .collect(Collectors.toSet())); + } + + private static List answerSetToTerms(AnswerSet answerSet) { + return Collections.emptyList(); // TODO + } + } From 13010e0c91f6317060460625ed517e84b3663415 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 26 Jul 2024 15:33:01 +0200 Subject: [PATCH 46/59] Evolog Modules: Finish ModuleLinker implementation. --- .../at/ac/tuwien/kr/alpha/api/AnswerSet.java | 1 + .../alpha/commons/programs/atoms/Atoms.java | 6 ++++ .../alpha/commons/programs/terms/Terms.java | 21 +++++++++++-- .../commons/programs/terms/TermsTest.java | 23 ++++++++++++++ .../programs/transformation/ModuleLinker.java | 31 ++++++++++++------- 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java index 8b80fc9ef..09ea75203 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java @@ -3,6 +3,7 @@ import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.AtomQuery; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import java.util.List; import java.util.Set; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java index d11e77e49..92bbbbb66 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/Atoms.java @@ -11,8 +11,10 @@ import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; +import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.programs.atoms.AggregateAtomImpl.AggregateElementImpl; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; public final class Atoms { @@ -71,4 +73,8 @@ public static AtomQuery query(String predicateName, int predicateArity) { return AtomQueryImpl.forPredicate(predicateName, predicateArity); } + public static FunctionTerm toFunctionTerm(Atom atom) { + return Terms.newFunctionTerm(atom.getPredicate().getName(), atom.getTerms()); + } + } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java index 7d0ac9971..0a8e8f11b 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java @@ -1,8 +1,6 @@ package at.ac.tuwien.kr.alpha.commons.programs.terms; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.terms.*; @@ -18,6 +16,9 @@ */ public final class Terms { + public static final String LIST_TERM_SYMBOL = "lst"; + public static final ConstantTerm EMPTY_LIST = Terms.newSymbolicConstant("emptyList"); + /** * Since this is purely a utility class, it may not be instantiated. * @@ -82,6 +83,20 @@ public static > List> asTermList(T... va return retVal; } + /** + * Constructs a single list term from a list of terms. + */ + public static Term asListTerm(Collection terms) { + List reversedTerms = new ArrayList<>(terms); + Collections.reverse(reversedTerms); + // iterate over the list in reverse order to build the list term from the back. + Term tail = EMPTY_LIST; + for (Term t : reversedTerms) { + tail = Terms.newFunctionTerm(LIST_TERM_SYMBOL, t, tail); + } + return tail; + } + public static List renameTerms(List terms, String prefix, int counterStartingValue) { List renamedTerms = new ArrayList<>(terms.size()); AbstractTerm.RenameCounterImpl renameCounter = new AbstractTerm.RenameCounterImpl(counterStartingValue); diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java index 50e5afb51..3c3d8aba7 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/programs/terms/TermsTest.java @@ -4,6 +4,7 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.programs.terms.ConstantTerm; @@ -42,4 +43,26 @@ public void functionTermVsActionSuccessTermHash() { assertEquals(funcTerm.hashCode(), actionSuccessTerm.hashCode()); } + @Test + public void asListTermSingleElement() { + List terms = List.of(Terms.newConstant(1)); + Term lstTerm = Terms.asListTerm(terms); + assertEquals(Terms.newFunctionTerm(Terms.LIST_TERM_SYMBOL, Terms.newConstant(1), Terms.EMPTY_LIST), lstTerm); + } + + @Test + public void asListTermEmptyList() { + assertEquals(Terms.asListTerm(List.of()), Terms.EMPTY_LIST); + } + + @Test + public void asListTermMultipleElements() { + List terms = List.of(Terms.newConstant(1), Terms.newConstant(2), Terms.newConstant(3)); + Term lstTerm = Terms.asListTerm(terms); + assertEquals(Terms.newFunctionTerm(Terms.LIST_TERM_SYMBOL, Terms.newConstant(1), + Terms.newFunctionTerm(Terms.LIST_TERM_SYMBOL, Terms.newConstant(2), + Terms.newFunctionTerm(Terms.LIST_TERM_SYMBOL, Terms.newConstant(3), + Terms.EMPTY_LIST))), lstTerm); + } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java index 85653f48f..a5196feb0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ModuleLinker.java @@ -15,17 +15,16 @@ import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule; import at.ac.tuwien.kr.alpha.api.programs.rules.Rule; import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.programs.Programs; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules; +import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.SetUtils; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -83,13 +82,13 @@ private ExternalAtom translateModuleAtom(ModuleAtom atom, Map mo NormalProgram normalizedImplementation = moduleRunner.normalizeProgram(definition.getImplementation()); // verify outputs Set outputSpec = definition.getOutputSpec(); - int expectedOutputTerms; + Set expectedOutputPredicates; if (outputSpec.isEmpty()) { - expectedOutputTerms = calculateOutputPredicates(normalizedImplementation).size(); + expectedOutputPredicates = calculateOutputPredicates(normalizedImplementation); } else { - expectedOutputTerms = outputSpec.size(); + expectedOutputPredicates = outputSpec; } - if (atom.getOutput().size() != expectedOutputTerms) { + if (atom.getOutput().size() != expectedOutputPredicates.size()) { throw new IllegalArgumentException("Module " + atom.getModuleName() + " expects " + outputSpec.size() + " outputs, but " + atom.getOutput().size() + " were given."); } // create the actual interpretation @@ -102,7 +101,7 @@ private ExternalAtom translateModuleAtom(ModuleAtom atom, Map mo if (atom.getInstantiationMode().requestedAnswerSets().isPresent()) { answerSets = answerSets.limit(atom.getInstantiationMode().requestedAnswerSets().get()); } - return answerSets.map(ModuleLinker::answerSetToTerms).collect(Collectors.toSet()); + return answerSets.map(as -> answerSetToTerms(as, expectedOutputPredicates)).collect(Collectors.toSet()); }; return Atoms.newExternalAtom(atom.getPredicate(), interpretation, atom.getInput(), atom.getOutput()); } @@ -119,8 +118,18 @@ private static Set calculateOutputPredicates(NormalProgram program) { .collect(Collectors.toSet())); } - private static List answerSetToTerms(AnswerSet answerSet) { - return Collections.emptyList(); // TODO + private static List answerSetToTerms(AnswerSet answerSet, Set moduleOutputSpec) { + List terms = new ArrayList<>(); + for (Predicate predicate : moduleOutputSpec) { + if (!answerSet.getPredicates().contains(predicate)) { + terms.add(Terms.EMPTY_LIST); + } else { + terms.add(Terms.asListTerm(answerSet.getPredicateInstances(predicate).stream() + .map(Atoms::toFunctionTerm).collect(Collectors.toList()))); + } + } + return terms; } + } From 8bf77b3cecdf26cc0a5cd27465c2e13887c61491 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 29 Jul 2024 15:53:38 +0200 Subject: [PATCH 47/59] Evolog Modules: Fix bugs where module definitions do not get passed on. Add very simple end2end test with module-based 3-coloring implementation. --- .../at/ac/tuwien/kr/alpha/api/AnswerSet.java | 1 - .../kr/alpha/commons/programs/Programs.java | 6 +- .../alpha/core/programs/InternalProgram.java | 2 +- .../ArithmeticTermsRewriting.java | 2 +- .../transformation/ChoiceHeadToNormal.java | 2 +- .../transformation/EnumerationRewriting.java | 2 +- .../IntervalTermToIntervalAtom.java | 4 +- .../programs/transformation/ModuleLinker.java | 11 +-- .../VariableEqualityRemoval.java | 2 +- .../aggregates/AggregateRewriting.java | 2 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 12 +-- .../tuwien/kr/alpha/api/impl/TestRunner.java | 2 +- .../kr/alpha/e2etests/End2EndTests.java | 3 +- .../resources/e2e-tests/modules-basic.evl | 83 +++++++++++++++++++ 14 files changed, 106 insertions(+), 28 deletions(-) create mode 100644 alpha-solver/src/test/resources/e2e-tests/modules-basic.evl diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java index 09ea75203..8b80fc9ef 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java @@ -3,7 +3,6 @@ import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.AtomQuery; -import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import java.util.List; import java.util.Set; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java index 379f75942..0d6895e9a 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/Programs.java @@ -47,9 +47,9 @@ public static InputProgramBuilder builder(InputProgram program) { return new InputProgramBuilder(program); } - public static NormalProgram newNormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { - return new NormalProgramImpl(rules, facts, inlineDirectives, Collections.emptyList()); - } +// public static NormalProgram newNormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { +// return new NormalProgramImpl(rules, facts, inlineDirectives, Collections.emptyList()); +// } public static NormalProgram newNormalProgram(List rules, List facts, InlineDirectives inlineDirectives, List modules) { return new NormalProgramImpl(rules, facts, inlineDirectives, modules); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java index afd2236ab..ea79c1ec6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java @@ -106,7 +106,7 @@ public NormalProgram toNormalProgram() { for (CompiledRule rule : getRules()) { normalRules.add(Rules.newNormalRule(rule.getHead(), new LinkedHashSet<>(rule.getBody()))); } - return Programs.newNormalProgram(normalRules, getFacts(), getInlineDirectives()); + return Programs.newNormalProgram(normalRules, getFacts(), getInlineDirectives(), Collections.emptyList()); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java index d7111f098..82e4e1b68 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ArithmeticTermsRewriting.java @@ -59,7 +59,7 @@ public NormalProgram apply(NormalProgram inputProgram) { return inputProgram; } // Create new program with rewritten rules. - return Programs.newNormalProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + return Programs.newNormalProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives(), inputProgram.getModules()); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java index 3b167ac9f..31e41846b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java @@ -114,7 +114,7 @@ public InputProgram apply(InputProgram inputProgram) { } } return programBuilder.addRules(srcRules).addRules(additionalRules).addFacts(inputProgram.getFacts()) - .addInlineDirectives(inputProgram.getInlineDirectives()).build(); + .addInlineDirectives(inputProgram.getInlineDirectives()).addModules(inputProgram.getModules()).build(); } private static boolean containsIntervalTerms(Atom atom) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java index 803af1879..a1cee5073 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java @@ -45,7 +45,7 @@ public InputProgram apply(InputProgram inputProgram) { programBuilder.addFacts(inputProgram.getFacts()); List> srcRules = new ArrayList<>(inputProgram.getRules()); - programBuilder.addRules(rewriteRules(srcRules, enumPredicate)); + programBuilder.addRules(rewriteRules(srcRules, enumPredicate)).addModules(inputProgram.getModules()); return programBuilder.build(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java index ef73eec08..08d5c94e1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java @@ -58,8 +58,6 @@ public class IntervalTermToIntervalAtom extends ProgramTransformation { // Note: References to a standard library of modules that are always available for linking should be member variables of a linker. - private final Alpha moduleRunner; public ModuleLinker(Alpha moduleRunner) { @@ -51,11 +49,10 @@ public NormalProgram apply(NormalProgram inputProgram) { List transformedRules = inputProgram.getRules().stream() .map(rule -> containsModuleAtom(rule) ? linkModuleAtoms(rule, moduleTable) : rule) .collect(Collectors.toList()); - return null; + return Programs.newNormalProgram(transformedRules, inputProgram.getFacts(), inputProgram.getInlineDirectives(), Collections.emptyList()); } private NormalRule linkModuleAtoms(NormalRule rule, Map moduleTable) { - NormalHead newHead = rule.getHead(); Set newBody = rule.getBody().stream() .map(literal -> { if (literal instanceof ModuleLiteral) { @@ -66,7 +63,7 @@ private NormalRule linkModuleAtoms(NormalRule rule, Map moduleTa } }) .collect(Collectors.toSet()); - return Rules.newNormalRule(newHead, newBody); + return Rules.newNormalRule(rule.getHead(), newBody); } private ExternalAtom translateModuleAtom(ModuleAtom atom, Map moduleTable) { @@ -95,7 +92,7 @@ private ExternalAtom translateModuleAtom(ModuleAtom atom, Map mo PredicateInterpretation interpretation = terms -> { BasicAtom inputAtom = Atoms.newBasicAtom(inputSpec, terms); NormalProgram program = Programs.newNormalProgram(normalizedImplementation.getRules(), - ListUtils.union(List.of(inputAtom), normalizedImplementation.getFacts()), normalizedImplementation.getInlineDirectives()); + ListUtils.union(List.of(inputAtom), normalizedImplementation.getFacts()), normalizedImplementation.getInlineDirectives(), Collections.emptyList()); java.util.function.Predicate filter = outputSpec.isEmpty() ? p -> true : outputSpec::contains; Stream answerSets = moduleRunner.solve(program, filter); if (atom.getInstantiationMode().requestedAnswerSets().isPresent()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 1ca5eb985..9cf70d16b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -58,7 +58,7 @@ public InputProgram apply(InputProgram inputProgram) { for (Rule rule : inputProgram.getRules()) { rewrittenRules.add(findAndReplaceVariableEquality(rule)); } - return Programs.newInputProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + return Programs.newInputProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives(), Collections.emptyList(), inputProgram.getModules()); } private Rule findAndReplaceVariableEquality(Rule rule) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java index 48d4747c9..4b97238d1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java @@ -83,7 +83,7 @@ public InputProgram apply(InputProgram inputProgram) { } // Substitute AggregateLiterals with generated result literals. outputRules.addAll(rewriteRulesWithAggregates(ctx)); - InputProgramBuilder resultBuilder = Programs.builder().addRules(outputRules).addFacts(inputProgram.getFacts()) + InputProgramBuilder resultBuilder = Programs.builder().addRules(outputRules).addFacts(inputProgram.getFacts()).addModules(inputProgram.getModules()) .addInlineDirectives(inputProgram.getInlineDirectives()); // Add sub-programs deriving respective aggregate literals. for (Map.Entry, Set> aggToRewrite : ctx.getAggregateFunctionsToRewrite() diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index f24c9df63..342d38ecc 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -52,6 +52,7 @@ import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ModuleLinker; import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; @@ -168,11 +169,9 @@ public NormalProgram normalizeProgram(InputProgram program) { @VisibleForTesting InternalProgram performProgramPreprocessing(NormalProgram program) { LOGGER.debug("Preprocessing InternalProgram!"); - LOGGER.debug("Preprocessing InternalProgram!"); - InternalProgram retVal = InternalProgram.fromNormalProgram(program); - AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); - retVal = stratifiedEvaluationFactory.get().apply(analyzed); - return retVal; + NormalProgram linkedProgram = new ModuleLinker(this).apply(program); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(linkedProgram); + return stratifiedEvaluationFactory.get().apply(analyzed); } /** @@ -255,7 +254,8 @@ public DebugSolvingContext prepareDebugSolve(final InputProgram program, java.ut public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.util.function.Predicate filter) { final DependencyGraph depGraph; final ComponentGraph compGraph; - final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); + NormalProgram linkedProgram = new ModuleLinker(this).apply(program); + final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(linkedProgram); final NormalProgram preprocessed; preprocessed = stratifiedEvaluationFactory.get().apply(analyzed).toNormalProgram(); depGraph = analyzed.getDependencyGraph(); diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java index 1b408270e..48735f7e1 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/TestRunner.java @@ -40,7 +40,7 @@ private TestResult.TestCaseResult runTestCase(NormalProgram programUnderTest, Te LOGGER.info("Running test case " + testCase.getName()); List facts = new ArrayList<>(programUnderTest.getFacts()); facts.addAll(testCase.getInput()); - NormalProgram prog = Programs.newNormalProgram(programUnderTest.getRules(), facts, programUnderTest.getInlineDirectives()); + NormalProgram prog = Programs.newNormalProgram(programUnderTest.getRules(), facts, programUnderTest.getInlineDirectives(), programUnderTest.getModules()); Set answerSets; try { answerSets = alpha.solve(prog).collect(Collectors.toSet()); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java index bc21144ef..a275ddfdb 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java @@ -63,7 +63,8 @@ private static DynamicTest alphaEnd2EndTest(String testName, String... fileset) @TestFactory Stream alphaEnd2EndTests() { return Stream.of( - alphaEnd2EndTest("3-Coloring", E2E_TESTS_DIR + "3col.asp") + alphaEnd2EndTest("3-Coloring", E2E_TESTS_DIR + "3col.asp"), + alphaEnd2EndTest("modules-basic", E2E_TESTS_DIR + "modules-basic.evl") ); } diff --git a/alpha-solver/src/test/resources/e2e-tests/modules-basic.evl b/alpha-solver/src/test/resources/e2e-tests/modules-basic.evl new file mode 100644 index 000000000..86dcca7c2 --- /dev/null +++ b/alpha-solver/src/test/resources/e2e-tests/modules-basic.evl @@ -0,0 +1,83 @@ +%%% Module 3col %%% +% +% Calculates 3-colorings of a given graph. +% Graph is expected to be represented as a function term with following +% structure: graph(list(V, TAIL), list(E, TAIL)), where list(V, TAIL) +% and list(E, TAIL) are vertex- and edge-lists. +% +%%% +#module threecol(graph/2 => {col/2}) { + % Unwrap input + vertex_element(V, TAIL) :- graph(list(V, TAIL), _). + vertex_element(V, TAIL) :- vertex_element(_, list(V, TAIL)). + vertex(V) :- vertex_element(V, _). + edge_element(E, TAIL) :- graph(_, list(E, TAIL)). + edge_element(E, TAIL) :- edge_element(_, list(E, TAIL)). + edge(V1, V2) :- edge_element(edge(V1, V2), _). + + % Make sure edges are symmetric + edge(V2, V1) :- edge(V1, V2). + + % Guess colors + red(V) :- vertex(V), not green(V), not blue(V). + green(V) :- vertex(V), not red(V), not blue(V). + blue(V) :- vertex(V), not red(V), not green(V). + + % Filter invalid guesses + :- vertex(V1), vertex(V2), edge(V1, V2), red(V1), red(V2). + :- vertex(V1), vertex(V2), edge(V1, V2), green(V1), green(V2). + :- vertex(V1), vertex(V2), edge(V1, V2), blue(V1), blue(V2). + + col(V, red) :- red(V). + col(V, blue) :- blue(V). + col(V, green) :- green(V). +} + +%%% Main program %%% +% +% This program uses the module "3col" to determine 3-colorability and actual colorings of a graph +% +%%% + +%% pack vertices into a vertex list +vertex_element(E) :- vertex(E). +% First, establish ordering of elements (which we need to establish the order within the list) +vertex_element_less(N, K) :- vertex_element(N), vertex_element(K), N < K. +vertex_element_not_predecessor(N, K) :- vertex_element_less(N, I), vertex_element_less(I, K). +vertex_element_predecessor(N, K) :- vertex_element_less(N, K), not vertex_element_not_predecessor(N, K). +vertex_element_has_predecessor(N) :- vertex_element_predecessor(_, N). +% Now build the list as a recursively nested function term +vertex_lst_element(IDX, list(N, list_empty)) :- vertex_element(N), not vertex_element_has_predecessor(N), IDX = 0. +vertex_lst_element(IDX, list(N, list(K, TAIL))) :- vertex_element(N), vertex_element_predecessor(K, N), vertex_lst_element(PREV_IDX, list(K, TAIL)), IDX = PREV_IDX + 1. +has_next_vertex_element(IDX) :- vertex_lst_element(IDX, _), NEXT_IDX = IDX + 1, vertex_lst_element(NEXT_IDX, _). +vertex_lst(LIST) :- vertex_lst_element(IDX, LIST), not has_next_vertex_element(IDX). + +%% pack edges into an edge list +edge_element(edge(V1, V2)) :- edge(V1, V2). +% First, establish ordering of elements (which we need to establish the order within the list) +edge_element_less(N, K) :- edge_element(N), edge_element(K), N < K. +edge_element_not_predecessor(N, K) :- edge_element_less(N, I), edge_element_less(I, K). +edge_element_predecessor(N, K) :- edge_element_less(N, K), not edge_element_not_predecessor(N, K). +edge_element_has_predecessor(N) :- edge_element_predecessor(_, N). +% Now build the list as a recursively nested function term +edge_lst_element(IDX, list(N, list_empty)) :- edge_element(N), not edge_element_has_predecessor(N), IDX = 0. +edge_lst_element(IDX, list(N, list(K, TAIL))) :- edge_element(N), edge_element_predecessor(K, N), edge_lst_element(PREV_IDX, list(K, TAIL)), IDX = PREV_IDX + 1. +has_next_edge_element(IDX) :- edge_lst_element(IDX, _), NEXT_IDX = IDX + 1, edge_lst_element(NEXT_IDX, _). +edge_lst(LIST) :- edge_lst_element(IDX, LIST), not has_next_edge_element(IDX). + +coloring(COL) :- vertex_lst(VERTEX_LST), edge_lst(EDGE_LST), #threecol[VERTEX_LST, EDGE_LST](COL). + +#test smokeTest(expect: >0) { + given { + vertex(a). + vertex(b). + vertex(c). + edge(a, b). + edge(b, c). + edge(c, a). + } + assertForAll { + coloring_found :- coloring(_). + :- not coloring_found. + } +} \ No newline at end of file From d1f349ebcad46e904811698adba664ea352e5fa8 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 1 Aug 2024 20:31:57 +0200 Subject: [PATCH 48/59] Evolog Modules: Add parsing for list collection aggregate --- .../api/programs/atoms/AggregateAtom.java | 8 +++- .../ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 | 8 +++- .../ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 | 1 + .../alpha/core/parser/ParseTreeVisitor.java | 31 +++++++++++- .../kr/alpha/core/parser/ParserTest.java | 48 +++++++++++++++++++ 5 files changed, 93 insertions(+), 3 deletions(-) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/AggregateAtom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/AggregateAtom.java index bd5127cf2..f5de58e46 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/AggregateAtom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/AggregateAtom.java @@ -24,7 +24,8 @@ enum AggregateFunctionSymbol { COUNT, MAX, MIN, - SUM + SUM, + LIST } ComparisonOperator getLowerBoundOperator(); @@ -44,6 +45,11 @@ enum AggregateFunctionSymbol { @Override AggregateLiteral toLiteral(boolean positive); + @Override + default AggregateLiteral toLiteral() { + return toLiteral(true); + } + interface AggregateElement { List getElementTerms(); diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 index 876c4e190..9eca2e92b 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4 @@ -34,7 +34,13 @@ choice_elements : choice_element (SEMICOLON choice_elements)?; choice_element : classical_literal (COLON naf_literals?)?; -aggregate : NAF? (lt=term lop=binop)? aggregate_function CURLY_OPEN aggregate_elements CURLY_CLOSE (uop=binop ut=term)?; +aggregate : (classic_aggregate | list_aggregate); + +list_aggregate: term EQUAL AGGREGATE_LIST CURLY_OPEN list_comprehension CURLY_CLOSE; + +list_comprehension: term COLON naf_literals; // Note: Term is expected to be a function term or basic_term + +classic_aggregate: NAF? (lt=term lop=binop)? aggregate_function CURLY_OPEN aggregate_elements CURLY_CLOSE (uop=binop ut=term)?; aggregate_elements : aggregate_element (SEMICOLON aggregate_elements)?; diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 index b0641ab1d..1825d3607 100644 --- a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPLexer.g4 @@ -40,6 +40,7 @@ AGGREGATE_COUNT : '#count'; AGGREGATE_MAX : '#max'; AGGREGATE_MIN : '#min'; AGGREGATE_SUM : '#sum'; +AGGREGATE_LIST : '#list'; DIRECTIVE_ENUM : 'enumeration_predicate_is'; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 16226a168..a28df0d9f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -388,7 +388,19 @@ public Set visitBody(ASPCore2Parser.BodyContext ctx) { @Override public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { - // aggregate : NAF? (lt=term lop=binop)? aggregate_function CURLY_OPEN aggregate_elements CURLY_CLOSE (uop=binop ut=term)?; + // aggregate : (classic_aggregate | list_aggregate); + if (ctx.classic_aggregate() != null) { + return visitClassic_aggregate(ctx.classic_aggregate()); + } else if (ctx.list_aggregate() != null) { + return visitList_aggregate(ctx.list_aggregate()); + } else { + throw notSupported(ctx); + } + } + + @Override + public AggregateLiteral visitClassic_aggregate(ASPCore2Parser.Classic_aggregateContext ctx) { + // classic_aggregate: NAF? (lt=term lop=binop)? aggregate_function CURLY_OPEN aggregate_elements CURLY_CLOSE (uop=binop ut=term)?; boolean isPositive = ctx.NAF() == null; Term lt = null; ComparisonOperator lop = null; @@ -407,6 +419,23 @@ public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { return Atoms.newAggregateAtom(lop, lt, uop, ut, aggregateFunction, aggregateElements).toLiteral(isPositive); } + @Override + public AggregateLiteral visitList_aggregate(ASPCore2Parser.List_aggregateContext ctx) { + // list_aggregate: term EQUAL AGGREGATE_LIST CURLY_OPEN list_comprehension CURLY_CLOSE; + Term listResultTerm = (Term) visit(ctx.term()); + ImmutablePair> listComprehension = visitList_comprehension(ctx.list_comprehension()); + return Atoms.newAggregateAtom(ComparisonOperators.EQ, listResultTerm, AggregateAtom.AggregateFunctionSymbol.LIST, + List.of(Atoms.newAggregateElement(List.of(listComprehension.left), listComprehension.right))).toLiteral(); + } + + @Override + public ImmutablePair> visitList_comprehension(ASPCore2Parser.List_comprehensionContext ctx) { + // list_comprehension: term COLON naf_literals; + Term elementTerm = (Term) visit(ctx.term()); + List elementSelectors = visitNaf_literals(ctx.naf_literals()); + return ImmutablePair.of(elementTerm, elementSelectors); + } + @Override public List visitAggregate_elements(ASPCore2Parser.Aggregate_elementsContext ctx) { // aggregate_elements : aggregate_element (SEMICOLON aggregate_elements)?; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 624658a64..676ce858b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -106,6 +106,10 @@ public class ParserTest { private static final String MODULE_LITERAL_NO_OUTPUT_WITH_NUM_ANSWER_SETS = "a(X) :- #something{4}[X]."; + private static final String LIST_AGGREGATE = "stuff_list(LST) :- LST = #list{X : stuff(X)}."; + + private static final String LIST_AGGREGATE_TUPLE = "stuff_list(LST) :- LST = #list{stuff_tuple(X,Y) : stuff(X,Y)}."; + private final ProgramParserImpl parser = new ProgramParserImpl(); @Test @@ -499,4 +503,48 @@ public void moduleLiteralNoOutputWithNumAnswerSets() { assertEquals(4, moduleLiteral.getAtom().getInstantiationMode().requestedAnswerSets().get()); } + @Test + public void listAggregate() { + InputProgram prog = parser.parse(LIST_AGGREGATE); + assertEquals(1, prog.getRules().size()); + Rule rule = prog.getRules().get(0); + assertEquals(1, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof AggregateLiteral).count()); + AggregateLiteral aggregateLiteral = (AggregateLiteral) rule.getBody().stream().filter(lit -> lit instanceof AggregateLiteral).findFirst().get(); + AggregateAtom aggregateAtom = aggregateLiteral.getAtom(); + assertEquals(ComparisonOperators.EQ, aggregateAtom.getLowerBoundOperator()); + assertEquals(Terms.newVariable("LST"), aggregateAtom.getLowerBoundTerm()); + assertEquals(AggregateAtom.AggregateFunctionSymbol.LIST, aggregateAtom.getAggregateFunction()); + assertEquals(1, aggregateAtom.getAggregateElements().size()); + AggregateAtom.AggregateElement aggregateElement = aggregateAtom.getAggregateElements().get(0); + assertEquals(1, aggregateElement.getElementTerms().size()); + Term elementTerm = aggregateElement.getElementTerms().get(0); + assertEquals(Terms.newVariable("X"), elementTerm); + assertEquals(1, aggregateElement.getElementLiterals().size()); + Literal elementLiteral = aggregateElement.getElementLiterals().get(0); + assertEquals(Atoms.newBasicAtom(Predicates.getPredicate("stuff", 1), Terms.newVariable("X")).toLiteral(), elementLiteral); + } + + @Test + public void listAggregateWithTuples() { + InputProgram prog = parser.parse(LIST_AGGREGATE_TUPLE); + assertEquals(1, prog.getRules().size()); + Rule rule = prog.getRules().get(0); + assertEquals(1, rule.getBody().size()); + assertEquals(1, rule.getBody().stream().filter(lit -> lit instanceof AggregateLiteral).count()); + AggregateLiteral aggregateLiteral = (AggregateLiteral) rule.getBody().stream().filter(lit -> lit instanceof AggregateLiteral).findFirst().get(); + AggregateAtom aggregateAtom = aggregateLiteral.getAtom(); + assertEquals(ComparisonOperators.EQ, aggregateAtom.getLowerBoundOperator()); + assertEquals(Terms.newVariable("LST"), aggregateAtom.getLowerBoundTerm()); + assertEquals(AggregateAtom.AggregateFunctionSymbol.LIST, aggregateAtom.getAggregateFunction()); + assertEquals(1, aggregateAtom.getAggregateElements().size()); + AggregateAtom.AggregateElement aggregateElement = aggregateAtom.getAggregateElements().get(0); + assertEquals(1, aggregateElement.getElementTerms().size()); + Term elementTerm = aggregateElement.getElementTerms().get(0); + assertEquals(Terms.newFunctionTerm("stuff_tuple", Terms.newVariable("X"), Terms.newVariable("Y")), elementTerm); + assertEquals(1, aggregateElement.getElementLiterals().size()); + Literal elementLiteral = aggregateElement.getElementLiterals().get(0); + assertEquals(Atoms.newBasicAtom(Predicates.getPredicate("stuff", 2), Terms.newVariable("X"), Terms.newVariable("Y")).toLiteral(), elementLiteral); + } + } From 35407623e19262dc3ff46bd0f394a9ad5cf13782 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 6 Aug 2024 18:09:35 +0200 Subject: [PATCH 49/59] Evolog Modules: aggregate terms into list using aggregate literal --- .../alpha/commons/programs/terms/Terms.java | 2 +- .../aggregates/AggregateRewriting.java | 5 ++ .../encoders/AggregateEncoders.java | 5 ++ .../aggregates/encoders/ListEncoder.java | 61 +++++++++++++++++++ .../kr/alpha/AggregateRewritingTest.java | 21 +++++++ .../kr/alpha/e2etests/End2EndTests.java | 3 +- .../e2e-tests/neighboring-vertices-list.evl | 45 ++++++++++++++ 7 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/ListEncoder.java create mode 100644 alpha-solver/src/test/resources/e2e-tests/neighboring-vertices-list.evl diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java index 0a8e8f11b..5e689ca4e 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/terms/Terms.java @@ -17,7 +17,7 @@ public final class Terms { public static final String LIST_TERM_SYMBOL = "lst"; - public static final ConstantTerm EMPTY_LIST = Terms.newSymbolicConstant("emptyList"); + public static final ConstantTerm EMPTY_LIST = Terms.newSymbolicConstant("lst_empty"); /** * Since this is purely a utility class, it may not be instantiated. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java index 4b97238d1..265ca735a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java @@ -33,6 +33,7 @@ public class AggregateRewriting extends ProgramTransformation K. " + + "$id$_element_not_successor(ARGS, N, K) :- $id$_element_greater(ARGS, N, I), $id$_element_greater(ARGS, I, K). " + + "$id$_element_successor(ARGS, N, K) :- $id$_element_greater(ARGS, N, K), not $id$_element_not_successor(ARGS, N, K). " + + "$id$_element_has_successor(ARGS, N) :- $id$_element_successor(ARGS, _, N). " + + // Now build the list as a recursively nested function term + "$id$_lst_element(ARGS, IDX, lst(N, lst_empty)) :- $id$_element(ARGS, N), not $id$_element_has_successor(ARGS, N), IDX = 0. " + + "$id$_lst_element(ARGS, IDX, lst(N, lst(K, TAIL))) :- $id$_element(ARGS, N), $id$_element_successor(ARGS, K, N), $id$_lst_element(ARGS, PREV_IDX, lst(K, TAIL)), IDX = PREV_IDX + 1. " + + "has_next_$id$_element(ARGS, IDX) :- $id$_lst_element(ARGS, IDX, _), NEXT_IDX = IDX + 1, $id$_lst_element(ARGS, NEXT_IDX, _). " + + "$aggregate_result$(ARGS, LIST) :- $id$_lst_element(ARGS, IDX, LIST), not has_next_$id$_element(ARGS, IDX)."); + + private final ProgramParser parser; + + protected ListEncoder(ProgramParser parser) { + super(AggregateAtom.AggregateFunctionSymbol.LIST, Set.of(ComparisonOperators.EQ)); + this.parser = parser; + } + + @Override + protected InputProgram encodeAggregateResult(AggregateRewritingContext.AggregateInfo aggregateToEncode) { + ST encodingTemplate = new ST(LIST_AGGREGATION); + encodingTemplate.add("id", aggregateToEncode.getId()); + encodingTemplate.add("aggregate_result", aggregateToEncode.getOutputAtom().getPredicate().getName()); + return parser.parse(encodingTemplate.render()); + } + + @Override + protected BasicAtom buildElementRuleHead(String aggregateId, AggregateAtom.AggregateElement element, Term aggregateArguments) { + Predicate headPredicate = Predicates.getPredicate(this.getElementTuplePredicateSymbol(aggregateId), 2); + if (element.getElementTerms().size() != 1) { + throw new IllegalArgumentException("List elements may only consist of one term."); + } + Term value = element.getElementTerms().get(0); + return Atoms.newBasicAtom(headPredicate, aggregateArguments, value); + } + + @Override + protected String getElementTuplePredicateSymbol(String aggregateId) { + return aggregateId + "_element"; + } +} diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java index 245304cc5..6fa33a5ba 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java @@ -5,6 +5,8 @@ import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.programs.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.programs.terms.Terms; @@ -12,6 +14,7 @@ import org.junit.jupiter.api.Test; import java.util.List; +import java.util.SortedSet; import java.util.function.Function; import java.util.stream.Collectors; @@ -74,6 +77,10 @@ public class AggregateRewritingTest { "p(1..10)." + "q :- X = #count { Y : p( Y ) }, X = #count { Z : p( Z ) }," + " Y = #count { X : p( X ) }, 1 <= #count { X : p( X ) }, Z = #max { W : p( W ) }."; + + private static final String LIST_COLLECT = + "p(1). p(2). p(3)." + + " q(X) :- X = #list{ Y : p(Y) }."; //@formatter:on // Use an alpha instance with default config for all test cases @@ -233,4 +240,18 @@ public void setComplexEqualityWithGlobals() { assertTrue(answerSet.getPredicateInstances(q).contains(Atoms.newBasicAtom(q))); } + @Test + public void listCollect() { + List answerSets = solve.apply(LIST_COLLECT); + assertEquals(1, answerSets.size()); + AnswerSet answerSet = answerSets.get(0); + Predicate q = Predicates.getPredicate("q", 1); + SortedSet instances = answerSet.getPredicateInstances(q); + assertEquals(1, instances.size()); + Atom instance = instances.first(); + assertEquals(1, instance.getTerms().size()); + Term term = instance.getTerms().get(0); + assertEquals(Terms.asListTerm(List.of(Terms.newConstant(1), Terms.newConstant(2), Terms.newConstant(3))), term); + } + } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java index a275ddfdb..15d8d1b98 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java @@ -64,7 +64,8 @@ private static DynamicTest alphaEnd2EndTest(String testName, String... fileset) Stream alphaEnd2EndTests() { return Stream.of( alphaEnd2EndTest("3-Coloring", E2E_TESTS_DIR + "3col.asp"), - alphaEnd2EndTest("modules-basic", E2E_TESTS_DIR + "modules-basic.evl") + alphaEnd2EndTest("modules-basic", E2E_TESTS_DIR + "modules-basic.evl"), + alphaEnd2EndTest("neighboring-vertices-list", E2E_TESTS_DIR + "neighboring-vertices-list.evl") ); } diff --git a/alpha-solver/src/test/resources/e2e-tests/neighboring-vertices-list.evl b/alpha-solver/src/test/resources/e2e-tests/neighboring-vertices-list.evl new file mode 100644 index 000000000..149a02a3f --- /dev/null +++ b/alpha-solver/src/test/resources/e2e-tests/neighboring-vertices-list.evl @@ -0,0 +1,45 @@ +% Graph is undirected +edge(Y, X) :- edge(X, Y). + +%% Generate list of neighboring vertices for each vertex in the graph +neighbor(V, N) :- vertex(V), vertex(N), edge(V, N). +neighbors(V, LST) :- vertex(V), LST = #list{ N : neighbor(V, N)}. + +#test lineGraph(expect: 1) { + given { + vertex(1). vertex(2). edge(1, 2). + } + assertForAll { + :- not neighbors(1, lst(2, lst_empty)). + :- not neighbors(2, lst(1, lst_empty)). + } +} + +#test network(expect: 1) { + given { + vertex(1..8). + + edge(1, 2). + edge(1, 3). + edge(1, 4). + edge(2, 5). + edge(1, 3). + edge(1, 4). + edge(2, 5). + edge(3, 6). + edge(4, 7). + edge(5, 8). + edge(6, 8). + edge(7, 8). + } + assertForAll { + :- not neighbors(1, lst(2, lst(3, lst(4, lst_empty)))). + :- not neighbors(2, lst(1, lst(5, lst_empty))). + :- not neighbors(3, lst(1, lst(6, lst_empty))). + :- not neighbors(4, lst(1, lst(7, lst_empty))). + :- not neighbors(5, lst(2, lst(8, lst_empty))). + :- not neighbors(6, lst(3, lst(8, lst_empty))). + :- not neighbors(7, lst(4, lst(8, lst_empty))). + :- not neighbors(8, lst(5, lst(6, lst(7, lst_empty)))). + } +} \ No newline at end of file From 1dcdbf0082c5cf14a612c5c2dd54452b1c89f64d Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 7 Aug 2024 15:44:55 +0200 Subject: [PATCH 50/59] Evolog Modules: module-based implementation of bin-packing problem including unit tests --- .../aggregates/encoders/ListEncoder.java | 4 +- .../kr/alpha/e2etests/End2EndTests.java | 5 +- .../test/resources/e2e-tests/bin-packing.evl | 66 ++++++++++++++ .../resources/e2e-tests/bin-packing.test.evl | 89 +++++++++++++++++++ 4 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 alpha-solver/src/test/resources/e2e-tests/bin-packing.evl create mode 100644 alpha-solver/src/test/resources/e2e-tests/bin-packing.test.evl diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/ListEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/ListEncoder.java index ed17b7075..10c3b8fcd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/ListEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/ListEncoder.java @@ -26,8 +26,8 @@ public class ListEncoder extends AbstractAggregateEncoder { // Now build the list as a recursively nested function term "$id$_lst_element(ARGS, IDX, lst(N, lst_empty)) :- $id$_element(ARGS, N), not $id$_element_has_successor(ARGS, N), IDX = 0. " + "$id$_lst_element(ARGS, IDX, lst(N, lst(K, TAIL))) :- $id$_element(ARGS, N), $id$_element_successor(ARGS, K, N), $id$_lst_element(ARGS, PREV_IDX, lst(K, TAIL)), IDX = PREV_IDX + 1. " + - "has_next_$id$_element(ARGS, IDX) :- $id$_lst_element(ARGS, IDX, _), NEXT_IDX = IDX + 1, $id$_lst_element(ARGS, NEXT_IDX, _). " + - "$aggregate_result$(ARGS, LIST) :- $id$_lst_element(ARGS, IDX, LIST), not has_next_$id$_element(ARGS, IDX)."); + "$id$_has_next_element(ARGS, IDX) :- $id$_lst_element(ARGS, IDX, _), NEXT_IDX = IDX + 1, $id$_lst_element(ARGS, NEXT_IDX, _). " + + "$aggregate_result$(ARGS, LIST) :- $id$_lst_element(ARGS, IDX, LIST), not $id$_has_next_element(ARGS, IDX)."); private final ProgramParser parser; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java index 15d8d1b98..31ad7d731 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/e2etests/End2EndTests.java @@ -65,10 +65,9 @@ Stream alphaEnd2EndTests() { return Stream.of( alphaEnd2EndTest("3-Coloring", E2E_TESTS_DIR + "3col.asp"), alphaEnd2EndTest("modules-basic", E2E_TESTS_DIR + "modules-basic.evl"), - alphaEnd2EndTest("neighboring-vertices-list", E2E_TESTS_DIR + "neighboring-vertices-list.evl") + alphaEnd2EndTest("neighboring-vertices-list", E2E_TESTS_DIR + "neighboring-vertices-list.evl"), + alphaEnd2EndTest("bin-packing", E2E_TESTS_DIR + "bin-packing.evl", E2E_TESTS_DIR + "bin-packing.test.evl") ); } - - } diff --git a/alpha-solver/src/test/resources/e2e-tests/bin-packing.evl b/alpha-solver/src/test/resources/e2e-tests/bin-packing.evl new file mode 100644 index 000000000..53b410fc0 --- /dev/null +++ b/alpha-solver/src/test/resources/e2e-tests/bin-packing.evl @@ -0,0 +1,66 @@ +%%% Module Bin-Packing %%% +% +% This module solves instances of the bin-packing decision problem: +% Given a set of bins, described as terms bin(B, SIZE), and items, described as terms item(I, SIZE), +% the module calculates all assignments of items to bins, such that all items are packed and no +% bin size is exceeded. Each answer set corresponds to one valid assignment. +% +% Input: a fact "instance(BIN_LST, ITEM_LST)", where +% - BIN_LST is a list of terms of form bin(B, SIZE), +% - and ITEM_LST is a list of terms of form item(I, SIZE) +% +%%% +#module bin_packing(instance/2 => {item_packed/2}) { + % Unpack input lists. + bin_element(E, TAIL) :- instance(lst(E, TAIL), _). + bin_element(E, TAIL) :- bin_element(_, lst(E, TAIL)). + bin(B, S) :- bin_element(bin(B, S), _). + + item_element(E, TAIL) :- instance(_, lst(E, TAIL)). + item_element(E, TAIL) :- item_element(_, lst(E, TAIL)). + item(I, S) :- item_element(item(I, S), _). + + % For every item, guess an assignment to each bin. + { item_packed(I, B) : bin(B, _) } :- item(I, _). + % An item may only be assigned to one bin at a time + :- item_packed(I, B1), item_packed(I, B2), B1 != B2. + + % We must not exceed the capacity of any bin. + capacity_used(B, C) :- C = #sum{S : item(I, S), item_packed(I, B)}, bin(B, _). + :- capacity_used(B, C), C > S, bin(B, S). + + % Every item must be packed. + item_packed_somewhere(I) :- item_packed(I, _). + :- item(I, _), not item_packed_somewhere(I). +} + + +%%% Bin-Packing Valuation %%% +% +% Given a Bin-Packing instance and a satisfying assignment, +% calculates a numeric value for the given assignment. +% The value is the sum of the capacities of all bins used in the assignment. +% Intuitively, we calculate the cost in total storage capacity of a given bin assignment. +% +%%% +#module bin_packing_valuation(instance_with_assignment/3 => {assignment_value/1}) { + %% Unpack input + % Extract bins from bin list + bin_element(E, TAIL) :- instance_with_assignment(lst(E, TAIL), _, _). + bin_element(E, TAIL) :- bin_element(_, lst(E, TAIL)). + bin(B, S) :- bin_element(bin(B, S), _). + + % Extract items from item list + item_element(E, TAIL) :- instance_with_assignment(_, lst(E, TAIL), _). + item_element(E, TAIL) :- item_element(_, lst(E, TAIL)). + item(I, S) :- item_element(item(I, S), _). + + % Extract individual item assignments + assignment_element(E, TAIL) :- instance_with_assignment(_, _, lst(E, TAIL)). + assignment_element(E, TAIL) :- assignment_element(_, lst(E, TAIL)). + assigned(I, B) :- assignment_element(item_packed(I, B), _). + + % Get all bins that are used in the assignment + bin_used(B) :- assigned(_, B). + assignment_value(V) :- V = #sum{ S : bin(B, S), bin_used(B)}. +} \ No newline at end of file diff --git a/alpha-solver/src/test/resources/e2e-tests/bin-packing.test.evl b/alpha-solver/src/test/resources/e2e-tests/bin-packing.test.evl new file mode 100644 index 000000000..c7279dbc0 --- /dev/null +++ b/alpha-solver/src/test/resources/e2e-tests/bin-packing.test.evl @@ -0,0 +1,89 @@ +%%% Unit tests for bin_packing module + +instance(BINS, ITEMS) :- BINS = #list{bin(B, S) : bin(B, S)}, ITEMS = #list{item(I, S) : item(I, S)}. +instance_with_assignment(BINS, ITEMS, ASSGN) :- instance(BINS, ITEMS), #bin_packing[BINS, ITEMS](ASSGN). +bin_assignment(A) :- instance_with_assignment(_, _, A). +assignment_valuation_result(A, V) :- instance_with_assignment(B, I, A), #bin_packing_valuation[B, I, A](V). +assignment_value(A, V) :- assignment_valuation_result(A, lst(assignment_value(V), lst_empty)). + +#test singleBinPositiveCase(expect: 1) { + given { + bin(a, 10). + + item(x, 3). + item(y, 2). + item(z, 4). + + } + assertForAll { + % There is excatly one assignment + assignment_found :- bin_assignment(_). + :- not assignment_found. + :- bin_assignment(A1), bin_assignment(A2), A1 != A2. + + % Every item is in a bin + assignment_element(lst(E, TAIL), E, TAIL) :- bin_assignment(lst(E, TAIL)). + assignment_element(ASSGN, E, TAIL) :- assignment_element(ASSGN, _, lst(E, TAIL)). + assigned(I, B, A) :- assignment_element(A, item_packed(I, B), _). + item_assigned(A, I) :- item(I, _), assigned(I, _, A). + :- bin_assignment(A), item(I, _), not item_assigned(A, I). + + % In no assignment, any bin capacity is exceeded + capacity_used(A, B, C) :- C = #sum{S : item(I, S), item_assigned(I, B, A)}, bin_assignment(A), bin(B, _). + :- bin_assignment(A), bin(B, S), capacity_used(A, B, C), C > S. + + % The single assignment has value 10 + :- bin_assignment(A), not assignment_value(A, 10). + } +} + +#test singleBinNegativeCase(expect: 1) { + given { + bin(a, 7). + + item(x, 3). + item(y, 2). + item(z, 4). + } + assertForAll { + % There is no assignment + assignment_found :- bin_assignment(_). + :- assignment_found. + } +} + +#test twoBinsTwoAssignments(expect: 1) { + given { + bin(a, 6). + bin(b, 4). + + item(x, 3). + item(y, 2). + item(z, 4). + + } + assertForAll { + % There are exactly two assignments + num_assignments(N) :- N = #count{ A : bin_assignment(A)}. + assignment_found :- bin_assignment(_). + :- num_assignments(N), N != 2. + + % Every item is in a bin + assignment_element(lst(E, TAIL), E, TAIL) :- bin_assignment(lst(E, TAIL)). + assignment_element(ASSGN, E, TAIL) :- assignment_element(ASSGN, _, lst(E, TAIL)). + assigned(I, B, A) :- assignment_element(A, item_packed(I, B), _). + item_assigned(A, I) :- item(I, _), assigned(I, _, A). + :- bin_assignment(A), item(I, _), not item_assigned(A, I). + + % In no assignment, any bin capacity is exceeded + capacity_used(A, B, C) :- C = #sum{S : item(I, S), item_assigned(I, B, A)}, bin_assignment(A), bin(B, _). + :- bin_assignment(A), bin(B, S), capacity_used(A, B, C), C > S. + + % There is an assignment in which items y and z are in bin a. + y_and_z_in_a :- bin_assignment(A), assigned(y, a, A), assigned(z, a, A). + :- not y_and_z_in_a. + + % Both assignments have value 10 + :- bin_assignment(A), not assignment_value(A, 10). + } +} \ No newline at end of file From 119e2b1d0c252d0840fcb0161334340fb0070c1e Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 9 Aug 2024 16:06:10 +0200 Subject: [PATCH 51/59] Bugfix: add toString for EnumerationAtom --- .../kr/alpha/commons/externals/AspStandardLibrary.java | 1 + .../kr/alpha/commons/programs/atoms/AbstractAtom.java | 3 +++ .../kr/alpha/core/programs/atoms/EnumerationAtom.java | 7 ++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java index 03682d772..54908ab14 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java @@ -245,6 +245,7 @@ public static Set>> substringOfString(String str, int } } + // TODO we could add something to convert string to list @Predicate(name = "str_x_xs") public static Set>> stringHeadRemainder(String str) { List> xXs = new ArrayList<>(); diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java index f014fe1e2..0d59ce8df 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/atoms/AbstractAtom.java @@ -98,4 +98,7 @@ public Atom renameVariables(String newVariablePrefix) { @Override public abstract int hashCode(); + @Override + public abstract String toString(); + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/atoms/EnumerationAtom.java index 97b9865fc..0eb7a0cab 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/atoms/EnumerationAtom.java @@ -167,5 +167,10 @@ public boolean equals(Object o) { public int hashCode() { return 31 * ENUMERATION_PREDICATE.hashCode() + getTerms().hashCode(); } - + + @Override + public String toString() { + return String.format("%s(%s,%s,%s)", ENUMERATION_PREDICATE.getName(), enumIdTerm, valueTerm, indexTerm); + } + } From 712f26309414b151ff0781083af999d3b7d049a6 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 21 Aug 2024 21:27:52 +0200 Subject: [PATCH 52/59] Enhancement: new external to get all matches plus their bounds of a regex in a string --- .../commons/externals/AspStandardLibrary.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java index 54908ab14..72eb7a467 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java @@ -27,10 +27,9 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -261,4 +260,14 @@ public static Set>> stringHeadRemainder(String str) { return Collections.singleton(xXs); } + @Predicate(name = "regex_matches") + public static Set>> regexMatchesInString(String regex, String str) { + Matcher matcher = Pattern.compile(regex).matcher(str); // Note: This could be done more efficiently by caching patterns. + Set>> result = new LinkedHashSet<>(); + while (matcher.find()) { + result.add(List.of(Terms.newConstant(matcher.group(1)), Terms.newConstant(matcher.start(1)), Terms.newConstant(matcher.end(1)))); + } + return result; + } + } From be6854ec89c336722ee0bf9ec8df8024ec62a860 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sun, 15 Sep 2024 17:32:03 +0200 Subject: [PATCH 53/59] bugfix: permit enum directives in modules --- .../tuwien/kr/alpha/core/parser/ParseTreeVisitor.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index a28df0d9f..0fc248b81 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -71,7 +71,7 @@ public class ParseTreeVisitor extends ASPCore2BaseVisitor { private final Map externals; private final boolean acceptVariables; - private InlineDirectives inlineDirectives; + //private InlineDirectives inlineDirectives; /* * Since verifiers for tests are ASP programs in themselves, we need to parse nested programs. @@ -156,10 +156,11 @@ public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { if (ctx.statements() == null) { return Programs.emptyProgram(); } - inlineDirectives = Programs.newInlineDirectives(); + + //inlineDirectives = Programs.newInlineDirectives(); currentLevelProgramBuilder = Programs.builder(); visitStatements(ctx.statements()); - currentLevelProgramBuilder.addInlineDirectives(inlineDirectives); + //currentLevelProgramBuilder.addInlineDirectives(inlineDirectives); return currentLevelProgramBuilder.build(); } @@ -302,7 +303,9 @@ public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { @Override public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx) { // directive_enumeration : DIRECTIVE_ENUM id DOT; - inlineDirectives.addDirective(InlineDirectives.DIRECTIVE.enum_predicate_is, visitId(ctx.id())); + InlineDirectives directives = Programs.newInlineDirectives(); + directives.addDirective(InlineDirectives.DIRECTIVE.enum_predicate_is, visitId(ctx.id())); + currentLevelProgramBuilder.addInlineDirectives(directives); return null; } From ec18c5eb43c935537ed6080f5146477aa1e741bd Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 28 Sep 2024 14:14:11 +0200 Subject: [PATCH 54/59] enhancement: add newline when writing strings to output stream --- .../core/actions/AbstractActionImplementationProvider.java | 3 +-- .../src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java index c23352dbd..aac6d0504 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/AbstractActionImplementationProvider.java @@ -113,8 +113,7 @@ private ActionResultTerm> outputStreamWriteAction(List) input.get(1)).getObject(); - // TODO this needs some built-in conversion function - byte[] data = str.getBytes(); + byte[] data = (str + "\n").getBytes(); OutputStream dst = dstHandle.getStream(); try { dst.write(data); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java index c954bfb46..cf9d627f7 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ActionsTest.java @@ -48,7 +48,7 @@ public void helloWorld() { Alpha alpha = alphaFactory.buildInstance(new SystemConfig()); InputProgram program = alpha.readProgramString(HELLO_WORLD); alpha.solve(program); - assertEquals("Hello World!", alphaFactory.getActionImplementationMock().getStdoutContent()); + assertEquals("Hello World!\n", alphaFactory.getActionImplementationMock().getStdoutContent()); } @Test @@ -100,7 +100,7 @@ public void writeToFile() { return funcTerm.getTerms().get(0) instanceof ConstantTerm && ((ConstantTerm) funcTerm.getTerms().get(0)).getObject().equals("ok"); }) ).size()); - assertEquals("Foo bar!", dummyFileContent.toString()); + assertEquals("Foo bar!\n", dummyFileContent.toString()); } } From 6ed327dcfc0895adae52eefd9e6ebfef4f2bd767 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 30 Oct 2024 20:16:19 +0100 Subject: [PATCH 55/59] enhancement: use more specific type for action result term --- .../core/actions/ActionExecutionServiceImpl.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java index 4067e2182..408cde90e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.core.actions; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.actions.Action; +import at.ac.tuwien.kr.alpha.api.programs.terms.ActionResultTerm; +import at.ac.tuwien.kr.alpha.api.programs.terms.Term; + import java.util.HashMap; import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.api.programs.terms.Term; -import at.ac.tuwien.kr.alpha.api.programs.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.programs.actions.Action; - public class ActionExecutionServiceImpl implements ActionExecutionService { private final ActionImplementationProvider actionProvider; @@ -18,6 +18,8 @@ public ActionExecutionServiceImpl(ActionImplementationProvider implementationPro this.actionProvider = implementationProvider; } + // TODO possible bug: For two identical rules, the action should only be executed once - test this. + // Note that there may be more answers to this: Formally, a program is a *set* of rules, i.e. duplicate rules are not allowed. @Override public ActionWitness execute(String actionName, int sourceRuleId, Substitution sourceRuleInstance, List inputTerms) { ActionInput actInput = new ActionInput(actionName, sourceRuleId, sourceRuleInstance, inputTerms); @@ -26,7 +28,7 @@ public ActionWitness execute(String actionName, int sourceRuleId, Substitution s private ActionWitness execute(ActionInput input) { Action action = actionProvider.getSupportedActions().get(input.name); - FunctionTerm result = action.execute(input.inputTerms); + ActionResultTerm result = action.execute(input.inputTerms); return new ActionWitness(input.sourceRule, input.instance, input.name, input.inputTerms, result); } From 171d2c8e0d8d585ecd52c409863d683358403ce8 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 30 Oct 2024 20:20:45 +0100 Subject: [PATCH 56/59] enhancement: more specific type for action result in action witness definition --- .../at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java index 265780719..a20e2eab4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionWitness.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.core.actions; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.programs.terms.ActionResultTerm; import at.ac.tuwien.kr.alpha.api.programs.terms.Term; import java.util.List; @@ -11,9 +12,9 @@ public class ActionWitness { private final Substitution groundSubstitution; private final String actionName; private final List actionInput; - private final Term actionResult; + private final ActionResultTerm actionResult; - public ActionWitness(int ruleId, Substitution groundSubstitution, String actionName, List actionInput, Term actionResult) { + public ActionWitness(int ruleId, Substitution groundSubstitution, String actionName, List actionInput, ActionResultTerm actionResult) { this.ruleId = ruleId; this.groundSubstitution = groundSubstitution; this.actionName = actionName; @@ -37,7 +38,7 @@ public List getActionInput() { return actionInput; } - public Term getActionResult() { + public ActionResultTerm getActionResult() { return actionResult; } From 57f6f5deb9e057c043f73da7c131d609f1c5c93f Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sun, 23 Feb 2025 13:05:21 +0100 Subject: [PATCH 57/59] Evolog Actions: Slight enhancements --- .../tuwien/kr/alpha/commons/externals/AspStandardLibrary.java | 2 +- .../alpha/core/actions/DefaultActionImplementationProvider.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java index 72eb7a467..85a935139 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/externals/AspStandardLibrary.java @@ -212,7 +212,7 @@ public static Set>> stringLength(String str) { * Concatenates the two given strings */ @Predicate(name = "stdlib_string_concat") - public static Set>> stringConcat(String s1, String s2) { + public static Set>> stringConcat(String s1, Object s2) { return Collections.singleton(Terms.asTermList(s1 + s2)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java index c6d9a26eb..39a479951 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/DefaultActionImplementationProvider.java @@ -21,7 +21,7 @@ protected InputStream getStdinStream() { @Override protected OutputStream getFileOutputStream(String path) throws IOException { - return Files.newOutputStream(Paths.get(path), StandardOpenOption.APPEND); + return Files.newOutputStream(Paths.get(path), StandardOpenOption.CREATE, StandardOpenOption.APPEND); } @Override From a4005f2e600ba8397ef7b2a9167ce8c2dab01873 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sun, 2 Nov 2025 19:41:55 +0100 Subject: [PATCH 58/59] update version for gradle wrapper validation action --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e9b76d03..8df9c80a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: submodules: recursive fetch-depth: 0 # See https://github.com/marketplace/actions/gradle-wrapper-validation - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@v5 # See https://github.com/marketplace/actions/setup-java-jdk - uses: actions/setup-java@v3 with: From 1ec659d61cf4d413fb0adaa86b9e40af6bca6938 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 22 Nov 2025 12:31:18 +0100 Subject: [PATCH 59/59] #364 add Evolog examples, improve javadoc on action support implementation. --- .../alpha/api/programs/rules/heads/ActionHead.java | 8 ++++++++ .../alpha/core/actions/ActionExecutionService.java | 13 +++++++++++++ .../core/actions/ActionExecutionServiceImpl.java | 2 -- examples/{ => evolog}/greet-me.evl | 0 examples/evolog/hello-world.evl | 2 ++ examples/{ => evolog}/write_something.evl | 0 6 files changed, 23 insertions(+), 2 deletions(-) rename examples/{ => evolog}/greet-me.evl (100%) create mode 100644 examples/evolog/hello-world.evl rename examples/{ => evolog}/write_something.evl (100%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java index 9956ccee8..42919da69 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/rules/heads/ActionHead.java @@ -5,6 +5,14 @@ import java.util.List; +/** + * Rule head implementation representing the head of an Evolog "Action Rule". + * In addition to a regular head atom, an action head encodes an action name (the name of an action function to be called + * when the rule fires) as well as a list input terms to said action function and one variable representing the result + * (i.e. output term) of the action function. + *

+ * Copyright (c) 2024, the Alpha Team. + */ public interface ActionHead extends NormalHead { String getActionName(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java index ef5d8daa6..b1d6f3ada 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionService.java @@ -7,6 +7,19 @@ public interface ActionExecutionService { + /** + * Executes the action with the given name using the provided input terms. + * If the action has been executed before with the same parameters, a cached result is returned. + * The general contract is that an action function is only called once per unique firing ground instance of an action rule + * in order to ensure that, regardless of how often a solver evaluates an action rule, the associated side effect is + * only executed once. + * + * @param actionName the name of the action function to call + * @param sourceRuleId the id of the rule which is fired to cause the action execution + * @param sourceRuleInstance the ground substitution used in firing the source rule + * @param inputTerms the input terms for the action (a subset of substition "sourceRuleInstance") + * @return an ActionWitness wrapping the input to and output of the executed action function. + */ ActionWitness execute(String actionName, int sourceRuleId, Substitution sourceRuleInstance, List inputTerms); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java index 408cde90e..ec37895ae 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/actions/ActionExecutionServiceImpl.java @@ -18,8 +18,6 @@ public ActionExecutionServiceImpl(ActionImplementationProvider implementationPro this.actionProvider = implementationProvider; } - // TODO possible bug: For two identical rules, the action should only be executed once - test this. - // Note that there may be more answers to this: Formally, a program is a *set* of rules, i.e. duplicate rules are not allowed. @Override public ActionWitness execute(String actionName, int sourceRuleId, Substitution sourceRuleInstance, List inputTerms) { ActionInput actInput = new ActionInput(actionName, sourceRuleId, sourceRuleInstance, inputTerms); diff --git a/examples/greet-me.evl b/examples/evolog/greet-me.evl similarity index 100% rename from examples/greet-me.evl rename to examples/evolog/greet-me.evl diff --git a/examples/evolog/hello-world.evl b/examples/evolog/hello-world.evl new file mode 100644 index 000000000..4cede8ed1 --- /dev/null +++ b/examples/evolog/hello-world.evl @@ -0,0 +1,2 @@ +hello_text("Hello World!"). +hello_result(R) : @streamWrite[STDOUT, TEXT] = R :- hello_text(TEXT), &stdout(STDOUT). \ No newline at end of file diff --git a/examples/write_something.evl b/examples/evolog/write_something.evl similarity index 100% rename from examples/write_something.evl rename to examples/evolog/write_something.evl