From fc3ff0d7689c9a105763ac23c07ab24ea021b037 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Tue, 27 Oct 2020 12:29:56 +0100 Subject: [PATCH 001/111] gradle: Introduce submodules --- api/build.gradle | 11 ++ .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 0 .../kr/alpha/api/externals/Externals.java | 0 .../kr/alpha/api/externals/Predicate.java | 0 .../externals/stdlib/AspStandardLibrary.java | 0 .../api/mapper/AnswerSetToObjectMapper.java | 0 .../api/mapper/AnswerSetToWorkbookMapper.java | 0 build.gradle | 121 ------------------ buildSrc/build.gradle | 8 ++ .../alpha.java-application-conventions.gradle | 5 + .../alpha.java-common-conventions.gradle | 59 +++++++++ .../alpha.java-library-conventions.gradle | 5 + cli/build.gradle | 38 ++++++ .../kr/alpha/AnswerSetToXlsxWriter.java | 0 .../main/java/at/ac/tuwien/kr/alpha/Main.java | 0 core/build.gradle | 58 +++++++++ .../tuwien/kr/alpha/CustomErrorListener.java | 0 .../main/java/at/ac/tuwien/kr/alpha/Util.java | 0 .../ac/tuwien/kr/alpha/common/AnswerSet.java | 0 .../kr/alpha/common/AnswerSetBuilder.java | 0 .../kr/alpha/common/AnswerSetFormatter.java | 0 .../ac/tuwien/kr/alpha/common/Assignment.java | 0 .../ac/tuwien/kr/alpha/common/AtomStore.java | 0 .../tuwien/kr/alpha/common/AtomStoreImpl.java | 0 .../kr/alpha/common/BasicAnswerSet.java | 0 .../kr/alpha/common/ComparisonOperator.java | 0 .../tuwien/kr/alpha/common/IntIterator.java | 0 .../ac/tuwien/kr/alpha/common/Interner.java | 0 .../ac/tuwien/kr/alpha/common/Literals.java | 0 .../at/ac/tuwien/kr/alpha/common/NoGood.java | 0 .../kr/alpha/common/NoGoodInterface.java | 0 .../ac/tuwien/kr/alpha/common/Predicate.java | 0 .../common/SimpleAnswerSetFormatter.java | 0 .../at/ac/tuwien/kr/alpha/common/Truth.java | 0 .../kr/alpha/common/atoms/AggregateAtom.java | 0 .../alpha/common/atoms/AggregateLiteral.java | 0 .../ac/tuwien/kr/alpha/common/atoms/Atom.java | 0 .../kr/alpha/common/atoms/BasicAtom.java | 0 .../kr/alpha/common/atoms/BasicLiteral.java | 0 .../kr/alpha/common/atoms/ComparisonAtom.java | 0 .../alpha/common/atoms/ComparisonLiteral.java | 0 .../kr/alpha/common/atoms/ExternalAtom.java | 0 .../alpha/common/atoms/ExternalLiteral.java | 0 .../atoms/FixedInterpretationLiteral.java | 0 .../tuwien/kr/alpha/common/atoms/Literal.java | 0 .../atoms/VariableNormalizableAtom.java | 0 .../alpha/common/depgraph/ComponentGraph.java | 0 .../common/depgraph/DependencyGraph.java | 0 .../depgraph/DepthFirstSearchAlgorithm.java | 0 .../tuwien/kr/alpha/common/depgraph/Edge.java | 0 .../tuwien/kr/alpha/common/depgraph/Node.java | 0 .../depgraph/StratificationAlgorithm.java | 0 .../StronglyConnectedComponentsAlgorithm.java | 0 .../BinaryPredicateInterpretation.java | 0 .../BindingMethodPredicateInterpretation.java | 0 .../BindingPredicateInterpretation.java | 0 .../IntPredicateInterpretation.java | 0 .../LongPredicateInterpretation.java | 0 .../MethodPredicateInterpretation.java | 0 .../NonBindingPredicateInterpretation.java | 0 .../PredicateInterpretation.java | 0 .../SuppliedPredicateInterpretation.java | 0 .../UnaryPredicateInterpretation.java | 0 .../common/graphio/ComponentGraphWriter.java | 0 .../common/graphio/DependencyGraphWriter.java | 0 .../alpha/common/program/AbstractProgram.java | 0 .../alpha/common/program/AnalyzedProgram.java | 0 .../kr/alpha/common/program/InputProgram.java | 0 .../alpha/common/program/InternalProgram.java | 0 .../alpha/common/program/NormalProgram.java | 0 .../kr/alpha/common/program/Programs.java | 0 .../kr/alpha/common/rule/AbstractRule.java | 0 .../kr/alpha/common/rule/BasicRule.java | 0 .../kr/alpha/common/rule/InternalRule.java | 0 .../kr/alpha/common/rule/NormalRule.java | 0 .../kr/alpha/common/rule/head/ChoiceHead.java | 0 .../common/rule/head/DisjunctiveHead.java | 0 .../kr/alpha/common/rule/head/Head.java | 0 .../kr/alpha/common/rule/head/NormalHead.java | 0 .../kr/alpha/common/terms/ArithmeticTerm.java | 0 .../kr/alpha/common/terms/ConstantTerm.java | 0 .../kr/alpha/common/terms/FunctionTerm.java | 0 .../kr/alpha/common/terms/IntervalTerm.java | 0 .../ac/tuwien/kr/alpha/common/terms/Term.java | 0 .../tuwien/kr/alpha/common/terms/Terms.java | 0 .../kr/alpha/common/terms/VariableTerm.java | 0 .../kr/alpha/grounder/AbstractGrounder.java | 0 .../kr/alpha/grounder/BridgedGrounder.java | 0 .../kr/alpha/grounder/ChoiceRecorder.java | 0 .../alpha/grounder/FactIntervalEvaluator.java | 0 .../kr/alpha/grounder/FilteringGrounder.java | 0 .../ac/tuwien/kr/alpha/grounder/Grounder.java | 0 .../kr/alpha/grounder/GrounderFactory.java | 0 .../grounder/IndexedInstanceStorage.java | 0 .../ac/tuwien/kr/alpha/grounder/Instance.java | 0 .../kr/alpha/grounder/IntIdGenerator.java | 0 .../kr/alpha/grounder/NaiveGrounder.java | 0 .../kr/alpha/grounder/NoGoodGenerator.java | 0 .../kr/alpha/grounder/NogoodRegistry.java | 0 .../grounder/ProgramAnalyzingGrounder.java | 0 .../kr/alpha/grounder/RuleGroundingOrder.java | 0 .../alpha/grounder/RuleGroundingOrders.java | 0 .../kr/alpha/grounder/Substitution.java | 0 .../tuwien/kr/alpha/grounder/Unification.java | 0 .../ac/tuwien/kr/alpha/grounder/Unifier.java | 0 .../kr/alpha/grounder/WorkingMemory.java | 0 .../kr/alpha/grounder/atoms/ChoiceAtom.java | 0 .../alpha/grounder/atoms/EnumerationAtom.java | 0 .../grounder/atoms/EnumerationLiteral.java | 0 .../kr/alpha/grounder/atoms/IntervalAtom.java | 0 .../alpha/grounder/atoms/IntervalLiteral.java | 0 .../kr/alpha/grounder/atoms/RuleAtom.java | 0 .../kr/alpha/grounder/bridges/Bridge.java | 0 .../GrounderHeuristicsConfiguration.java | 0 .../AbstractLiteralInstantiationStrategy.java | 0 .../instantiation/AssignmentStatus.java | 0 .../grounder/instantiation/BindingResult.java | 0 ...ultLazyGroundingInstantiationStrategy.java | 0 .../LiteralInstantiationResult.java | 0 .../LiteralInstantiationStrategy.java | 0 .../instantiation/LiteralInstantiator.java | 0 ...rkingMemoryBasedInstantiationStrategy.java | 0 .../grounder/parser/InlineDirectives.java | 0 .../grounder/parser/ParseTreeVisitor.java | 0 .../alpha/grounder/parser/ProgramParser.java | 0 .../grounder/parser/ProgramPartParser.java | 0 .../kr/alpha/grounder/rete/TupleIndex.java | 0 .../kr/alpha/grounder/rete/TupleStore.java | 0 .../structure/AnalyzeUnjustified.java | 0 .../kr/alpha/grounder/structure/LitSet.java | 0 .../CardinalityNormalization.java | 0 .../transformation/ChoiceHeadToNormal.java | 0 .../transformation/EnumerationRewriting.java | 0 .../IntervalTermToIntervalAtom.java | 0 .../NormalizeProgramTransformation.java | 0 .../transformation/PredicateInternalizer.java | 0 .../transformation/ProgramTransformation.java | 0 .../transformation/StratifiedEvaluation.java | 0 .../transformation/SumNormalization.java | 0 .../VariableEqualityRemoval.java | 0 .../kr/alpha/solver/AbstractSolver.java | 0 .../ac/tuwien/kr/alpha/solver/Antecedent.java | 0 .../tuwien/kr/alpha/solver/AtomCounter.java | 0 .../at/ac/tuwien/kr/alpha/solver/Atoms.java | 0 .../BinaryNoGoodPropagationEstimation.java | 0 .../ac/tuwien/kr/alpha/solver/Checkable.java | 0 .../at/ac/tuwien/kr/alpha/solver/Choice.java | 0 .../alpha/solver/ChoiceInfluenceManager.java | 0 .../tuwien/kr/alpha/solver/ChoiceManager.java | 0 .../tuwien/kr/alpha/solver/ConflictCause.java | 0 .../tuwien/kr/alpha/solver/DefaultSolver.java | 0 .../alpha/solver/LearnedNoGoodDeletion.java | 0 .../kr/alpha/solver/NaiveNoGoodStore.java | 0 .../tuwien/kr/alpha/solver/NaiveSolver.java | 0 .../tuwien/kr/alpha/solver/NoGoodCounter.java | 0 .../tuwien/kr/alpha/solver/NoGoodStore.java | 0 .../alpha/solver/NoGoodStoreAlphaRoaming.java | 0 .../kr/alpha/solver/PerformanceLog.java | 0 .../kr/alpha/solver/ShallowAntecedent.java | 0 .../at/ac/tuwien/kr/alpha/solver/Solver.java | 0 .../tuwien/kr/alpha/solver/SolverFactory.java | 0 .../solver/SolverMaintainingStatistics.java | 0 .../tuwien/kr/alpha/solver/ThriceTruth.java | 0 .../kr/alpha/solver/TrailAssignment.java | 0 .../tuwien/kr/alpha/solver/WatchedNoGood.java | 0 .../kr/alpha/solver/WritableAssignment.java | 0 .../ActivityBasedBranchingHeuristic.java | 0 .../heuristics/AlphaActiveRuleHeuristic.java | 0 .../AlphaHeadMustBeTrueHeuristic.java | 0 .../heuristics/AlphaRandomSignHeuristic.java | 0 .../kr/alpha/solver/heuristics/BerkMin.java | 0 .../solver/heuristics/BerkMinLiteral.java | 0 .../solver/heuristics/BranchingHeuristic.java | 0 .../heuristics/BranchingHeuristicFactory.java | 0 .../ChainedBranchingHeuristics.java | 0 .../heuristics/DependencyDrivenHeuristic.java | 0 .../DependencyDrivenPyroHeuristic.java | 0 .../heuristics/DependencyDrivenVSIDS.java | 0 .../GeneralizedDependencyDrivenHeuristic.java | 0 ...eralizedDependencyDrivenPyroHeuristic.java | 0 .../solver/heuristics/HeapOfActiveAtoms.java | 0 .../heuristics/HeapOfActiveChoicePoints.java | 0 .../heuristics/HeuristicsConfiguration.java | 0 .../HeuristicsConfigurationBuilder.java | 0 .../kr/alpha/solver/heuristics/MOMs.java | 0 .../solver/heuristics/NaiveHeuristic.java | 0 .../solver/heuristics/ReplayHeuristic.java | 0 .../kr/alpha/solver/heuristics/VSIDS.java | 0 .../activity/AvgBodyActivityProvider.java | 0 .../activity/BodyActivityProvider.java | 0 .../activity/BodyActivityProviderFactory.java | 0 .../activity/DefaultBodyActivityProvider.java | 0 .../activity/MaxBodyActivityProvider.java | 0 .../activity/MinBodyActivityProvider.java | 0 .../activity/SumBodyActivityProvider.java | 0 .../learning/GroundConflictNoGoodLearner.java | 0 .../solver/learning/ResolutionSequence.java | 0 settings.gradle | 2 + 198 files changed, 186 insertions(+), 121 deletions(-) create mode 100644 api/build.gradle rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java (100%) rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java (100%) rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java (100%) rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java (100%) rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java (100%) rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java (100%) create mode 100644 buildSrc/build.gradle create mode 100644 buildSrc/src/main/groovy/alpha.java-application-conventions.gradle create mode 100644 buildSrc/src/main/groovy/alpha.java-common-conventions.gradle create mode 100644 buildSrc/src/main/groovy/alpha.java-library-conventions.gradle create mode 100644 cli/build.gradle rename {src => cli/src}/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java (100%) rename {src => cli/src}/main/java/at/ac/tuwien/kr/alpha/Main.java (100%) create mode 100644 core/build.gradle rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/Util.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/Interner.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/Literals.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/Truth.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java (100%) rename {src => core/src}/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java (100%) create mode 100644 settings.gradle diff --git a/api/build.gradle b/api/build.gradle new file mode 100644 index 000000000..105ea638a --- /dev/null +++ b/api/build.gradle @@ -0,0 +1,11 @@ +plugins { + id 'alpha.java-library-conventions' +} + +dependencies { + implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7' + implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' + implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' + implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' +} + diff --git a/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java diff --git a/build.gradle b/build.gradle index eb1838701..64084a8f3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,130 +1,9 @@ plugins { - id 'antlr' - id 'application' - id 'checkstyle' - id 'java' id 'jacoco' id 'com.github.kt3k.coveralls' version '2.8.1' } -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -mainClassName = 'at.ac.tuwien.kr.alpha.Main' - -def antlrVersion = '4.7' - -repositories { - mavenCentral() - jcenter() -} - -/* The following configuration directive is a work-around for a fault in the Gradle - * ANTLR plugin. It would require both antlr4 and antlr4-runtime at compile time and - * at run time, which unnecessarily bloats our JARs. Only antlr4-runtime is needed. - * We therefore remove this extension of antlr dependencies being compile dependencies - * and reintroduce them on our own. - */ -configurations { - implementation { - extendsFrom = extendsFrom.findAll { it != configurations.antlr } - } -} - -dependencies { - // We need to give the ANTLR Plugin a hint. - antlr group: 'org.antlr', name: 'antlr4', version: "${antlrVersion}" - - // Re-introduce antlr4-runtime as compile dependency. - implementation group: 'org.antlr', name: 'antlr4-runtime', version: "${antlrVersion}" - - implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7' - implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' - implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.1' - implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.6' - implementation group: 'org.apache.commons', name: 'commons-text', version: '1.8' - implementation group: 'org.reflections', name: 'reflections', version: '0.9.11' - implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' - implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' - - testImplementation group: 'junit', name: 'junit', version: '4.12' -} - -tasks.withType(AntlrTask) { - // See https://github.com/antlr/antlr4/blob/master/doc/tool-options.md - arguments += [ - "-visitor", - "-no-listener", - "-long-messages", - "-package", "at.ac.tuwien.kr.alpha.antlr", - "-Werror", - "-Xlog", - "-lib", "src/main/antlr/at/ac/tuwien/kr/alpha/antlr" - ] -} - -compileJava { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" -} - -compileTestJava { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" -} - -// Fix checkstyle version. -checkstyle { - toolVersion = "7.6" -} - - -task bundledJar(type: Jar) { - manifest { - attributes 'Main-Class': mainClassName - } - - from { - configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } - - archiveFileName = "${project.name}-bundled.jar" - - /* - * In order to make sure we don't overwrite NOTICE and LICENSE files coming from dependency - * jars with each other, number them while copying - */ - int i = 1 - rename { name -> (name.equals("NOTICE.txt") || name.equals("NOTICE")) ? "NOTICE." + (i++) + ".txt" : null } - - int j = 1 - rename { name -> (name.equals("LICENSE.txt") || name.equals("LICENSE")) ? "LICENSE." + (j++) + ".txt" : null } - - with jar -} - -jacocoTestReport { - reports { - xml.enabled = true - html.enabled = true - } - - // NOTE: Contents of the antlr subpackage are autogenerated (see configuration of - // AntlrTasks above). It does not make sense to include them in our coverage - // report. - afterEvaluate { - getClassDirectories().setFrom(files(classDirectories.files.collect { - fileTree(dir: it, exclude: "at/ac/tuwien/kr/alpha/antlr/**") - })) - } -} - -test { - testLogging { - exceptionFormat = 'full' - } - -} - wrapper { gradleVersion = '6.7' distributionType = 'ALL' diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 000000000..93d747dcb --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'groovy-gradle-plugin' +} + +repositories { + gradlePluginPortal() +} + diff --git a/buildSrc/src/main/groovy/alpha.java-application-conventions.gradle b/buildSrc/src/main/groovy/alpha.java-application-conventions.gradle new file mode 100644 index 000000000..96782eb7a --- /dev/null +++ b/buildSrc/src/main/groovy/alpha.java-application-conventions.gradle @@ -0,0 +1,5 @@ +plugins { + id 'alpha.java-common-conventions' + id 'application' +} + diff --git a/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle b/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle new file mode 100644 index 000000000..a8252d569 --- /dev/null +++ b/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle @@ -0,0 +1,59 @@ +plugins { + id 'java' + id 'jacoco' + id 'checkstyle' +} + +repositories { + mavenCentral() + jcenter() +} + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +dependencies { + implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.1' + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3' + implementation group: 'org.apache.commons', name: 'commons-text', version: '1.8' + implementation group: 'org.reflections', name: 'reflections', version: '0.9.11' + implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.20' + + testImplementation group: 'junit', name: 'junit', version: '4.12' + + // JUnit 5 + // testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2' + // testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' +} + +/* JUnit 5 +tasks.named('test') { + useJUnitPlatform() +} +*/ + +test { + testLogging { + exceptionFormat = 'full' + } + +} + +// Fix checkstyle version. +checkstyle { + toolVersion = "7.6" +} + +compileJava { + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" +} + +compileTestJava { + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" +} + +jacocoTestReport { + reports { + xml.enabled = true + } +} diff --git a/buildSrc/src/main/groovy/alpha.java-library-conventions.gradle b/buildSrc/src/main/groovy/alpha.java-library-conventions.gradle new file mode 100644 index 000000000..4ac840e19 --- /dev/null +++ b/buildSrc/src/main/groovy/alpha.java-library-conventions.gradle @@ -0,0 +1,5 @@ +plugins { + id 'alpha.java-common-conventions' + id 'java-library' +} + diff --git a/cli/build.gradle b/cli/build.gradle new file mode 100644 index 000000000..7fdb9058f --- /dev/null +++ b/cli/build.gradle @@ -0,0 +1,38 @@ +plugins { + id 'alpha.java-application-conventions' +} + +dependencies { + implementation project(':core') + implementation project(':api') +} + +def mainClassName = 'at.ac.tuwien.kr.alpha.Main' + +application { + mainClass = mainClassName +} + +task bundledJar(type: Jar) { + manifest { + attributes 'Main-Class': mainClassName + } + + from { + configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } + + archiveFileName = "${project.name}-bundled.jar" + + /* + * In order to make sure we don't overwrite NOTICE and LICENSE files coming from dependency + * jars with each other, number them while copying + */ + int i = 1 + rename { name -> (name.equals("NOTICE.txt") || name.equals("NOTICE")) ? "NOTICE." + (i++) + ".txt" : null } + + int j = 1 + rename { name -> (name.equals("LICENSE.txt") || name.equals("LICENSE")) ? "LICENSE." + (j++) + ".txt" : null } + + with jar +} diff --git a/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java rename to cli/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/Main.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/Main.java rename to cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java diff --git a/core/build.gradle b/core/build.gradle new file mode 100644 index 000000000..65fad3019 --- /dev/null +++ b/core/build.gradle @@ -0,0 +1,58 @@ +plugins { + id 'antlr' + id 'alpha.java-library-conventions' +} + + +def antlrVersion = '4.7' + +/* The following configuration directive is a work-around for a fault in the Gradle + * ANTLR plugin. It would require both antlr4 and antlr4-runtime at compile time and + * at run time, which unnecessarily bloats our JARs. Only antlr4-runtime is needed. + * We therefore remove this extension of antlr dependencies being compile dependencies + * and reintroduce them on our own. + */ +configurations { + implementation { + extendsFrom = extendsFrom.findAll { it != configurations.antlr } + } +} + +dependencies { + api project(':api') + + // We need to give the ANTLR Plugin a hint. + antlr group: 'org.antlr', name: 'antlr4', version: "${antlrVersion}" + + // Re-introduce antlr4-runtime as compile dependency. + implementation group: 'org.antlr', name: 'antlr4-runtime', version: "${antlrVersion}" +} + +tasks.withType(AntlrTask) { + // See https://github.com/antlr/antlr4/blob/master/doc/tool-options.md + arguments += [ + "-visitor", + "-no-listener", + "-long-messages", + "-package", "at.ac.tuwien.kr.alpha.antlr", + "-Werror", + "-Xlog", + "-lib", "src/main/antlr/at/ac/tuwien/kr/alpha/antlr" + ] +} + +jacocoTestReport { + reports { + xml.enabled = true + } + + // NOTE: Contents of the antlr subpackage are autogenerated (see configuration of + // AntlrTasks above). It does not make sense to include them in our coverage + // report. + afterEvaluate { + getClassDirectories().setFrom(files(classDirectories.files.collect { + fileTree(dir: it, exclude: "at/ac/tuwien/kr/alpha/antlr/**") + })) + } +} + diff --git a/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java b/core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/Util.java b/core/src/main/java/at/ac/tuwien/kr/alpha/Util.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/Util.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/Util.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..aafbb5363 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "alpha" +include("api", "cli", "core") From ab5d5bfb870658e6b00c9b084c6cbcc3c1477e9b Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Tue, 27 Oct 2020 13:14:49 +0100 Subject: [PATCH 002/111] core: Move ANTLR sources --- .../src}/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 | 0 .../src}/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {src => core/src}/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 (100%) rename {src => core/src}/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 (100%) diff --git a/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 b/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 similarity index 100% rename from src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 rename to core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 diff --git a/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 b/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 similarity index 100% rename from src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 rename to core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 From f93ab1613040affc1fbf3e29489288edd6958bad Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Tue, 27 Oct 2020 13:15:26 +0100 Subject: [PATCH 003/111] cli: Move resources --- {src => cli/src}/main/resources/logback.xml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src => cli/src}/main/resources/logback.xml (100%) diff --git a/src/main/resources/logback.xml b/cli/src/main/resources/logback.xml similarity index 100% rename from src/main/resources/logback.xml rename to cli/src/main/resources/logback.xml From 89dcda4494ec0001b06e13e7e9a46a7f9c7d9946 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Tue, 27 Oct 2020 15:41:55 +0100 Subject: [PATCH 004/111] git: Ignore */build --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 097f6d161..da0daf5a0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Temporary/Generated Files /out/ +*/build # Created by https://www.gitignore.io/api/java,gradle,eclipse From 1dfa72a2205a84282d66f48078723184318d371d Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Tue, 27 Oct 2020 15:42:14 +0100 Subject: [PATCH 005/111] WIP: Extract interfaces --- .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 224 +- .../api/mapper/AnswerSetToWorkbookMapper.java | 2 +- .../ac/tuwien/kr/alpha/common/AnswerSet.java | 13 + .../ac/tuwien/kr/alpha/common/Predicate.java | 7 + .../ac/tuwien/kr/alpha/common/atoms/Atom.java | 29 + .../tuwien/kr/alpha/common/atoms/Literal.java | 20 + .../BindingPredicateInterpretation.java | 0 .../PredicateInterpretation.java | 2 +- .../kr/alpha/common/program/Program.java | 4 + .../ac/tuwien/kr/alpha/common/rules/Head.java | 4 + .../ac/tuwien/kr/alpha/common/rules/Rule.java | 4 + .../kr/alpha/common/terms/ConstantTerm.java | 4 + .../ac/tuwien/kr/alpha/common/terms/Term.java | 5 + .../tuwien/kr/alpha/config/AlphaConfig.java | 0 .../tuwien/kr/alpha/config/InputConfig.java | 11 +- .../tuwien/kr/alpha/config/SystemConfig.java | 14 +- .../GrounderHeuristicsConfiguration.java | 34 +- ...ryNoGoodPropagationEstimationStrategy.java | 27 + .../kr/alpha/solver/heuristics/Heuristic.java | 52 + ...AlphaJavaApplicationConventionsPlugin.java | 36 + .../AlphaJavaCommonConventionsPlugin.java | 37 + .../AlphaJavaLibraryConventionsPlugin.java | 36 + .../alpha.java-common-conventions.gradle | 2 +- .../alpha.java-library-conventions.gradle | 3 +- cli/build.gradle | 2 + .../main/java/at/ac/tuwien/kr/alpha/Main.java | 5 +- .../kr/alpha/config/CliOptionHandler.java | 0 .../kr/alpha/config/CommandLineParser.java | 6 +- .../kr/alpha/antlr/ASPCore2BaseVisitor.java | 350 +++ .../tuwien/kr/alpha/antlr/ASPCore2Lexer.java | 218 ++ .../tuwien/kr/alpha/antlr/ASPCore2Parser.java | 2632 +++++++++++++++++ .../kr/alpha/antlr/ASPCore2Visitor.java | 319 ++ .../at/ac/tuwien/kr/alpha/antlr/ASPLexer.java | 209 ++ .../java/at/ac/tuwien/kr/alpha/AlphaImpl.java | 226 ++ .../kr/alpha/api/externals/Externals.java | 38 +- .../externals/stdlib/AspStandardLibrary.java | 0 .../ac/tuwien/kr/alpha/common/AnswerSet.java | 34 - .../kr/alpha/common/AnswerSetBuilder.java | 20 +- .../ac/tuwien/kr/alpha/common/AtomStore.java | 5 +- .../tuwien/kr/alpha/common/AtomStoreImpl.java | 5 +- .../kr/alpha/common/BasicAnswerSet.java | 31 +- .../kr/alpha/common/ComparisonOperator.java | 4 +- .../{Predicate.java => PredicateImpl.java} | 18 +- .../common/SimpleAnswerSetFormatter.java | 2 +- .../kr/alpha/common/atoms/AggregateAtom.java | 25 +- .../alpha/common/atoms/AggregateLiteral.java | 4 +- .../common/atoms/{Atom.java => AtomImpl.java} | 63 +- .../kr/alpha/common/atoms/BasicAtom.java | 26 +- .../kr/alpha/common/atoms/BasicLiteral.java | 32 +- .../kr/alpha/common/atoms/ComparisonAtom.java | 23 +- .../alpha/common/atoms/ComparisonLiteral.java | 30 +- .../kr/alpha/common/atoms/ExternalAtom.java | 55 +- .../alpha/common/atoms/ExternalLiteral.java | 66 +- .../atoms/FixedInterpretationLiteral.java | 4 +- .../atoms/{Literal.java => LiteralImpl.java} | 64 +- .../atoms/VariableNormalizableAtom.java | 2 +- .../common/depgraph/DependencyGraph.java | 32 +- .../tuwien/kr/alpha/common/depgraph/Node.java | 8 +- .../BindingMethodPredicateInterpretation.java | 2 +- .../NonBindingPredicateInterpretation.java | 2 +- .../PredicateInterpretationImpl.java | 12 + .../SuppliedPredicateInterpretation.java | 2 +- .../alpha/common/program/AbstractProgram.java | 12 +- .../alpha/common/program/AnalyzedProgram.java | 5 +- .../kr/alpha/common/program/InputProgram.java | 39 +- .../alpha/common/program/InternalProgram.java | 36 +- .../alpha/common/program/NormalProgram.java | 3 +- .../kr/alpha/common/rule/AbstractRule.java | 19 +- .../kr/alpha/common/rule/BasicRule.java | 7 +- .../kr/alpha/common/rule/InternalRule.java | 23 +- .../kr/alpha/common/rule/NormalRule.java | 9 +- .../kr/alpha/common/rule/head/ChoiceHead.java | 9 +- .../kr/alpha/common/rule/head/NormalHead.java | 8 +- .../kr/alpha/common/terms/ArithmeticTerm.java | 40 +- ...onstantTerm.java => ConstantTermImpl.java} | 28 +- .../kr/alpha/common/terms/FunctionTerm.java | 30 +- .../kr/alpha/common/terms/IntervalTerm.java | 14 +- .../common/terms/{Term.java => TermImpl.java} | 17 +- .../tuwien/kr/alpha/common/terms/Terms.java | 6 +- .../kr/alpha/common/terms/VariableTerm.java | 10 +- .../kr/alpha/grounder/AbstractGrounder.java | 6 +- .../kr/alpha/grounder/BridgedGrounder.java | 4 +- .../alpha/grounder/FactIntervalEvaluator.java | 20 +- .../kr/alpha/grounder/FilteringGrounder.java | 6 +- .../kr/alpha/grounder/GrounderFactory.java | 6 +- .../grounder/IndexedInstanceStorage.java | 8 +- .../ac/tuwien/kr/alpha/grounder/Instance.java | 11 +- .../kr/alpha/grounder/NaiveGrounder.java | 131 +- .../kr/alpha/grounder/NoGoodGenerator.java | 23 +- .../kr/alpha/grounder/RuleGroundingOrder.java | 7 +- .../alpha/grounder/RuleGroundingOrders.java | 35 +- .../kr/alpha/grounder/Substitution.java | 26 +- .../tuwien/kr/alpha/grounder/Unification.java | 23 +- .../ac/tuwien/kr/alpha/grounder/Unifier.java | 7 +- .../kr/alpha/grounder/WorkingMemory.java | 14 +- .../kr/alpha/grounder/atoms/ChoiceAtom.java | 22 +- .../alpha/grounder/atoms/EnumerationAtom.java | 4 +- .../kr/alpha/grounder/atoms/IntervalAtom.java | 14 +- .../kr/alpha/grounder/atoms/RuleAtom.java | 21 +- .../AbstractLiteralInstantiationStrategy.java | 12 +- ...ultLazyGroundingInstantiationStrategy.java | 27 +- .../LiteralInstantiationResult.java | 3 +- .../LiteralInstantiationStrategy.java | 5 +- .../instantiation/LiteralInstantiator.java | 62 +- ...rkingMemoryBasedInstantiationStrategy.java | 3 +- .../grounder/parser/ParseTreeVisitor.java | 120 +- .../grounder/parser/ProgramPartParser.java | 6 +- .../structure/AnalyzeUnjustified.java | 105 +- .../kr/alpha/grounder/structure/LitSet.java | 17 +- .../CardinalityNormalization.java | 9 +- .../transformation/ChoiceHeadToNormal.java | 28 +- .../transformation/EnumerationRewriting.java | 8 +- .../IntervalTermToIntervalAtom.java | 19 +- .../transformation/PredicateInternalizer.java | 16 +- .../transformation/StratifiedEvaluation.java | 22 +- .../VariableEqualityRemoval.java | 17 +- .../tuwien/kr/alpha/solver/AtomCounter.java | 5 +- .../BinaryNoGoodPropagationEstimation.java | 36 +- .../tuwien/kr/alpha/solver/DefaultSolver.java | 14 +- .../alpha/solver/NoGoodStoreAlphaRoaming.java | 2 +- .../heuristics/BranchingHeuristicFactory.java | 48 - .../heuristics/DependencyDrivenVSIDS.java | 6 +- .../solver/heuristics/HeapOfActiveAtoms.java | 3 +- .../heuristics/HeuristicsConfiguration.java | 11 +- .../HeuristicsConfigurationBuilder.java | 7 +- .../kr/alpha/solver/heuristics/MOMs.java | 12 +- .../kr/alpha/solver/heuristics/VSIDS.java | 8 +- 127 files changed, 5166 insertions(+), 1314 deletions(-) create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java rename {core => api}/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java (100%) rename {core => api}/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java (96%) create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java (100%) rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java (95%) rename {src => api/src}/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java (93%) rename {core => api}/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java (95%) create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java create mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java create mode 100644 buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaApplicationConventionsPlugin.java create mode 100644 buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaCommonConventionsPlugin.java create mode 100644 buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaLibraryConventionsPlugin.java rename {src => cli/src}/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java (100%) rename {src => cli/src}/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java (99%) create mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java create mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java create mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java create mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java create mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java create mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java rename {api => core}/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java (82%) rename {api => core}/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java (100%) delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java rename core/src/main/java/at/ac/tuwien/kr/alpha/common/{Predicate.java => PredicateImpl.java} (73%) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/{Atom.java => AtomImpl.java} (74%) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/{Literal.java => LiteralImpl.java} (78%) create mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java rename core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/{ConstantTerm.java => ConstantTermImpl.java} (75%) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/{Term.java => TermImpl.java} (83%) diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java index 6a40b6a6c..a267fc6f4 100644 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java @@ -1,226 +1,4 @@ -/** - * 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. - * - * 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.api; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.grounder.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation; -import at.ac.tuwien.kr.alpha.solver.Solver; -import at.ac.tuwien.kr.alpha.solver.SolverFactory; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.charset.CodingErrorAction; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class Alpha { - - private static final Logger LOGGER = LoggerFactory.getLogger(Alpha.class); - - private SystemConfig config = new SystemConfig(); // The config is initialized with default values. - - public Alpha(SystemConfig cfg) { - this.config = cfg; - } - - public Alpha() { - } - - public InputProgram readProgram(InputConfig cfg) throws IOException { - InputProgram.Builder prgBuilder = InputProgram.builder(); - InputProgram tmpProg; - if (!cfg.getFiles().isEmpty()) { - tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); - prgBuilder.accumulate(tmpProg); - } - if (!cfg.getAspStrings().isEmpty()) { - tmpProg = readProgramString(StringUtils.join(cfg.getAspStrings(), System.lineSeparator()), cfg.getPredicateMethods()); - prgBuilder.accumulate(tmpProg); - } - return prgBuilder.build(); - } - - 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[] {})); - } - - public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - ProgramParser parser = new ProgramParser(externals); - InputProgram.Builder prgBuilder = InputProgram.builder(); - InputProgram tmpProg; - for (Path path : paths) { - CharStream stream; - if (!literate) { - stream = CharStreams.fromPath(path); - } else { - stream = CharStreams.fromChannel(Util.streamToChannel(Util.literate(Files.lines(path))), 4096, CodingErrorAction.REPLACE, path.toString()); - } - tmpProg = parser.parse(stream); - prgBuilder.accumulate(tmpProg); - } - return prgBuilder.build(); - } - - public InputProgram readProgramString(String aspString, Map externals) { - ProgramParser parser = new ProgramParser(externals); - return parser.parse(aspString); - } - - public InputProgram readProgramString(String aspString) { - return readProgramString(aspString, null); - } - - public NormalProgram normalizeProgram(InputProgram program) { - return new NormalizeProgramTransformation(config.isUseNormalizationGrid()).apply(program); - } - - public InternalProgram performProgramPreprocessing(InternalProgram program) { - LOGGER.debug("Preprocessing InternalProgram!"); - InternalProgram retVal = program; - if (config.isEvaluateStratifiedPart()) { - AnalyzedProgram analyzed = new AnalyzedProgram(program.getRules(), program.getFacts()); - retVal = new StratifiedEvaluation().apply(analyzed); - } - return retVal; - } - - public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { - LOGGER.debug("Preprocessing AnalyzedProgram!"); - InternalProgram retVal = program; - if (config.isEvaluateStratifiedPart()) { - retVal = new StratifiedEvaluation().apply(program); - } - return retVal; - } - - /** - * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the - * program analysis and normalization aren't of interest. - */ - public Stream solve(InputProgram program) { - return solve(program, InputConfig.DEFAULT_FILTER); - } - - /** - * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where - * details of the program analysis and normalization aren't of interest. - */ - public Stream solve(InputProgram program, java.util.function.Predicate filter) { - NormalProgram normalized = normalizeProgram(program); - return solve(normalized, filter); - } - - /** - * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the - * program analysis aren't of interest. - */ - public Stream solve(NormalProgram program, java.util.function.Predicate filter) { - InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); - return solve(preprocessed, filter); - } - - /** - * Overloaded version of solve({@link InternalProgram}, {@link Predicate}) that uses a default filter (accept - * everything). - * - * @param program the program to solve - * @return a stream of answer sets - */ - public Stream solve(InternalProgram program) { - return solve(program, InputConfig.DEFAULT_FILTER); - } - - /** - * 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 - * @return a Stream of answer sets representing stable models of the given program - */ - public Stream solve(InternalProgram program, java.util.function.Predicate filter) { - Stream retVal = prepareSolverFor(program, filter).stream(); - return config.isSortAnswerSets() ? retVal.sorted() : retVal; - } - - /** - * 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. - * @return a solver (and accompanying grounder) instance pre-loaded with the given program. - */ - public Solver prepareSolverFor(InternalProgram 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 SystemConfig getConfig() { - return config; - } - - public void setConfig(SystemConfig config) { - this.config = config; - } - +public interface Alpha { } diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java index 0f6499728..4b7af303a 100644 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java @@ -95,7 +95,7 @@ private void writeAtomToSheet(Sheet sheet, Atom atom) { rownum = sheet.getLastRowNum() + 1; } Row atomRow = sheet.createRow(rownum); - List terms = atom.getTerms(); + List terms = atom.getTerms(); Cell currCell; if (terms.isEmpty()) { // 0-arity atom diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java new file mode 100644 index 000000000..11c98b9e6 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java @@ -0,0 +1,13 @@ +package at.ac.tuwien.kr.alpha.common; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; + +import java.util.SortedSet; + +public interface AnswerSet extends Comparable { + SortedSet getPredicates(); + + SortedSet getPredicateInstances(Predicate predicate); + + boolean isEmpty(); +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java new file mode 100644 index 000000000..28d5811e4 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java @@ -0,0 +1,7 @@ +package at.ac.tuwien.kr.alpha.common; + +public interface Predicate extends Comparable { + String getName(); + + int getArity(); +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java new file mode 100644 index 000000000..41bf3da32 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java @@ -0,0 +1,29 @@ +package at.ac.tuwien.kr.alpha.common.atoms; + +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; + +public interface Atom extends Comparable { + Predicate getPredicate(); + + List getTerms(); + + /** + * Returns whether this atom is ground, i.e., variable-free. + * + * @return true iff the terms of this atom contain no {@link VariableTerm}. + */ + boolean isGround(); + + Literal toLiteral(); + + /** + * Creates a literal containing this atom which will be negated if {@code positive} is {@code false}. + * + * @param positive the polarity of the resulting literal. + * @return a literal that is positive iff the given parameter is true. + */ + Literal toLiteral(boolean positive); +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java new file mode 100644 index 000000000..12b583fd2 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java @@ -0,0 +1,20 @@ +package at.ac.tuwien.kr.alpha.common.atoms; + +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; + +public interface Literal { + Atom getAtom(); + + boolean isNegated(); + + Literal negate(); + + Predicate getPredicate(); + + List getTerms(); + + boolean isGround(); +} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java similarity index 100% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java similarity index 96% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java index 337dbc372..96f454b8e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java @@ -42,5 +42,5 @@ public interface PredicateInterpretation { 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/api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java new file mode 100644 index 000000000..4327a4c0e --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.program; + +public interface Program { +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java new file mode 100644 index 000000000..0b16a5ecf --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.rules; + +public interface Head { +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java new file mode 100644 index 000000000..35778c7fb --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.rules; + +public interface Rule { +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java new file mode 100644 index 000000000..795680347 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +public interface ConstantTerm> { +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java new file mode 100644 index 000000000..9aae02494 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +public interface Term extends Comparable { + boolean isGround(); +} diff --git a/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java b/api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java b/api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java similarity index 95% rename from src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java index 3459af103..12e5d3167 100644 --- a/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java @@ -1,14 +1,9 @@ package at.ac.tuwien.kr.alpha.config; -import at.ac.tuwien.kr.alpha.api.externals.Externals; import at.ac.tuwien.kr.alpha.common.Predicate; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class InputConfig { @@ -36,8 +31,8 @@ public class InputConfig { private String compgraphPath = InputConfig.DEFAULT_COMPGRAPH_TARGET_FILE; private boolean writePreprocessed = InputConfig.DEFAULT_WRITE_PREPROCESSED_PROG; private String preprocessedPath = InputConfig.DEFAULT_PREPROC_TARGET_FILE; - // standard library externals are always loaded - private Map predicateMethods = Externals.getStandardLibraryExternals(); + // TODO: standard library externals are NOT always loaded, but this was the case before introducing modules + private Map predicateMethods = new HashMap<>(); // Externals.getStandardLibraryExternals(); private boolean writeAnswerSetsAsXlsx = InputConfig.DEFAULT_WRITE_XLSX; private String answerSetFileOutputPath; diff --git a/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java b/api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java similarity index 93% rename from src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java index 44071a47a..4f38c37ba 100644 --- a/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java @@ -28,8 +28,8 @@ package at.ac.tuwien.kr.alpha.config; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; import java.util.Arrays; import java.util.Collections; @@ -46,7 +46,7 @@ public class SystemConfig { 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 BinaryNoGoodPropagationEstimation.Strategy DEFAULT_MOMS_STRATEGY = BinaryNoGoodPropagationEstimation.Strategy.CountBinaryWatches; + 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; @@ -70,7 +70,7 @@ public class SystemConfig { private long seed = SystemConfig.DEFAULT_SEED; private boolean debugInternalChecks = SystemConfig.DEFAULT_DEBUG_INTERNAL_CHECKS; private Heuristic branchingHeuristic = SystemConfig.DEFAULT_BRANCHING_HEURISTIC; - private BinaryNoGoodPropagationEstimation.Strategy momsStrategy = SystemConfig.DEFAULT_MOMS_STRATEGY; + private BinaryNoGoodPropagationEstimationStrategy momsStrategy = SystemConfig.DEFAULT_MOMS_STRATEGY; private boolean quiet = SystemConfig.DEFAULT_QUIET; private boolean printStats = SystemConfig.DEFAULT_PRINT_STATS; private boolean disableJustificationSearch = SystemConfig.DEFAULT_DISABLE_JUSTIFICATION_SEARCH; @@ -144,16 +144,16 @@ public void setBranchingHeuristicName(String branchingHeuristicName) { this.branchingHeuristic = Heuristic.valueOf(branchingHeuristicName.replace("-", "_").toUpperCase()); } - public BinaryNoGoodPropagationEstimation.Strategy getMomsStrategy() { + public BinaryNoGoodPropagationEstimationStrategy getMomsStrategy() { return momsStrategy; } - public void setMomsStrategy(BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + public void setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { this.momsStrategy = momsStrategy; } public void setMomsStrategyName(String momsStrategyName) { - this.momsStrategy = BinaryNoGoodPropagationEstimation.Strategy.valueOf(momsStrategyName); + this.momsStrategy = BinaryNoGoodPropagationEstimationStrategy.valueOf(momsStrategyName); } public boolean isQuiet() { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java b/api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java similarity index 95% rename from core/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java rename to api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java index 5b501c2cc..9348af476 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java @@ -1,17 +1,17 @@ /** * Copyright (c) 2019 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. - * + * 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 @@ -25,11 +25,9 @@ */ package at.ac.tuwien.kr.alpha.grounder.heuristics; -import at.ac.tuwien.kr.alpha.grounder.Grounder; - /** - * Contains configuration parameters for heuristics used by {@link Grounder}s. - * + * Contains configuration parameters for heuristics used by {@link at.ac.tuwien.kr.alpha.grounder.Grounder}s. + * * Both parameters {@link #toleranceConstraints} and {@link #toleranceRules} are interpreted as follows: * A rule (or constraint) is grounded if the following conditions are satisfied: *

    @@ -41,7 +39,7 @@ * being a fact, because the alternative would necessitate triggering re-grounding during backtracking.) *
  • At most {@code N} atoms occurring positively in the body are still unassigned.
  • *
- * + * * The parameter {@link #toleranceConstraints} specifies {@code N} for constraints, while {@link #toleranceRules} * specifies {@code N} for all other rules. Infinity is represented by the value {@code -1}. * The default value for both parameters is {@code 0}, which means that only those rules and constraints are @@ -57,17 +55,17 @@ public class GrounderHeuristicsConfiguration { public static final int STRICT_INT = 0; public static final String PERMISSIVE_STRING = "permissive"; public static final int PERMISSIVE_INT = -1; - + private int toleranceConstraints; private int toleranceRules; private boolean accumulatorEnabled; - + public GrounderHeuristicsConfiguration() { super(); this.toleranceConstraints = STRICT_INT; this.toleranceRules = STRICT_INT; } - + /** * @param toleranceConstraints * @param toleranceRules @@ -119,11 +117,11 @@ public void setAccumulatorEnabled(boolean accumulatorEnabled) { public static GrounderHeuristicsConfiguration strict() { return new GrounderHeuristicsConfiguration(STRICT_INT, STRICT_INT); } - + public static GrounderHeuristicsConfiguration permissive() { return new GrounderHeuristicsConfiguration(PERMISSIVE_INT, PERMISSIVE_INT); } - + public static GrounderHeuristicsConfiguration getInstance(int toleranceConstraints, int toleranceRules) { return new GrounderHeuristicsConfiguration(toleranceConstraints, toleranceRules); } @@ -141,7 +139,7 @@ private static int parseTolerance(String tolerance) { return Integer.parseInt(tolerance); } } - + @Override public String toString() { return this.getClass().getSimpleName() + "(toleranceConstraints=" + toleranceConstraints + ",toleranceRules=" + toleranceRules + ",disableInstanceRemoval=" + accumulatorEnabled + ")"; diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java b/api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java new file mode 100644 index 000000000..bf3ad5242 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java @@ -0,0 +1,27 @@ +package at.ac.tuwien.kr.alpha.solver; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * Strategies to estimate the amount of influence of a literal. + */ +public enum BinaryNoGoodPropagationEstimationStrategy { + /** + * Counts binary watches involving the literal under consideration + */ + CountBinaryWatches, + + /** + * Assigns true to the literal under consideration, then does propagation only on binary nogoods + * and counts how many other atoms are assigned during this process, then backtracks + */ + BinaryNoGoodPropagation; + + /** + * @return a comma-separated list of names of known heuristics + */ + public static String listAllowedValues() { + return Arrays.stream(values()).map(BinaryNoGoodPropagationEstimationStrategy::toString).collect(Collectors.joining(", ")); + } +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java b/api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java new file mode 100644 index 000000000..f9aa16953 --- /dev/null +++ b/api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java @@ -0,0 +1,52 @@ +package at.ac.tuwien.kr.alpha.solver.heuristics; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * The available domain-independent heuristics. + * Some are deprecated because they perform poorly and have not been improved for some time, + * however the code is kept for now so that it stays compatible when interfaces are refactored. + */ +public enum Heuristic { + NAIVE, + BERKMIN, + BERKMINLITERAL, + @Deprecated + DD, + @Deprecated + DD_SUM, + @Deprecated + DD_AVG, + @Deprecated + DD_MAX, + @Deprecated + DD_MIN, + @Deprecated + DD_PYRO, + @Deprecated + GDD, + @Deprecated + GDD_SUM, + @Deprecated + GDD_AVG, + @Deprecated + GDD_MAX, + @Deprecated + GDD_MIN, + @Deprecated + GDD_PYRO, + @Deprecated + ALPHA_ACTIVE_RULE, + @Deprecated + ALPHA_HEAD_MBT, + VSIDS, + GDD_VSIDS; + + /** + * @return a comma-separated list of names of known heuristics + */ + public static String listAllowedValues() { + return Arrays.stream(values()).map(Heuristic::toString).collect(Collectors.joining(", ")); + } +} diff --git a/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaApplicationConventionsPlugin.java b/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaApplicationConventionsPlugin.java new file mode 100644 index 000000000..9b59efd2e --- /dev/null +++ b/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaApplicationConventionsPlugin.java @@ -0,0 +1,36 @@ +//CHECKSTYLE:OFF +import org.gradle.util.GradleVersion; +import org.gradle.groovy.scripts.BasicScript; +import org.gradle.groovy.scripts.ScriptSource; +import org.gradle.groovy.scripts.TextResourceScriptSource; +import org.gradle.internal.resource.StringTextResource; +/** + * Precompiled alpha.java-application-conventions script plugin. + **/ +public class AlphaJavaApplicationConventionsPlugin implements org.gradle.api.Plugin { + private static final String MIN_SUPPORTED_GRADLE_VERSION = "5.0"; + public void apply(org.gradle.api.internal.project.ProjectInternal target) { + assertSupportedByCurrentGradleVersion(); + target.getPluginManager().apply("alpha.java-common-conventions"); + target.getPluginManager().apply("application"); + + try { + Class precompiledScriptClass = Class.forName("precompiled_AlphaJavaApplicationConventions").asSubclass(BasicScript.class); + BasicScript script = precompiledScriptClass.getDeclaredConstructor().newInstance(); + script.setScriptSource(scriptSource(precompiledScriptClass)); + script.init(target, target.getServices()); + script.run(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + private static ScriptSource scriptSource(Class scriptClass) { + return new TextResourceScriptSource(new StringTextResource(scriptClass.getSimpleName(), "")); + } + private static void assertSupportedByCurrentGradleVersion() { + if (GradleVersion.current().getBaseVersion().compareTo(GradleVersion.version(MIN_SUPPORTED_GRADLE_VERSION)) < 0) { + throw new RuntimeException("Precompiled Groovy script plugins require Gradle "+MIN_SUPPORTED_GRADLE_VERSION+" or higher"); + } + } +} +//CHECKSTYLE:ON diff --git a/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaCommonConventionsPlugin.java b/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaCommonConventionsPlugin.java new file mode 100644 index 000000000..8d9bff142 --- /dev/null +++ b/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaCommonConventionsPlugin.java @@ -0,0 +1,37 @@ +//CHECKSTYLE:OFF +import org.gradle.util.GradleVersion; +import org.gradle.groovy.scripts.BasicScript; +import org.gradle.groovy.scripts.ScriptSource; +import org.gradle.groovy.scripts.TextResourceScriptSource; +import org.gradle.internal.resource.StringTextResource; +/** + * Precompiled alpha.java-common-conventions script plugin. + **/ +public class AlphaJavaCommonConventionsPlugin implements org.gradle.api.Plugin { + private static final String MIN_SUPPORTED_GRADLE_VERSION = "5.0"; + public void apply(org.gradle.api.internal.project.ProjectInternal target) { + assertSupportedByCurrentGradleVersion(); + target.getPluginManager().apply("java"); + target.getPluginManager().apply("jacoco"); + target.getPluginManager().apply("checkstyle"); + + try { + Class precompiledScriptClass = Class.forName("precompiled_AlphaJavaCommonConventions").asSubclass(BasicScript.class); + BasicScript script = precompiledScriptClass.getDeclaredConstructor().newInstance(); + script.setScriptSource(scriptSource(precompiledScriptClass)); + script.init(target, target.getServices()); + script.run(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + private static ScriptSource scriptSource(Class scriptClass) { + return new TextResourceScriptSource(new StringTextResource(scriptClass.getSimpleName(), "")); + } + private static void assertSupportedByCurrentGradleVersion() { + if (GradleVersion.current().getBaseVersion().compareTo(GradleVersion.version(MIN_SUPPORTED_GRADLE_VERSION)) < 0) { + throw new RuntimeException("Precompiled Groovy script plugins require Gradle "+MIN_SUPPORTED_GRADLE_VERSION+" or higher"); + } + } +} +//CHECKSTYLE:ON diff --git a/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaLibraryConventionsPlugin.java b/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaLibraryConventionsPlugin.java new file mode 100644 index 000000000..5eb74ded6 --- /dev/null +++ b/buildSrc/build/groovy-dsl-plugins/output/adapter-src/AlphaJavaLibraryConventionsPlugin.java @@ -0,0 +1,36 @@ +//CHECKSTYLE:OFF +import org.gradle.util.GradleVersion; +import org.gradle.groovy.scripts.BasicScript; +import org.gradle.groovy.scripts.ScriptSource; +import org.gradle.groovy.scripts.TextResourceScriptSource; +import org.gradle.internal.resource.StringTextResource; +/** + * Precompiled alpha.java-library-conventions script plugin. + **/ +public class AlphaJavaLibraryConventionsPlugin implements org.gradle.api.Plugin { + private static final String MIN_SUPPORTED_GRADLE_VERSION = "5.0"; + public void apply(org.gradle.api.internal.project.ProjectInternal target) { + assertSupportedByCurrentGradleVersion(); + target.getPluginManager().apply("alpha.java-common-conventions"); + target.getPluginManager().apply("java-library"); + + try { + Class precompiledScriptClass = Class.forName("precompiled_AlphaJavaLibraryConventions").asSubclass(BasicScript.class); + BasicScript script = precompiledScriptClass.getDeclaredConstructor().newInstance(); + script.setScriptSource(scriptSource(precompiledScriptClass)); + script.init(target, target.getServices()); + script.run(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + private static ScriptSource scriptSource(Class scriptClass) { + return new TextResourceScriptSource(new StringTextResource(scriptClass.getSimpleName(), "")); + } + private static void assertSupportedByCurrentGradleVersion() { + if (GradleVersion.current().getBaseVersion().compareTo(GradleVersion.version(MIN_SUPPORTED_GRADLE_VERSION)) < 0) { + throw new RuntimeException("Precompiled Groovy script plugins require Gradle "+MIN_SUPPORTED_GRADLE_VERSION+" or higher"); + } + } +} +//CHECKSTYLE:ON diff --git a/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle b/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle index a8252d569..e8efe3857 100644 --- a/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle +++ b/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle @@ -45,7 +45,7 @@ checkstyle { } compileJava { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-Xmaxerrs" << "1000" } compileTestJava { diff --git a/buildSrc/src/main/groovy/alpha.java-library-conventions.gradle b/buildSrc/src/main/groovy/alpha.java-library-conventions.gradle index 4ac840e19..34fded8ac 100644 --- a/buildSrc/src/main/groovy/alpha.java-library-conventions.gradle +++ b/buildSrc/src/main/groovy/alpha.java-library-conventions.gradle @@ -1,5 +1,4 @@ plugins { id 'alpha.java-common-conventions' id 'java-library' -} - +} \ No newline at end of file diff --git a/cli/build.gradle b/cli/build.gradle index 7fdb9058f..a89bb1994 100644 --- a/cli/build.gradle +++ b/cli/build.gradle @@ -5,6 +5,8 @@ plugins { dependencies { implementation project(':core') implementation project(':api') + + implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' } def mainClassName = 'at.ac.tuwien.kr.alpha.Main' diff --git a/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java index bcc79c8e9..da7d22a12 100644 --- a/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java +++ b/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java @@ -27,7 +27,6 @@ */ package at.ac.tuwien.kr.alpha; -import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.common.AnswerSet; import at.ac.tuwien.kr.alpha.common.AnswerSetFormatter; import at.ac.tuwien.kr.alpha.common.SimpleAnswerSetFormatter; @@ -79,7 +78,7 @@ public static void main(String[] args) { Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); } - Alpha alpha = new Alpha(cfg.getSystemConfig()); + AlphaImpl alpha = new AlphaImpl(cfg.getSystemConfig()); InputProgram program = null; try { @@ -171,7 +170,7 @@ private static void writeInternalProgram(InternalProgram prg, String path) { } } - private static void computeAndConsumeAnswerSets(Alpha alpha, InputConfig inputCfg, InternalProgram program) { + private static void computeAndConsumeAnswerSets(AlphaImpl alpha, InputConfig inputCfg, InternalProgram program) { Solver solver = alpha.prepareSolverFor(program, inputCfg.getFilter()); Stream stream = solver.stream(); if (alpha.getConfig().isSortAnswerSets()) { diff --git a/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java similarity index 100% rename from src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java rename to cli/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java diff --git a/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java similarity index 99% rename from src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java rename to cli/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java index b709c02b5..dca1d5d90 100644 --- a/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java +++ b/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java @@ -27,8 +27,8 @@ */ package at.ac.tuwien.kr.alpha.config; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; @@ -396,7 +396,7 @@ private void handleMomsStrategy(Option opt, SystemConfig cfg) throws ParseExcept cfg.setMomsStrategyName(momsStrategyName); } catch (IllegalArgumentException e) { throw new ParseException("Unknown mom's strategy: " + momsStrategyName + ". Please try one of the following: " - + BinaryNoGoodPropagationEstimation.Strategy.listAllowedValues()); + + BinaryNoGoodPropagationEstimationStrategy.listAllowedValues()); } } diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java new file mode 100644 index 000000000..2a6ff3bbb --- /dev/null +++ b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java @@ -0,0 +1,350 @@ +// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 +package at.ac.tuwien.kr.alpha.antlr; +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link ASPCore2Visitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public class ASPCore2BaseVisitor extends AbstractParseTreeVisitor implements ASPCore2Visitor { + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitProgram(ASPCore2Parser.ProgramContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStatements(ASPCore2Parser.StatementsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitQuery(ASPCore2Parser.QueryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStatement_rule(ASPCore2Parser.Statement_ruleContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStatement_weightConstraint(ASPCore2Parser.Statement_weightConstraintContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStatement_directive(ASPCore2Parser.Statement_directiveContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitHead(ASPCore2Parser.HeadContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitBody(ASPCore2Parser.BodyContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitChoice(ASPCore2Parser.ChoiceContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAggregate(ASPCore2Parser.AggregateContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAggregate_elements(ASPCore2Parser.Aggregate_elementsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAggregate_function(ASPCore2Parser.Aggregate_functionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitWeight_at_level(ASPCore2Parser.Weight_at_levelContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitClassical_literal(ASPCore2Parser.Classical_literalContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitBinop(ASPCore2Parser.BinopContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerms(ASPCore2Parser.TermsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_const(ASPCore2Parser.Term_constContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_variable(ASPCore2Parser.Term_variableContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTerm_parenthesisedTerm(ASPCore2Parser.Term_parenthesisedTermContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInterval(ASPCore2Parser.IntervalContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExternal_atom(ASPCore2Parser.External_atomContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDirective(ASPCore2Parser.DirectiveContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitGround_term(ASPCore2Parser.Ground_termContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { return visitChildren(ctx); } +} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java new file mode 100644 index 000000000..f4de95f3f --- /dev/null +++ b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java @@ -0,0 +1,218 @@ +// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 +package at.ac.tuwien.kr.alpha.antlr; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class ASPCore2Lexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, ANONYMOUS_VARIABLE=2, DOT=3, COMMA=4, QUERY_MARK=5, COLON=6, SEMICOLON=7, + OR=8, NAF=9, CONS=10, WCONS=11, PLUS=12, MINUS=13, TIMES=14, DIV=15, POWER=16, + MODULO=17, BITXOR=18, AT=19, SHARP=20, AMPERSAND=21, QUOTE=22, PAREN_OPEN=23, + PAREN_CLOSE=24, SQUARE_OPEN=25, SQUARE_CLOSE=26, CURLY_OPEN=27, CURLY_CLOSE=28, + EQUAL=29, UNEQUAL=30, LESS=31, GREATER=32, LESS_OR_EQ=33, GREATER_OR_EQ=34, + AGGREGATE_COUNT=35, AGGREGATE_MAX=36, AGGREGATE_MIN=37, AGGREGATE_SUM=38, + ID=39, VARIABLE=40, NUMBER=41, QUOTED_STRING=42, COMMENT=43, MULTI_LINE_COMMEN=44, + BLANK=45; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + public static final String[] ruleNames = { + "T__0", "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", "SEMICOLON", + "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", "POWER", + "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", + "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", + "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", + "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", + "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", + "BLANK" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'enumeration_predicate_is'", "'_'", "'.'", "','", "'?'", "':'", + "';'", "'|'", "'not'", "':-'", "':~'", "'+'", "'-'", "'*'", "'/'", "'**'", + "'\\'", "'^'", "'@'", "'#'", "'&'", "'\"'", "'('", "')'", "'['", "']'", + "'{'", "'}'", "'='", null, "'<'", "'>'", "'<='", "'>='", "'#count'", "'#max'", + "'#min'", "'#sum'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, null, "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", + "SEMICOLON", "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", + "POWER", "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", + "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", + "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", + "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", + "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", + "BLANK" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public ASPCore2Lexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "ASPCore2.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2/\u011a\b\1\4\2\t"+ + "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ + "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ + ",\t,\4-\t-\4.\t.\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3"+ + "\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5"+ + "\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3"+ + "\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\21\3\22\3\22"+ + "\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31"+ + "\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\37\3\37\3\37\3\37"+ + "\5\37\u00b8\n\37\3 \3 \3!\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3$\3$\3$\3"+ + "$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3(\3(\7(\u00dc\n("+ + "\f(\16(\u00df\13(\3)\3)\7)\u00e3\n)\f)\16)\u00e6\13)\3*\3*\3*\7*\u00eb"+ + "\n*\f*\16*\u00ee\13*\5*\u00f0\n*\3+\3+\3+\3+\7+\u00f6\n+\f+\16+\u00f9"+ + "\13+\3+\3+\3,\3,\7,\u00ff\n,\f,\16,\u0102\13,\3,\3,\3-\3-\3-\3-\7-\u010a"+ + "\n-\f-\16-\u010d\13-\3-\3-\3-\3-\3-\3.\6.\u0115\n.\r.\16.\u0116\3.\3."+ + "\4\u00f7\u010b\2/\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31"+ + "\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65"+ + "\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/\3\2\5\6\2\62;C\\a"+ + "ac|\4\2\f\f\17\17\5\2\13\f\16\17\"\"\2\u0123\2\3\3\2\2\2\2\5\3\2\2\2\2"+ + "\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2"+ + "\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2"+ + "\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2"+ + "\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2"+ + "\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2"+ + "\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2"+ + "M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3"+ + "\2\2\2\2[\3\2\2\2\3]\3\2\2\2\5v\3\2\2\2\7x\3\2\2\2\tz\3\2\2\2\13|\3\2"+ + "\2\2\r~\3\2\2\2\17\u0080\3\2\2\2\21\u0082\3\2\2\2\23\u0084\3\2\2\2\25"+ + "\u0088\3\2\2\2\27\u008b\3\2\2\2\31\u008e\3\2\2\2\33\u0090\3\2\2\2\35\u0092"+ + "\3\2\2\2\37\u0094\3\2\2\2!\u0096\3\2\2\2#\u0099\3\2\2\2%\u009b\3\2\2\2"+ + "\'\u009d\3\2\2\2)\u009f\3\2\2\2+\u00a1\3\2\2\2-\u00a3\3\2\2\2/\u00a5\3"+ + "\2\2\2\61\u00a7\3\2\2\2\63\u00a9\3\2\2\2\65\u00ab\3\2\2\2\67\u00ad\3\2"+ + "\2\29\u00af\3\2\2\2;\u00b1\3\2\2\2=\u00b7\3\2\2\2?\u00b9\3\2\2\2A\u00bb"+ + "\3\2\2\2C\u00bd\3\2\2\2E\u00c0\3\2\2\2G\u00c3\3\2\2\2I\u00ca\3\2\2\2K"+ + "\u00cf\3\2\2\2M\u00d4\3\2\2\2O\u00d9\3\2\2\2Q\u00e0\3\2\2\2S\u00ef\3\2"+ + "\2\2U\u00f1\3\2\2\2W\u00fc\3\2\2\2Y\u0105\3\2\2\2[\u0114\3\2\2\2]^\7g"+ + "\2\2^_\7p\2\2_`\7w\2\2`a\7o\2\2ab\7g\2\2bc\7t\2\2cd\7c\2\2de\7v\2\2ef"+ + "\7k\2\2fg\7q\2\2gh\7p\2\2hi\7a\2\2ij\7r\2\2jk\7t\2\2kl\7g\2\2lm\7f\2\2"+ + "mn\7k\2\2no\7e\2\2op\7c\2\2pq\7v\2\2qr\7g\2\2rs\7a\2\2st\7k\2\2tu\7u\2"+ + "\2u\4\3\2\2\2vw\7a\2\2w\6\3\2\2\2xy\7\60\2\2y\b\3\2\2\2z{\7.\2\2{\n\3"+ + "\2\2\2|}\7A\2\2}\f\3\2\2\2~\177\7<\2\2\177\16\3\2\2\2\u0080\u0081\7=\2"+ + "\2\u0081\20\3\2\2\2\u0082\u0083\7~\2\2\u0083\22\3\2\2\2\u0084\u0085\7"+ + "p\2\2\u0085\u0086\7q\2\2\u0086\u0087\7v\2\2\u0087\24\3\2\2\2\u0088\u0089"+ + "\7<\2\2\u0089\u008a\7/\2\2\u008a\26\3\2\2\2\u008b\u008c\7<\2\2\u008c\u008d"+ + "\7\u0080\2\2\u008d\30\3\2\2\2\u008e\u008f\7-\2\2\u008f\32\3\2\2\2\u0090"+ + "\u0091\7/\2\2\u0091\34\3\2\2\2\u0092\u0093\7,\2\2\u0093\36\3\2\2\2\u0094"+ + "\u0095\7\61\2\2\u0095 \3\2\2\2\u0096\u0097\7,\2\2\u0097\u0098\7,\2\2\u0098"+ + "\"\3\2\2\2\u0099\u009a\7^\2\2\u009a$\3\2\2\2\u009b\u009c\7`\2\2\u009c"+ + "&\3\2\2\2\u009d\u009e\7B\2\2\u009e(\3\2\2\2\u009f\u00a0\7%\2\2\u00a0*"+ + "\3\2\2\2\u00a1\u00a2\7(\2\2\u00a2,\3\2\2\2\u00a3\u00a4\7$\2\2\u00a4.\3"+ + "\2\2\2\u00a5\u00a6\7*\2\2\u00a6\60\3\2\2\2\u00a7\u00a8\7+\2\2\u00a8\62"+ + "\3\2\2\2\u00a9\u00aa\7]\2\2\u00aa\64\3\2\2\2\u00ab\u00ac\7_\2\2\u00ac"+ + "\66\3\2\2\2\u00ad\u00ae\7}\2\2\u00ae8\3\2\2\2\u00af\u00b0\7\177\2\2\u00b0"+ + ":\3\2\2\2\u00b1\u00b2\7?\2\2\u00b2<\3\2\2\2\u00b3\u00b4\7>\2\2\u00b4\u00b8"+ + "\7@\2\2\u00b5\u00b6\7#\2\2\u00b6\u00b8\7?\2\2\u00b7\u00b3\3\2\2\2\u00b7"+ + "\u00b5\3\2\2\2\u00b8>\3\2\2\2\u00b9\u00ba\7>\2\2\u00ba@\3\2\2\2\u00bb"+ + "\u00bc\7@\2\2\u00bcB\3\2\2\2\u00bd\u00be\7>\2\2\u00be\u00bf\7?\2\2\u00bf"+ + "D\3\2\2\2\u00c0\u00c1\7@\2\2\u00c1\u00c2\7?\2\2\u00c2F\3\2\2\2\u00c3\u00c4"+ + "\7%\2\2\u00c4\u00c5\7e\2\2\u00c5\u00c6\7q\2\2\u00c6\u00c7\7w\2\2\u00c7"+ + "\u00c8\7p\2\2\u00c8\u00c9\7v\2\2\u00c9H\3\2\2\2\u00ca\u00cb\7%\2\2\u00cb"+ + "\u00cc\7o\2\2\u00cc\u00cd\7c\2\2\u00cd\u00ce\7z\2\2\u00ceJ\3\2\2\2\u00cf"+ + "\u00d0\7%\2\2\u00d0\u00d1\7o\2\2\u00d1\u00d2\7k\2\2\u00d2\u00d3\7p\2\2"+ + "\u00d3L\3\2\2\2\u00d4\u00d5\7%\2\2\u00d5\u00d6\7u\2\2\u00d6\u00d7\7w\2"+ + "\2\u00d7\u00d8\7o\2\2\u00d8N\3\2\2\2\u00d9\u00dd\4c|\2\u00da\u00dc\t\2"+ + "\2\2\u00db\u00da\3\2\2\2\u00dc\u00df\3\2\2\2\u00dd\u00db\3\2\2\2\u00dd"+ + "\u00de\3\2\2\2\u00deP\3\2\2\2\u00df\u00dd\3\2\2\2\u00e0\u00e4\4C\\\2\u00e1"+ + "\u00e3\t\2\2\2\u00e2\u00e1\3\2\2\2\u00e3\u00e6\3\2\2\2\u00e4\u00e2\3\2"+ + "\2\2\u00e4\u00e5\3\2\2\2\u00e5R\3\2\2\2\u00e6\u00e4\3\2\2\2\u00e7\u00f0"+ + "\7\62\2\2\u00e8\u00ec\4\63;\2\u00e9\u00eb\4\62;\2\u00ea\u00e9\3\2\2\2"+ + "\u00eb\u00ee\3\2\2\2\u00ec\u00ea\3\2\2\2\u00ec\u00ed\3\2\2\2\u00ed\u00f0"+ + "\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ef\u00e7\3\2\2\2\u00ef\u00e8\3\2\2\2\u00f0"+ + "T\3\2\2\2\u00f1\u00f7\5-\27\2\u00f2\u00f3\7^\2\2\u00f3\u00f6\7$\2\2\u00f4"+ + "\u00f6\13\2\2\2\u00f5\u00f2\3\2\2\2\u00f5\u00f4\3\2\2\2\u00f6\u00f9\3"+ + "\2\2\2\u00f7\u00f8\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f8\u00fa\3\2\2\2\u00f9"+ + "\u00f7\3\2\2\2\u00fa\u00fb\5-\27\2\u00fbV\3\2\2\2\u00fc\u0100\7\'\2\2"+ + "\u00fd\u00ff\n\3\2\2\u00fe\u00fd\3\2\2\2\u00ff\u0102\3\2\2\2\u0100\u00fe"+ + "\3\2\2\2\u0100\u0101\3\2\2\2\u0101\u0103\3\2\2\2\u0102\u0100\3\2\2\2\u0103"+ + "\u0104\b,\2\2\u0104X\3\2\2\2\u0105\u0106\7\'\2\2\u0106\u0107\7,\2\2\u0107"+ + "\u010b\3\2\2\2\u0108\u010a\13\2\2\2\u0109\u0108\3\2\2\2\u010a\u010d\3"+ + "\2\2\2\u010b\u010c\3\2\2\2\u010b\u0109\3\2\2\2\u010c\u010e\3\2\2\2\u010d"+ + "\u010b\3\2\2\2\u010e\u010f\7,\2\2\u010f\u0110\7\'\2\2\u0110\u0111\3\2"+ + "\2\2\u0111\u0112\b-\2\2\u0112Z\3\2\2\2\u0113\u0115\t\4\2\2\u0114\u0113"+ + "\3\2\2\2\u0115\u0116\3\2\2\2\u0116\u0114\3\2\2\2\u0116\u0117\3\2\2\2\u0117"+ + "\u0118\3\2\2\2\u0118\u0119\b.\2\2\u0119\\\3\2\2\2\r\2\u00b7\u00dd\u00e4"+ + "\u00ec\u00ef\u00f5\u00f7\u0100\u010b\u0116\3\2\3\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java new file mode 100644 index 000000000..491bd12ca --- /dev/null +++ b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java @@ -0,0 +1,2632 @@ +// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 +package at.ac.tuwien.kr.alpha.antlr; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class ASPCore2Parser extends Parser { + static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, ANONYMOUS_VARIABLE=2, DOT=3, COMMA=4, QUERY_MARK=5, COLON=6, SEMICOLON=7, + OR=8, NAF=9, CONS=10, WCONS=11, PLUS=12, MINUS=13, TIMES=14, DIV=15, POWER=16, + MODULO=17, BITXOR=18, AT=19, SHARP=20, AMPERSAND=21, QUOTE=22, PAREN_OPEN=23, + PAREN_CLOSE=24, SQUARE_OPEN=25, SQUARE_CLOSE=26, CURLY_OPEN=27, CURLY_CLOSE=28, + EQUAL=29, UNEQUAL=30, LESS=31, GREATER=32, LESS_OR_EQ=33, GREATER_OR_EQ=34, + AGGREGATE_COUNT=35, AGGREGATE_MAX=36, AGGREGATE_MIN=37, AGGREGATE_SUM=38, + ID=39, VARIABLE=40, NUMBER=41, QUOTED_STRING=42, COMMENT=43, MULTI_LINE_COMMEN=44, + BLANK=45; + public static final int + RULE_program = 0, RULE_statements = 1, RULE_query = 2, RULE_statement = 3, + RULE_head = 4, RULE_body = 5, RULE_disjunction = 6, RULE_choice = 7, RULE_choice_elements = 8, + RULE_choice_element = 9, RULE_aggregate = 10, RULE_aggregate_elements = 11, + RULE_aggregate_element = 12, RULE_aggregate_function = 13, RULE_weight_at_level = 14, + RULE_naf_literals = 15, RULE_naf_literal = 16, RULE_classical_literal = 17, + RULE_builtin_atom = 18, RULE_binop = 19, RULE_terms = 20, RULE_term = 21, + RULE_interval = 22, RULE_external_atom = 23, RULE_directive = 24, RULE_directive_enumeration = 25, + RULE_basic_terms = 26, RULE_basic_term = 27, RULE_ground_term = 28, RULE_variable_term = 29, + RULE_answer_set = 30, RULE_answer_sets = 31; + public static final String[] ruleNames = { + "program", "statements", "query", "statement", "head", "body", "disjunction", + "choice", "choice_elements", "choice_element", "aggregate", "aggregate_elements", + "aggregate_element", "aggregate_function", "weight_at_level", "naf_literals", + "naf_literal", "classical_literal", "builtin_atom", "binop", "terms", + "term", "interval", "external_atom", "directive", "directive_enumeration", + "basic_terms", "basic_term", "ground_term", "variable_term", "answer_set", + "answer_sets" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'enumeration_predicate_is'", "'_'", "'.'", "','", "'?'", "':'", + "';'", "'|'", "'not'", "':-'", "':~'", "'+'", "'-'", "'*'", "'/'", "'**'", + "'\\'", "'^'", "'@'", "'#'", "'&'", "'\"'", "'('", "')'", "'['", "']'", + "'{'", "'}'", "'='", null, "'<'", "'>'", "'<='", "'>='", "'#count'", "'#max'", + "'#min'", "'#sum'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, null, "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", + "SEMICOLON", "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", + "POWER", "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", + "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", + "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", + "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", + "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", + "BLANK" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "ASPCore2.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public ASPCore2Parser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + public static class ProgramContext extends ParserRuleContext { + public TerminalNode EOF() { return getToken(ASPCore2Parser.EOF, 0); } + public StatementsContext statements() { + return getRuleContext(StatementsContext.class,0); + } + public QueryContext query() { + return getRuleContext(QueryContext.class,0); + } + public ProgramContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_program; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitProgram(this); + else return visitor.visitChildren(this); + } + } + + public final ProgramContext program() throws RecognitionException { + ProgramContext _localctx = new ProgramContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_program); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(65); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) { + case 1: + { + setState(64); + statements(); + } + break; + } + setState(68); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MINUS || _la==ID) { + { + setState(67); + query(); + } + } + + setState(70); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StatementsContext extends ParserRuleContext { + public List statement() { + return getRuleContexts(StatementContext.class); + } + public StatementContext statement(int i) { + return getRuleContext(StatementContext.class,i); + } + public StatementsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_statements; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatements(this); + else return visitor.visitChildren(this); + } + } + + public final StatementsContext statements() throws RecognitionException { + StatementsContext _localctx = new StatementsContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_statements); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(73); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(72); + statement(); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(75); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class QueryContext extends ParserRuleContext { + public Classical_literalContext classical_literal() { + return getRuleContext(Classical_literalContext.class,0); + } + public TerminalNode QUERY_MARK() { return getToken(ASPCore2Parser.QUERY_MARK, 0); } + public QueryContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_query; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitQuery(this); + else return visitor.visitChildren(this); + } + } + + public final QueryContext query() throws RecognitionException { + QueryContext _localctx = new QueryContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_query); + try { + enterOuterAlt(_localctx, 1); + { + setState(77); + classical_literal(); + setState(78); + match(QUERY_MARK); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StatementContext extends ParserRuleContext { + public StatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_statement; } + + public StatementContext() { } + public void copyFrom(StatementContext ctx) { + super.copyFrom(ctx); + } + } + public static class Statement_factContext extends StatementContext { + public HeadContext head() { + return getRuleContext(HeadContext.class,0); + } + public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } + public Statement_factContext(StatementContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_fact(this); + else return visitor.visitChildren(this); + } + } + public static class Statement_ruleContext extends StatementContext { + public HeadContext head() { + return getRuleContext(HeadContext.class,0); + } + public TerminalNode CONS() { return getToken(ASPCore2Parser.CONS, 0); } + public BodyContext body() { + return getRuleContext(BodyContext.class,0); + } + public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } + public Statement_ruleContext(StatementContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_rule(this); + else return visitor.visitChildren(this); + } + } + public static class Statement_weightConstraintContext extends StatementContext { + public TerminalNode WCONS() { return getToken(ASPCore2Parser.WCONS, 0); } + public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } + public TerminalNode SQUARE_OPEN() { return getToken(ASPCore2Parser.SQUARE_OPEN, 0); } + public Weight_at_levelContext weight_at_level() { + return getRuleContext(Weight_at_levelContext.class,0); + } + public TerminalNode SQUARE_CLOSE() { return getToken(ASPCore2Parser.SQUARE_CLOSE, 0); } + public BodyContext body() { + return getRuleContext(BodyContext.class,0); + } + public Statement_weightConstraintContext(StatementContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_weightConstraint(this); + else return visitor.visitChildren(this); + } + } + public static class Statement_constraintContext extends StatementContext { + public TerminalNode CONS() { return getToken(ASPCore2Parser.CONS, 0); } + public BodyContext body() { + return getRuleContext(BodyContext.class,0); + } + public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } + public Statement_constraintContext(StatementContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_constraint(this); + else return visitor.visitChildren(this); + } + } + public static class Statement_directiveContext extends StatementContext { + public DirectiveContext directive() { + return getRuleContext(DirectiveContext.class,0); + } + public Statement_directiveContext(StatementContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_directive(this); + else return visitor.visitChildren(this); + } + } + + public final StatementContext statement() throws RecognitionException { + StatementContext _localctx = new StatementContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_statement); + int _la; + try { + setState(102); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { + case 1: + _localctx = new Statement_factContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(80); + head(); + setState(81); + match(DOT); + } + break; + case 2: + _localctx = new Statement_constraintContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(83); + match(CONS); + setState(84); + body(); + setState(85); + match(DOT); + } + break; + case 3: + _localctx = new Statement_ruleContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(87); + head(); + setState(88); + match(CONS); + setState(89); + body(); + setState(90); + match(DOT); + } + break; + case 4: + _localctx = new Statement_weightConstraintContext(_localctx); + enterOuterAlt(_localctx, 4); + { + setState(92); + match(WCONS); + setState(94); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << NAF) | (1L << MINUS) | (1L << AMPERSAND) | (1L << PAREN_OPEN) | (1L << AGGREGATE_COUNT) | (1L << AGGREGATE_MAX) | (1L << AGGREGATE_MIN) | (1L << AGGREGATE_SUM) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { + { + setState(93); + body(); + } + } + + setState(96); + match(DOT); + setState(97); + match(SQUARE_OPEN); + setState(98); + weight_at_level(); + setState(99); + match(SQUARE_CLOSE); + } + break; + case 5: + _localctx = new Statement_directiveContext(_localctx); + enterOuterAlt(_localctx, 5); + { + setState(101); + directive(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class HeadContext extends ParserRuleContext { + public DisjunctionContext disjunction() { + return getRuleContext(DisjunctionContext.class,0); + } + public ChoiceContext choice() { + return getRuleContext(ChoiceContext.class,0); + } + public HeadContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_head; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitHead(this); + else return visitor.visitChildren(this); + } + } + + public final HeadContext head() throws RecognitionException { + HeadContext _localctx = new HeadContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_head); + try { + setState(106); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(104); + disjunction(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(105); + choice(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class BodyContext extends ParserRuleContext { + public Naf_literalContext naf_literal() { + return getRuleContext(Naf_literalContext.class,0); + } + public AggregateContext aggregate() { + return getRuleContext(AggregateContext.class,0); + } + public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } + public BodyContext body() { + return getRuleContext(BodyContext.class,0); + } + public BodyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_body; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBody(this); + else return visitor.visitChildren(this); + } + } + + public final BodyContext body() throws RecognitionException { + BodyContext _localctx = new BodyContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_body); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(110); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { + case 1: + { + setState(108); + naf_literal(); + } + break; + case 2: + { + setState(109); + aggregate(); + } + break; + } + setState(114); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(112); + match(COMMA); + setState(113); + body(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class DisjunctionContext extends ParserRuleContext { + public Classical_literalContext classical_literal() { + return getRuleContext(Classical_literalContext.class,0); + } + public TerminalNode OR() { return getToken(ASPCore2Parser.OR, 0); } + public DisjunctionContext disjunction() { + return getRuleContext(DisjunctionContext.class,0); + } + public DisjunctionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_disjunction; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitDisjunction(this); + else return visitor.visitChildren(this); + } + } + + public final DisjunctionContext disjunction() throws RecognitionException { + DisjunctionContext _localctx = new DisjunctionContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_disjunction); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(116); + classical_literal(); + setState(119); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==OR) { + { + setState(117); + match(OR); + setState(118); + disjunction(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ChoiceContext extends ParserRuleContext { + public TermContext lt; + public BinopContext lop; + public BinopContext uop; + public TermContext ut; + public TerminalNode CURLY_OPEN() { return getToken(ASPCore2Parser.CURLY_OPEN, 0); } + public TerminalNode CURLY_CLOSE() { return getToken(ASPCore2Parser.CURLY_CLOSE, 0); } + public Choice_elementsContext choice_elements() { + return getRuleContext(Choice_elementsContext.class,0); + } + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public List binop() { + return getRuleContexts(BinopContext.class); + } + public BinopContext binop(int i) { + return getRuleContext(BinopContext.class,i); + } + public ChoiceContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_choice; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitChoice(this); + else return visitor.visitChildren(this); + } + } + + public final ChoiceContext choice() throws RecognitionException { + ChoiceContext _localctx = new ChoiceContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_choice); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(124); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { + { + setState(121); + ((ChoiceContext)_localctx).lt = term(0); + setState(122); + ((ChoiceContext)_localctx).lop = binop(); + } + } + + setState(126); + match(CURLY_OPEN); + setState(128); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MINUS || _la==ID) { + { + setState(127); + choice_elements(); + } + } + + setState(130); + match(CURLY_CLOSE); + setState(134); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQUAL) | (1L << UNEQUAL) | (1L << LESS) | (1L << GREATER) | (1L << LESS_OR_EQ) | (1L << GREATER_OR_EQ))) != 0)) { + { + setState(131); + ((ChoiceContext)_localctx).uop = binop(); + setState(132); + ((ChoiceContext)_localctx).ut = term(0); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Choice_elementsContext extends ParserRuleContext { + public Choice_elementContext choice_element() { + return getRuleContext(Choice_elementContext.class,0); + } + public TerminalNode SEMICOLON() { return getToken(ASPCore2Parser.SEMICOLON, 0); } + public Choice_elementsContext choice_elements() { + return getRuleContext(Choice_elementsContext.class,0); + } + public Choice_elementsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_choice_elements; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitChoice_elements(this); + else return visitor.visitChildren(this); + } + } + + public final Choice_elementsContext choice_elements() throws RecognitionException { + Choice_elementsContext _localctx = new Choice_elementsContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_choice_elements); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(136); + choice_element(); + setState(139); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SEMICOLON) { + { + setState(137); + match(SEMICOLON); + setState(138); + choice_elements(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Choice_elementContext extends ParserRuleContext { + public Classical_literalContext classical_literal() { + return getRuleContext(Classical_literalContext.class,0); + } + public TerminalNode COLON() { return getToken(ASPCore2Parser.COLON, 0); } + public Naf_literalsContext naf_literals() { + return getRuleContext(Naf_literalsContext.class,0); + } + public Choice_elementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_choice_element; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitChoice_element(this); + else return visitor.visitChildren(this); + } + } + + public final Choice_elementContext choice_element() throws RecognitionException { + Choice_elementContext _localctx = new Choice_elementContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_choice_element); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(141); + classical_literal(); + setState(146); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(142); + match(COLON); + setState(144); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << NAF) | (1L << MINUS) | (1L << AMPERSAND) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { + { + setState(143); + naf_literals(); + } + } + + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class AggregateContext extends ParserRuleContext { + public TermContext lt; + public BinopContext lop; + public BinopContext uop; + public TermContext ut; + public Aggregate_functionContext aggregate_function() { + return getRuleContext(Aggregate_functionContext.class,0); + } + public TerminalNode CURLY_OPEN() { return getToken(ASPCore2Parser.CURLY_OPEN, 0); } + public Aggregate_elementsContext aggregate_elements() { + return getRuleContext(Aggregate_elementsContext.class,0); + } + public TerminalNode CURLY_CLOSE() { return getToken(ASPCore2Parser.CURLY_CLOSE, 0); } + public TerminalNode NAF() { return getToken(ASPCore2Parser.NAF, 0); } + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public List binop() { + return getRuleContexts(BinopContext.class); + } + public BinopContext binop(int i) { + return getRuleContext(BinopContext.class,i); + } + public AggregateContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_aggregate; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate(this); + else return visitor.visitChildren(this); + } + } + + public final AggregateContext aggregate() throws RecognitionException { + AggregateContext _localctx = new AggregateContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_aggregate); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(149); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==NAF) { + { + setState(148); + match(NAF); + } + } + + setState(154); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { + { + setState(151); + ((AggregateContext)_localctx).lt = term(0); + setState(152); + ((AggregateContext)_localctx).lop = binop(); + } + } + + setState(156); + aggregate_function(); + setState(157); + match(CURLY_OPEN); + setState(158); + aggregate_elements(); + setState(159); + match(CURLY_CLOSE); + setState(163); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQUAL) | (1L << UNEQUAL) | (1L << LESS) | (1L << GREATER) | (1L << LESS_OR_EQ) | (1L << GREATER_OR_EQ))) != 0)) { + { + setState(160); + ((AggregateContext)_localctx).uop = binop(); + setState(161); + ((AggregateContext)_localctx).ut = term(0); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Aggregate_elementsContext extends ParserRuleContext { + public Aggregate_elementContext aggregate_element() { + return getRuleContext(Aggregate_elementContext.class,0); + } + public TerminalNode SEMICOLON() { return getToken(ASPCore2Parser.SEMICOLON, 0); } + public Aggregate_elementsContext aggregate_elements() { + return getRuleContext(Aggregate_elementsContext.class,0); + } + public Aggregate_elementsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_aggregate_elements; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate_elements(this); + else return visitor.visitChildren(this); + } + } + + public final Aggregate_elementsContext aggregate_elements() throws RecognitionException { + Aggregate_elementsContext _localctx = new Aggregate_elementsContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_aggregate_elements); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(165); + aggregate_element(); + setState(168); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SEMICOLON) { + { + setState(166); + match(SEMICOLON); + setState(167); + aggregate_elements(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Aggregate_elementContext extends ParserRuleContext { + public Basic_termsContext basic_terms() { + return getRuleContext(Basic_termsContext.class,0); + } + public TerminalNode COLON() { return getToken(ASPCore2Parser.COLON, 0); } + public Naf_literalsContext naf_literals() { + return getRuleContext(Naf_literalsContext.class,0); + } + public Aggregate_elementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_aggregate_element; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate_element(this); + else return visitor.visitChildren(this); + } + } + + public final Aggregate_elementContext aggregate_element() throws RecognitionException { + Aggregate_elementContext _localctx = new Aggregate_elementContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_aggregate_element); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(171); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { + { + setState(170); + basic_terms(); + } + } + + setState(177); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(173); + match(COLON); + setState(175); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << NAF) | (1L << MINUS) | (1L << AMPERSAND) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { + { + setState(174); + naf_literals(); + } + } + + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Aggregate_functionContext extends ParserRuleContext { + public TerminalNode AGGREGATE_COUNT() { return getToken(ASPCore2Parser.AGGREGATE_COUNT, 0); } + public TerminalNode AGGREGATE_MAX() { return getToken(ASPCore2Parser.AGGREGATE_MAX, 0); } + public TerminalNode AGGREGATE_MIN() { return getToken(ASPCore2Parser.AGGREGATE_MIN, 0); } + public TerminalNode AGGREGATE_SUM() { return getToken(ASPCore2Parser.AGGREGATE_SUM, 0); } + public Aggregate_functionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_aggregate_function; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate_function(this); + else return visitor.visitChildren(this); + } + } + + public final Aggregate_functionContext aggregate_function() throws RecognitionException { + Aggregate_functionContext _localctx = new Aggregate_functionContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_aggregate_function); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(179); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << AGGREGATE_COUNT) | (1L << AGGREGATE_MAX) | (1L << AGGREGATE_MIN) | (1L << AGGREGATE_SUM))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Weight_at_levelContext extends ParserRuleContext { + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public TerminalNode AT() { return getToken(ASPCore2Parser.AT, 0); } + public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } + public TermsContext terms() { + return getRuleContext(TermsContext.class,0); + } + public Weight_at_levelContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_weight_at_level; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitWeight_at_level(this); + else return visitor.visitChildren(this); + } + } + + public final Weight_at_levelContext weight_at_level() throws RecognitionException { + Weight_at_levelContext _localctx = new Weight_at_levelContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_weight_at_level); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(181); + term(0); + setState(184); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==AT) { + { + setState(182); + match(AT); + setState(183); + term(0); + } + } + + setState(188); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(186); + match(COMMA); + setState(187); + terms(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Naf_literalsContext extends ParserRuleContext { + public Naf_literalContext naf_literal() { + return getRuleContext(Naf_literalContext.class,0); + } + public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } + public Naf_literalsContext naf_literals() { + return getRuleContext(Naf_literalsContext.class,0); + } + public Naf_literalsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_naf_literals; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitNaf_literals(this); + else return visitor.visitChildren(this); + } + } + + public final Naf_literalsContext naf_literals() throws RecognitionException { + Naf_literalsContext _localctx = new Naf_literalsContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_naf_literals); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(190); + naf_literal(); + setState(193); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(191); + match(COMMA); + setState(192); + naf_literals(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Naf_literalContext extends ParserRuleContext { + public External_atomContext external_atom() { + return getRuleContext(External_atomContext.class,0); + } + public Classical_literalContext classical_literal() { + return getRuleContext(Classical_literalContext.class,0); + } + public Builtin_atomContext builtin_atom() { + return getRuleContext(Builtin_atomContext.class,0); + } + public TerminalNode NAF() { return getToken(ASPCore2Parser.NAF, 0); } + public Naf_literalContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_naf_literal; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitNaf_literal(this); + else return visitor.visitChildren(this); + } + } + + public final Naf_literalContext naf_literal() throws RecognitionException { + Naf_literalContext _localctx = new Naf_literalContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_naf_literal); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(196); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==NAF) { + { + setState(195); + match(NAF); + } + } + + setState(201); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { + case 1: + { + setState(198); + external_atom(); + } + break; + case 2: + { + setState(199); + classical_literal(); + } + break; + case 3: + { + setState(200); + builtin_atom(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Classical_literalContext extends ParserRuleContext { + public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } + public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } + public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } + public TermsContext terms() { + return getRuleContext(TermsContext.class,0); + } + public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } + public Classical_literalContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_classical_literal; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitClassical_literal(this); + else return visitor.visitChildren(this); + } + } + + public final Classical_literalContext classical_literal() throws RecognitionException { + Classical_literalContext _localctx = new Classical_literalContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_classical_literal); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(204); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MINUS) { + { + setState(203); + match(MINUS); + } + } + + setState(206); + match(ID); + setState(211); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==PAREN_OPEN) { + { + setState(207); + match(PAREN_OPEN); + setState(208); + terms(); + setState(209); + match(PAREN_CLOSE); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Builtin_atomContext extends ParserRuleContext { + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public BinopContext binop() { + return getRuleContext(BinopContext.class,0); + } + public Builtin_atomContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_builtin_atom; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBuiltin_atom(this); + else return visitor.visitChildren(this); + } + } + + public final Builtin_atomContext builtin_atom() throws RecognitionException { + Builtin_atomContext _localctx = new Builtin_atomContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_builtin_atom); + try { + enterOuterAlt(_localctx, 1); + { + setState(213); + term(0); + setState(214); + binop(); + setState(215); + term(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class BinopContext extends ParserRuleContext { + public TerminalNode EQUAL() { return getToken(ASPCore2Parser.EQUAL, 0); } + public TerminalNode UNEQUAL() { return getToken(ASPCore2Parser.UNEQUAL, 0); } + public TerminalNode LESS() { return getToken(ASPCore2Parser.LESS, 0); } + public TerminalNode GREATER() { return getToken(ASPCore2Parser.GREATER, 0); } + public TerminalNode LESS_OR_EQ() { return getToken(ASPCore2Parser.LESS_OR_EQ, 0); } + public TerminalNode GREATER_OR_EQ() { return getToken(ASPCore2Parser.GREATER_OR_EQ, 0); } + public BinopContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_binop; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBinop(this); + else return visitor.visitChildren(this); + } + } + + public final BinopContext binop() throws RecognitionException { + BinopContext _localctx = new BinopContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_binop); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(217); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQUAL) | (1L << UNEQUAL) | (1L << LESS) | (1L << GREATER) | (1L << LESS_OR_EQ) | (1L << GREATER_OR_EQ))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TermsContext extends ParserRuleContext { + public TermContext term() { + return getRuleContext(TermContext.class,0); + } + public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } + public TermsContext terms() { + return getRuleContext(TermsContext.class,0); + } + public TermsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_terms; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerms(this); + else return visitor.visitChildren(this); + } + } + + public final TermsContext terms() throws RecognitionException { + TermsContext _localctx = new TermsContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_terms); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(219); + term(0); + setState(222); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(220); + match(COMMA); + setState(221); + terms(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TermContext extends ParserRuleContext { + public TermContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_term; } + + public TermContext() { } + public void copyFrom(TermContext ctx) { + super.copyFrom(ctx); + } + } + public static class Term_numberContext extends TermContext { + public TerminalNode NUMBER() { return getToken(ASPCore2Parser.NUMBER, 0); } + public Term_numberContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_number(this); + else return visitor.visitChildren(this); + } + } + public static class Term_anonymousVariableContext extends TermContext { + public TerminalNode ANONYMOUS_VARIABLE() { return getToken(ASPCore2Parser.ANONYMOUS_VARIABLE, 0); } + public Term_anonymousVariableContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_anonymousVariable(this); + else return visitor.visitChildren(this); + } + } + public static class Term_constContext extends TermContext { + public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } + public Term_constContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_const(this); + else return visitor.visitChildren(this); + } + } + public static class Term_minusArithTermContext extends TermContext { + public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } + public TermContext term() { + return getRuleContext(TermContext.class,0); + } + public Term_minusArithTermContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_minusArithTerm(this); + else return visitor.visitChildren(this); + } + } + public static class Term_bitxorArithTermContext extends TermContext { + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public TerminalNode BITXOR() { return getToken(ASPCore2Parser.BITXOR, 0); } + public Term_bitxorArithTermContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_bitxorArithTerm(this); + else return visitor.visitChildren(this); + } + } + public static class Term_intervalContext extends TermContext { + public IntervalContext interval() { + return getRuleContext(IntervalContext.class,0); + } + public Term_intervalContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_interval(this); + else return visitor.visitChildren(this); + } + } + public static class Term_variableContext extends TermContext { + public TerminalNode VARIABLE() { return getToken(ASPCore2Parser.VARIABLE, 0); } + public Term_variableContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_variable(this); + else return visitor.visitChildren(this); + } + } + public static class Term_timesdivmodArithTermContext extends TermContext { + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public TerminalNode TIMES() { return getToken(ASPCore2Parser.TIMES, 0); } + public TerminalNode DIV() { return getToken(ASPCore2Parser.DIV, 0); } + public TerminalNode MODULO() { return getToken(ASPCore2Parser.MODULO, 0); } + public Term_timesdivmodArithTermContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_timesdivmodArithTerm(this); + else return visitor.visitChildren(this); + } + } + public static class Term_plusminusArithTermContext extends TermContext { + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public TerminalNode PLUS() { return getToken(ASPCore2Parser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } + public Term_plusminusArithTermContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_plusminusArithTerm(this); + else return visitor.visitChildren(this); + } + } + public static class Term_powerArithTermContext extends TermContext { + public List term() { + return getRuleContexts(TermContext.class); + } + public TermContext term(int i) { + return getRuleContext(TermContext.class,i); + } + public TerminalNode POWER() { return getToken(ASPCore2Parser.POWER, 0); } + public Term_powerArithTermContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_powerArithTerm(this); + else return visitor.visitChildren(this); + } + } + public static class Term_funcContext extends TermContext { + public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } + public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } + public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } + public TermsContext terms() { + return getRuleContext(TermsContext.class,0); + } + public Term_funcContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_func(this); + else return visitor.visitChildren(this); + } + } + public static class Term_stringContext extends TermContext { + public TerminalNode QUOTED_STRING() { return getToken(ASPCore2Parser.QUOTED_STRING, 0); } + public Term_stringContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_string(this); + else return visitor.visitChildren(this); + } + } + public static class Term_parenthesisedTermContext extends TermContext { + public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } + public TermContext term() { + return getRuleContext(TermContext.class,0); + } + public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } + public Term_parenthesisedTermContext(TermContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_parenthesisedTerm(this); + else return visitor.visitChildren(this); + } + } + + public final TermContext term() throws RecognitionException { + return term(0); + } + + private TermContext term(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + TermContext _localctx = new TermContext(_ctx, _parentState); + TermContext _prevctx = _localctx; + int _startState = 42; + enterRecursionRule(_localctx, 42, RULE_term, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(243); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { + case 1: + { + _localctx = new Term_constContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(225); + match(ID); + } + break; + case 2: + { + _localctx = new Term_funcContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(226); + match(ID); + { + setState(227); + match(PAREN_OPEN); + setState(229); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { + { + setState(228); + terms(); + } + } + + setState(231); + match(PAREN_CLOSE); + } + } + break; + case 3: + { + _localctx = new Term_numberContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(232); + match(NUMBER); + } + break; + case 4: + { + _localctx = new Term_stringContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(233); + match(QUOTED_STRING); + } + break; + case 5: + { + _localctx = new Term_variableContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(234); + match(VARIABLE); + } + break; + case 6: + { + _localctx = new Term_anonymousVariableContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(235); + match(ANONYMOUS_VARIABLE); + } + break; + case 7: + { + _localctx = new Term_parenthesisedTermContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(236); + match(PAREN_OPEN); + setState(237); + term(0); + setState(238); + match(PAREN_CLOSE); + } + break; + case 8: + { + _localctx = new Term_intervalContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(240); + interval(); + } + break; + case 9: + { + _localctx = new Term_minusArithTermContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(241); + match(MINUS); + setState(242); + term(5); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(259); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,33,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(257); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,32,_ctx) ) { + case 1: + { + _localctx = new Term_powerArithTermContext(new TermContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_term); + setState(245); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(246); + match(POWER); + setState(247); + term(4); + } + break; + case 2: + { + _localctx = new Term_timesdivmodArithTermContext(new TermContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_term); + setState(248); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(249); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TIMES) | (1L << DIV) | (1L << MODULO))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(250); + term(4); + } + break; + case 3: + { + _localctx = new Term_plusminusArithTermContext(new TermContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_term); + setState(251); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(252); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(253); + term(3); + } + break; + case 4: + { + _localctx = new Term_bitxorArithTermContext(new TermContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_term); + setState(254); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(255); + match(BITXOR); + setState(256); + term(2); + } + break; + } + } + } + setState(261); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,33,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + public static class IntervalContext extends ParserRuleContext { + public Token lower; + public Token upper; + public List DOT() { return getTokens(ASPCore2Parser.DOT); } + public TerminalNode DOT(int i) { + return getToken(ASPCore2Parser.DOT, i); + } + public List NUMBER() { return getTokens(ASPCore2Parser.NUMBER); } + public TerminalNode NUMBER(int i) { + return getToken(ASPCore2Parser.NUMBER, i); + } + public List VARIABLE() { return getTokens(ASPCore2Parser.VARIABLE); } + public TerminalNode VARIABLE(int i) { + return getToken(ASPCore2Parser.VARIABLE, i); + } + public IntervalContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_interval; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitInterval(this); + else return visitor.visitChildren(this); + } + } + + public final IntervalContext interval() throws RecognitionException { + IntervalContext _localctx = new IntervalContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_interval); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(262); + ((IntervalContext)_localctx).lower = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==VARIABLE || _la==NUMBER) ) { + ((IntervalContext)_localctx).lower = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(263); + match(DOT); + setState(264); + match(DOT); + setState(265); + ((IntervalContext)_localctx).upper = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==VARIABLE || _la==NUMBER) ) { + ((IntervalContext)_localctx).upper = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class External_atomContext extends ParserRuleContext { + public TermsContext input; + public TermsContext output; + public TerminalNode AMPERSAND() { return getToken(ASPCore2Parser.AMPERSAND, 0); } + public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } + public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } + public TerminalNode SQUARE_OPEN() { return getToken(ASPCore2Parser.SQUARE_OPEN, 0); } + public TerminalNode SQUARE_CLOSE() { return getToken(ASPCore2Parser.SQUARE_CLOSE, 0); } + public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } + public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } + public List terms() { + return getRuleContexts(TermsContext.class); + } + public TermsContext terms(int i) { + return getRuleContext(TermsContext.class,i); + } + public External_atomContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_external_atom; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitExternal_atom(this); + else return visitor.visitChildren(this); + } + } + + public final External_atomContext external_atom() throws RecognitionException { + External_atomContext _localctx = new External_atomContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_external_atom); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(268); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MINUS) { + { + setState(267); + match(MINUS); + } + } + + setState(270); + match(AMPERSAND); + setState(271); + match(ID); + setState(276); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SQUARE_OPEN) { + { + setState(272); + match(SQUARE_OPEN); + setState(273); + ((External_atomContext)_localctx).input = terms(); + setState(274); + match(SQUARE_CLOSE); + } + } + + setState(282); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==PAREN_OPEN) { + { + setState(278); + match(PAREN_OPEN); + setState(279); + ((External_atomContext)_localctx).output = terms(); + setState(280); + match(PAREN_CLOSE); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class DirectiveContext extends ParserRuleContext { + public Directive_enumerationContext directive_enumeration() { + return getRuleContext(Directive_enumerationContext.class,0); + } + public DirectiveContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_directive; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitDirective(this); + else return visitor.visitChildren(this); + } + } + + public final DirectiveContext directive() throws RecognitionException { + DirectiveContext _localctx = new DirectiveContext(_ctx, getState()); + enterRule(_localctx, 48, RULE_directive); + try { + enterOuterAlt(_localctx, 1); + { + setState(284); + directive_enumeration(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Directive_enumerationContext extends ParserRuleContext { + public TerminalNode SHARP() { return getToken(ASPCore2Parser.SHARP, 0); } + public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } + public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } + public Directive_enumerationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_directive_enumeration; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitDirective_enumeration(this); + else return visitor.visitChildren(this); + } + } + + public final Directive_enumerationContext directive_enumeration() throws RecognitionException { + Directive_enumerationContext _localctx = new Directive_enumerationContext(_ctx, getState()); + enterRule(_localctx, 50, RULE_directive_enumeration); + try { + enterOuterAlt(_localctx, 1); + { + setState(286); + match(SHARP); + setState(287); + match(T__0); + setState(288); + match(ID); + setState(289); + match(DOT); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Basic_termsContext extends ParserRuleContext { + public Basic_termContext basic_term() { + return getRuleContext(Basic_termContext.class,0); + } + public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } + public Basic_termsContext basic_terms() { + return getRuleContext(Basic_termsContext.class,0); + } + public Basic_termsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_basic_terms; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBasic_terms(this); + else return visitor.visitChildren(this); + } + } + + public final Basic_termsContext basic_terms() throws RecognitionException { + Basic_termsContext _localctx = new Basic_termsContext(_ctx, getState()); + enterRule(_localctx, 52, RULE_basic_terms); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(291); + basic_term(); + setState(294); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(292); + match(COMMA); + setState(293); + basic_terms(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Basic_termContext extends ParserRuleContext { + public Ground_termContext ground_term() { + return getRuleContext(Ground_termContext.class,0); + } + public Variable_termContext variable_term() { + return getRuleContext(Variable_termContext.class,0); + } + public Basic_termContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_basic_term; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBasic_term(this); + else return visitor.visitChildren(this); + } + } + + public final Basic_termContext basic_term() throws RecognitionException { + Basic_termContext _localctx = new Basic_termContext(_ctx, getState()); + enterRule(_localctx, 54, RULE_basic_term); + try { + setState(298); + _errHandler.sync(this); + switch (_input.LA(1)) { + case MINUS: + case ID: + case NUMBER: + case QUOTED_STRING: + enterOuterAlt(_localctx, 1); + { + setState(296); + ground_term(); + } + break; + case ANONYMOUS_VARIABLE: + case VARIABLE: + enterOuterAlt(_localctx, 2); + { + setState(297); + variable_term(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Ground_termContext extends ParserRuleContext { + public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } + public TerminalNode QUOTED_STRING() { return getToken(ASPCore2Parser.QUOTED_STRING, 0); } + public TerminalNode NUMBER() { return getToken(ASPCore2Parser.NUMBER, 0); } + public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } + public Ground_termContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_ground_term; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitGround_term(this); + else return visitor.visitChildren(this); + } + } + + public final Ground_termContext ground_term() throws RecognitionException { + Ground_termContext _localctx = new Ground_termContext(_ctx, getState()); + enterRule(_localctx, 56, RULE_ground_term); + int _la; + try { + setState(306); + _errHandler.sync(this); + switch (_input.LA(1)) { + case ID: + enterOuterAlt(_localctx, 1); + { + setState(300); + match(ID); + } + break; + case QUOTED_STRING: + enterOuterAlt(_localctx, 2); + { + setState(301); + match(QUOTED_STRING); + } + break; + case MINUS: + case NUMBER: + enterOuterAlt(_localctx, 3); + { + setState(303); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MINUS) { + { + setState(302); + match(MINUS); + } + } + + setState(305); + match(NUMBER); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Variable_termContext extends ParserRuleContext { + public TerminalNode VARIABLE() { return getToken(ASPCore2Parser.VARIABLE, 0); } + public TerminalNode ANONYMOUS_VARIABLE() { return getToken(ASPCore2Parser.ANONYMOUS_VARIABLE, 0); } + public Variable_termContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_variable_term; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitVariable_term(this); + else return visitor.visitChildren(this); + } + } + + public final Variable_termContext variable_term() throws RecognitionException { + Variable_termContext _localctx = new Variable_termContext(_ctx, getState()); + enterRule(_localctx, 58, RULE_variable_term); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(308); + _la = _input.LA(1); + if ( !(_la==ANONYMOUS_VARIABLE || _la==VARIABLE) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Answer_setContext extends ParserRuleContext { + public TerminalNode CURLY_OPEN() { return getToken(ASPCore2Parser.CURLY_OPEN, 0); } + public TerminalNode CURLY_CLOSE() { return getToken(ASPCore2Parser.CURLY_CLOSE, 0); } + public List classical_literal() { + return getRuleContexts(Classical_literalContext.class); + } + public Classical_literalContext classical_literal(int i) { + return getRuleContext(Classical_literalContext.class,i); + } + public List COMMA() { return getTokens(ASPCore2Parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(ASPCore2Parser.COMMA, i); + } + public Answer_setContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_answer_set; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAnswer_set(this); + else return visitor.visitChildren(this); + } + } + + public final Answer_setContext answer_set() throws RecognitionException { + Answer_setContext _localctx = new Answer_setContext(_ctx, getState()); + enterRule(_localctx, 60, RULE_answer_set); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(310); + match(CURLY_OPEN); + setState(312); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MINUS || _la==ID) { + { + setState(311); + classical_literal(); + } + } + + setState(318); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(314); + match(COMMA); + setState(315); + classical_literal(); + } + } + setState(320); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(321); + match(CURLY_CLOSE); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Answer_setsContext extends ParserRuleContext { + public TerminalNode EOF() { return getToken(ASPCore2Parser.EOF, 0); } + public List answer_set() { + return getRuleContexts(Answer_setContext.class); + } + public Answer_setContext answer_set(int i) { + return getRuleContext(Answer_setContext.class,i); + } + public Answer_setsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_answer_sets; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAnswer_sets(this); + else return visitor.visitChildren(this); + } + } + + public final Answer_setsContext answer_sets() throws RecognitionException { + Answer_setsContext _localctx = new Answer_setsContext(_ctx, getState()); + enterRule(_localctx, 62, RULE_answer_sets); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(326); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==CURLY_OPEN) { + { + { + setState(323); + answer_set(); + } + } + setState(328); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(329); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 21: + return term_sempred((TermContext)_localctx, predIndex); + } + return true; + } + private boolean term_sempred(TermContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 4); + case 1: + return precpred(_ctx, 3); + case 2: + return precpred(_ctx, 2); + case 3: + return precpred(_ctx, 1); + } + return true; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3/\u014e\4\2\t\2\4"+ + "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ + "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ + "\t!\3\2\5\2D\n\2\3\2\5\2G\n\2\3\2\3\2\3\3\6\3L\n\3\r\3\16\3M\3\4\3\4\3"+ + "\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5a\n\5\3"+ + "\5\3\5\3\5\3\5\3\5\3\5\5\5i\n\5\3\6\3\6\5\6m\n\6\3\7\3\7\5\7q\n\7\3\7"+ + "\3\7\5\7u\n\7\3\b\3\b\3\b\5\bz\n\b\3\t\3\t\3\t\5\t\177\n\t\3\t\3\t\5\t"+ + "\u0083\n\t\3\t\3\t\3\t\3\t\5\t\u0089\n\t\3\n\3\n\3\n\5\n\u008e\n\n\3\13"+ + "\3\13\3\13\5\13\u0093\n\13\5\13\u0095\n\13\3\f\5\f\u0098\n\f\3\f\3\f\3"+ + "\f\5\f\u009d\n\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00a6\n\f\3\r\3\r\3\r"+ + "\5\r\u00ab\n\r\3\16\5\16\u00ae\n\16\3\16\3\16\5\16\u00b2\n\16\5\16\u00b4"+ + "\n\16\3\17\3\17\3\20\3\20\3\20\5\20\u00bb\n\20\3\20\3\20\5\20\u00bf\n"+ + "\20\3\21\3\21\3\21\5\21\u00c4\n\21\3\22\5\22\u00c7\n\22\3\22\3\22\3\22"+ + "\5\22\u00cc\n\22\3\23\5\23\u00cf\n\23\3\23\3\23\3\23\3\23\3\23\5\23\u00d6"+ + "\n\23\3\24\3\24\3\24\3\24\3\25\3\25\3\26\3\26\3\26\5\26\u00e1\n\26\3\27"+ + "\3\27\3\27\3\27\3\27\5\27\u00e8\n\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\3\27\3\27\3\27\3\27\5\27\u00f6\n\27\3\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\3\27\3\27\3\27\3\27\3\27\7\27\u0104\n\27\f\27\16\27\u0107\13\27"+ + "\3\30\3\30\3\30\3\30\3\30\3\31\5\31\u010f\n\31\3\31\3\31\3\31\3\31\3\31"+ + "\3\31\5\31\u0117\n\31\3\31\3\31\3\31\3\31\5\31\u011d\n\31\3\32\3\32\3"+ + "\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\5\34\u0129\n\34\3\35\3\35\5\35"+ + "\u012d\n\35\3\36\3\36\3\36\5\36\u0132\n\36\3\36\5\36\u0135\n\36\3\37\3"+ + "\37\3 \3 \5 \u013b\n \3 \3 \7 \u013f\n \f \16 \u0142\13 \3 \3 \3!\7!\u0147"+ + "\n!\f!\16!\u014a\13!\3!\3!\3!\2\3,\"\2\4\6\b\n\f\16\20\22\24\26\30\32"+ + "\34\36 \"$&(*,.\60\62\64\668:<>@\2\b\3\2%(\3\2\37$\4\2\20\21\23\23\3\2"+ + "\16\17\3\2*+\4\2\4\4**\2\u0167\2C\3\2\2\2\4K\3\2\2\2\6O\3\2\2\2\bh\3\2"+ + "\2\2\nl\3\2\2\2\fp\3\2\2\2\16v\3\2\2\2\20~\3\2\2\2\22\u008a\3\2\2\2\24"+ + "\u008f\3\2\2\2\26\u0097\3\2\2\2\30\u00a7\3\2\2\2\32\u00ad\3\2\2\2\34\u00b5"+ + "\3\2\2\2\36\u00b7\3\2\2\2 \u00c0\3\2\2\2\"\u00c6\3\2\2\2$\u00ce\3\2\2"+ + "\2&\u00d7\3\2\2\2(\u00db\3\2\2\2*\u00dd\3\2\2\2,\u00f5\3\2\2\2.\u0108"+ + "\3\2\2\2\60\u010e\3\2\2\2\62\u011e\3\2\2\2\64\u0120\3\2\2\2\66\u0125\3"+ + "\2\2\28\u012c\3\2\2\2:\u0134\3\2\2\2<\u0136\3\2\2\2>\u0138\3\2\2\2@\u0148"+ + "\3\2\2\2BD\5\4\3\2CB\3\2\2\2CD\3\2\2\2DF\3\2\2\2EG\5\6\4\2FE\3\2\2\2F"+ + "G\3\2\2\2GH\3\2\2\2HI\7\2\2\3I\3\3\2\2\2JL\5\b\5\2KJ\3\2\2\2LM\3\2\2\2"+ + "MK\3\2\2\2MN\3\2\2\2N\5\3\2\2\2OP\5$\23\2PQ\7\7\2\2Q\7\3\2\2\2RS\5\n\6"+ + "\2ST\7\5\2\2Ti\3\2\2\2UV\7\f\2\2VW\5\f\7\2WX\7\5\2\2Xi\3\2\2\2YZ\5\n\6"+ + "\2Z[\7\f\2\2[\\\5\f\7\2\\]\7\5\2\2]i\3\2\2\2^`\7\r\2\2_a\5\f\7\2`_\3\2"+ + "\2\2`a\3\2\2\2ab\3\2\2\2bc\7\5\2\2cd\7\33\2\2de\5\36\20\2ef\7\34\2\2f"+ + "i\3\2\2\2gi\5\62\32\2hR\3\2\2\2hU\3\2\2\2hY\3\2\2\2h^\3\2\2\2hg\3\2\2"+ + "\2i\t\3\2\2\2jm\5\16\b\2km\5\20\t\2lj\3\2\2\2lk\3\2\2\2m\13\3\2\2\2nq"+ + "\5\"\22\2oq\5\26\f\2pn\3\2\2\2po\3\2\2\2qt\3\2\2\2rs\7\6\2\2su\5\f\7\2"+ + "tr\3\2\2\2tu\3\2\2\2u\r\3\2\2\2vy\5$\23\2wx\7\n\2\2xz\5\16\b\2yw\3\2\2"+ + "\2yz\3\2\2\2z\17\3\2\2\2{|\5,\27\2|}\5(\25\2}\177\3\2\2\2~{\3\2\2\2~\177"+ + "\3\2\2\2\177\u0080\3\2\2\2\u0080\u0082\7\35\2\2\u0081\u0083\5\22\n\2\u0082"+ + "\u0081\3\2\2\2\u0082\u0083\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0088\7\36"+ + "\2\2\u0085\u0086\5(\25\2\u0086\u0087\5,\27\2\u0087\u0089\3\2\2\2\u0088"+ + "\u0085\3\2\2\2\u0088\u0089\3\2\2\2\u0089\21\3\2\2\2\u008a\u008d\5\24\13"+ + "\2\u008b\u008c\7\t\2\2\u008c\u008e\5\22\n\2\u008d\u008b\3\2\2\2\u008d"+ + "\u008e\3\2\2\2\u008e\23\3\2\2\2\u008f\u0094\5$\23\2\u0090\u0092\7\b\2"+ + "\2\u0091\u0093\5 \21\2\u0092\u0091\3\2\2\2\u0092\u0093\3\2\2\2\u0093\u0095"+ + "\3\2\2\2\u0094\u0090\3\2\2\2\u0094\u0095\3\2\2\2\u0095\25\3\2\2\2\u0096"+ + "\u0098\7\13\2\2\u0097\u0096\3\2\2\2\u0097\u0098\3\2\2\2\u0098\u009c\3"+ + "\2\2\2\u0099\u009a\5,\27\2\u009a\u009b\5(\25\2\u009b\u009d\3\2\2\2\u009c"+ + "\u0099\3\2\2\2\u009c\u009d\3\2\2\2\u009d\u009e\3\2\2\2\u009e\u009f\5\34"+ + "\17\2\u009f\u00a0\7\35\2\2\u00a0\u00a1\5\30\r\2\u00a1\u00a5\7\36\2\2\u00a2"+ + "\u00a3\5(\25\2\u00a3\u00a4\5,\27\2\u00a4\u00a6\3\2\2\2\u00a5\u00a2\3\2"+ + "\2\2\u00a5\u00a6\3\2\2\2\u00a6\27\3\2\2\2\u00a7\u00aa\5\32\16\2\u00a8"+ + "\u00a9\7\t\2\2\u00a9\u00ab\5\30\r\2\u00aa\u00a8\3\2\2\2\u00aa\u00ab\3"+ + "\2\2\2\u00ab\31\3\2\2\2\u00ac\u00ae\5\66\34\2\u00ad\u00ac\3\2\2\2\u00ad"+ + "\u00ae\3\2\2\2\u00ae\u00b3\3\2\2\2\u00af\u00b1\7\b\2\2\u00b0\u00b2\5 "+ + "\21\2\u00b1\u00b0\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\u00b4\3\2\2\2\u00b3"+ + "\u00af\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\33\3\2\2\2\u00b5\u00b6\t\2\2"+ + "\2\u00b6\35\3\2\2\2\u00b7\u00ba\5,\27\2\u00b8\u00b9\7\25\2\2\u00b9\u00bb"+ + "\5,\27\2\u00ba\u00b8\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc"+ + "\u00bd\7\6\2\2\u00bd\u00bf\5*\26\2\u00be\u00bc\3\2\2\2\u00be\u00bf\3\2"+ + "\2\2\u00bf\37\3\2\2\2\u00c0\u00c3\5\"\22\2\u00c1\u00c2\7\6\2\2\u00c2\u00c4"+ + "\5 \21\2\u00c3\u00c1\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4!\3\2\2\2\u00c5"+ + "\u00c7\7\13\2\2\u00c6\u00c5\3\2\2\2\u00c6\u00c7\3\2\2\2\u00c7\u00cb\3"+ + "\2\2\2\u00c8\u00cc\5\60\31\2\u00c9\u00cc\5$\23\2\u00ca\u00cc\5&\24\2\u00cb"+ + "\u00c8\3\2\2\2\u00cb\u00c9\3\2\2\2\u00cb\u00ca\3\2\2\2\u00cc#\3\2\2\2"+ + "\u00cd\u00cf\7\17\2\2\u00ce\u00cd\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cf\u00d0"+ + "\3\2\2\2\u00d0\u00d5\7)\2\2\u00d1\u00d2\7\31\2\2\u00d2\u00d3\5*\26\2\u00d3"+ + "\u00d4\7\32\2\2\u00d4\u00d6\3\2\2\2\u00d5\u00d1\3\2\2\2\u00d5\u00d6\3"+ + "\2\2\2\u00d6%\3\2\2\2\u00d7\u00d8\5,\27\2\u00d8\u00d9\5(\25\2\u00d9\u00da"+ + "\5,\27\2\u00da\'\3\2\2\2\u00db\u00dc\t\3\2\2\u00dc)\3\2\2\2\u00dd\u00e0"+ + "\5,\27\2\u00de\u00df\7\6\2\2\u00df\u00e1\5*\26\2\u00e0\u00de\3\2\2\2\u00e0"+ + "\u00e1\3\2\2\2\u00e1+\3\2\2\2\u00e2\u00e3\b\27\1\2\u00e3\u00f6\7)\2\2"+ + "\u00e4\u00e5\7)\2\2\u00e5\u00e7\7\31\2\2\u00e6\u00e8\5*\26\2\u00e7\u00e6"+ + "\3\2\2\2\u00e7\u00e8\3\2\2\2\u00e8\u00e9\3\2\2\2\u00e9\u00f6\7\32\2\2"+ + "\u00ea\u00f6\7+\2\2\u00eb\u00f6\7,\2\2\u00ec\u00f6\7*\2\2\u00ed\u00f6"+ + "\7\4\2\2\u00ee\u00ef\7\31\2\2\u00ef\u00f0\5,\27\2\u00f0\u00f1\7\32\2\2"+ + "\u00f1\u00f6\3\2\2\2\u00f2\u00f6\5.\30\2\u00f3\u00f4\7\17\2\2\u00f4\u00f6"+ + "\5,\27\7\u00f5\u00e2\3\2\2\2\u00f5\u00e4\3\2\2\2\u00f5\u00ea\3\2\2\2\u00f5"+ + "\u00eb\3\2\2\2\u00f5\u00ec\3\2\2\2\u00f5\u00ed\3\2\2\2\u00f5\u00ee\3\2"+ + "\2\2\u00f5\u00f2\3\2\2\2\u00f5\u00f3\3\2\2\2\u00f6\u0105\3\2\2\2\u00f7"+ + "\u00f8\f\6\2\2\u00f8\u00f9\7\22\2\2\u00f9\u0104\5,\27\6\u00fa\u00fb\f"+ + "\5\2\2\u00fb\u00fc\t\4\2\2\u00fc\u0104\5,\27\6\u00fd\u00fe\f\4\2\2\u00fe"+ + "\u00ff\t\5\2\2\u00ff\u0104\5,\27\5\u0100\u0101\f\3\2\2\u0101\u0102\7\24"+ + "\2\2\u0102\u0104\5,\27\4\u0103\u00f7\3\2\2\2\u0103\u00fa\3\2\2\2\u0103"+ + "\u00fd\3\2\2\2\u0103\u0100\3\2\2\2\u0104\u0107\3\2\2\2\u0105\u0103\3\2"+ + "\2\2\u0105\u0106\3\2\2\2\u0106-\3\2\2\2\u0107\u0105\3\2\2\2\u0108\u0109"+ + "\t\6\2\2\u0109\u010a\7\5\2\2\u010a\u010b\7\5\2\2\u010b\u010c\t\6\2\2\u010c"+ + "/\3\2\2\2\u010d\u010f\7\17\2\2\u010e\u010d\3\2\2\2\u010e\u010f\3\2\2\2"+ + "\u010f\u0110\3\2\2\2\u0110\u0111\7\27\2\2\u0111\u0116\7)\2\2\u0112\u0113"+ + "\7\33\2\2\u0113\u0114\5*\26\2\u0114\u0115\7\34\2\2\u0115\u0117\3\2\2\2"+ + "\u0116\u0112\3\2\2\2\u0116\u0117\3\2\2\2\u0117\u011c\3\2\2\2\u0118\u0119"+ + "\7\31\2\2\u0119\u011a\5*\26\2\u011a\u011b\7\32\2\2\u011b\u011d\3\2\2\2"+ + "\u011c\u0118\3\2\2\2\u011c\u011d\3\2\2\2\u011d\61\3\2\2\2\u011e\u011f"+ + "\5\64\33\2\u011f\63\3\2\2\2\u0120\u0121\7\26\2\2\u0121\u0122\7\3\2\2\u0122"+ + "\u0123\7)\2\2\u0123\u0124\7\5\2\2\u0124\65\3\2\2\2\u0125\u0128\58\35\2"+ + "\u0126\u0127\7\6\2\2\u0127\u0129\5\66\34\2\u0128\u0126\3\2\2\2\u0128\u0129"+ + "\3\2\2\2\u0129\67\3\2\2\2\u012a\u012d\5:\36\2\u012b\u012d\5<\37\2\u012c"+ + "\u012a\3\2\2\2\u012c\u012b\3\2\2\2\u012d9\3\2\2\2\u012e\u0135\7)\2\2\u012f"+ + "\u0135\7,\2\2\u0130\u0132\7\17\2\2\u0131\u0130\3\2\2\2\u0131\u0132\3\2"+ + "\2\2\u0132\u0133\3\2\2\2\u0133\u0135\7+\2\2\u0134\u012e\3\2\2\2\u0134"+ + "\u012f\3\2\2\2\u0134\u0131\3\2\2\2\u0135;\3\2\2\2\u0136\u0137\t\7\2\2"+ + "\u0137=\3\2\2\2\u0138\u013a\7\35\2\2\u0139\u013b\5$\23\2\u013a\u0139\3"+ + "\2\2\2\u013a\u013b\3\2\2\2\u013b\u0140\3\2\2\2\u013c\u013d\7\6\2\2\u013d"+ + "\u013f\5$\23\2\u013e\u013c\3\2\2\2\u013f\u0142\3\2\2\2\u0140\u013e\3\2"+ + "\2\2\u0140\u0141\3\2\2\2\u0141\u0143\3\2\2\2\u0142\u0140\3\2\2\2\u0143"+ + "\u0144\7\36\2\2\u0144?\3\2\2\2\u0145\u0147\5> \2\u0146\u0145\3\2\2\2\u0147"+ + "\u014a\3\2\2\2\u0148\u0146\3\2\2\2\u0148\u0149\3\2\2\2\u0149\u014b\3\2"+ + "\2\2\u014a\u0148\3\2\2\2\u014b\u014c\7\2\2\3\u014cA\3\2\2\2.CFM`hlpty"+ + "~\u0082\u0088\u008d\u0092\u0094\u0097\u009c\u00a5\u00aa\u00ad\u00b1\u00b3"+ + "\u00ba\u00be\u00c3\u00c6\u00cb\u00ce\u00d5\u00e0\u00e7\u00f5\u0103\u0105"+ + "\u010e\u0116\u011c\u0128\u012c\u0131\u0134\u013a\u0140\u0148"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java new file mode 100644 index 000000000..39b3c55e7 --- /dev/null +++ b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java @@ -0,0 +1,319 @@ +// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 +package at.ac.tuwien.kr.alpha.antlr; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link ASPCore2Parser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface ASPCore2Visitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link ASPCore2Parser#program}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitProgram(ASPCore2Parser.ProgramContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#statements}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatements(ASPCore2Parser.StatementsContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#query}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitQuery(ASPCore2Parser.QueryContext ctx); + /** + * Visit a parse tree produced by the {@code statement_fact} + * labeled alternative in {@link ASPCore2Parser#statement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatement_fact(ASPCore2Parser.Statement_factContext ctx); + /** + * Visit a parse tree produced by the {@code statement_constraint} + * labeled alternative in {@link ASPCore2Parser#statement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx); + /** + * Visit a parse tree produced by the {@code statement_rule} + * labeled alternative in {@link ASPCore2Parser#statement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatement_rule(ASPCore2Parser.Statement_ruleContext ctx); + /** + * Visit a parse tree produced by the {@code statement_weightConstraint} + * labeled alternative in {@link ASPCore2Parser#statement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatement_weightConstraint(ASPCore2Parser.Statement_weightConstraintContext ctx); + /** + * Visit a parse tree produced by the {@code statement_directive} + * labeled alternative in {@link ASPCore2Parser#statement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatement_directive(ASPCore2Parser.Statement_directiveContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#head}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitHead(ASPCore2Parser.HeadContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#body}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBody(ASPCore2Parser.BodyContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#disjunction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDisjunction(ASPCore2Parser.DisjunctionContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#choice}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitChoice(ASPCore2Parser.ChoiceContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#choice_elements}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#choice_element}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitChoice_element(ASPCore2Parser.Choice_elementContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#aggregate}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAggregate(ASPCore2Parser.AggregateContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#aggregate_elements}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAggregate_elements(ASPCore2Parser.Aggregate_elementsContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#aggregate_element}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#aggregate_function}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAggregate_function(ASPCore2Parser.Aggregate_functionContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#weight_at_level}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWeight_at_level(ASPCore2Parser.Weight_at_levelContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#naf_literals}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#naf_literal}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#classical_literal}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitClassical_literal(ASPCore2Parser.Classical_literalContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#builtin_atom}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#binop}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBinop(ASPCore2Parser.BinopContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#terms}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerms(ASPCore2Parser.TermsContext ctx); + /** + * Visit a parse tree produced by the {@code term_number} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_number(ASPCore2Parser.Term_numberContext ctx); + /** + * Visit a parse tree produced by the {@code term_anonymousVariable} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx); + /** + * Visit a parse tree produced by the {@code term_const} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_const(ASPCore2Parser.Term_constContext ctx); + /** + * Visit a parse tree produced by the {@code term_minusArithTerm} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx); + /** + * Visit a parse tree produced by the {@code term_bitxorArithTerm} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx); + /** + * Visit a parse tree produced by the {@code term_interval} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx); + /** + * Visit a parse tree produced by the {@code term_variable} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_variable(ASPCore2Parser.Term_variableContext ctx); + /** + * Visit a parse tree produced by the {@code term_timesdivmodArithTerm} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx); + /** + * Visit a parse tree produced by the {@code term_plusminusArithTerm} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx); + /** + * Visit a parse tree produced by the {@code term_powerArithTerm} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx); + /** + * Visit a parse tree produced by the {@code term_func} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_func(ASPCore2Parser.Term_funcContext ctx); + /** + * Visit a parse tree produced by the {@code term_string} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_string(ASPCore2Parser.Term_stringContext ctx); + /** + * Visit a parse tree produced by the {@code term_parenthesisedTerm} + * labeled alternative in {@link ASPCore2Parser#term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTerm_parenthesisedTerm(ASPCore2Parser.Term_parenthesisedTermContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#interval}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInterval(ASPCore2Parser.IntervalContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#external_atom}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternal_atom(ASPCore2Parser.External_atomContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#directive}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDirective(ASPCore2Parser.DirectiveContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#directive_enumeration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#basic_terms}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#basic_term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBasic_term(ASPCore2Parser.Basic_termContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#ground_term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGround_term(ASPCore2Parser.Ground_termContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#variable_term}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitVariable_term(ASPCore2Parser.Variable_termContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#answer_set}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAnswer_set(ASPCore2Parser.Answer_setContext ctx); + /** + * Visit a parse tree produced by {@link ASPCore2Parser#answer_sets}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx); +} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java new file mode 100644 index 000000000..2a3f15b4e --- /dev/null +++ b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java @@ -0,0 +1,209 @@ +// Generated from at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 by ANTLR 4.7 +package at.ac.tuwien.kr.alpha.antlr; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class ASPLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + ANONYMOUS_VARIABLE=1, DOT=2, COMMA=3, QUERY_MARK=4, COLON=5, SEMICOLON=6, + OR=7, NAF=8, CONS=9, WCONS=10, PLUS=11, MINUS=12, TIMES=13, DIV=14, POWER=15, + MODULO=16, BITXOR=17, AT=18, SHARP=19, AMPERSAND=20, QUOTE=21, PAREN_OPEN=22, + PAREN_CLOSE=23, SQUARE_OPEN=24, SQUARE_CLOSE=25, CURLY_OPEN=26, CURLY_CLOSE=27, + EQUAL=28, UNEQUAL=29, LESS=30, GREATER=31, LESS_OR_EQ=32, GREATER_OR_EQ=33, + AGGREGATE_COUNT=34, AGGREGATE_MAX=35, AGGREGATE_MIN=36, AGGREGATE_SUM=37, + ID=38, VARIABLE=39, NUMBER=40, QUOTED_STRING=41, COMMENT=42, MULTI_LINE_COMMEN=43, + BLANK=44; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + public static final String[] ruleNames = { + "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", "SEMICOLON", + "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", "POWER", + "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", + "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", + "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", + "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", + "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", + "BLANK" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'_'", "'.'", "','", "'?'", "':'", "';'", "'|'", "'not'", "':-'", + "':~'", "'+'", "'-'", "'*'", "'/'", "'**'", "'\\'", "'^'", "'@'", "'#'", + "'&'", "'\"'", "'('", "')'", "'['", "']'", "'{'", "'}'", "'='", null, + "'<'", "'>'", "'<='", "'>='", "'#count'", "'#max'", "'#min'", "'#sum'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", "SEMICOLON", + "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", "POWER", + "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", + "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", + "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", + "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", + "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", + "BLANK" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public ASPLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "ASPLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2.\u00ff\b\1\4\2\t"+ + "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ + "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ + ",\t,\4-\t-\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t"+ + "\3\t\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17"+ + "\3\17\3\20\3\20\3\20\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25"+ + "\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34"+ + "\3\35\3\35\3\36\3\36\3\36\3\36\5\36\u009d\n\36\3\37\3\37\3 \3 \3!\3!\3"+ + "!\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3"+ + "&\3&\3&\3&\3\'\3\'\7\'\u00c1\n\'\f\'\16\'\u00c4\13\'\3(\3(\7(\u00c8\n"+ + "(\f(\16(\u00cb\13(\3)\3)\3)\7)\u00d0\n)\f)\16)\u00d3\13)\5)\u00d5\n)\3"+ + "*\3*\3*\3*\7*\u00db\n*\f*\16*\u00de\13*\3*\3*\3+\3+\7+\u00e4\n+\f+\16"+ + "+\u00e7\13+\3+\3+\3,\3,\3,\3,\7,\u00ef\n,\f,\16,\u00f2\13,\3,\3,\3,\3"+ + ",\3,\3-\6-\u00fa\n-\r-\16-\u00fb\3-\3-\4\u00dc\u00f0\2.\3\3\5\4\7\5\t"+ + "\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23"+ + "%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G"+ + "%I&K\'M(O)Q*S+U,W-Y.\3\2\5\6\2\62;C\\aac|\4\2\f\f\17\17\5\2\13\f\16\17"+ + "\"\"\2\u0108\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2"+ + "\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2"+ + "\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2"+ + "\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2"+ + "\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3"+ + "\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2"+ + "\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2"+ + "S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\3[\3\2\2\2\5]\3\2\2\2\7_\3"+ + "\2\2\2\ta\3\2\2\2\13c\3\2\2\2\re\3\2\2\2\17g\3\2\2\2\21i\3\2\2\2\23m\3"+ + "\2\2\2\25p\3\2\2\2\27s\3\2\2\2\31u\3\2\2\2\33w\3\2\2\2\35y\3\2\2\2\37"+ + "{\3\2\2\2!~\3\2\2\2#\u0080\3\2\2\2%\u0082\3\2\2\2\'\u0084\3\2\2\2)\u0086"+ + "\3\2\2\2+\u0088\3\2\2\2-\u008a\3\2\2\2/\u008c\3\2\2\2\61\u008e\3\2\2\2"+ + "\63\u0090\3\2\2\2\65\u0092\3\2\2\2\67\u0094\3\2\2\29\u0096\3\2\2\2;\u009c"+ + "\3\2\2\2=\u009e\3\2\2\2?\u00a0\3\2\2\2A\u00a2\3\2\2\2C\u00a5\3\2\2\2E"+ + "\u00a8\3\2\2\2G\u00af\3\2\2\2I\u00b4\3\2\2\2K\u00b9\3\2\2\2M\u00be\3\2"+ + "\2\2O\u00c5\3\2\2\2Q\u00d4\3\2\2\2S\u00d6\3\2\2\2U\u00e1\3\2\2\2W\u00ea"+ + "\3\2\2\2Y\u00f9\3\2\2\2[\\\7a\2\2\\\4\3\2\2\2]^\7\60\2\2^\6\3\2\2\2_`"+ + "\7.\2\2`\b\3\2\2\2ab\7A\2\2b\n\3\2\2\2cd\7<\2\2d\f\3\2\2\2ef\7=\2\2f\16"+ + "\3\2\2\2gh\7~\2\2h\20\3\2\2\2ij\7p\2\2jk\7q\2\2kl\7v\2\2l\22\3\2\2\2m"+ + "n\7<\2\2no\7/\2\2o\24\3\2\2\2pq\7<\2\2qr\7\u0080\2\2r\26\3\2\2\2st\7-"+ + "\2\2t\30\3\2\2\2uv\7/\2\2v\32\3\2\2\2wx\7,\2\2x\34\3\2\2\2yz\7\61\2\2"+ + "z\36\3\2\2\2{|\7,\2\2|}\7,\2\2} \3\2\2\2~\177\7^\2\2\177\"\3\2\2\2\u0080"+ + "\u0081\7`\2\2\u0081$\3\2\2\2\u0082\u0083\7B\2\2\u0083&\3\2\2\2\u0084\u0085"+ + "\7%\2\2\u0085(\3\2\2\2\u0086\u0087\7(\2\2\u0087*\3\2\2\2\u0088\u0089\7"+ + "$\2\2\u0089,\3\2\2\2\u008a\u008b\7*\2\2\u008b.\3\2\2\2\u008c\u008d\7+"+ + "\2\2\u008d\60\3\2\2\2\u008e\u008f\7]\2\2\u008f\62\3\2\2\2\u0090\u0091"+ + "\7_\2\2\u0091\64\3\2\2\2\u0092\u0093\7}\2\2\u0093\66\3\2\2\2\u0094\u0095"+ + "\7\177\2\2\u00958\3\2\2\2\u0096\u0097\7?\2\2\u0097:\3\2\2\2\u0098\u0099"+ + "\7>\2\2\u0099\u009d\7@\2\2\u009a\u009b\7#\2\2\u009b\u009d\7?\2\2\u009c"+ + "\u0098\3\2\2\2\u009c\u009a\3\2\2\2\u009d<\3\2\2\2\u009e\u009f\7>\2\2\u009f"+ + ">\3\2\2\2\u00a0\u00a1\7@\2\2\u00a1@\3\2\2\2\u00a2\u00a3\7>\2\2\u00a3\u00a4"+ + "\7?\2\2\u00a4B\3\2\2\2\u00a5\u00a6\7@\2\2\u00a6\u00a7\7?\2\2\u00a7D\3"+ + "\2\2\2\u00a8\u00a9\7%\2\2\u00a9\u00aa\7e\2\2\u00aa\u00ab\7q\2\2\u00ab"+ + "\u00ac\7w\2\2\u00ac\u00ad\7p\2\2\u00ad\u00ae\7v\2\2\u00aeF\3\2\2\2\u00af"+ + "\u00b0\7%\2\2\u00b0\u00b1\7o\2\2\u00b1\u00b2\7c\2\2\u00b2\u00b3\7z\2\2"+ + "\u00b3H\3\2\2\2\u00b4\u00b5\7%\2\2\u00b5\u00b6\7o\2\2\u00b6\u00b7\7k\2"+ + "\2\u00b7\u00b8\7p\2\2\u00b8J\3\2\2\2\u00b9\u00ba\7%\2\2\u00ba\u00bb\7"+ + "u\2\2\u00bb\u00bc\7w\2\2\u00bc\u00bd\7o\2\2\u00bdL\3\2\2\2\u00be\u00c2"+ + "\4c|\2\u00bf\u00c1\t\2\2\2\u00c0\u00bf\3\2\2\2\u00c1\u00c4\3\2\2\2\u00c2"+ + "\u00c0\3\2\2\2\u00c2\u00c3\3\2\2\2\u00c3N\3\2\2\2\u00c4\u00c2\3\2\2\2"+ + "\u00c5\u00c9\4C\\\2\u00c6\u00c8\t\2\2\2\u00c7\u00c6\3\2\2\2\u00c8\u00cb"+ + "\3\2\2\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2\2\2\u00caP\3\2\2\2\u00cb"+ + "\u00c9\3\2\2\2\u00cc\u00d5\7\62\2\2\u00cd\u00d1\4\63;\2\u00ce\u00d0\4"+ + "\62;\2\u00cf\u00ce\3\2\2\2\u00d0\u00d3\3\2\2\2\u00d1\u00cf\3\2\2\2\u00d1"+ + "\u00d2\3\2\2\2\u00d2\u00d5\3\2\2\2\u00d3\u00d1\3\2\2\2\u00d4\u00cc\3\2"+ + "\2\2\u00d4\u00cd\3\2\2\2\u00d5R\3\2\2\2\u00d6\u00dc\5+\26\2\u00d7\u00d8"+ + "\7^\2\2\u00d8\u00db\7$\2\2\u00d9\u00db\13\2\2\2\u00da\u00d7\3\2\2\2\u00da"+ + "\u00d9\3\2\2\2\u00db\u00de\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dc\u00da\3\2"+ + "\2\2\u00dd\u00df\3\2\2\2\u00de\u00dc\3\2\2\2\u00df\u00e0\5+\26\2\u00e0"+ + "T\3\2\2\2\u00e1\u00e5\7\'\2\2\u00e2\u00e4\n\3\2\2\u00e3\u00e2\3\2\2\2"+ + "\u00e4\u00e7\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6\u00e8"+ + "\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e8\u00e9\b+\2\2\u00e9V\3\2\2\2\u00ea\u00eb"+ + "\7\'\2\2\u00eb\u00ec\7,\2\2\u00ec\u00f0\3\2\2\2\u00ed\u00ef\13\2\2\2\u00ee"+ + "\u00ed\3\2\2\2\u00ef\u00f2\3\2\2\2\u00f0\u00f1\3\2\2\2\u00f0\u00ee\3\2"+ + "\2\2\u00f1\u00f3\3\2\2\2\u00f2\u00f0\3\2\2\2\u00f3\u00f4\7,\2\2\u00f4"+ + "\u00f5\7\'\2\2\u00f5\u00f6\3\2\2\2\u00f6\u00f7\b,\2\2\u00f7X\3\2\2\2\u00f8"+ + "\u00fa\t\4\2\2\u00f9\u00f8\3\2\2\2\u00fa\u00fb\3\2\2\2\u00fb\u00f9\3\2"+ + "\2\2\u00fb\u00fc\3\2\2\2\u00fc\u00fd\3\2\2\2\u00fd\u00fe\b-\2\2\u00fe"+ + "Z\3\2\2\2\r\2\u009c\u00c2\u00c9\u00d1\u00d4\u00da\u00dc\u00e5\u00f0\u00fb"+ + "\3\2\3\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java new file mode 100644 index 000000000..fada6277c --- /dev/null +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java @@ -0,0 +1,226 @@ +/** + * 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. + * + * 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; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.config.InputConfig; +import at.ac.tuwien.kr.alpha.config.SystemConfig; +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.grounder.GrounderFactory; +import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.grounder.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation; +import at.ac.tuwien.kr.alpha.solver.Solver; +import at.ac.tuwien.kr.alpha.solver.SolverFactory; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.charset.CodingErrorAction; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class AlphaImpl implements Alpha { + + private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); + + private SystemConfig config = new SystemConfig(); // The config is initialized with default values. + + public AlphaImpl(SystemConfig cfg) { + this.config = cfg; + } + + public AlphaImpl() { + } + + public InputProgram readProgram(InputConfig cfg) throws IOException { + InputProgram.Builder prgBuilder = InputProgram.builder(); + InputProgram tmpProg; + if (!cfg.getFiles().isEmpty()) { + tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); + prgBuilder.accumulate(tmpProg); + } + if (!cfg.getAspStrings().isEmpty()) { + tmpProg = readProgramString(StringUtils.join(cfg.getAspStrings(), System.lineSeparator()), cfg.getPredicateMethods()); + prgBuilder.accumulate(tmpProg); + } + return prgBuilder.build(); + } + + 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[] {})); + } + + public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { + ProgramParser parser = new ProgramParser(externals); + InputProgram.Builder prgBuilder = InputProgram.builder(); + InputProgram tmpProg; + for (Path path : paths) { + CharStream stream; + if (!literate) { + stream = CharStreams.fromPath(path); + } else { + stream = CharStreams.fromChannel(Util.streamToChannel(Util.literate(Files.lines(path))), 4096, CodingErrorAction.REPLACE, path.toString()); + } + tmpProg = parser.parse(stream); + prgBuilder.accumulate(tmpProg); + } + return prgBuilder.build(); + } + + public InputProgram readProgramString(String aspString, Map externals) { + ProgramParser parser = new ProgramParser(externals); + return parser.parse(aspString); + } + + public InputProgram readProgramString(String aspString) { + return readProgramString(aspString, null); + } + + public NormalProgram normalizeProgram(InputProgram program) { + return new NormalizeProgramTransformation(config.isUseNormalizationGrid()).apply(program); + } + + public InternalProgram performProgramPreprocessing(InternalProgram program) { + LOGGER.debug("Preprocessing InternalProgram!"); + InternalProgram retVal = program; + if (config.isEvaluateStratifiedPart()) { + AnalyzedProgram analyzed = new AnalyzedProgram(program.getRules(), program.getFacts()); + retVal = new StratifiedEvaluation().apply(analyzed); + } + return retVal; + } + + public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { + LOGGER.debug("Preprocessing AnalyzedProgram!"); + InternalProgram retVal = program; + if (config.isEvaluateStratifiedPart()) { + retVal = new StratifiedEvaluation().apply(program); + } + return retVal; + } + + /** + * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the + * program analysis and normalization aren't of interest. + */ + public Stream solve(InputProgram program) { + return solve(program, InputConfig.DEFAULT_FILTER); + } + + /** + * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where + * details of the program analysis and normalization aren't of interest. + */ + public Stream solve(InputProgram program, java.util.function.Predicate filter) { + NormalProgram normalized = normalizeProgram(program); + return solve(normalized, filter); + } + + /** + * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the + * program analysis aren't of interest. + */ + public Stream solve(NormalProgram program, java.util.function.Predicate filter) { + InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); + return solve(preprocessed, filter); + } + + /** + * Overloaded version of solve({@link InternalProgram}, {@link Predicate}) that uses a default filter (accept + * everything). + * + * @param program the program to solve + * @return a stream of answer sets + */ + public Stream solve(InternalProgram program) { + return solve(program, InputConfig.DEFAULT_FILTER); + } + + /** + * 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 + * @return a Stream of answer sets representing stable models of the given program + */ + public Stream solve(InternalProgram program, java.util.function.Predicate filter) { + Stream retVal = prepareSolverFor(program, filter).stream(); + return config.isSortAnswerSets() ? retVal.sorted() : retVal; + } + + /** + * 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. + * @return a solver (and accompanying grounder) instance pre-loaded with the given program. + */ + public Solver prepareSolverFor(InternalProgram 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 SystemConfig getConfig() { + return config; + } + + public void setConfig(SystemConfig config) { + this.config = config; + } + +} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java similarity index 82% rename from api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java index 9f2f459b1..e03e8530e 100644 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java @@ -1,17 +1,17 @@ /** * Copyright (c) 2020, the Alpha Team. * 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. - * + * 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 @@ -28,26 +28,14 @@ import at.ac.tuwien.kr.alpha.api.externals.stdlib.AspStandardLibrary; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.BinaryPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.BindingMethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.IntPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.LongPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.MethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.SuppliedPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.UnaryPredicateInterpretation; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.*; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; import org.reflections.Reflections; import org.reflections.scanners.MethodAnnotationsScanner; 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 java.util.*; public final class Externals { @@ -106,7 +94,7 @@ public static PredicateInterpretation processPredicateMethod(Method method) { } throw new IllegalArgumentException("Passed method has unexpected return type. Should be either boolean or start with " - + PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX + "."); + + PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX + "."); } public static PredicateInterpretation processPredicate(java.util.function.Predicate predicate) { @@ -134,7 +122,7 @@ public static PredicateInterpretation processPredicate(java.util.function.Suppli * Every item in the collection is wrapped in a {@link ConstantTerm}, which is the argument of a unary predicate whose * symbol is the class name of the given class (i.e. the declared type of objects inside the collection), modified to * start with a lower-case letter. - * + * * @param the type of the objects to use as facts * @param classOfExtFacts the {@link Class} object of the value type * @param extFacts a {@link Collection} of objects of type classOfExtFacts @@ -146,7 +134,7 @@ public static > List asFacts(Class classOfExtFa String javaName = classOfExtFacts.getSimpleName(); String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. for (T instance : extFacts) { - retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.Predicate.getInstance(name, 1), ConstantTerm.getInstance(instance))); + retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.PredicateImpl.getInstance(name, 1), ConstantTermImpl.getInstance(instance))); } return retVal; } diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java similarity index 100% rename from api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java deleted file mode 100644 index 40a316159..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; - -import java.util.SortedSet; - -public interface AnswerSet extends Comparable { - SortedSet getPredicates(); - - SortedSet getPredicateInstances(Predicate predicate); - - boolean isEmpty(); - - @Override - default int compareTo(AnswerSet other) { - final SortedSet predicates = this.getPredicates(); - int result = Util.compareSortedSets(predicates, other.getPredicates()); - - if (result != 0) { - return result; - } - - for (Predicate predicate : predicates) { - result = Util.compareSortedSets(this.getPredicateInstances(predicate), other.getPredicateInstances(predicate)); - - if (result != 0) { - return result; - } - } - - return 0; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java index 9cc1b9c0d..3ebe7a880 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java @@ -3,7 +3,9 @@ import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import java.util.*; import java.util.stream.Collectors; @@ -14,10 +16,10 @@ public class AnswerSetBuilder { private boolean firstInstance = true; private String predicateSymbol; - private Predicate predicate; - private SortedSet predicates = new TreeSet<>(); + private PredicateImpl predicate; + private SortedSet predicates = new TreeSet<>(); private SortedSet instances = new TreeSet<>(); - private Map> predicateInstances = new HashMap<>(); + private Map> predicateInstances = new HashMap<>(); public AnswerSetBuilder() { } @@ -35,7 +37,7 @@ public AnswerSetBuilder(AnswerSetBuilder copy) { private void flush() { if (firstInstance) { - predicate = Predicate.getInstance(predicateSymbol, 0); + predicate = PredicateImpl.getInstance(predicateSymbol, 0); predicates.add(predicate); predicateInstances.put(predicate, new TreeSet<>(singletonList(new BasicAtom(predicate)))); } else { @@ -63,15 +65,15 @@ public AnswerSetBuilder predicate(String predicateSymbol) { public final > AnswerSetBuilder instance(final T... terms) { if (firstInstance) { firstInstance = false; - predicate = Predicate.getInstance(predicateSymbol, terms.length); + predicate = PredicateImpl.getInstance(predicateSymbol, terms.length); predicates.add(predicate); } // Note that usage of terms does not pollute the heap, // since we are only reading, not writing. - List termList = Stream + List termList = Stream .of(terms) - .map(ConstantTerm::getInstance) + .map(ConstantTermImpl::getInstance) .collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); @@ -81,11 +83,11 @@ public final > AnswerSetBuilder instance(final T... term public AnswerSetBuilder symbolicInstance(String... terms) { if (firstInstance) { firstInstance = false; - predicate = Predicate.getInstance(predicateSymbol, terms.length); + predicate = PredicateImpl.getInstance(predicateSymbol, terms.length); predicates.add(predicate); } - List termList = Stream.of(terms).map(ConstantTerm::getSymbolicInstance).collect(Collectors.toList()); + List termList = Stream.of(terms).map(ConstantTermImpl::getSymbolicInstance).collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); return this; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java index ec8278b82..eb5f81434 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java @@ -28,6 +28,7 @@ package at.ac.tuwien.kr.alpha.common; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.solver.AtomCounter; import java.util.Iterator; @@ -58,7 +59,7 @@ public interface AtomStore { * @param atom the atom to translate. * @return the Atom object represented by the int. */ - Atom get(int atom); + AtomImpl get(int atom); /** * Translates an atom represented as Atom object into an int. @@ -74,7 +75,7 @@ public interface AtomStore { * @param groundAtom the ground atom to look up in the store. * @return the integer ID of the ground atom, possibly newly assigned. */ - int putIfAbsent(Atom groundAtom); + int putIfAbsent(AtomImpl groundAtom); /** * Returns whether the given ground atom is known to the AtomStore. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java index 1e94e8381..d95771477 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java @@ -28,6 +28,7 @@ package at.ac.tuwien.kr.alpha.common; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.solver.AtomCounter; @@ -56,7 +57,7 @@ public AtomStoreImpl() { } @Override - public int putIfAbsent(Atom groundAtom) { + public int putIfAbsent(AtomImpl groundAtom) { if (!groundAtom.isGround()) { throw new IllegalArgumentException("Atom must be ground: " + groundAtom); } @@ -111,7 +112,7 @@ public int getMaxAtomId() { } @Override - public Atom get(int atom) { + public AtomImpl get(int atom) { try { return atomIdsToInternalBasicAtoms.get(atom); } catch (IndexOutOfBoundsException e) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java index 7d4f8137d..07a4b0203 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java @@ -1,5 +1,6 @@ package at.ac.tuwien.kr.alpha.common; +import at.ac.tuwien.kr.alpha.Util; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import java.util.Iterator; @@ -16,16 +17,16 @@ public class BasicAnswerSet implements AnswerSet { public static final BasicAnswerSet EMPTY = new BasicAnswerSet(emptySortedSet(), emptyMap()); - private final SortedSet predicates; - private final Map> predicateInstances; + private final SortedSet predicates; + private final Map> predicateInstances; - public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { + public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { this.predicates = predicates; this.predicateInstances = predicateInstances; } @Override - public SortedSet getPredicates() { + public SortedSet getPredicates() { return predicates; } @@ -46,7 +47,7 @@ public String toString() { } final StringBuilder sb = new StringBuilder("{ "); - for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { + for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { Predicate predicate = iterator.next(); Set instances = getPredicateInstances(predicate); @@ -92,4 +93,24 @@ public boolean equals(Object o) { public int hashCode() { return 31 * predicates.hashCode() + predicateInstances.hashCode(); } + + @Override + public int compareTo(AnswerSet other) { + final SortedSet predicates = this.getPredicates(); + int result = Util.compareSortedSets(predicates, other.getPredicates()); + + if (result != 0) { + return result; + } + + for (Predicate predicate : predicates) { + result = Util.compareSortedSets(this.getPredicateInstances(predicate), other.getPredicateInstances(predicate)); + + if (result != 0) { + return result; + } + } + + return 0; + } } \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java index 3aeefc182..c0b762cbe 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java @@ -33,7 +33,7 @@ public ComparisonOperator getNegation() { throw oops("Unknown binary operator encountered, cannot negate it"); } - public Predicate predicate() { - return Predicate.getInstance(this.asString, 2); + public PredicateImpl predicate() { + return PredicateImpl.getInstance(this.asString, 2); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java similarity index 73% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java index e181c9200..ddec9604a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java @@ -3,31 +3,31 @@ /** * Copyright (c) 2016, the Alpha Team. */ -public class Predicate implements Comparable { - private static final Interner INTERNER = new Interner<>(); +public class PredicateImpl implements Comparable, Predicate { + private static final Interner INTERNER = new Interner<>(); private final String name; private final int arity; private final boolean internal; private final boolean solverInternal; - protected Predicate(String name, int arity, boolean internal, boolean solverInternal) { + protected PredicateImpl(String name, int arity, boolean internal, boolean solverInternal) { this.name = name; this.arity = arity; this.internal = internal; this.solverInternal = solverInternal; } - public static Predicate getInstance(String symbol, int arity) { + public static PredicateImpl getInstance(String symbol, int arity) { return getInstance(symbol, arity, false, false); } - public static Predicate getInstance(String symbol, int arity, boolean internal) { + public static PredicateImpl getInstance(String symbol, int arity, boolean internal) { return getInstance(symbol, arity, internal, false); } - public static Predicate getInstance(String symbol, int arity, boolean internal, boolean solverInternal) { - return INTERNER.intern(new Predicate(symbol, arity, internal, solverInternal)); + public static PredicateImpl getInstance(String symbol, int arity, boolean internal, boolean solverInternal) { + return INTERNER.intern(new PredicateImpl(symbol, arity, internal, solverInternal)); } @Override @@ -44,11 +44,11 @@ public boolean equals(Object o) { return true; } - if (!(o instanceof Predicate)) { + if (!(o instanceof PredicateImpl)) { return false; } - Predicate predicate = (Predicate) o; + PredicateImpl predicate = (PredicateImpl) o; if (arity != predicate.arity) { return false; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java index 35139441f..0a655658c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java @@ -18,7 +18,7 @@ public SimpleAnswerSetFormatter(String atomSeparator) { @Override public String format(AnswerSet answerSet) { List predicateInstanceStrings = new ArrayList<>(); - for (Predicate p : answerSet.getPredicates()) { + for (PredicateImpl p : answerSet.getPredicates()) { SortedSet instances; if ((instances = answerSet.getPredicateInstances(p)) == null || instances.isEmpty()) { predicateInstanceStrings.add(p.getName()); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java index a1829269b..49bda0c52 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java @@ -28,8 +28,9 @@ package at.ac.tuwien.kr.alpha.common.atoms; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; @@ -40,16 +41,16 @@ import static at.ac.tuwien.kr.alpha.Util.join; import static at.ac.tuwien.kr.alpha.Util.oops; -public class AggregateAtom extends Atom { +public class AggregateAtom extends AtomImpl { private final ComparisonOperator lowerBoundOperator; - private final Term lowerBoundTerm; + private final TermImpl lowerBoundTerm; private final ComparisonOperator upperBoundOperator; private final Term upperBoundTerm; private final AGGREGATEFUNCTION aggregatefunction; private final List aggregateElements; - public AggregateAtom(ComparisonOperator lowerBoundOperator, Term lowerBoundTerm, ComparisonOperator upperBoundOperator, Term upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { + public AggregateAtom(ComparisonOperator lowerBoundOperator, TermImpl lowerBoundTerm, ComparisonOperator upperBoundOperator, Term upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { this.lowerBoundOperator = lowerBoundOperator; this.lowerBoundTerm = lowerBoundTerm; this.upperBoundOperator = upperBoundOperator; @@ -82,17 +83,17 @@ public AggregateLiteral toLiteral(boolean positive) { } @Override - public List getTerms() { + public List getTerms() { throw oops("Aggregate atom cannot report terms."); } @Override - public Atom withTerms(List terms) { + public AtomImpl withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for aggregate atoms!"); } @Override - public Predicate getPredicate() { + public PredicateImpl getPredicate() { throw oops("Aggregate atom cannot report predicate."); } @@ -164,7 +165,7 @@ public ComparisonOperator getLowerBoundOperator() { return lowerBoundOperator; } - public Term getLowerBoundTerm() { + public TermImpl getLowerBoundTerm() { return lowerBoundTerm; } @@ -193,9 +194,9 @@ public enum AGGREGATEFUNCTION { public static class AggregateElement { final List elementTerms; - final List elementLiterals; + final List elementLiterals; - public AggregateElement(List elementTerms, List elementLiterals) { + public AggregateElement(List elementTerms, List elementLiterals) { this.elementTerms = elementTerms; this.elementLiterals = elementLiterals; } @@ -204,7 +205,7 @@ public List getElementTerms() { return elementTerms; } - public List getElementLiterals() { + public List getElementLiterals() { return elementLiterals; } @@ -229,7 +230,7 @@ public List getOccurringVariables() { occurringVariables.add((VariableTerm) term); } } - for (Literal literal : elementLiterals) { + for (LiteralImpl literal : elementLiterals) { occurringVariables.addAll(literal.getBindingVariables()); occurringVariables.addAll(literal.getNonBindingVariables()); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java index 087b191c6..068232033 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java @@ -11,7 +11,7 @@ /** * Copyright (c) 2018, the Alpha Team. */ -public class AggregateLiteral extends Literal { +public class AggregateLiteral extends LiteralImpl { public AggregateLiteral(AggregateAtom atom, boolean positive) { super(atom, positive); } @@ -27,7 +27,7 @@ public AggregateLiteral negate() { } /** - * @see Atom#substitute(Substitution) + * @see AtomImpl#substitute(Substitution) */ @Override public AggregateLiteral substitute(Substitution substitution) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AtomImpl.java similarity index 74% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AtomImpl.java index 7c5b32f5e..7e8578e6a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AtomImpl.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2016-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. - * + * 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 @@ -28,7 +28,9 @@ package at.ac.tuwien.kr.alpha.common.atoms; import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import at.ac.tuwien.kr.alpha.grounder.Unifier; @@ -39,26 +41,15 @@ /** * An Atom is the common superclass of all representations of ASP atoms used by Alpha. */ -public abstract class Atom implements Comparable { - - public abstract Predicate getPredicate(); - - public abstract List getTerms(); +public abstract class AtomImpl implements Atom { /** * Creates a new Atom that represents this Atom, but has the given term list instead. - * + * * @param terms the terms to set. * @return a new Atom with the given terms set. */ - public abstract Atom withTerms(List terms); - - /** - * Returns whether this atom is ground, i.e., variable-free. - * - * @return true iff the terms of this atom contain no {@link VariableTerm}. - */ - public abstract boolean isGround(); + public abstract AtomImpl withTerms(List terms); /** * Returns the set of all variables occurring in the Atom. @@ -70,28 +61,30 @@ public Set getOccurringVariables() { /** * This method applies a substitution to the atom. Note that, depending on the atom and the substitution, the * resulting atom may still contain variables. - * + * * @param substitution the variable substitution to apply. * @return the atom resulting from the application of the substitution. */ - public abstract Atom substitute(Substitution substitution); + public abstract AtomImpl substitute(Substitution substitution); + + @Override + public abstract List getTerms(); + + @Override + public abstract PredicateImpl getPredicate(); /** * Creates a non-negated literal containing this atom. */ - public Literal toLiteral() { + @Override + public LiteralImpl toLiteral() { return toLiteral(true); } - /** - * Creates a literal containing this atom which will be negated if {@code positive} is {@code false}. - * - * @param positive the polarity of the resulting literal. - * @return a literal that is positive iff the given parameter is true. - */ - public abstract Literal toLiteral(boolean positive); + @Override + public abstract LiteralImpl toLiteral(boolean positive); - public Atom renameVariables(String newVariablePrefix) { + public AtomImpl renameVariables(String newVariablePrefix) { Unifier renamingSubstitution = new Unifier(); int counter = 0; for (VariableTerm variable : getOccurringVariables()) { @@ -106,8 +99,8 @@ public int compareTo(Atom o) { return 1; } - final List aTerms = this.getTerms(); - final List bTerms = o.getTerms(); + final List aTerms = this.getTerms(); + final List bTerms = o.getTerms(); if (aTerms.size() != bTerms.size()) { return Integer.compare(aTerms.size(), bTerms.size()); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java index 15e8dbe82..1fedbd4ac 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java @@ -27,8 +27,9 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; import java.util.Arrays; @@ -41,9 +42,9 @@ /** * Represents ordinary ASP atoms. */ -public class BasicAtom extends Atom implements VariableNormalizableAtom { - private final Predicate predicate; - private final List terms; +public class BasicAtom extends AtomImpl implements VariableNormalizableAtom { + private final PredicateImpl predicate; + private final List terms; private final boolean ground; /** @@ -52,7 +53,7 @@ public class BasicAtom extends Atom implements VariableNormalizableAtom { * @param predicate * @param terms */ - public BasicAtom(Predicate predicate, List terms) { + public BasicAtom(PredicateImpl predicate, List terms) { this.predicate = predicate; this.terms = terms; @@ -67,21 +68,21 @@ public BasicAtom(Predicate predicate, List terms) { this.ground = ground; } - public BasicAtom(Predicate predicate, Term... terms) { + public BasicAtom(PredicateImpl predicate, TermImpl... terms) { this(predicate, Arrays.asList(terms)); } - public BasicAtom(Predicate predicate) { + public BasicAtom(PredicateImpl predicate) { this(predicate, Collections.emptyList()); } @Override - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return predicate; } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -99,12 +100,12 @@ public BasicAtom substitute(Substitution substitution) { @Override public BasicAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = Term.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = TermImpl.renameTerms(terms, prefix, counterStartingValue); return new BasicAtom(predicate, renamedTerms); } @Override - public BasicLiteral toLiteral(boolean positive) { + public LiteralImpl toLiteral(boolean positive) { return new BasicLiteral(this, positive); } @@ -160,8 +161,7 @@ public int hashCode() { } @Override - public Atom withTerms(List terms) { + public AtomImpl withTerms(List terms) { return new BasicAtom(predicate, terms); } - } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java index c3a078fd8..306d97e87 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2017-2018, 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 @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; @@ -37,18 +37,18 @@ /** * Contains a potentially negated {@link BasicAtom}. - * + * * Copyright (c) 2017-2018, the Alpha Team. */ -public class BasicLiteral extends Literal { - +public class BasicLiteral extends LiteralImpl { + public BasicLiteral(BasicAtom atom, boolean positive) { super(atom, positive); } - + @Override public BasicAtom getAtom() { - return (BasicAtom)atom; + return (BasicAtom) atom; } /** @@ -60,7 +60,7 @@ public BasicLiteral negate() { } /** - * @see Atom#substitute(Substitution) + * @see AtomImpl#substitute(Substitution) */ @Override public BasicLiteral substitute(Substitution substitution) { @@ -69,7 +69,7 @@ public BasicLiteral substitute(Substitution substitution) { /** * Set of all variables occurring in the Atom that are potentially binding, i.e., variables in positive atoms. - * + * * @return */ @Override @@ -79,7 +79,7 @@ public Set getBindingVariables() { return Collections.emptySet(); } Set bindingVariables = new HashSet<>(); - for (Term term : atom.getTerms()) { + for (TermImpl term : atom.getTerms()) { bindingVariables.addAll(term.getOccurringVariables()); } return bindingVariables; @@ -87,7 +87,7 @@ public Set getBindingVariables() { /** * Set of all variables occurring in the Atom that are never binding, not even in positive atoms, e.g., variables in intervals or built-in atoms. - * + * * @return */ @Override @@ -97,7 +97,7 @@ public Set getNonBindingVariables() { return Collections.emptySet(); } Set nonbindingVariables = new HashSet<>(); - for (Term term : atom.getTerms()) { + for (TermImpl term : atom.getTerms()) { nonbindingVariables.addAll(term.getOccurringVariables()); } return nonbindingVariables; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java index 55c2629b3..bcd3991ab 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java @@ -28,8 +28,9 @@ package at.ac.tuwien.kr.alpha.common.atoms; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; import java.util.Arrays; @@ -39,28 +40,28 @@ /** * Represents a builtin comparison atom according to the standard. */ -public class ComparisonAtom extends Atom implements VariableNormalizableAtom { - private final Predicate predicate; +public class ComparisonAtom extends AtomImpl implements VariableNormalizableAtom { + private final PredicateImpl predicate; final ComparisonOperator operator; - private final List terms; + private final List terms; - private ComparisonAtom(List terms, ComparisonOperator operator) { + private ComparisonAtom(List terms, ComparisonOperator operator) { this.terms = terms; this.operator = operator; this.predicate = operator.predicate(); } - public ComparisonAtom(Term term1, Term term2, ComparisonOperator operator) { + public ComparisonAtom(TermImpl term1, TermImpl term2, ComparisonOperator operator) { this(Arrays.asList(term1, term2), operator); } @Override - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return predicate; } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -71,7 +72,7 @@ public boolean isGround() { @Override public ComparisonAtom substitute(Substitution substitution) { - List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); + List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); return new ComparisonAtom(substitutedTerms, operator); } @@ -115,12 +116,12 @@ public int hashCode() { @Override public ComparisonAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = Term.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = TermImpl.renameTerms(terms, prefix, counterStartingValue); return new ComparisonAtom(renamedTerms.get(0), renamedTerms.get(1), operator); } @Override - public Atom withTerms(List terms) { + public AtomImpl withTerms(List terms) { return new ComparisonAtom(terms, operator); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java index d7639e108..0aa65d6f4 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java @@ -28,10 +28,8 @@ package at.ac.tuwien.kr.alpha.common.atoms; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.common.terms.*; import at.ac.tuwien.kr.alpha.grounder.Substitution; import java.util.*; @@ -69,7 +67,7 @@ public ComparisonLiteral negate() { } /** - * @see Atom#substitute(Substitution) + * @see AtomImpl#substitute(Substitution) */ @Override public ComparisonLiteral substitute(Substitution substitution) { @@ -100,8 +98,8 @@ public Set getBindingVariables() { @Override public Set getNonBindingVariables() { - final Term left = getTerms().get(0); - final Term right = getTerms().get(1); + final TermImpl left = getTerms().get(0); + final TermImpl right = getTerms().get(1); HashSet occurringVariables = new HashSet<>(); List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); @@ -123,13 +121,13 @@ public Set getNonBindingVariables() { @Override public List getSatisfyingSubstitutions(Substitution partialSubstitution) { // Treat case where this is just comparison with all variables bound by partialSubstitution. - final Term left = getAtom().getTerms().get(0).substitute(partialSubstitution); - final Term right = getAtom().getTerms().get(1).substitute(partialSubstitution); + final TermImpl left = getAtom().getTerms().get(0).substitute(partialSubstitution); + final TermImpl right = getAtom().getTerms().get(1).substitute(partialSubstitution); final boolean leftAssigning = assignable(left); final boolean rightAssigning = assignable(right); if (!leftAssigning && !rightAssigning) { // No assignment (variables are bound by partialSubstitution), thus evaluate comparison only. - Term leftEvaluatedSubstitute = evaluateTerm(left); + TermImpl leftEvaluatedSubstitute = evaluateTerm(left); if (leftEvaluatedSubstitute == null) { return Collections.emptyList(); } @@ -145,7 +143,7 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit } // Treat case that this is X = t or t = X. VariableTerm variable = null; - Term expression = null; + TermImpl expression = null; if (leftAssigning) { variable = (VariableTerm) left; expression = right; @@ -154,15 +152,15 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit variable = (VariableTerm) right; expression = left; } - Term groundTerm = expression.substitute(partialSubstitution); - Term resultTerm = null; + TermImpl groundTerm = expression.substitute(partialSubstitution); + TermImpl resultTerm = null; // Check if the groundTerm is an arithmetic expression and evaluate it if so. if (groundTerm instanceof ArithmeticTerm) { Integer result = evaluateGroundTerm(groundTerm); if (result == null) { return Collections.emptyList(); } - resultTerm = ConstantTerm.getInstance(result); + resultTerm = ConstantTermImpl.getInstance(result); } else { // Ground term is another term (constant, or function term). resultTerm = groundTerm; @@ -178,19 +176,19 @@ public boolean isLeftOrRightAssigning() { return isNormalizedEquality && (assignable(left) && right.isGround() || assignable(right) && left.isGround()); } - private Term evaluateTerm(Term term) { + private TermImpl evaluateTerm(TermImpl term) { // Evaluate arithmetics. if (term instanceof ArithmeticTerm) { Integer result = ArithmeticTerm.evaluateGroundTerm(term); if (result == null) { return null; } - return ConstantTerm.getInstance(result); + return ConstantTermImpl.getInstance(result); } return term; } - private boolean compare(Term x, Term y) { + private boolean compare(TermImpl x, Term y) { final int comparisonResult = x.compareTo(y); ComparisonOperator operator = isNegated() ? getAtom().operator.getNegation() : getAtom().operator; switch (operator) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java index e57871a8f..d3e0781de 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.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 @@ -27,26 +27,27 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import static at.ac.tuwien.kr.alpha.Util.join; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.grounder.Substitution; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import static at.ac.tuwien.kr.alpha.Util.join; -public class ExternalAtom extends Atom implements VariableNormalizableAtom { +public class ExternalAtom extends AtomImpl implements VariableNormalizableAtom { - private final List input; - private final List output; + private final List input; + private final List output; - protected final Predicate predicate; + protected final PredicateImpl predicate; protected final PredicateInterpretation interpretation; - public ExternalAtom(Predicate predicate, PredicateInterpretation interpretation, List input, List output) { + public ExternalAtom(PredicateImpl predicate, PredicateInterpretation interpretation, List input, List output) { if (predicate == null) { throw new IllegalArgumentException("predicate must not be null!"); } @@ -70,7 +71,7 @@ public boolean hasOutput() { } @Override - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return predicate; } @@ -78,16 +79,16 @@ public PredicateInterpretation getInterpretation() { return interpretation; } - public List getInput() { + public List getInput() { return Collections.unmodifiableList(input); } - public List getOutput() { + public List getOutput() { return Collections.unmodifiableList(output); } @Override - public List getTerms() { + public List getTerms() { return input; } @@ -108,8 +109,8 @@ public boolean isGround() { @Override public ExternalAtom 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()); + 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 ExternalAtom(predicate, interpretation, substitutedInput, substitutedOutput); } @@ -131,7 +132,7 @@ public String toString() { } @Override - public Atom withTerms(List terms) { + public AtomImpl withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for external atoms!"); } @@ -171,8 +172,8 @@ public boolean equals(Object obj) { @Override public ExternalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedInput = Term.renameTerms(this.input, prefix + "_IN_", counterStartingValue); - List renamedOutput = Term.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); + List renamedInput = TermImpl.renameTerms(this.input, prefix + "_IN_", counterStartingValue); + List renamedOutput = TermImpl.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); return new ExternalAtom(this.predicate, this.interpretation, renamedInput, renamedOutput); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java index 6141d77e5..d2dc3ef6a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java @@ -1,19 +1,19 @@ /** * 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. - * + * 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 @@ -27,17 +27,11 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -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.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.common.terms.*; import at.ac.tuwien.kr.alpha.grounder.Substitution; +import java.util.*; + /** * Contains a potentially negated {@link ExternalAtom}. */ @@ -62,7 +56,7 @@ public ExternalLiteral negate() { } /** - * @see Atom#substitute(Substitution) + * @see AtomImpl#substitute(Substitution) */ @Override public ExternalLiteral substitute(Substitution substitution) { @@ -79,7 +73,7 @@ public Set getBindingVariables() { return Collections.emptySet(); } - List output = getAtom().getOutput(); + List output = getAtom().getOutput(); Set binding = new HashSet<>(output.size()); @@ -94,13 +88,13 @@ public Set getBindingVariables() { @Override public Set getNonBindingVariables() { - List input = getAtom().getInput(); - List output = getAtom().getOutput(); + 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) { + for (TermImpl term : input) { nonbindingVariables.addAll(term.getOccurringVariables()); } @@ -119,15 +113,15 @@ public Set getNonBindingVariables() { @Override public List getSatisfyingSubstitutions(Substitution partialSubstitution) { - List input = getAtom().getInput(); - List substitutes = new ArrayList<>(input.size()); + List input = getAtom().getInput(); + List substitutes = new ArrayList<>(input.size()); // In preparation for evaluating the external atom, set the input values according // to the partial substitution supplied by the grounder. - for (Term t : input) { + for (TermImpl t : input) { substitutes.add(t.substitute(partialSubstitution)); } - Set>> results = getAtom().getInterpretation().evaluate(substitutes); + Set>> results = getAtom().getInterpretation().evaluate(substitutes); if (results == null) { throw new NullPointerException("Predicate " + getPredicate().getName() + " returned null. It must return a Set."); } @@ -141,7 +135,7 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit /** * Checks whether this negated external literal is satisfied. - * + * * Note that this method must only be called on negated external literals. * In that case, the literal itself does not bind any output variables, * i.e. the underlying atom is satisfied iff the output terms obtained by @@ -154,16 +148,16 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit * substitution has already been applied to them. That assumption is safe since * in case of a negated external literal, the output variables are always * non-binding. - * + * * @param externalMethodResult The term lists obtained from evaluating the external atom * (i.e. calling the java method) encapsulated by this literal * @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) { - List externalAtomOutTerms = this.getAtom().getOutput(); + 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,14 +176,14 @@ 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) { + List externalAtomOutputTerms = this.getAtom().getOutput(); + for (List> bindings : outputs) { if (bindings.size() < externalAtomOutputTerms.size()) { throw new RuntimeException( - "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() - + " were expected."); + "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() + + " were expected."); } Substitution ith = new Substitution(partialSubstitution); boolean skip = false; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java index 835260b72..c01f11c94 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java @@ -38,9 +38,9 @@ * atoms. * Copyright (c) 2017-2018, the Alpha Team. */ -public abstract class FixedInterpretationLiteral extends Literal { +public abstract class FixedInterpretationLiteral extends LiteralImpl { - public FixedInterpretationLiteral(Atom atom, boolean positive) { + public FixedInterpretationLiteral(AtomImpl atom, boolean positive) { super(atom, positive); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralImpl.java similarity index 78% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralImpl.java index 907a38b04..e702dab0b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralImpl.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2017-2018, 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 @@ -27,8 +27,8 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import org.apache.commons.collections4.SetUtils; @@ -37,36 +37,39 @@ import java.util.Set; /** - * A potentially negated {@link Atom} - * + * A potentially negated {@link AtomImpl} + * * Copyright (c) 2017-2018, the Alpha Team. */ -public abstract class Literal { - - protected final Atom atom; +public abstract class LiteralImpl implements Literal { + + protected final AtomImpl atom; protected final boolean positive; - - public Literal(Atom atom, boolean positive) { + + public LiteralImpl(AtomImpl atom, boolean positive) { this.atom = atom; this.positive = positive; } - public Atom getAtom() { + @Override + public AtomImpl getAtom() { return atom; } + @Override public boolean isNegated() { return !positive; } - - public abstract Literal negate(); - - public abstract Literal substitute(Substitution substitution); - + + @Override + public abstract LiteralImpl negate(); + + public abstract LiteralImpl substitute(Substitution substitution); + public abstract Set getBindingVariables(); - + public abstract Set getNonBindingVariables(); - + /** * Union of {@link #getBindingVariables()} and {@link #getNonBindingVariables()} */ @@ -75,26 +78,29 @@ public Set getOccurringVariables() { } /** - * @see Atom#getPredicate() + * @see AtomImpl#getPredicate() */ - public Predicate getPredicate() { + @Override + public PredicateImpl getPredicate() { return atom.getPredicate(); } /** - * @see Atom#getTerms() + * @see AtomImpl#getTerms() */ - public List getTerms() { + @Override + public List getTerms() { return atom.getTerms(); } /** - * @see Atom#isGround() + * @see AtomImpl#isGround() */ + @Override public boolean isGround() { return atom.isGround(); } - + @Override public String toString() { return (positive ? "" : "not ") + atom.toString(); @@ -109,7 +115,7 @@ public boolean equals(Object o) { return false; } - Literal that = (Literal) o; + LiteralImpl that = (LiteralImpl) o; return atom.equals(that.atom) && positive == that.positive; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java index c6fbe0856..9b891ef38 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java @@ -15,6 +15,6 @@ public interface VariableNormalizableAtom { * @return the Atom where all variables are renamed and enumerated * left-to-right. */ - Atom normalizeVariables(String prefix, int counterStartingValue); + AtomImpl normalizeVariables(String prefix, int counterStartingValue); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java index f0a6e2b2e..41117fa9c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java @@ -25,10 +25,8 @@ */ package at.ac.tuwien.kr.alpha.common.depgraph; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,7 +40,7 @@ /** * Internal representation of an {@link at.ac.tuwien.kr.alpha.common.program.InternalProgram}'s dependency graph. The dependency graph tracks dependencies - * between rules of a program. Each {@link Node} of the graph represents a {@link Predicate} occurring in the program. A node has an incoming {@link Edge} for + * between rules of a program. Each {@link Node} of the graph represents a {@link PredicateImpl} occurring in the program. A node has an incoming {@link Edge} for * every {@link Literal} in some rule body that depends on it, i.e. the predicate of the literal in question is the same as that of the node. The "sign" flag of * an {@link Edge} indicates whether the dependency is a positive or negative one, i.e. if the atom in question is preceded by a "not". * @@ -62,9 +60,9 @@ public final class DependencyGraph { */ private final Map> adjacencyMap; - private final Map nodesByPredicate; + private final Map nodesByPredicate; - private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { + private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { this.adjacencyMap = adjacencyMap; this.nodesByPredicate = nodesByPredicate; } @@ -73,7 +71,7 @@ public static DependencyGraph buildDependencyGraph(Map no return new DependencyGraph.Builder(nonGroundRules.values()).build(); } - public Node getNodeForPredicate(Predicate p) { + public Node getNodeForPredicate(PredicateImpl p) { return nodesByPredicate.get(p); } @@ -89,7 +87,7 @@ private static class Builder { private Collection rules; private Map> adjacentNodesMap = new HashMap<>(); - private Map nodesByPredicate = new HashMap<>(); + private Map nodesByPredicate = new HashMap<>(); private Builder(Collection rules) { this.rules = rules; @@ -100,7 +98,7 @@ private DependencyGraph build() { for (InternalRule rule : rules) { LOGGER.debug("Processing rule: {}", rule); Node headNode = handleRuleHead(rule); - for (Literal literal : rule.getBody()) { + for (LiteralImpl literal : rule.getBody()) { LOGGER.trace("Processing rule body literal: {}", literal); if (literal instanceof FixedInterpretationLiteral) { LOGGER.trace("Ignoring FixedInterpretationLiteral {}", literal); @@ -116,7 +114,7 @@ private Node handleRuleHead(InternalRule rule) { LOGGER.trace("Processing head of rule: {}", rule); Node headNode; if (rule.isConstraint()) { - Predicate pred = generateConstraintDummyPredicate(); + PredicateImpl pred = generateConstraintDummyPredicate(); headNode = new Node(pred); List dependencies = new ArrayList<>(); dependencies.add(new Edge(headNode, false)); @@ -126,8 +124,8 @@ private Node handleRuleHead(InternalRule rule) { adjacentNodesMap.put(headNode, dependencies); nodesByPredicate.put(pred, headNode); } else { - Atom head = rule.getHeadAtom(); - Predicate pred = head.getPredicate(); + AtomImpl head = rule.getHeadAtom(); + PredicateImpl pred = head.getPredicate(); if (!nodesByPredicate.containsKey(pred)) { headNode = new Node(pred); adjacentNodesMap.put(headNode, new ArrayList<>()); @@ -139,10 +137,10 @@ private Node handleRuleHead(InternalRule rule) { return headNode; } - private void handleRuleBodyLiteral(Node headNode, Literal lit) { + private void handleRuleBodyLiteral(Node headNode, LiteralImpl lit) { List dependants; Node bodyNode; - Predicate bodyPred = lit.getPredicate(); + PredicateImpl bodyPred = lit.getPredicate(); if (!nodesByPredicate.containsKey(bodyPred)) { LOGGER.trace("Creating new node for bodyPred {}", bodyPred); dependants = new ArrayList<>(); @@ -162,8 +160,8 @@ private void handleRuleBodyLiteral(Node headNode, Literal lit) { nodesByPredicate.put(bodyPred, bodyNode); } - private Predicate generateConstraintDummyPredicate() { - return Predicate.getInstance(String.format(DependencyGraph.Builder.CONSTRAINT_PREDICATE_FORMAT, ++constraintNumber), 0); + private PredicateImpl generateConstraintDummyPredicate() { + return PredicateImpl.getInstance(String.format(DependencyGraph.Builder.CONSTRAINT_PREDICATE_FORMAT, ++constraintNumber), 0); } } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java index 58ad1a0f8..5a5ebf76f 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.common.depgraph; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; /** * A node in a dependency graph. One node references exactly one predicate. This means that all rule heads deriving the @@ -36,9 +36,9 @@ */ public class Node { - private final Predicate predicate; + private final PredicateImpl predicate; - public Node(Predicate predicate) { + public Node(PredicateImpl predicate) { this.predicate = predicate; } @@ -64,7 +64,7 @@ public String getLabel() { return predicate.toString(); } - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return predicate; } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java index ffa76a477..081de663b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java @@ -51,7 +51,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() + ". " + diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java index 66faab911..9ff2080a6 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java @@ -50,7 +50,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/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java new file mode 100644 index 000000000..c59499477 --- /dev/null +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java @@ -0,0 +1,12 @@ +package at.ac.tuwien.kr.alpha.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; +import java.util.Set; + +public interface PredicateInterpretationImpl extends PredicateInterpretation { + @Override + Set>> evaluate(List terms); +} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java index 33e91817b..d440837b8 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java @@ -42,7 +42,7 @@ public SuppliedPredicateInterpretation(Supplier>>> supp } @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/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java index 05fb07ea1..cbccf4802 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.common.program; import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.rule.AbstractRule; import at.ac.tuwien.kr.alpha.common.rule.head.Head; import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; @@ -11,17 +11,17 @@ /** * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives) - * + * * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an implementation permits - * Copyright (c) 2019, the Alpha Team. + * Copyright (c) 2019, the Alpha Team. */ public abstract class AbstractProgram> { private final List rules; - private final List facts; + private final List facts; private final InlineDirectives inlineDirectives; - public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { this.rules = rules; this.facts = facts; this.inlineDirectives = inlineDirectives; @@ -31,7 +31,7 @@ public List getRules() { return Collections.unmodifiableList(rules); } - public List getFacts() { + public List getFacts() { return Collections.unmodifiableList(facts); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java index 1494729fe..d89254a56 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.common.program; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; import at.ac.tuwien.kr.alpha.common.depgraph.StronglyConnectedComponentsAlgorithm; @@ -20,14 +21,14 @@ public class AnalyzedProgram extends InternalProgram { private final DependencyGraph dependencyGraph; private final ComponentGraph componentGraph; - public AnalyzedProgram(List rules, List facts) { + public AnalyzedProgram(List rules, List facts) { super(rules, facts); dependencyGraph = DependencyGraph.buildDependencyGraph(getRulesById()); componentGraph = buildComponentGraph(dependencyGraph); } public static AnalyzedProgram analyzeNormalProgram(NormalProgram prog) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); return new AnalyzedProgram(rulesAndFacts.left, rulesAndFacts.right); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java index 2869e2adf..ea0ed8f22 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java @@ -1,19 +1,19 @@ /** * Copyright (c) 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 @@ -27,24 +27,25 @@ */ package at.ac.tuwien.kr.alpha.common.program; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. - * + *

* Copyright (c) 2017-2019, the Alpha Team. */ -public class InputProgram extends AbstractProgram { +public class InputProgram extends AbstractProgram implements Program { public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectives()); - public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } @@ -61,12 +62,12 @@ public static Builder builder(InputProgram 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 InputProgram} is immutable */ public static class Builder { private List rules = new ArrayList<>(); - private List facts = new ArrayList<>(); + private List facts = new ArrayList<>(); private InlineDirectives inlineDirectives = new InlineDirectives(); public Builder(InputProgram prog) { @@ -89,12 +90,12 @@ public Builder addRule(BasicRule r) { return this; } - public Builder addFacts(List facts) { + public Builder addFacts(List facts) { this.facts.addAll(facts); return this; } - public Builder addFact(Atom fact) { + public Builder addFact(AtomImpl fact) { this.facts.add(fact); return this; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java index 0a710e48b..ba9468b0f 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java @@ -1,42 +1,38 @@ package at.ac.tuwien.kr.alpha.common.program; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.grounder.FactIntervalEvaluator; import at.ac.tuwien.kr.alpha.grounder.Instance; import org.apache.commons.lang3.tuple.ImmutablePair; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; +import java.util.*; /** * A program in the internal representation needed for grounder and solver, i.e.: rules must have normal heads, all * aggregates must be rewritten, all intervals must be preprocessed (into interval atoms), and equality predicates must * be rewritten. - * + *

* Copyright (c) 2017-2020, the Alpha Team. */ public class InternalProgram extends AbstractProgram { - private final Map> predicateDefiningRules = new LinkedHashMap<>(); - private final Map> factsByPredicate = new LinkedHashMap<>(); + private final Map> predicateDefiningRules = new LinkedHashMap<>(); + private final Map> factsByPredicate = new LinkedHashMap<>(); private final Map rulesById = new LinkedHashMap<>(); - public InternalProgram(List rules, List facts) { + public InternalProgram(List rules, List facts) { super(rules, facts, null); recordFacts(facts); recordRules(rules); } - static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { + static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { List internalRules = new ArrayList<>(); - List facts = new ArrayList<>(normalProgram.getFacts()); + List facts = new ArrayList<>(normalProgram.getFacts()); for (NormalRule r : normalProgram.getRules()) { if (r.getBody().isEmpty()) { if (!r.getHead().isGround()) { @@ -51,14 +47,14 @@ static ImmutablePair, List> internalizeRulesAndFacts(No } public static InternalProgram fromNormalProgram(NormalProgram normalProgram) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); return new InternalProgram(rulesAndFacts.left, rulesAndFacts.right); } - private void recordFacts(List facts) { - for (Atom fact : facts) { + private void recordFacts(List facts) { + for (AtomImpl fact : facts) { List tmpInstances = FactIntervalEvaluator.constructFactInstances(fact); - Predicate tmpPredicate = fact.getPredicate(); + PredicateImpl tmpPredicate = fact.getPredicate(); factsByPredicate.putIfAbsent(tmpPredicate, new LinkedHashSet<>()); factsByPredicate.get(tmpPredicate).addAll(tmpInstances); } @@ -73,16 +69,16 @@ private void recordRules(List rules) { } } - private void recordDefiningRule(Predicate headPredicate, InternalRule rule) { + private void recordDefiningRule(PredicateImpl headPredicate, InternalRule rule) { predicateDefiningRules.putIfAbsent(headPredicate, new LinkedHashSet<>()); predicateDefiningRules.get(headPredicate).add(rule); } - public Map> getPredicateDefiningRules() { + public Map> getPredicateDefiningRules() { return Collections.unmodifiableMap(predicateDefiningRules); } - public Map> getFactsByPredicate() { + public Map> getFactsByPredicate() { return Collections.unmodifiableMap(factsByPredicate); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java index 8a7f20122..f102c2b4f 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java @@ -4,6 +4,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; @@ -15,7 +16,7 @@ */ public class NormalProgram extends AbstractProgram { - public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java index cb1356d2e..012da514d 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java @@ -2,6 +2,7 @@ import at.ac.tuwien.kr.alpha.Util; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.rule.head.Head; import org.apache.commons.collections4.SetUtils; @@ -21,14 +22,14 @@ public abstract class AbstractRule { private final H head; - private final Set bodyLiteralsPositive; - private final Set bodyLiteralsNegative; + private final Set bodyLiteralsPositive; + private final Set bodyLiteralsNegative; - public AbstractRule(H head, List body) { + public AbstractRule(H head, List body) { this.head = head; - Set positiveBody = new LinkedHashSet<>(); - Set negativeBody = new LinkedHashSet<>(); - for (Literal bodyLiteral : body) { + Set positiveBody = new LinkedHashSet<>(); + Set negativeBody = new LinkedHashSet<>(); + for (LiteralImpl bodyLiteral : body) { if (bodyLiteral.isNegated()) { negativeBody.add(bodyLiteral); } else { @@ -93,15 +94,15 @@ public H getHead() { return head; } - public Set getBody() { + public Set getBody() { return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); } - public Set getPositiveBody() { + public Set getPositiveBody() { return this.bodyLiteralsPositive; } - public Set getNegativeBody() { + public Set getNegativeBody() { return this.bodyLiteralsNegative; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java index 2e14dc9ac..84660bf52 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java @@ -30,15 +30,16 @@ import java.util.List; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.rule.head.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 NormalRule}. + * 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 NormalRule}. */ public class BasicRule extends AbstractRule { - public BasicRule(Head head, List body) { + public BasicRule(Head head, List body) { super(head, body); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java index a6e21a6d3..f41a1cab5 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java @@ -27,14 +27,15 @@ */ package at.ac.tuwien.kr.alpha.common.rule; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; @@ -52,11 +53,11 @@ public class InternalRule extends NormalRule { private final int ruleId; - private final List occurringPredicates; + private final List occurringPredicates; private final RuleGroundingOrders groundingOrders; - public InternalRule(NormalHead head, List body) { + public InternalRule(NormalHead head, List body) { super(head, body); if (body.isEmpty()) { throw new IllegalArgumentException( @@ -69,7 +70,7 @@ public InternalRule(NormalHead head, List body) { this.occurringPredicates.add(this.getHeadAtom().getPredicate()); } - for (Literal literal : body) { + for (LiteralImpl literal : body) { if (literal instanceof AggregateLiteral) { throw new IllegalArgumentException("AggregateLiterals aren't supported in InternalRules! (lit: " + literal.toString() + ")"); } @@ -102,9 +103,9 @@ public static InternalRule fromNormalRule(NormalRule rule) { */ public InternalRule renameVariables(String newVariablePostfix) { List occurringVariables = new ArrayList<>(); - Atom headAtom = this.getHeadAtom(); + AtomImpl headAtom = this.getHeadAtom(); occurringVariables.addAll(headAtom.getOccurringVariables()); - for (Literal literal : this.getBody()) { + for (LiteralImpl literal : this.getBody()) { occurringVariables.addAll(literal.getOccurringVariables()); } Unifier variableReplacement = new Unifier(); @@ -112,9 +113,9 @@ public InternalRule renameVariables(String newVariablePostfix) { final String newVariableName = occurringVariable.toString() + newVariablePostfix; variableReplacement.put(occurringVariable, VariableTerm.getInstance(newVariableName)); } - Atom renamedHeadAtom = headAtom.substitute(variableReplacement); - ArrayList renamedBody = new ArrayList<>(this.getBody().size()); - for (Literal literal : this.getBody()) { + AtomImpl renamedHeadAtom = headAtom.substitute(variableReplacement); + ArrayList renamedBody = new ArrayList<>(this.getBody().size()); + for (LiteralImpl literal : this.getBody()) { renamedBody.add(literal.substitute(variableReplacement)); } return new InternalRule(new NormalHead(renamedHeadAtom), renamedBody); @@ -124,7 +125,7 @@ public InternalRule renameVariables(String newVariablePostfix) { * Returns the predicates occurring in this rule. * @return a list of all predicates occurring in the rule (may contain duplicates and builtin atoms). */ - public List getOccurringPredicates() { + public List getOccurringPredicates() { return this.occurringPredicates; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java index 7eac409eb..fe94e3a70 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java @@ -1,8 +1,9 @@ package at.ac.tuwien.kr.alpha.common.rule; import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import java.util.ArrayList; @@ -16,12 +17,12 @@ */ public class NormalRule extends AbstractRule { - public NormalRule(NormalHead head, List body) { + public NormalRule(NormalHead head, List body) { super(head, body); } public static NormalRule fromBasicRule(BasicRule rule) { - Atom headAtom = null; + AtomImpl 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()); @@ -43,7 +44,7 @@ public boolean isGround() { return true; } - public Atom getHeadAtom() { + public AtomImpl getHeadAtom() { return this.isConstraint() ? null : this.getHead().getAtom(); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java index 46620fce1..5dc261490 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java @@ -1,8 +1,9 @@ package at.ac.tuwien.kr.alpha.common.rule.head; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.terms.Term; import java.util.List; @@ -24,10 +25,10 @@ public class ChoiceHead extends Head { private final ComparisonOperator upperOp; public static class ChoiceElement { - public final Atom choiceAtom; - public final List conditionLiterals; + public final AtomImpl choiceAtom; + public final List conditionLiterals; - public ChoiceElement(Atom choiceAtom, List conditionLiterals) { + public ChoiceElement(AtomImpl choiceAtom, List conditionLiterals) { this.choiceAtom = choiceAtom; this.conditionLiterals = conditionLiterals; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java index cb88e8229..3e0a01b0e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.common.rule.head; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; /** * Represents a normal head, i.e., a head that is an Atom. @@ -8,9 +8,9 @@ */ public class NormalHead extends Head { - private final Atom atom; + private final AtomImpl atom; - public NormalHead(Atom atom) { + public NormalHead(AtomImpl atom) { this.atom = atom; } @@ -19,7 +19,7 @@ public boolean isGround() { return atom.isGround(); } - public Atom getAtom() { + public AtomImpl getAtom() { return atom; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java index cf01f5f6e..3e8786fc0 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java @@ -39,23 +39,23 @@ * This class represents an arithmetic expression occurring as a term. * Copyright (c) 2017-2019, the Alpha Team. */ -public class ArithmeticTerm extends Term { +public class ArithmeticTerm extends TermImpl { private static final Interner INTERNER = new Interner<>(); - protected final Term left; + protected final TermImpl left; private final ArithmeticOperator arithmeticOperator; - private final Term right; + private final TermImpl right; - private ArithmeticTerm(Term left, ArithmeticOperator arithmeticOperator, Term right) { + private ArithmeticTerm(TermImpl left, ArithmeticOperator arithmeticOperator, TermImpl right) { this.left = left; this.arithmeticOperator = arithmeticOperator; this.right = right; } - public static Term getInstance(Term left, ArithmeticOperator arithmeticOperator, Term right) { + public static TermImpl getInstance(TermImpl left, ArithmeticOperator arithmeticOperator, TermImpl right) { // Evaluate ground arithmetic terms immediately and return result. if (left.isGround() && right.isGround()) { Integer result = new ArithmeticTerm(left, arithmeticOperator, right).evaluateExpression(); - return ConstantTerm.getInstance(result); + return ConstantTermImpl.getInstance(result); } return INTERNER.intern(new ArithmeticTerm(left, arithmeticOperator, right)); } @@ -74,19 +74,19 @@ public List getOccurringVariables() { } @Override - public Term substitute(Substitution substitution) { + public TermImpl substitute(Substitution substitution) { return getInstance(left.substitute(substitution), arithmeticOperator, right.substitute(substitution)); } @Override - public Term renameVariables(String renamePrefix) { + public TermImpl renameVariables(String renamePrefix) { return getInstance(left.renameVariables(renamePrefix), arithmeticOperator, right.renameVariables(renamePrefix)); } @Override - public Term normalizeVariables(String renamePrefix, RenameCounter counter) { - Term normalizedLeft = left.normalizeVariables(renamePrefix, counter); - Term normalizedRight = right.normalizeVariables(renamePrefix, counter); + public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { + TermImpl normalizedLeft = left.normalizeVariables(renamePrefix, counter); + TermImpl normalizedRight = right.normalizeVariables(renamePrefix, counter); return ArithmeticTerm.getInstance(normalizedLeft, arithmeticOperator, normalizedRight); } @@ -100,9 +100,9 @@ public static Integer evaluateGroundTerm(Term term) { private static Integer evaluateGroundTermHelper(Term term) { if (term instanceof ConstantTerm - && ((ConstantTerm) term).getObject() instanceof Integer) { + && ((ConstantTermImpl) term).getObject() instanceof Integer) { // Extract integer from the constant. - return (Integer) ((ConstantTerm) term).getObject(); + return (Integer) ((ConstantTermImpl) term).getObject(); } else if (term instanceof ArithmeticTerm) { return ((ArithmeticTerm) term).evaluateExpression(); } else { @@ -196,16 +196,16 @@ public Integer eval(Integer left, Integer right) { public static class MinusTerm extends ArithmeticTerm { - private MinusTerm(Term term) { + private MinusTerm(TermImpl term) { super(term, null, null); } - public static Term getInstance(Term term) { + public static TermImpl getInstance(TermImpl term) { // Evaluate ground arithmetic terms immediately and return result. if (term.isGround()) { Integer result = evaluateGroundTermHelper(term) * -1; - return ConstantTerm.getInstance(result); + return ConstantTermImpl.getInstance(result); } return INTERNER.intern(new MinusTerm(term)); } @@ -226,18 +226,18 @@ public List getOccurringVariables() { } @Override - public Term substitute(Substitution substitution) { + public TermImpl substitute(Substitution substitution) { return getInstance(left.substitute(substitution)); } @Override - public Term renameVariables(String renamePrefix) { + public TermImpl renameVariables(String renamePrefix) { return getInstance(left.renameVariables(renamePrefix)); } @Override - public Term normalizeVariables(String renamePrefix, RenameCounter counter) { - Term normalizedLeft = left.normalizeVariables(renamePrefix, counter); + public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { + TermImpl normalizedLeft = left.normalizeVariables(renamePrefix, counter); return MinusTerm.getInstance(normalizedLeft); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTermImpl.java similarity index 75% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTermImpl.java index c0fa1fe43..1f421c2e4 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTermImpl.java @@ -9,25 +9,25 @@ /** * Copyright (c) 2016-2020, the Alpha Team. */ -public class ConstantTerm> extends Term { - private static final Interner> INTERNER = new Interner<>(); +public class ConstantTermImpl> extends TermImpl implements ConstantTerm { + private static final Interner> INTERNER = new Interner<>(); private final T object; private final boolean symbolic; - private ConstantTerm(T object, boolean symbolic) { + private ConstantTermImpl(T object, boolean symbolic) { this.object = object; this.symbolic = symbolic; } @SuppressWarnings("unchecked") - public static > ConstantTerm getInstance(T symbol) { - return (ConstantTerm) INTERNER.intern(new ConstantTerm<>(symbol, false)); + public static > ConstantTermImpl getInstance(T symbol) { + return (ConstantTermImpl) INTERNER.intern(new ConstantTermImpl<>(symbol, false)); } @SuppressWarnings("unchecked") - public static > ConstantTerm getSymbolicInstance(String symbol) { - return (ConstantTerm) INTERNER.intern(new ConstantTerm<>(symbol, true)); + public static > ConstantTermImpl getSymbolicInstance(String symbol) { + return (ConstantTermImpl) INTERNER.intern(new ConstantTermImpl<>(symbol, true)); } @Override @@ -41,7 +41,7 @@ public List getOccurringVariables() { } @Override - public Term substitute(Substitution substitution) { + public TermImpl substitute(Substitution substitution) { return this; } @@ -67,7 +67,7 @@ public boolean equals(Object o) { return false; } - ConstantTerm that = (ConstantTerm) o; + ConstantTermImpl that = (ConstantTermImpl) o; if (this.symbolic != that.symbolic) { return false; } @@ -86,7 +86,7 @@ public int hashCode() { * Establishes "priority" for ordering of constant terms depending on the type * of the corresponding object according to ASP-Core-2.03c. */ - private static final int priority(final Class clazz, ConstantTerm term) { + private static final int priority(final Class clazz, ConstantTermImpl term) { if (clazz.equals(Integer.class)) { return 1; } else if (clazz.equals(String.class)) { @@ -102,11 +102,11 @@ public int compareTo(Term o) { return 0; } - if (!(o instanceof ConstantTerm)) { + if (!(o instanceof ConstantTermImpl)) { return super.compareTo(o); } - ConstantTerm other = (ConstantTerm) o; + ConstantTermImpl other = (ConstantTermImpl) o; // We will perform an unchecked cast. // Because of type erasure, we cannot know the exact type @@ -138,13 +138,13 @@ public int compareTo(Term o) { } @Override - public Term renameVariables(String renamePrefix) { + public TermImpl renameVariables(String renamePrefix) { // Constant contains no variables, hence stays the same. return this; } @Override - public Term normalizeVariables(String renamePrefix, RenameCounter counter) { + public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { return this; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java index 9e3847ac4..6a51c8778 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java @@ -10,14 +10,14 @@ /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class FunctionTerm extends Term { +public class FunctionTerm extends TermImpl { private static final Interner INTERNER = new Interner<>(); private final String symbol; - private final List terms; + private final List terms; private final boolean ground; - private FunctionTerm(String symbol, List terms) { + private FunctionTerm(String symbol, List terms) { if (symbol == null) { throw new IllegalArgumentException(); } @@ -35,15 +35,15 @@ private FunctionTerm(String symbol, List terms) { this.ground = ground; } - public static FunctionTerm getInstance(String functionSymbol, List termList) { + public static FunctionTerm getInstance(String functionSymbol, List termList) { return INTERNER.intern(new FunctionTerm(functionSymbol, termList)); } - public static FunctionTerm getInstance(String functionSymbol, Term... terms) { + public static FunctionTerm getInstance(String functionSymbol, TermImpl... terms) { return getInstance(functionSymbol, Arrays.asList(terms)); } - public List getTerms() { + public List getTerms() { return terms; } @@ -59,7 +59,7 @@ public boolean isGround() { @Override public List getOccurringVariables() { LinkedList vars = new LinkedList<>(); - for (Term term : terms) { + for (TermImpl term : terms) { vars.addAll(term.getOccurringVariables()); } return vars; @@ -67,8 +67,8 @@ public List getOccurringVariables() { @Override public FunctionTerm substitute(Substitution substitution) { - List groundTermList = new ArrayList<>(terms.size()); - for (Term term : terms) { + List groundTermList = new ArrayList<>(terms.size()); + for (TermImpl term : terms) { groundTermList.add(term.substitute(substitution)); } return FunctionTerm.getInstance(symbol, groundTermList); @@ -138,18 +138,18 @@ public int compareTo(Term o) { } @Override - public Term renameVariables(String renamePrefix) { - ArrayList renamedTerms = new ArrayList<>(terms.size()); - for (Term term : terms) { + public TermImpl renameVariables(String renamePrefix) { + List renamedTerms = new ArrayList<>(terms.size()); + for (TermImpl term : terms) { renamedTerms.add(term.renameVariables(renamePrefix)); } return FunctionTerm.getInstance(symbol, renamedTerms); } @Override - public Term normalizeVariables(String renamePrefix, RenameCounter counter) { - List normalizedTerms = new ArrayList<>(terms.size()); - for (Term term : terms) { + public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { + List normalizedTerms = new ArrayList<>(terms.size()); + for (TermImpl term : terms) { normalizedTerms.add(term.normalizeVariables(renamePrefix, counter)); } return FunctionTerm.getInstance(symbol, normalizedTerms); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java index 8383b55ca..2736ebf58 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java @@ -13,17 +13,17 @@ * An IntervalTerm is a meta-term and the grounder must replace it with its corresponding set of facts or rules. * Copyright (c) 2017, the Alpha Team. */ -public class IntervalTerm extends Term { +public class IntervalTerm extends TermImpl { private static final Interner INTERNER = new Interner<>(); - private final Term lowerBoundTerm; - private final Term upperBoundTerm; + private final TermImpl lowerBoundTerm; + private final TermImpl upperBoundTerm; private final int lowerBound; private final int upperBound; private final boolean ground; - private IntervalTerm(Term lowerBound, Term upperBound) { + private IntervalTerm(TermImpl lowerBound, TermImpl upperBound) { if (lowerBound == null || upperBound == null) { throw new IllegalArgumentException(); } @@ -42,7 +42,7 @@ private IntervalTerm(Term lowerBound, Term upperBound) { } } - public static IntervalTerm getInstance(Term lowerBound, Term upperBound) { + public static IntervalTerm getInstance(TermImpl lowerBound, TermImpl upperBound) { return INTERNER.intern(new IntervalTerm(lowerBound, upperBound)); } @@ -119,12 +119,12 @@ public int compareTo(Term o) { } @Override - public Term renameVariables(String renamePrefix) { + public TermImpl renameVariables(String renamePrefix) { return new IntervalTerm(lowerBoundTerm.renameVariables(renamePrefix), upperBoundTerm.renameVariables(renamePrefix)); } @Override - public Term normalizeVariables(String renamePrefix, RenameCounter counter) { + public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { return IntervalTerm.getInstance( lowerBoundTerm.normalizeVariables(renamePrefix, counter), upperBoundTerm.normalizeVariables(renamePrefix, counter)); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/TermImpl.java similarity index 83% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/TermImpl.java index 490fb46b8..793016361 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/TermImpl.java @@ -31,8 +31,7 @@ * Copyright (c) 2016-2020, the Alpha Team. */ //@formatter:on -public abstract class Term implements Comparable { - public abstract boolean isGround(); +public abstract class TermImpl implements Term { public abstract List getOccurringVariables(); @@ -42,7 +41,7 @@ public abstract class Term implements Comparable { * @param substitution the variable substitution to apply. * @return the non-substitute term where all variable substitutions have been applied. */ - public abstract Term substitute(Substitution substitution); + public abstract TermImpl substitute(Substitution substitution); private static int priority(Term term) { final Class clazz = term.getClass(); @@ -67,9 +66,9 @@ public int compareTo(Term o) { * @param renamePrefix the name to prefix all occurring variables. * @return the term with all variables renamed. */ - public abstract Term renameVariables(String renamePrefix); + public abstract TermImpl renameVariables(String renamePrefix); - public abstract Term normalizeVariables(String renamePrefix, RenameCounter counter); + public abstract TermImpl normalizeVariables(String renamePrefix, RenameCounter counter); public static class RenameCounter { int counter; @@ -81,10 +80,10 @@ public RenameCounter(int startingValue) { } } - public static List renameTerms(List terms, String prefix, int counterStartingValue) { - List renamedTerms = new ArrayList<>(terms.size()); - Term.RenameCounter renameCounter = new Term.RenameCounter(counterStartingValue); - for (Term term : terms) { + public static List renameTerms(List terms, String prefix, int counterStartingValue) { + List renamedTerms = new ArrayList<>(terms.size()); + TermImpl.RenameCounter renameCounter = new TermImpl.RenameCounter(counterStartingValue); + for (TermImpl term : terms) { renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); } return renamedTerms; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java index 0e5c36745..07d628121 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java @@ -4,9 +4,9 @@ import java.util.List; /** - * Convenience methods for {@link Term}s. The methods provided here are an + * Convenience methods for {@link TermImpl}s. The methods provided here are an * attempt to avoid repeating commonly used code snippets, like wrapping sets of - * values in {@link Term}s and creating lists of those terms, etc. + * values in {@link TermImpl}s and creating lists of those terms, etc. * * Copyright (c) 2020, the Alpha Team. */ @@ -25,7 +25,7 @@ private Terms() { public static > List> asTermList(T... values) { List> retVal = new ArrayList<>(); for (T value : values) { - retVal.add(ConstantTerm.getInstance(value)); + retVal.add(ConstantTermImpl.getInstance(value)); } return retVal; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java index 8396b4102..904f7f3a4 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java @@ -10,7 +10,7 @@ /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class VariableTerm extends Term { +public class VariableTerm extends TermImpl { private static final Interner INTERNER = new Interner<>(); private static final String ANONYMOUS_VARIABLE_PREFIX = "_"; @@ -41,8 +41,8 @@ public List getOccurringVariables() { } @Override - public Term substitute(Substitution substitution) { - Term groundTerm = substitution.eval(this); + public TermImpl substitute(Substitution substitution) { + TermImpl groundTerm = substitution.eval(this); if (groundTerm == null) { // If variable is not substituted, keep term as is. return this; @@ -90,12 +90,12 @@ public int compareTo(Term o) { } @Override - public Term renameVariables(String renamePrefix) { + public TermImpl renameVariables(String renamePrefix) { return VariableTerm.getInstance(renamePrefix + variableName); } @Override - public Term normalizeVariables(String renamePrefix, RenameCounter counter) { + public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { VariableTerm renamedThis = counter.renamedVariables.get(this); if (renamedThis != null) { return renamedThis; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java index 0d75fb5a3..6a2b04039 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.grounder; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; /** * Copyright (c) 2016, the Alpha Team. */ public abstract class AbstractGrounder implements Grounder { - protected final java.util.function.Predicate filter; + protected final java.util.function.Predicate filter; - protected AbstractGrounder(java.util.function.Predicate filter) { + protected AbstractGrounder(java.util.function.Predicate filter) { this.filter = filter; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java index 55c04d942..0be02b2e8 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java @@ -2,7 +2,7 @@ import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; @@ -12,7 +12,7 @@ public abstract class BridgedGrounder extends AbstractGrounder { protected final Bridge[] bridges; - protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { + protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { super(filter); this.bridges = bridges; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java index d22f549c8..bd34ef18e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java @@ -1,10 +1,7 @@ package at.ac.tuwien.kr.alpha.grounder; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.terms.*; import java.util.ArrayList; import java.util.Collections; @@ -18,17 +15,18 @@ public class FactIntervalEvaluator { /** * Helper to construct Instances from a fact that may contain intervals. + * * @param fact the fact potentially containing intervals. * @return all instances stemming from unfolding the intervals. */ - public static List constructFactInstances(Atom fact) { + public static List constructFactInstances(AtomImpl fact) { // Construct instance(s) from the fact. int arity = fact.getPredicate().getArity(); - Term[] currentTerms = new Term[arity]; + TermImpl[] currentTerms = new TermImpl[arity]; boolean containsIntervals = false; // Check if instance contains intervals at all. for (int i = 0; i < arity; i++) { - Term term = fact.getTerms().get(i); + TermImpl term = fact.getTerms().get(i); currentTerms[i] = term; if (term instanceof IntervalTerm) { containsIntervals = true; @@ -45,7 +43,7 @@ public static List constructFactInstances(Atom fact) { return unrollInstances(currentTerms, 0); } - private static List unrollInstances(Term[] currentTerms, int currentPosition) { + private static List unrollInstances(TermImpl[] currentTerms, int currentPosition) { if (currentPosition == currentTerms.length) { return Collections.singletonList(new Instance(currentTerms)); } @@ -60,8 +58,8 @@ private static List unrollInstances(Term[] currentTerms, int currentPo int upper = ((IntervalTerm) currentTerm).getUpperBound(); for (int i = lower; i <= upper; i++) { - Term[] clonedTerms = currentTerms.clone(); - clonedTerms[currentPosition] = ConstantTerm.getInstance(i); + TermImpl[] clonedTerms = currentTerms.clone(); + clonedTerms[currentPosition] = ConstantTermImpl.getInstance(i); instances.addAll(unrollInstances(clonedTerms, currentPosition + 1)); } return instances; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java index c5a5e82e4..73424f16c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.grounder; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; /** * Copyright (c) 2016, the Alpha Team. */ public abstract class FilteringGrounder implements Grounder { - protected final java.util.function.Predicate filter; + protected final java.util.function.Predicate filter; - protected FilteringGrounder(java.util.function.Predicate filter) { + protected FilteringGrounder(java.util.function.Predicate filter) { this.filter = filter; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java index 5c3afda3a..8e29f999b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java @@ -28,14 +28,14 @@ package at.ac.tuwien.kr.alpha.grounder; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.config.InputConfig; import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; public final class GrounderFactory { - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + public static Grounder getInstance(String name, InternalProgram 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); @@ -43,7 +43,7 @@ public static Grounder getInstance(String name, InternalProgram program, AtomSto throw new IllegalArgumentException("Unknown grounder requested."); } - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { return getInstance(name, program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java index c05be6d25..ad2fc3d43 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java @@ -36,7 +36,7 @@ import java.util.Map; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.terms.Term; @@ -47,7 +47,7 @@ * Copyright (c) 2016-2020, the Alpha Team. */ public class IndexedInstanceStorage { - private final Predicate predicate; + private final PredicateImpl predicate; private final boolean positive; /** @@ -62,7 +62,7 @@ public class IndexedInstanceStorage { private final ArrayList recentlyAddedInstances = new ArrayList<>(); - public IndexedInstanceStorage(Predicate predicate, boolean positive) { + public IndexedInstanceStorage(PredicateImpl predicate, boolean positive) { this.predicate = predicate; this.positive = positive; @@ -72,7 +72,7 @@ public IndexedInstanceStorage(Predicate predicate, boolean positive) { } } - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return predicate; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java index 480d58d80..1242e0243 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java @@ -6,8 +6,9 @@ import java.util.List; import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; /** * An instance is a positional association of terms, e.g., representing a variable substitution, or a ground instance of @@ -15,17 +16,17 @@ * Copyright (c) 2016, the Alpha Team. */ public class Instance { - public final List terms; + public final List terms; - public Instance(Term... terms) { + public Instance(TermImpl... terms) { this(Arrays.asList(terms)); } - public Instance(List terms) { + public Instance(List terms) { this.terms = terms; } - public static Instance fromAtom(Atom atom) { + public static Instance fromAtom(AtomImpl atom) { if (!atom.isGround()) { throw Util.oops("Cannot create instance from non-ground atom " + atom.toString()); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java index 0e676bee1..1d54b8c78 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.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. - * + * 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 @@ -28,17 +28,8 @@ package at.ac.tuwien.kr.alpha.grounder; import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.*; +import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; @@ -46,29 +37,14 @@ import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; -import at.ac.tuwien.kr.alpha.grounder.instantiation.BindingResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.DefaultLazyGroundingInstantiationStrategy; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; +import at.ac.tuwien.kr.alpha.grounder.instantiation.*; import at.ac.tuwien.kr.alpha.grounder.structure.AnalyzeUnjustified; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Collection; -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.Set; -import java.util.SortedSet; -import java.util.TreeSet; +import java.util.*; import static at.ac.tuwien.kr.alpha.Util.oops; import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; @@ -89,12 +65,12 @@ public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGr private final InternalProgram program; private final AnalyzeUnjustified analyzeUnjustified; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private final Map> rulesUsingPredicateWorkingMemory = new HashMap<>(); private final Map knownNonGroundRules; private ArrayList fixedRules = new ArrayList<>(); - private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); + private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); private final boolean debugInternalChecks; private final GrounderHeuristicsConfiguration heuristicsConfiguration; @@ -112,7 +88,7 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, bridges); } - NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { super(filter, bridges); this.atomStore = atomStore; this.heuristicsConfiguration = heuristicsConfiguration; @@ -130,7 +106,7 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur final Set uniqueGroundRulePerGroundHead = getRulesWithUniqueHead(); choiceRecorder = new ChoiceRecorder(atomStore); noGoodGenerator = new NoGoodGenerator(atomStore, choiceRecorder, factsFromProgram, this.program, uniqueGroundRulePerGroundHead); - + this.debugInternalChecks = debugInternalChecks; // Initialize RuleInstantiator and instantiation strategy. Note that the instantiation strategy also @@ -142,8 +118,8 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur private void initializeFactsAndRules() { // Initialize all facts. - for (Atom fact : program.getFacts()) { - final Predicate predicate = fact.getPredicate(); + for (AtomImpl fact : program.getFacts()) { + final PredicateImpl predicate = fact.getPredicate(); // Record predicate workingMemory.initialize(predicate); @@ -157,7 +133,7 @@ private void initializeFactsAndRules() { // Initialize rules and constraints in working memory. for (InternalRule nonGroundRule : program.getRulesById().values()) { // Create working memories for all predicates occurring in the rule. - for (Predicate predicate : nonGroundRule.getOccurringPredicates()) { + for (PredicateImpl predicate : nonGroundRule.getOccurringPredicates()) { // FIXME: this also contains interval/builtin predicates that are not needed. workingMemory.initialize(predicate); } @@ -169,7 +145,7 @@ private void initializeFactsAndRules() { } // Register each starting literal at the corresponding working memory. - for (Literal literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { + for (LiteralImpl literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { registerLiteralAtWorkingMemory(literal, nonGroundRule); } } @@ -180,14 +156,14 @@ private Set getRulesWithUniqueHead() { // Record all unique rule heads. final Set uniqueGroundRulePerGroundHead = new HashSet<>(); - for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { + for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { if (headDefiningRules.getValue().size() != 1) { continue; } InternalRule nonGroundRule = headDefiningRules.getValue().iterator().next(); // Check that all variables of the body also occur in the head (otherwise grounding is not unique). - Atom headAtom = nonGroundRule.getHeadAtom(); + AtomImpl headAtom = nonGroundRule.getHeadAtom(); // Rule is not guaranteed unique if there are facts for it. HashSet potentialFacts = factsFromProgram.get(headAtom.getPredicate()); @@ -198,7 +174,7 @@ private Set getRulesWithUniqueHead() { // Collect head and body variables. HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); HashSet occurringVariablesBody = new HashSet<>(); - for (Literal lit : nonGroundRule.getPositiveBody()) { + for (LiteralImpl lit : nonGroundRule.getPositiveBody()) { occurringVariablesBody.addAll(lit.getBindingVariables()); } occurringVariablesBody.removeAll(occurringVariablesHead); @@ -215,7 +191,7 @@ private Set getRulesWithUniqueHead() { * Registers a starting literal of a NonGroundRule at its corresponding working memory. * @param nonGroundRule the rule in which the literal occurs. */ - private void registerLiteralAtWorkingMemory(Literal literal, InternalRule nonGroundRule) { + private void registerLiteralAtWorkingMemory(LiteralImpl literal, InternalRule nonGroundRule) { if (literal.isNegated()) { throw new RuntimeException("Literal to register is negated. Should not happen."); } @@ -226,13 +202,13 @@ private void registerLiteralAtWorkingMemory(Literal literal, InternalRule nonGro @Override public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { - Map> predicateInstances = new LinkedHashMap<>(); - SortedSet knownPredicates = new TreeSet<>(); + Map> predicateInstances = new LinkedHashMap<>(); + SortedSet knownPredicates = new TreeSet<>(); // Iterate over all true atomIds, computeNextAnswerSet instances from atomStore and add them if not filtered. for (int trueAtom : trueAtoms) { final Atom atom = atomStore.get(trueAtom); - Predicate predicate = atom.getPredicate(); + PredicateImpl predicate = atom.getPredicate(); // Skip atoms over internal predicates. if (predicate.isInternal()) { @@ -251,8 +227,8 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { } // Add true atoms from facts. - for (Map.Entry> facts : factsFromProgram.entrySet()) { - Predicate factPredicate = facts.getKey(); + for (Map.Entry> facts : factsFromProgram.entrySet()) { + PredicateImpl factPredicate = facts.getKey(); // Skip atoms over internal predicates. if (factPredicate.isInternal()) { continue; @@ -276,10 +252,10 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { if (knownPredicates.isEmpty()) { return BasicAnswerSet.EMPTY; } - + return new BasicAnswerSet(knownPredicates, predicateInstances); } - + /** * Prepares facts of the input program for joining and derives all NoGoods representing ground rules. May only be called once. * @return @@ -287,7 +263,7 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { protected HashMap bootstrap() { final HashMap groundNogoods = new LinkedHashMap<>(); - for (Predicate predicate : factsFromProgram.keySet()) { + for (PredicateImpl predicate : factsFromProgram.keySet()) { // Instead of generating NoGoods, add instance to working memories directly. workingMemory.addInstances(predicate, true, factsFromProgram.get(predicate)); } @@ -312,7 +288,7 @@ public Map getNoGoods(Assignment currentAssignment) { // Compute new ground rule (evaluate joins with newly changed atoms) for (IndexedInstanceStorage modifiedWorkingMemory : workingMemory.modified()) { // Skip predicates solely used in the solver which do not occur in rules. - Predicate workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); + PredicateImpl workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); if (workingMemoryPredicate.isSolverInternal()) { continue; } @@ -355,7 +331,7 @@ public Map getNoGoods(Assignment currentAssignment) { } workingMemory.reset(); - for (Atom removeAtom : removeAfterObtainingNewNoGoods) { + for (AtomImpl removeAtom : removeAfterObtainingNewNoGoods) { final IndexedInstanceStorage storage = workingMemory.get(removeAtom, true); Instance instance = new Instance(removeAtom.getTerms()); if (storage.containsInstance(instance)) { @@ -385,9 +361,9 @@ public Map getNoGoods(Assignment currentAssignment) { /** * Grounds the given {@code nonGroundRule} by applying the given {@code substitutions} and registers the nogoods generated during that process. * - * @param nonGroundRule the rule to be grounded. - * @param substitutions the substitutions to be applied. - * @param newNoGoods a set of nogoods to which newly generated nogoods will be added. + * @param nonGroundRule the rule to be grounded. + * @param substitutions the substitutions to be applied. + * @param newNoGoods a set of nogoods to which newly generated nogoods will be added. */ private void groundAndRegister(final InternalRule nonGroundRule, final List substitutions, final Map newNoGoods) { for (Substitution substitution : substitutions) { @@ -403,7 +379,7 @@ public int register(NoGood noGood) { // Ideally, this method should be private. It's only visible because NaiveGrounderTest needs to access it. BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder groundingOrder, Substitution partialSubstitution, - Assignment currentAssignment) { + Assignment currentAssignment) { int tolerance = heuristicsConfiguration.getTolerance(rule.isConstraint()); if (tolerance < 0) { tolerance = Integer.MAX_VALUE; @@ -427,12 +403,12 @@ BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder grou /** * Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrder, int, int, int, Substitution)}. - * + * * Takes an ImmutablePair of a {@link Substitution} and an accompanying {@link AssignmentStatus} and calls * bindNextAtomInRule for the next literal in the grounding order. * If the assignment status for the last bound literal was {@link AssignmentStatus#UNASSIGNED}, the remainingTolerance * parameter is decreased by 1. If the remaining tolerance drops below zero, this method returns an empty {@link BindingResult}. - * + * * @param groundingOrder * @param orderPosition * @param originalTolerance @@ -442,7 +418,7 @@ BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder grou * tolerance is less than zero. */ private BindingResult continueBinding(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - ImmutablePair lastLiteralBindingResult) { + ImmutablePair lastLiteralBindingResult) { Substitution substitution = lastLiteralBindingResult.left; AssignmentStatus lastBoundLiteralAssignmentStatus = lastLiteralBindingResult.right; switch (lastBoundLiteralAssignmentStatus) { @@ -459,20 +435,20 @@ private BindingResult continueBinding(RuleGroundingOrder groundingOrder, int ord } case FALSE: throw Util.oops("Got an assignmentStatus FALSE for literal " + groundingOrder.getLiteralAtOrderPosition(orderPosition) + " and substitution " - + substitution + " - should not happen!"); + + substitution + " - should not happen!"); default: throw Util.oops("Got unsupported assignmentStatus " + lastBoundLiteralAssignmentStatus); } } private BindingResult advanceAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { + Substitution partialSubstitution) { groundingOrder.considerUntilCurrentEnd(); return bindNextAtomInRule(groundingOrder, orderPosition + 1, originalTolerance, remainingTolerance, partialSubstitution); } private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { + Substitution partialSubstitution) { RuleGroundingOrder modifiedGroundingOrder = groundingOrder.pushBack(orderPosition); if (modifiedGroundingOrder == null) { return BindingResult.empty(); @@ -481,12 +457,13 @@ private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder grounding } //@formatter:off + /** * Computes ground substitutions for a literal based on a {@link RuleGroundingOrder} and a {@link Substitution}. - * + * * Computes ground substitutions for the literal at position orderPosition of groundingOrder * Actual substitutions are computed by this grounder's {@link LiteralInstantiator}. - * + * * @param groundingOrder a {@link RuleGroundingOrder} representing the body literals of a rule in the * sequence in which the should be bound during grounding. * @param orderPosition the current position within groundingOrder, indicates which literal should be bound @@ -497,14 +474,14 @@ private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder grounding */ //@formatter:on private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { - Literal currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); + Substitution partialSubstitution) { + LiteralImpl currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); if (currentLiteral == null) { LOGGER.trace("No more literals found in grounding order, therefore stopping binding!"); return BindingResult.singleton(partialSubstitution, originalTolerance - remainingTolerance); } LOGGER.trace("Binding current literal {} with remaining tolerance {} and partial substitution {}.", currentLiteral, - remainingTolerance, partialSubstitution); + remainingTolerance, partialSubstitution); LiteralInstantiationResult instantiationResult = ruleInstantiator.instantiateLiteral(currentLiteral, partialSubstitution); switch (instantiationResult.getType()) { case CONTINUE: @@ -519,7 +496,7 @@ private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int BindingResult retVal = new BindingResult(); for (ImmutablePair substitutionInfo : substitutionInfos) { retVal.add(this.continueBinding(groundingOrder, orderPosition, originalTolerance, remainingTolerance, - substitutionInfo)); + substitutionInfo)); } return retVal; case PUSH_BACK: @@ -591,7 +568,7 @@ public boolean isFact(Atom atom) { public Set justifyAtom(int atomToJustify, Assignment currentAssignment) { Set literals = analyzeUnjustified.analyze(atomToJustify, currentAssignment); // Remove facts from justification before handing it over to the solver. - for (Iterator iterator = literals.iterator(); iterator.hasNext();) { + for (Iterator iterator = literals.iterator(); iterator.hasNext(); ) { Literal literal = iterator.next(); if (literal.isNegated()) { continue; @@ -606,8 +583,8 @@ public Set justifyAtom(int atomToJustify, Assignment currentAssignment) /** * Checks that every nogood not marked as {@link NoGoodInterface.Type#INTERNAL} contains only - * atoms which are not {@link Predicate#isSolverInternal()} (except {@link RuleAtom}s, which are allowed). - * + * atoms which are not {@link PredicateImpl#isSolverInternal()} (except {@link RuleAtom}s, which are allowed). + * * @param newNoGoods */ private void checkTypesOfNoGoods(Collection newNoGoods) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java index 75a27929d..aea9a8fd4 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java @@ -42,10 +42,11 @@ import at.ac.tuwien.kr.alpha.common.AtomStore; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; @@ -58,11 +59,11 @@ public class NoGoodGenerator { private final AtomStore atomStore; private final ChoiceRecorder choiceRecorder; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private final InternalProgram programAnalysis; private final Set uniqueGroundRulePerGroundHead; - NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { + NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { this.atomStore = atomStore; this.choiceRecorder = recorder; this.factsFromProgram = factsFromProgram; @@ -95,7 +96,7 @@ List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundR final List result = new ArrayList<>(); - final Atom groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); + final AtomImpl groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); final int headId = atomStore.putIfAbsent(groundHeadAtom); // Prepare atom representing the rule body. @@ -140,8 +141,8 @@ List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundR List collectNegLiterals(final InternalRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsNegative = new ArrayList<>(); - for (Literal lit : nonGroundRule.getNegativeBody()) { - Atom groundAtom = lit.getAtom().substitute(substitution); + for (LiteralImpl lit : nonGroundRule.getNegativeBody()) { + AtomImpl groundAtom = lit.getAtom().substitute(substitution); final Set factInstances = factsFromProgram.get(groundAtom.getPredicate()); @@ -162,7 +163,7 @@ List collectNegLiterals(final InternalRule nonGroundRule, final Substit private List collectPosLiterals(final InternalRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsPositive = new ArrayList<>(); - for (Literal lit : nonGroundRule.getPositiveBody()) { + for (LiteralImpl lit : nonGroundRule.getPositiveBody()) { if (lit instanceof FixedInterpretationLiteral) { // TODO: conversion of atom to literal is ugly. NonGroundRule could manage atoms instead of literals, cf. FIXME there // Atom has fixed interpretation, hence was checked earlier that it @@ -170,13 +171,13 @@ private List collectPosLiterals(final InternalRule nonGroundRule, final // FixedInterpretationAtoms need not be shown to the solver, skip it. continue; } - final Atom atom = lit.getAtom(); + final AtomImpl atom = lit.getAtom(); // Skip the special enumeration atom. if (atom instanceof EnumerationAtom) { continue; } - final Atom groundAtom = atom.substitute(substitution); + final AtomImpl groundAtom = atom.substitute(substitution); // Consider facts to eliminate ground atoms from the generated nogoods that are always true // and eliminate nogoods that are always satisfied due to facts. @@ -196,7 +197,7 @@ private List collectPosLiterals(final InternalRule nonGroundRule, final return bodyLiteralsPositive; } - private boolean existsRuleWithPredicateInHead(final Predicate predicate) { + private boolean existsRuleWithPredicateInHead(final PredicateImpl predicate) { final HashSet definingRules = programAnalysis.getPredicateDefiningRules().get(predicate); return definingRules != null && !definingRules.isEmpty(); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java index 602a7aedf..ee30ac7a1 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java @@ -29,6 +29,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; /** @@ -37,12 +38,12 @@ public class RuleGroundingOrder { private Literal startingLiteral; - private List otherLiterals; + private List otherLiterals; private int positionLastVarBound; private int stopBindingAtOrderPosition; private final boolean ground; - RuleGroundingOrder(Literal startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { + RuleGroundingOrder(Literal startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { super(); this.startingLiteral = startingLiteral; this.otherLiterals = otherLiterals; @@ -66,7 +67,7 @@ private RuleGroundingOrder(RuleGroundingOrder otherRuleGroundingOrder) { * @param orderPosition zero-based index into list of literals except the starting literal * @return the literal at the given position, or {@code null} if it is already known that this literal is not able to yield new bindings */ - public Literal getLiteralAtOrderPosition(int orderPosition) { + public LiteralImpl getLiteralAtOrderPosition(int orderPosition) { if (orderPosition >= stopBindingAtOrderPosition) { return null; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java index 6d903d938..f37d43f74 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java @@ -39,6 +39,7 @@ import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; @@ -62,9 +63,9 @@ */ public class RuleGroundingOrders { private final InternalRule internalRule; - HashMap groundingOrders; - private HashMap literalSelectivity; - private List startingLiterals; + HashMap groundingOrders; + private HashMap literalSelectivity; + private List startingLiterals; private final boolean fixedGroundingInstantiation; private RuleGroundingOrder fixedGroundingOrder; @@ -79,7 +80,7 @@ public RuleGroundingOrders(InternalRule internalRule) { private void resetLiteralSelectivity() { // Set selectivity of all literals to 1.0f. - for (Literal literal : internalRule.getBody()) { + for (LiteralImpl literal : internalRule.getBody()) { literalSelectivity.put(literal, 1.0f); } } @@ -89,8 +90,8 @@ private void resetLiteralSelectivity() { * @return true iff the rule has a fixed ground instantiation. */ private boolean computeStartingLiterals() { - LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); - LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); + LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); + LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); // If the rule is ground, every body literal is a starting literal and the ground instantiation is fixed. if (internalRule.isGround()) { @@ -99,7 +100,7 @@ private boolean computeStartingLiterals() { } // Check each literal in the rule body whether it is eligible. - for (Literal literal : internalRule.getBody()) { + for (LiteralImpl literal : internalRule.getBody()) { // Only literals that need no variables already bound can start grounding. if (literal.getNonBindingVariables().size() != 0) { continue; @@ -127,7 +128,7 @@ private boolean computeStartingLiterals() { } } - public List getStartingLiterals() { + public List getStartingLiterals() { return Collections.unmodifiableList(startingLiterals); } @@ -159,18 +160,18 @@ public void computeGroundingOrders() { return; } // Compute grounding orders for all positive BasicAtoms. - for (Literal literal : startingLiterals) { + for (LiteralImpl literal : startingLiterals) { computeGroundingOrder(literal); } } - private void computeGroundingOrder(Literal startingLiteral) { - Set bodyLiterals = internalRule.getBody(); + private void computeGroundingOrder(LiteralImpl startingLiteral) { + Set bodyLiterals = internalRule.getBody(); HashSet boundVariables = new HashSet<>(); boundVariables.addAll(startingLiteral.getBindingVariables()); - LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); + LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); remainingLiterals.remove(startingLiteral); - ArrayList literalsOrder; + ArrayList literalsOrder; if (fixedGroundingInstantiation) { literalsOrder = new ArrayList<>(bodyLiterals.size()); literalsOrder.add(startingLiteral); @@ -181,7 +182,7 @@ private void computeGroundingOrder(Literal startingLiteral) { int position = 0; int positionLastVarBound = -1; while (!remainingLiterals.isEmpty()) { - Literal nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); + LiteralImpl nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); if (nextGroundingLiteral == null) { throw new RuntimeException("Could not find a grounding order for rule " + internalRule + " with starting literal: " + startingLiteral + ". Rule is not safe."); } @@ -199,13 +200,13 @@ private void computeGroundingOrder(Literal startingLiteral) { groundingOrders.put(startingLiteral, new RuleGroundingOrder(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); } - private Literal selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { + private LiteralImpl selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { Float bestSelectivity = Float.MAX_VALUE; - Literal bestLiteral = null; + LiteralImpl bestLiteral = null; boolean bestLiteralSharesVariables = false; // Find the best literal whose nonbinding variables are already bound and whose selectivity is highest. // To avoid cross products, select those first that have some of their variables already bound. - for (Literal literal : remainingLiterals) { + for (LiteralImpl literal : remainingLiterals) { if (!boundVariables.containsAll(literal.getNonBindingVariables())) { // Only consider literals whose nonbinding variables are already bound. continue; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java index c90bb4846..73fa3727b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java @@ -27,12 +27,10 @@ */ package at.ac.tuwien.kr.alpha.grounder; +import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.common.terms.*; import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; import java.util.List; @@ -48,14 +46,14 @@ public class Substitution { private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); public static final Substitution EMPTY_SUBSTITUTION = new Substitution() { @Override - public > Term put(VariableTerm variableTerm, Term groundTerm) { + public > Term put(VariableTerm variableTerm, TermImpl groundTerm) { throw oops("Should not be called on EMPTY_SUBSTITUTION"); } }; - protected TreeMap substitution; + protected TreeMap substitution; - private Substitution(TreeMap substitution) { + private Substitution(TreeMap substitution) { if (substitution == null) { throw oops("Substitution is null."); } @@ -80,7 +78,7 @@ public static Substitution specializeSubstitution(Literal literal, Instance inst private static class SpecializationHelper { Substitution updatedSubstitution; // Is null for as long as the given partial substitution is not extended, afterwards holds the updated/extended/specialized substitution. - Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { + Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { for (int i = 0; i < termList.size(); i++) { if (!unifyTerms(termList.get(i), instance.terms.get(i), partialSubstitution)) { return null; @@ -93,7 +91,7 @@ Substitution unify(List termList, Instance instance, Substitution partialS return updatedSubstitution; } - boolean unifyTerms(Term termNonGround, Term termGround, Substitution partialSubstitution) { + boolean unifyTerms(Term termNonGround, TermImpl termGround, Substitution partialSubstitution) { if (termNonGround == termGround) { // Both terms are either the same constant or the same variable term return true; @@ -160,16 +158,16 @@ public static Substitution specializeSubstitution(Atom atom, Instance instance, } /** - * This method should be used to obtain the {@link Term} to be used in place of a given {@link VariableTerm} under this substitution. + * This method should be used to obtain the {@link TermImpl} to be used in place of a given {@link VariableTerm} under this substitution. * * @param variableTerm the variable term to substitute, if possible * @return a constant term if the substitution contains the given variable, {@code null} otherwise. */ - public Term eval(VariableTerm variableTerm) { + public TermImpl eval(VariableTerm variableTerm) { return this.substitution.get(variableTerm); } - public > Term put(VariableTerm variableTerm, Term groundTerm) { + public > Term put(VariableTerm variableTerm, TermImpl groundTerm) { if (!groundTerm.isGround()) { throw oops("Right-hand term is not ground."); } @@ -202,7 +200,7 @@ public Set getMappedVariables() { public String toString() { final StringBuilder ret = new StringBuilder("{"); boolean isFirst = true; - for (Map.Entry e : substitution.entrySet()) { + for (Map.Entry e : substitution.entrySet()) { if (isFirst) { isFirst = false; } else { @@ -221,7 +219,7 @@ public static Substitution fromString(String substitution) { for (String assignment : assignments) { String[] keyVal = assignment.split("->"); VariableTerm variable = VariableTerm.getInstance(keyVal[0]); - Term assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); + TermImpl assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); ret.put(variable, assignedTerm); } return ret; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java index b448dc29f..1303e3dec 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java @@ -28,8 +28,9 @@ package at.ac.tuwien.kr.alpha.grounder; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import java.util.Set; @@ -41,7 +42,7 @@ */ public class Unification { - public static Unifier unifyAtoms(Atom left, Atom right) { + public static Unifier unifyAtoms(AtomImpl left, AtomImpl right) { return unifyAtoms(left, right, false); } @@ -51,11 +52,11 @@ public static Unifier unifyAtoms(Atom left, Atom right) { * @param specific the specific Atom. * @return a Unifier sigma such that specific == general.substitute(sigma), returns null if no such sigma exists. */ - public static Unifier instantiate(Atom general, Atom specific) { + public static Unifier instantiate(AtomImpl general, AtomImpl specific) { return unifyAtoms(specific, general, true); } - private static Unifier unifyAtoms(Atom left, Atom right, boolean keepLeftAsIs) { + private static Unifier unifyAtoms(AtomImpl left, AtomImpl right, boolean keepLeftAsIs) { Set leftOccurringVariables = left.getOccurringVariables(); Set rightOccurringVaribles = right.getOccurringVariables(); boolean leftSmaller = leftOccurringVariables.size() < rightOccurringVaribles.size(); @@ -71,8 +72,8 @@ private static Unifier unifyAtoms(Atom left, Atom right, boolean keepLeftAsIs) { return null; } for (int i = 0; i < left.getPredicate().getArity(); i++) { - final Term leftTerm = left.getTerms().get(i); - final Term rightTerm = right.getTerms().get(i); + final TermImpl leftTerm = left.getTerms().get(i); + final TermImpl rightTerm = right.getTerms().get(i); if (!unifyTerms(leftTerm, rightTerm, mgu, keepLeftAsIs)) { return null; } @@ -80,9 +81,9 @@ private static Unifier unifyAtoms(Atom left, Atom right, boolean keepLeftAsIs) { return mgu; } - private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitution, boolean keepLeftAsIs) { - final Term leftSubs = left.substitute(currentSubstitution); - final Term rightSubs = right.substitute(currentSubstitution); + private static boolean unifyTerms(TermImpl left, TermImpl right, Unifier currentSubstitution, boolean keepLeftAsIs) { + final TermImpl leftSubs = left.substitute(currentSubstitution); + final TermImpl rightSubs = right.substitute(currentSubstitution); if (leftSubs == rightSubs) { return true; } @@ -102,8 +103,8 @@ private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitu return false; } for (int i = 0; i < leftFunction.getTerms().size(); i++) { - final Term leftTerm = leftFunction.getTerms().get(i); - final Term rightTerm = rightFunction.getTerms().get(i); + final TermImpl leftTerm = leftFunction.getTerms().get(i); + final TermImpl rightTerm = rightFunction.getTerms().get(i); if (!unifyTerms(leftTerm, rightTerm, currentSubstitution, keepLeftAsIs)) { return false; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java index 1fed02c15..3e326e1b1 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java @@ -10,6 +10,7 @@ import java.util.TreeMap; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; /** @@ -65,7 +66,7 @@ public Set getMappedVariables() { @Override - public > Term put(VariableTerm variableTerm, Term term) { + public > Term put(VariableTerm variableTerm, TermImpl term) { // If term is not ground, store it for right-hand side reverse-lookup. if (!term.isGround()) { for (VariableTerm rightHandVariable : term.getOccurringVariables()) { @@ -82,7 +83,7 @@ public > Term put(VariableTerm variableTerm, Term term) // Replace all occurrences on the right-hand side with the just-assigned term. for (VariableTerm rightHandOccurrence : rightHandOccurrences) { // Substitute the right hand where this assigned variable occurs with the new value and store it. - Term previousRightHand = substitution.get(rightHandOccurrence); + TermImpl previousRightHand = substitution.get(rightHandOccurrence); if (previousRightHand == null) { // Variable does not occur on the lef-hand side, skip. continue; @@ -108,7 +109,7 @@ public static Unifier mergeIntoLeft(Unifier left, Unifier right) { Unifier ret = new Unifier(left); for (Map.Entry mapping : right.substitution.entrySet()) { VariableTerm variable = mapping.getKey(); - Term term = mapping.getValue(); + TermImpl term = mapping.getValue(); // If variable is unset, simply add. if (!ret.isVariableSet(variable)) { ret.put(variable, term); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java index 438fa2238..ca7b89b90 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java @@ -34,19 +34,19 @@ import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; public class WorkingMemory { - protected HashMap> workingMemory = new HashMap<>(); + protected HashMap> workingMemory = new HashMap<>(); private HashSet modifiedWorkingMemories = new LinkedHashSet<>(); - public boolean contains(Predicate predicate) { + public boolean contains(PredicateImpl predicate) { return workingMemory.containsKey(predicate); } - public void initialize(Predicate predicate) { + public void initialize(PredicateImpl predicate) { if (workingMemory.containsKey(predicate)) { return; } @@ -70,7 +70,7 @@ public IndexedInstanceStorage get(Atom atom, boolean value) { return get(atom.getPredicate(), value); } - public IndexedInstanceStorage get(Predicate predicate, boolean value) { + public IndexedInstanceStorage get(PredicateImpl predicate, boolean value) { ImmutablePair pair = workingMemory.get(predicate); if (value) { return pair.getLeft(); @@ -83,7 +83,7 @@ public void addInstance(Atom atom, boolean value) { addInstance(atom.getPredicate(), value, new Instance(atom.getTerms())); } - public void addInstance(Predicate predicate, boolean value, Instance instance) { + public void addInstance(PredicateImpl predicate, boolean value, Instance instance) { IndexedInstanceStorage storage = get(predicate, value); if (!storage.containsInstance(instance)) { @@ -92,7 +92,7 @@ public void addInstance(Predicate predicate, boolean value, Instance instance) { } } - public void addInstances(Predicate predicate, boolean value, Iterable instances) { + public void addInstances(PredicateImpl predicate, boolean value, Iterable instances) { IndexedInstanceStorage storage = get(predicate, value); for (Instance instance : instances) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java index 6584eaa94..080451244 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java @@ -32,27 +32,29 @@ import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; -public class ChoiceAtom extends Atom { +public class ChoiceAtom extends AtomImpl { - public static final Predicate ON = Predicate.getInstance("ChoiceOn", 1, true, true); - public static final Predicate OFF = Predicate.getInstance("ChoiceOff", 1, true, true); + public static final PredicateImpl ON = PredicateImpl.getInstance("ChoiceOn", 1, true, true); + public static final PredicateImpl OFF = PredicateImpl.getInstance("ChoiceOff", 1, true, true); - private final Predicate predicate; + private final PredicateImpl predicate; private final List terms; - private ChoiceAtom(Predicate predicate, Term term) { + private ChoiceAtom(PredicateImpl predicate, Term term) { this.predicate = predicate; this.terms = Collections.singletonList(term); } - private ChoiceAtom(Predicate predicate, int id) { + private ChoiceAtom(PredicateImpl predicate, int id) { this(predicate, ConstantTerm.getInstance(Integer.toString(id))); } @@ -65,7 +67,7 @@ public static ChoiceAtom off(int id) { } @Override - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return predicate; } @@ -86,7 +88,7 @@ public Literal toLiteral(boolean negated) { } @Override - public Atom substitute(Substitution substitution) { + public AtomImpl substitute(Substitution substitution) { return this; } @@ -96,7 +98,7 @@ public String toString() { } @Override - public Atom withTerms(List terms) { + public AtomImpl withTerms(List terms) { throw new UnsupportedOperationException("Changing terms is not supported for ChoiceAtoms!"); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java index 3ba9f5fb8..18da329e9 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java @@ -5,7 +5,7 @@ import java.util.HashMap; import java.util.List; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; @@ -24,7 +24,7 @@ * Copyright (c) 2017, the Alpha Team. */ public class EnumerationAtom extends BasicAtom { - public static final Predicate ENUMERATION_PREDICATE = Predicate.getInstance("_Enumeration", 3); + public static final PredicateImpl ENUMERATION_PREDICATE = PredicateImpl.getInstance("_Enumeration", 3); private static final HashMap> ENUMERATIONS = new HashMap<>(); public EnumerationAtom(List terms) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java index 115a29e8e..830ee4567 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java @@ -33,11 +33,13 @@ import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; /** @@ -52,8 +54,8 @@ * * Copyright (c) 2017, the Alpha Team. */ -public class IntervalAtom extends Atom implements VariableNormalizableAtom { - private static final Predicate PREDICATE = Predicate.getInstance("_interval", 2, true); +public class IntervalAtom extends AtomImpl implements VariableNormalizableAtom { + private static final PredicateImpl PREDICATE = PredicateImpl.getInstance("_interval", 2, true); private final List terms; @@ -62,7 +64,7 @@ public IntervalAtom(IntervalTerm intervalTerm, Term intervalRepresentingVariable } @Override - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return PREDICATE; } @@ -125,12 +127,12 @@ public IntervalAtom substitute(Substitution substitution) { @Override public IntervalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = Term.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = TermImpl.renameTerms(terms, prefix, counterStartingValue); return new IntervalAtom((IntervalTerm) renamedTerms.get(0), renamedTerms.get(1)); } @Override - public Atom withTerms(List terms) { + public AtomImpl withTerms(List terms) { throw new UnsupportedOperationException("IntervalAtoms do not support setting of terms!"); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java index ff6f7a90e..87a219210 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java @@ -27,25 +27,28 @@ */ package at.ac.tuwien.kr.alpha.grounder.atoms; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; import java.util.Arrays; import java.util.List; -import static at.ac.tuwien.kr.alpha.common.terms.ConstantTerm.getInstance; +import static at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl.getInstance; /** * Atoms corresponding to rule bodies use this predicate, first term is rule number, * second is a term containing variable substitutions. */ -public class RuleAtom extends Atom { - public static final Predicate PREDICATE = Predicate.getInstance("_R_", 2, true, true); +public class RuleAtom extends AtomImpl { + public static final PredicateImpl PREDICATE = PredicateImpl.getInstance("_R_", 2, true, true); private final List> terms; @@ -66,12 +69,12 @@ public RuleAtom(InternalRule nonGroundRule, Substitution substitution) { } @Override - public Predicate getPredicate() { + public PredicateImpl getPredicate() { return PREDICATE; } @Override - public List getTerms() { + public List getTerms() { return Arrays.asList(terms.get(0), terms.get(1)); } @@ -82,12 +85,12 @@ public boolean isGround() { } @Override - public Literal toLiteral(boolean positive) { + public LiteralImpl toLiteral(boolean positive) { throw new UnsupportedOperationException("RuleAtom cannot be literalized"); } @Override - public Atom substitute(Substitution substitution) { + public AtomImpl substitute(Substitution substitution) { return this; } @@ -116,7 +119,7 @@ public String toString() { } @Override - public Atom withTerms(List terms) { + public AtomImpl withTerms(List terms) { throw new UnsupportedOperationException("RuleAtoms do not support setting of terms!"); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java index 787cb9510..82eac356c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -25,9 +25,7 @@ */ package at.ac.tuwien.kr.alpha.grounder.instantiation; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.grounder.Instance; import at.ac.tuwien.kr.alpha.grounder.Substitution; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -54,7 +52,7 @@ public abstract class AbstractLiteralInstantiationStrategy implements LiteralIns * literals is determined using the abstract method {@link AbstractLiteralInstantiationStrategy#getAssignmentStatusForAtom(Atom)}. */ @Override - public final AssignmentStatus getTruthForGroundLiteral(Literal groundLiteral) { + public final AssignmentStatus getTruthForGroundLiteral(LiteralImpl groundLiteral) { if (groundLiteral.isNegated()) { return this.getAssignmentStatusForNegatedGroundLiteral(groundLiteral); } @@ -71,7 +69,7 @@ public final AssignmentStatus getTruthForGroundLiteral(Literal groundLiteral) { * {@link AbstractLiteralInstantiationStrategy#assignmentStatusAccepted(AssignmentStatus)}. */ @Override - public final List> getAcceptedSubstitutions(Literal lit, Substitution partialSubstitution) { + public final List> getAcceptedSubstitutions(LiteralImpl lit, Substitution partialSubstitution) { Atom atom = lit.getAtom(); Iterable groundInstances = this.computeCandidateInstances(atom); return this.buildSubstitutionsFromInstances(atom, groundInstances, partialSubstitution); @@ -103,7 +101,7 @@ protected final List> buildSubstit List> retVal = new ArrayList<>(); // Filter for only instances unifying with partialSubsitution, i.e. "where all joins work out". Substitution currentInstanceSubstitution; - Atom atomForCurrentInstance; + AtomImpl atomForCurrentInstance; for (Instance instance : candidateInstances) { currentInstanceSubstitution = Substitution.specializeSubstitution(atomToSubstitute, instance, partialSubstitution); if (currentInstanceSubstitution == null) { @@ -124,7 +122,7 @@ protected final List> buildSubstit return retVal; } - protected abstract AssignmentStatus getAssignmentStatusForAtom(Atom atom); + protected abstract AssignmentStatus getAssignmentStatusForAtom(AtomImpl atom); protected abstract AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(Literal negatedGroundLiteral); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java index 9b789317a..950b06ea2 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java @@ -31,8 +31,9 @@ import at.ac.tuwien.kr.alpha.Util; import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; import at.ac.tuwien.kr.alpha.grounder.Instance; @@ -45,7 +46,7 @@ * Implementation of {@link AbstractLiteralInstantiationStrategy} designed for use in {@link NaiveGrounder}. * * The instantiation strategy shares a {@link WorkingMemory}, an {@link AtomStore}, an {@link Assignment}, a {@link Map} of atoms that were - * facts of the currently grounded program, as well as a list of {@link Atom}s that should be lazily deleted from the working memory, with + * facts of the currently grounded program, as well as a list of {@link AtomImpl}s that should be lazily deleted from the working memory, with * the grounder. * * The working memory and the facts map are maintained by the grounder and are being read by @@ -54,10 +55,10 @@ * are added by the instantiation strategy. The {@link Assignment} reflects the {@link Solver}s "current view of the world". It is used by * {@link DefaultLazyGroundingInstantiationStrategy} to determine {@link AssignmentStatus}es for atoms. * - * A specialty of this implementation is that - since deletion of obsolete {@link Atom}s from {@link NaiveGrounder}s {@link WorkingMemory} + * A specialty of this implementation is that - since deletion of obsolete {@link AtomImpl}s from {@link NaiveGrounder}s {@link WorkingMemory} * happens lazily (i.e. at the end of each run of {@link NaiveGrounder#getNoGoods(Assignment)}) - it maintains a set of "stale" atoms that * is shared with the grounder. Specifically, whenever {@link DefaultLazyGroundingInstantiationStrategy#getAssignmentStatusForAtom(Atom)} - * determines that an {@link Atom} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link Atom} is added to + * determines that an {@link AtomImpl} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link AtomImpl} is added to * the stale atom set, which in turn is processed by the grounder, which then deletes the respective atoms from the working memory. * * Copyright (c) 2020, the Alpha Team. @@ -67,11 +68,11 @@ public class DefaultLazyGroundingInstantiationStrategy extends AbstractLiteralIn private WorkingMemory workingMemory; private AtomStore atomStore; private Assignment currentAssignment; - private LinkedHashSet staleWorkingMemoryEntries; - private Map> facts; + private LinkedHashSet staleWorkingMemoryEntries; + private Map> facts; public DefaultLazyGroundingInstantiationStrategy(WorkingMemory workingMemory, AtomStore atomStore, - Map> facts) { + Map> facts) { this.workingMemory = workingMemory; this.atomStore = atomStore; this.facts = facts; @@ -85,7 +86,7 @@ protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) //@formatter:off /** - * Computes the {@link AssignmentStatus} for a given {@link Atom} a. + * Computes the {@link AssignmentStatus} for a given {@link AtomImpl} a. * * The atom a is {@link AssignmentStatus#TRUE} iff *

    @@ -97,12 +98,12 @@ protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) * An atom is {@link AssignmentStatus#UNASSIGNED} iff it has no {@link ThriceTruth} assigned to it in the current assignment. * An atom is {@link AssignmentStatus#FALSE} iff it is assigned {@link ThriceTruth#FALSE} in the current assignment by the {@link Solver}. * - * Whenever an {@link Atom} is found to be UNASSIGNED or FALSE, - * that {@link Atom} is added to the stale atom set for later deletion from working memory by the grounder. + * Whenever an {@link AtomImpl} is found to be UNASSIGNED or FALSE, + * that {@link AtomImpl} is added to the stale atom set for later deletion from working memory by the grounder. */ //@formatter:on @Override - protected AssignmentStatus getAssignmentStatusForAtom(Atom atom) { + protected AssignmentStatus getAssignmentStatusForAtom(AtomImpl atom) { if (this.currentAssignment == null || this.isFact(atom)) { // currentAssignment == null is a legitimate case, grounder may be in bootstrap // and will call bindNextAtom with null assignment in that case. @@ -130,7 +131,7 @@ protected AssignmentStatus getAssignmentStatusForAtom(Atom atom) { return retVal; } - private boolean isFact(Atom atom) { + private boolean isFact(AtomImpl atom) { if (this.facts.get(atom.getPredicate()) == null) { return false; } else { @@ -166,7 +167,7 @@ public void setCurrentAssignment(Assignment currentAssignment) { this.currentAssignment = currentAssignment; } - public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { + public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { this.staleWorkingMemoryEntries = staleWorkingMemoryEntries; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java index b02b76096..42d7be9f1 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java @@ -25,6 +25,7 @@ */ package at.ac.tuwien.kr.alpha.grounder.instantiation; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; import org.apache.commons.lang3.tuple.ImmutablePair; import java.util.Collections; @@ -37,7 +38,7 @@ /** * Representation of the result of instantiating, i.e. finding ground instances for a literal, as performed by - * {@link LiteralInstantiator#instantiateLiteral(at.ac.tuwien.kr.alpha.common.atoms.Literal, Substitution)}. + * {@link LiteralInstantiator#instantiateLiteral(Literal, Substitution)}. * * 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}. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java index f264d418b..54e3dbd43 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java @@ -27,6 +27,7 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import org.apache.commons.lang3.tuple.ImmutablePair; import at.ac.tuwien.kr.alpha.common.atoms.Literal; @@ -46,7 +47,7 @@ public interface LiteralInstantiationStrategy { * @param groundLiteral a ground {@link Literal} for which to compute an {@link AssignmentStatus} * @return the current {@link AssignmentStatus} for the given literal according to the rules of this {@link LiteralInstantiationStrategy} */ - AssignmentStatus getTruthForGroundLiteral(Literal groundLiteral); + AssignmentStatus getTruthForGroundLiteral(LiteralImpl groundLiteral); /** * Computes {@link Substitution}s that yield ground instances for a given literal and starting substitution along with the @@ -59,6 +60,6 @@ public interface LiteralInstantiationStrategy { * @param partialSubstitution a (possibly empty) substitution to use as a starting point * @return a list of substitutions along with the assignment status of the respective ground atoms */ - List> getAcceptedSubstitutions(Literal lit, Substitution partialSubstitution); + List> getAcceptedSubstitutions(LiteralImpl lit, Substitution partialSubstitution); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java index 904caa961..aaae8cff4 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java @@ -1,17 +1,17 @@ /** * Copyright (c) 2020, the Alpha Team. * 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. - * + * 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 @@ -25,27 +25,23 @@ */ package at.ac.tuwien.kr.alpha.grounder.instantiation; -import java.util.List; - +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationLiteral; +import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalLiteral; import org.apache.commons.lang3.tuple.ImmutablePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.ExternalLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationLiteral; -import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalLiteral; +import java.util.List; /** * Provides ground instantiations for literals. - * + * * This class is intended to be used for grounding and other use cases where ground instantiations of literals need to be computed and * serves as an abstraction layer to decouple the knowledge of how to ground literals from the overall (rule-)grounding workflow. The task of * actually finding fitting ground substitutions is mostly delegated to a {@link LiteralInstantiationStrategy}. - * + * * Copyright (c) 2020, the Alpha Team. */ public class LiteralInstantiator { @@ -56,7 +52,7 @@ public class LiteralInstantiator { /** * Creates a new {@link LiteralInstantiator} with the given {@link LiteralInstantiationStrategy}. - * + * * @param instantiationStrategy the instantiation strategy to use for this instantiator */ public LiteralInstantiator(LiteralInstantiationStrategy instantiationStrategy) { @@ -65,16 +61,16 @@ public LiteralInstantiator(LiteralInstantiationStrategy instantiationStrategy) { /** * Instantiates a literal using an existing {@link Substitution} as starting point. - * + * * This method is intended to be called as part of a larger rule instantiation (i.e. grounding) workflow in order to find ground * instantiations of literals, i.e. extensions of the given partial substitution that yield useable ground instances for the given literal. * These substitutions (if any exist) are wrapped together with some additional status information in a {@link LiteralInstantiationResult}. - * + * * @param lit the literal for which to find substitutions that yield ground instances * @param partialSubstitution a substitution that serves as a starting point. May be empty. * @return a {@link LiteralInstantiationResult} containing ground substitutions - if any exist - along with some metadata for the grounder */ - public LiteralInstantiationResult instantiateLiteral(Literal lit, Substitution partialSubstitution) { + public LiteralInstantiationResult instantiateLiteral(LiteralImpl lit, Substitution partialSubstitution) { LOGGER.trace("Instantiating literal: {}", lit); if (lit instanceof FixedInterpretationLiteral) { return this.instantiateFixedInterpretationLiteral((FixedInterpretationLiteral) lit, partialSubstitution); @@ -92,7 +88,7 @@ public LiteralInstantiationResult instantiateLiteral(Literal lit, Substitution p /** * Calculates satisfying substitutions for a given {@link FixedInterpretationLiteral} based on a partial substitution. This method assumes * that the partial substitution has not been applied to the passed literal. - * + * * @param lit the (fixed interpretation) literal for which to calculate substitutions * @param partialSubstitution * @return a LiteralInstantiationResult representing the result of the search for substitutions @@ -106,7 +102,7 @@ private LiteralInstantiationResult instantiateFixedInterpretationLiteral(FixedIn } else { substitutions = substitutedLiteral.getSatisfyingSubstitutions(partialSubstitution); return substitutions.isEmpty() ? LiteralInstantiationResult.stopBinding() - : LiteralInstantiationResult.continueBindingWithTrueSubstitutions(substitutions); + : LiteralInstantiationResult.continueBindingWithTrueSubstitutions(substitutions); } } @@ -115,7 +111,7 @@ private LiteralInstantiationResult instantiateFixedInterpretationLiteral(FixedIn * 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. - * + * * @param lit an enumeration literal * @param partialSubstitution */ @@ -130,14 +126,14 @@ private LiteralInstantiationResult instantiateEnumerationLiteral(EnumerationLite * this instantiators {@link LiteralInstantiationStrategy}. If the literal is only partially ground after applying the partial substitution, * ground substitutions are looked up using the instantiators {@link LiteralInstantiationStrategy}. This method assumes that the partial * substitution has not been applied to the passed literal. - * + * * @param lit * @param partialSubstitution */ - private LiteralInstantiationResult instantiateBasicLiteral(Literal lit, Substitution partialSubstitution) { + private LiteralInstantiationResult instantiateBasicLiteral(LiteralImpl lit, Substitution partialSubstitution) { LOGGER.trace("Instantiating basic literal: {}", lit); List> substitutions; - Literal substitutedLiteral = lit.substitute(partialSubstitution); + LiteralImpl substitutedLiteral = lit.substitute(partialSubstitution); LOGGER.trace("Substituted literal is {}", substitutedLiteral); if (substitutedLiteral.isGround()) { LOGGER.trace("Literal {} is already ground, checking truth", substitutedLiteral); @@ -168,7 +164,7 @@ private LiteralInstantiationResult instantiateBasicLiteral(Literal lit, Substitu /** * Helper method for instantiateLiteral to determine whether a {@link FixedInterpretationLiteral} may have substitutions later * on and should therefore be pushed back in the grounding order. - * + * * Any {@link FixedInterpretationLiteral} that does not fulfil any of the following conditions is "pushed back" in the * grounding order because it cannot be used to generate substitutions now but maybe later: *

      @@ -177,15 +173,15 @@ private LiteralInstantiationResult instantiateBasicLiteral(Literal lit, Substitu *
    • the literal is an {@link IntervalLiteral} representing a ground interval term
    • *
    • the literal is an {@link ExternalLiteral}.
    • *
    - * + * * @param lit a {@link FixedInterpretationLiteral} that is substituted with the partial substitution passed into * instantiateLiteral */ private boolean shouldPushBackFixedInterpretationLiteral(FixedInterpretationLiteral lit) { return !(lit.isGround() || - (lit instanceof ComparisonLiteral && ((ComparisonLiteral) lit).isLeftOrRightAssigning()) || - (lit instanceof IntervalLiteral && lit.getTerms().get(0).isGround()) || - (lit instanceof ExternalLiteral)); + (lit instanceof ComparisonLiteral && ((ComparisonLiteral) lit).isLeftOrRightAssigning()) || + (lit instanceof IntervalLiteral && lit.getTerms().get(0).isGround()) || + (lit instanceof ExternalLiteral)); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java index 7c2889570..a243a8091 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java @@ -26,6 +26,7 @@ package at.ac.tuwien.kr.alpha.grounder.instantiation; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.grounder.Instance; import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; @@ -52,7 +53,7 @@ protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) } @Override - protected AssignmentStatus getAssignmentStatusForAtom(Atom atom) { + protected AssignmentStatus getAssignmentStatusForAtom(AtomImpl atom) { return this.workingMemory.get(atom, true).containsInstance(Instance.fromAtom(atom)) ? AssignmentStatus.TRUE : AssignmentStatus.FALSE; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java index fa08f314e..c0c814330 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2016-2018, 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 @@ -33,41 +33,19 @@ import at.ac.tuwien.kr.alpha.common.AnswerSet; import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.ExternalAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ExternalLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; import at.ac.tuwien.kr.alpha.common.rule.head.Head; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.common.terms.*; import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.tree.TerminalNode; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; +import java.util.*; import static java.util.Collections.emptyList; @@ -121,11 +99,11 @@ public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { @Override public AnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { - SortedSet predicates = new TreeSet<>(); - Map> predicateInstances = new TreeMap<>(); + SortedSet predicates = new TreeSet<>(); + Map> predicateInstances = new TreeMap<>(); for (ASPCore2Parser.Classical_literalContext classicalLiteralContext : ctx.classical_literal()) { - Atom atom = visitClassical_literal(classicalLiteralContext); + AtomImpl atom = visitClassical_literal(classicalLiteralContext); predicates.add(atom.getPredicate()); predicateInstances.compute(atom.getPredicate(), (k, v) -> { @@ -274,9 +252,9 @@ public ChoiceHead.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elemen } @Override - public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { + public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { // naf_literals : naf_literal (COMMA naf_literals)?; - List literals; + List literals; if (ctx.naf_literals() != null) { literals = visitNaf_literals(ctx.naf_literals()); } else { @@ -294,13 +272,13 @@ public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationCon } @Override - public List visitBody(ASPCore2Parser.BodyContext ctx) { + public List visitBody(ASPCore2Parser.BodyContext ctx) { // body : ( naf_literal | aggregate ) (COMMA body)?; if (ctx == null) { return emptyList(); } - final List literals = new ArrayList<>(); + final List literals = new ArrayList<>(); do { if (ctx.naf_literal() != null) { literals.add(visitNaf_literal(ctx.naf_literal())); @@ -317,12 +295,12 @@ public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { // 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; + TermImpl lt = null; ComparisonOperator lop = null; Term ut = null; ComparisonOperator uop = null; if (ctx.lt != null) { - lt = (Term) visit(ctx.lt); + lt = (TermImpl) visit(ctx.lt); lop = visitBinop(ctx.lop); } if (ctx.ut != null) { @@ -379,16 +357,16 @@ public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { // ground_term : ID | QUOTED_STRING | MINUS? NUMBER; if (ctx.ID() != null) { - return ConstantTerm.getSymbolicInstance(ctx.ID().getText()); + return ConstantTermImpl.getSymbolicInstance(ctx.ID().getText()); } else if (ctx.QUOTED_STRING() != null) { String quotedString = ctx.QUOTED_STRING().getText(); - return ConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); + return ConstantTermImpl.getInstance(quotedString.substring(1, quotedString.length() - 1)); } else { int multiplier = 1; if (ctx.MINUS() != null) { multiplier = -1; } - return ConstantTerm.getInstance(multiplier * Integer.parseInt(ctx.NUMBER().getText())); + return ConstantTermImpl.getInstance(multiplier * Integer.parseInt(ctx.NUMBER().getText())); } } @@ -442,14 +420,14 @@ public ComparisonOperator visitBinop(ASPCore2Parser.BinopContext ctx) { public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { // builtin_atom : term binop term; return new ComparisonAtom( - (Term) visit(ctx.term(0)), - (Term) visit(ctx.term(1)), - visitBinop(ctx.binop()) + (TermImpl) visit(ctx.term(0)), + (TermImpl) visit(ctx.term(1)), + visitBinop(ctx.binop()) ); } @Override - public Literal visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { + public LiteralImpl visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { // naf_literal : NAF? (external_atom | classical_literal | builtin_atom); boolean isCurrentLiteralNegated = ctx.NAF() != null; if (ctx.builtin_atom() != null) { @@ -469,21 +447,21 @@ public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext throw notSupported(ctx); } - final List terms = visitTerms(ctx.terms()); - return new BasicAtom(Predicate.getInstance(ctx.ID().getText(), terms.size()), terms); + final List terms = visitTerms(ctx.terms()); + return new BasicAtom(PredicateImpl.getInstance(ctx.ID().getText(), terms.size()), terms); } @Override - public List visitTerms(ASPCore2Parser.TermsContext ctx) { + public List visitTerms(ASPCore2Parser.TermsContext ctx) { // terms : term (COMMA terms)?; if (ctx == null) { return emptyList(); } - final List terms = new ArrayList<>(); + final List terms = new ArrayList<>(); do { ASPCore2Parser.TermContext term = ctx.term(); - terms.add((Term) visit(term)); + terms.add((TermImpl) visit(term)); } while ((ctx = ctx.terms()) != null); return terms; @@ -491,18 +469,18 @@ public List visitTerms(ASPCore2Parser.TermsContext ctx) { @Override public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { - return ConstantTerm.getInstance(Integer.parseInt(ctx.NUMBER().getText())); + return ConstantTermImpl.getInstance(Integer.parseInt(ctx.NUMBER().getText())); } @Override public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { - return ConstantTerm.getSymbolicInstance(ctx.ID().getText()); + return ConstantTermImpl.getSymbolicInstance(ctx.ID().getText()); } @Override public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { String quotedString = ctx.QUOTED_STRING().getText().replace("\\\"", "\""); - return ConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); + return ConstantTermImpl.getInstance(quotedString.substring(1, quotedString.length() - 1)); } @Override @@ -548,13 +526,13 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) throw new IllegalArgumentException("Unknown interpretation name encountered: " + predicateName); } - List outputTerms = visitTerms(ctx.output); + List outputTerms = visitTerms(ctx.output); return new ExternalAtom( - Predicate.getInstance(predicateName, outputTerms.size()), - interpretation, - visitTerms(ctx.input), - outputTerms + PredicateImpl.getInstance(predicateName, outputTerms.size()), + interpretation, + visitTerms(ctx.input), + outputTerms ); } @@ -564,42 +542,42 @@ public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) ASPCore2Parser.IntervalContext ictx = ctx.interval(); String lowerText = ictx.lower.getText(); String upperText = ictx.upper.getText(); - Term lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? ConstantTerm.getInstance(Integer.parseInt(lowerText)) : VariableTerm.getInstance(lowerText); - Term upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? ConstantTerm.getInstance(Integer.parseInt(upperText)) : VariableTerm.getInstance(upperText); + TermImpl lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? ConstantTermImpl.getInstance(Integer.parseInt(lowerText)) : VariableTerm.getInstance(lowerText); + TermImpl upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? ConstantTermImpl.getInstance(Integer.parseInt(upperText)) : VariableTerm.getInstance(upperText); return IntervalTerm.getInstance(lower, upper); } @Override public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { // | MINUS term - return ArithmeticTerm.MinusTerm.getInstance((Term) visit(ctx.term())); + return ArithmeticTerm.MinusTerm.getInstance((TermImpl) visit(ctx.term())); } @Override public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { // | term (TIMES | DIV | MODULO) term ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES - : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); + : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; + return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), op, (TermImpl) visit(ctx.term(1))); } @Override public Object visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { // | term (PLUS | MINUS) term ArithmeticTerm.ArithmeticOperator op = ctx.PLUS() != null ? ArithmeticTerm.ArithmeticOperator.PLUS : ArithmeticTerm.ArithmeticOperator.MINUS; - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), op, (TermImpl) visit(ctx.term(1))); } @Override public Object visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { // | term POWER term ArithmeticTerm.ArithmeticOperator op = ArithmeticTerm.ArithmeticOperator.POWER; - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), op, (TermImpl) visit(ctx.term(1))); } @Override public Object visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { // | term BITXOR term - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (Term) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (TermImpl) visit(ctx.term(1))); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java index 56593b6a3..9dc07e1c6 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java @@ -32,7 +32,7 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; @@ -48,9 +48,9 @@ public class ProgramPartParser { private final ParseTreeVisitor visitor = new ParseTreeVisitor(Collections.emptyMap(), true); - public Term parseTerm(String s) { + public TermImpl parseTerm(String s) { final ASPCore2Parser parser = getASPCore2Parser(s); - return (Term)parse(parser.term()); + return (TermImpl)parse(parser.term()); } public BasicAtom parseBasicAtom(String s) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java index 658429f70..4a965260d 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java @@ -1,36 +1,23 @@ package at.ac.tuwien.kr.alpha.grounder.structure; -import static at.ac.tuwien.kr.alpha.Util.oops; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collections; -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.NoSuchElementException; -import java.util.Set; - import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Instance; import at.ac.tuwien.kr.alpha.grounder.Unification; import at.ac.tuwien.kr.alpha.grounder.Unifier; import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.Util.oops; /** * Copyright (c) 2018-2020, the Alpha Team. @@ -39,22 +26,22 @@ public class AnalyzeUnjustified { private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeUnjustified.class); private final InternalProgram programAnalysis; private final AtomStore atomStore; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private int renamingCounter; private int padDepth; - public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { + public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { this.programAnalysis = programAnalysis; this.atomStore = atomStore; this.factsFromProgram = factsFromProgram; padDepth = 0; } - private Map> assignedAtoms; + private Map> assignedAtoms; public Set analyze(int atomToJustify, Assignment currentAssignment) { padDepth = 0; - Atom atom = atomStore.get(atomToJustify); + AtomImpl atom = atomStore.get(atomToJustify); if (!(atom instanceof BasicAtom)) { throw oops("Starting atom must be a BasicAtom, but received: " + atom + " of type: " + atom.getClass()); } @@ -71,7 +58,7 @@ public Set analyze(int atomToJustify, Assignment currentAssignment) { if (truth == null) { continue; } - Atom assignedAtom = atomStore.get(i); + AtomImpl assignedAtom = atomStore.get(i); assignedAtoms.putIfAbsent(assignedAtom.getPredicate(), new ArrayList<>()); assignedAtoms.get(assignedAtom.getPredicate()).add(assignedAtom); } @@ -106,7 +93,7 @@ private Set analyze(BasicAtom atom, Assignment currentAssignment) { private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment) { padDepth += 2; log("Begin explainUnjust(): {}", x); - Atom p = x.getAtom(); + AtomImpl p = x.getAtom(); ReturnExplainUnjust ret = new ReturnExplainUnjust(); @@ -116,8 +103,8 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment rulesLoop: for (RuleAndUnifier ruleUnifier : rulesUnifyingWithP) { Unifier sigma = ruleUnifier.unifier; - Set bodyR = ruleUnifier.ruleBody; - Atom sigmaHr = ruleUnifier.originalHead.substitute(sigma); + Set bodyR = ruleUnifier.ruleBody; + AtomImpl sigmaHr = ruleUnifier.originalHead.substitute(sigma); log("Considering now: {}", ruleUnifier); Set vN = new LinkedHashSet<>(x.getComplementSubstitutions()); for (Unifier sigmaN : vN) { @@ -138,15 +125,15 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment log("Adapting N to N'. Original N is {}", vN); log("Adapted N' is {}", vNp); log("Searching for falsified negated literals in the body: {}", bodyR); - for (Literal lit : bodyR) { + for (LiteralImpl lit : bodyR) { if (!lit.isNegated()) { continue; } - Atom lb = lit.getAtom().substitute(sigma); + AtomImpl lb = lit.getAtom().substitute(sigma); log("Found: {}, searching falsifying ground instances of {} (with unifier from the head) now.", lit, lb); AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(lb.getPredicate()); while (assignedAtomsOverPredicate.hasNext()) { - Atom lg = assignedAtomsOverPredicate.next(); + AtomImpl lg = assignedAtomsOverPredicate.next(); log("Considering: {}", lg); if (atomStore.contains(lg)) { int atomId = atomStore.get(lg); @@ -180,8 +167,8 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment } } - List bodyPos = new ArrayList<>(); - for (Literal literal : bodyR) { + List bodyPos = new ArrayList<>(); + for (LiteralImpl literal : bodyR) { if (!literal.isNegated()) { bodyPos.add(literal); } @@ -194,7 +181,7 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment return ret; } - private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { + private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { padDepth += 2; log("Begin UnjustCoverFixed()"); log("Finding unjustified body literals in: {} / {} excluded {}", vB, vY, vN); @@ -212,10 +199,10 @@ private Set unjustCover(List vB, Set vY, Set break; } } - Atom b = vB.get(chosenLiteralPos).getAtom(); + AtomImpl b = vB.get(chosenLiteralPos).getAtom(); log("Picked literal from body is: {}", b); for (Unifier sigmaY : vY) { - Atom bSigmaY = b.substitute(sigmaY); + AtomImpl bSigmaY = b.substitute(sigmaY); log("Treating substitution for: {}", bSigmaY); Set vYp = new LinkedHashSet<>(); @@ -223,7 +210,7 @@ private Set unjustCover(List vB, Set vY, Set AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(b.getPredicate()); atomLoop: while (assignedAtomsOverPredicate.hasNext()) { - Atom atom = assignedAtomsOverPredicate.next(); + AtomImpl atom = assignedAtomsOverPredicate.next(); // Check that atom is justified/true. log("Checking atom: {}", atom); if (atomStore.contains(atom)) { @@ -239,17 +226,17 @@ private Set unjustCover(List vB, Set vY, Set continue; } - Atom bSigma = b.substitute(sigma); + AtomImpl bSigma = b.substitute(sigma); if (!bSigma.isGround()) { throw oops("Resulting atom is not ground."); } Set variablesOccurringInSigma = sigma.getMappedVariables(); if (Unification.instantiate(bSigmaY, bSigma) != null) { for (Unifier sigmaN : vN) { - ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); + ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); occurringVariables.addAll(sigmaN.getMappedVariables()); - BasicAtom genericAtom = new BasicAtom(Predicate.getInstance("_", occurringVariables.size(), true), occurringVariables); - Atom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); + BasicAtom genericAtom = new BasicAtom(PredicateImpl.getInstance("_", occurringVariables.size(), true), occurringVariables); + AtomImpl genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); if (Unification.instantiate(genericSubstituted, genericAtom.substitute(sigma)) != null) { log("Atom {} is excluded by: {} via {}", genericSubstituted, sigmaN, sigma); continue atomLoop; @@ -272,7 +259,7 @@ private Set unjustCover(List vB, Set vY, Set } else { log("Generated LitSet covers nothing. Ignoring: {}", toJustify); } - ArrayList newB = new ArrayList<>(vB); + ArrayList newB = new ArrayList<>(vB); newB.remove(chosenLiteralPos); ret.addAll(unjustCover(newB, vYp, vN, currentAssignment)); log("Literal set(s) to treat: {}", ret); @@ -291,20 +278,20 @@ private String pad(String string) { return sb.toString(); } - private AssignedAtomsIterator getAssignedAtomsOverPredicate(Predicate predicate) { + private AssignedAtomsIterator getAssignedAtomsOverPredicate(PredicateImpl predicate) { // Find more substitutions, consider currentAssignment. - List assignedAtoms = this.assignedAtoms.get(predicate); + List assignedAtoms = this.assignedAtoms.get(predicate); // Consider instances from facts. LinkedHashSet factsOverPredicate = factsFromProgram.get(predicate); return new AssignedAtomsIterator(predicate, assignedAtoms, factsOverPredicate); } - private static class AssignedAtomsIterator implements Iterator { - private final Predicate predicate; - private final Iterator assignedAtomsIterator; + private static class AssignedAtomsIterator implements Iterator { + private final PredicateImpl predicate; + private final Iterator assignedAtomsIterator; private final Iterator factsIterator; - public AssignedAtomsIterator(Predicate predicate, List assignedAtoms, Set facts) { + public AssignedAtomsIterator(PredicateImpl predicate, List assignedAtoms, Set facts) { this.predicate = predicate; this.assignedAtomsIterator = assignedAtoms == null ? Collections.emptyIterator() : assignedAtoms.iterator(); this.factsIterator = facts == null ? Collections.emptyIterator() : facts.iterator(); @@ -316,7 +303,7 @@ public boolean hasNext() { } @Override - public Atom next() { + public AtomImpl next() { if (assignedAtomsIterator.hasNext()) { return assignedAtomsIterator.next(); } @@ -327,11 +314,11 @@ public Atom next() { } } - private List rulesHeadUnifyingWith(Atom p) { + private List rulesHeadUnifyingWith(AtomImpl p) { List rulesWithUnifier = new ArrayList<>(); - Predicate predicate = p.getPredicate(); - + PredicateImpl predicate = p.getPredicate(); + ArrayList definingRulesAndFacts = new ArrayList<>(); // Get facts over the same predicate. LinkedHashSet factInstances = factsFromProgram.get(predicate); @@ -349,8 +336,8 @@ private List rulesHeadUnifyingWith(Atom p) { } for (FactOrNonGroundRule factOrNonGroundRule : definingRulesAndFacts) { boolean isNonGroundRule = factOrNonGroundRule.nonGroundRule != null; - Set renamedBody; - Atom headAtom; + Set renamedBody; + AtomImpl headAtom; if (isNonGroundRule) { // First rename all variables in the rule. InternalRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++); @@ -388,11 +375,11 @@ private static class ReturnExplainUnjust { } private static class RuleAndUnifier { - final Set ruleBody; + final Set ruleBody; final Unifier unifier; - final Atom originalHead; + final AtomImpl originalHead; - private RuleAndUnifier(Set ruleBody, Unifier unifier, Atom originalHead) { + private RuleAndUnifier(Set ruleBody, Unifier unifier, AtomImpl originalHead) { this.ruleBody = ruleBody; this.unifier = unifier; this.originalHead = originalHead; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java index 2e415af08..24de12007 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.grounder.structure; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; import at.ac.tuwien.kr.alpha.grounder.Unifier; import at.ac.tuwien.kr.alpha.grounder.Unification; @@ -16,14 +17,14 @@ * Copyright (c) 2018, the Alpha Team. */ public class LitSet { - private final Atom atom; + private final AtomImpl atom; private final Set complementSubstitutions; private final int hashCode; - private final Atom normalizedLiteral; + private final AtomImpl normalizedLiteral; private final Set normalizedSubstitutions; private static int litSetCounter = 1; - LitSet(Atom atom, Set complementSubstitutions) { + LitSet(AtomImpl atom, Set complementSubstitutions) { this.atom = atom.renameVariables("_AS" + litSetCounter++); this.complementSubstitutions = new HashSet<>(); for (Unifier complementSubstitution : complementSubstitutions) { @@ -48,8 +49,8 @@ public class LitSet { * @param normalizedAtom * @return */ - private Unifier normalizeSubstitution(Atom originalAtom, Unifier substitution, Atom normalizedAtom) { - Atom substitutedLiteral = originalAtom.substitute(substitution); + private Unifier normalizeSubstitution(AtomImpl originalAtom, Unifier substitution, AtomImpl normalizedAtom) { + AtomImpl substitutedLiteral = originalAtom.substitute(substitution); return Unification.instantiate(normalizedAtom, substitutedLiteral); } @@ -66,7 +67,7 @@ public boolean coversNothing() { return false; } - public Atom getAtom() { + public AtomImpl getAtom() { return atom; } @@ -118,7 +119,7 @@ private int computeHashCode() { return result; } - private Atom computeNormalized(Atom atom, String prefix) { + private AtomImpl computeNormalized(Atom atom, String prefix) { if (atom instanceof VariableNormalizableAtom) { return ((VariableNormalizableAtom) atom).normalizeVariables(prefix, 0); } else { @@ -133,7 +134,7 @@ private Set computeNormalizedSubstitutions() { // Unifier may still contain variables in the right-hand side, those have to be normalized, too. Atom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); // Apply substitution and normalize all remaining variables, i.e., those appearing at the right-hand side of the substitution. - Atom normalized = computeNormalized(appliedSub, "_X"); + AtomImpl normalized = computeNormalized(appliedSub, "_X"); // Compute final substitution from normalized atom to the one where also variables are normalized. Unifier normalizedSubstitution = new Unifier(Unification.instantiate(normalizedLiteral, normalized)); ret.add(normalizedSubstitution); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java index 393eeb21c..f58a09fad 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java @@ -7,10 +7,7 @@ import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.common.terms.*; import at.ac.tuwien.kr.alpha.grounder.Substitution; import at.ac.tuwien.kr.alpha.grounder.Unifier; import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; @@ -194,8 +191,8 @@ private List rewriteAggregatesInRule(BasicRule rule) { aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), ConstantTerm.getInstance(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier - ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); - globalVariableTermlist.add(ConstantTerm.getInstance(aggregateCount)); + ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); + globalVariableTermlist.add(ConstantTermImpl.getInstance(aggregateCount)); aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); } aggregateSubstitution.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java index a38bcce0c..50bf0b9a0 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java @@ -27,18 +27,14 @@ */ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; import at.ac.tuwien.kr.alpha.common.rule.head.Head; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.*; import java.util.ArrayList; import java.util.Iterator; @@ -80,8 +76,8 @@ public InputProgram apply(InputProgram inputProgram) { // Create two guessing rules for each choiceElement. // Construct common body to both rules. - Atom head = choiceElement.choiceAtom; - List ruleBody = new ArrayList<>(rule.getBody()); + AtomImpl head = choiceElement.choiceAtom; + List ruleBody = new ArrayList<>(rule.getBody()); ruleBody.addAll(choiceElement.conditionLiterals); if (containsIntervalTerms(head)) { @@ -89,20 +85,20 @@ public InputProgram apply(InputProgram inputProgram) { } // Construct head atom for the choice. - Predicate headPredicate = head.getPredicate(); + PredicateImpl headPredicate = head.getPredicate(); - Predicate negPredicate = Predicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); - List headTerms = new ArrayList<>(head.getTerms()); - headTerms.add(0, ConstantTerm.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for + PredicateImpl negPredicate = PredicateImpl.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); + List headTerms = new ArrayList<>(head.getTerms()); + headTerms.add(0, ConstantTermImpl.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for // classical negative atoms. - Atom negHead = new BasicAtom(negPredicate, headTerms); + AtomImpl negHead = new BasicAtom(negPredicate, headTerms); // Construct two guessing rules. - List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); + List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); guessingRuleBodyWithNegHead.add(new BasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); additionalRules.add(new BasicRule(new NormalHead(negHead), guessingRuleBodyWithNegHead)); - List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); + List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); guessingRuleBodyWithHead.add(new BasicAtom(negPredicate, headTerms).toLiteral(false)); additionalRules.add(new BasicRule(new NormalHead(head), guessingRuleBodyWithHead)); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java index f080496e7..e65dc928c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.common.atoms.Literal; @@ -33,7 +33,7 @@ public InputProgram apply(InputProgram inputProgram) { // Directive not set, nothing to rewrite. return inputProgram; } - Predicate enumPredicate = Predicate.getInstance(enumDirective, 3); + PredicateImpl enumPredicate = PredicateImpl.getInstance(enumDirective, 3); InputProgram.Builder programBuilder = InputProgram.builder().addInlineDirectives(inputProgram.getInlineDirectives()); @@ -45,7 +45,7 @@ public InputProgram apply(InputProgram inputProgram) { return programBuilder.build(); } - private void checkFactsAreEnumerationFree(List srcFacts, Predicate enumPredicate) { + private void checkFactsAreEnumerationFree(List srcFacts, PredicateImpl enumPredicate) { for (Atom fact : srcFacts) { if (fact.getPredicate().equals(enumPredicate)) { throw oops("Atom declared as enumeration atom by directive occurs in a fact: " + fact); @@ -53,7 +53,7 @@ private void checkFactsAreEnumerationFree(List srcFacts, Predicate enumPre } } - private List rewriteRules(List srcRules, Predicate enumPredicate) { + private List rewriteRules(List srcRules, PredicateImpl enumPredicate) { List rewrittenRules = new ArrayList<>(); for (BasicRule rule : srcRules) { if (rule.getHead() != null && !(rule.getHead() instanceof NormalHead)) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java index 6faa93fbe..9a185316e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java @@ -28,14 +28,13 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; import at.ac.tuwien.kr.alpha.common.program.NormalProgram; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.common.terms.*; import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalAtom; import java.util.ArrayList; @@ -60,9 +59,9 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { // Collect all intervals and replace them with variables. Map intervalReplacements = new LinkedHashMap<>(); - List rewrittenBody = new ArrayList<>(); + List rewrittenBody = new ArrayList<>(); - for (Literal literal : rule.getBody()) { + for (LiteralImpl literal : rule.getBody()) { rewrittenBody.add(rewriteLiteral(literal, intervalReplacements)); } NormalHead rewrittenHead = rule.isConstraint() ? null : @@ -83,9 +82,9 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { /** * Replaces every IntervalTerm by a new variable and returns a mapping of the replaced VariableTerm -> IntervalTerm. */ - private static Literal rewriteLiteral(Literal lit, Map intervalReplacement) { - Atom atom = lit.getAtom(); - List termList = new ArrayList<>(atom.getTerms()); + private static LiteralImpl rewriteLiteral(LiteralImpl lit, Map intervalReplacement) { + AtomImpl atom = lit.getAtom(); + List termList = new ArrayList<>(atom.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { Term term = termList.get(i); @@ -103,7 +102,7 @@ private static Literal rewriteLiteral(Literal lit, Map newBody = new ArrayList<>(); - for (Literal bodyElement : rule.getBody()) { + List newBody = new ArrayList<>(); + for (LiteralImpl bodyElement : rule.getBody()) { // Only rewrite BasicAtoms. if (bodyElement instanceof BasicLiteral) { newBody.add(makePredicateInternal(bodyElement.getAtom()).toLiteral()); @@ -54,8 +52,8 @@ private static BasicRule makePredicateInternal(BasicRule rule) { return new BasicRule(newHead, newBody); } - private static Atom makePredicateInternal(Atom atom) { - Predicate newInternalPredicate = Predicate.getInstance(atom.getPredicate().getName(), atom.getPredicate().getArity(), true); + private static AtomImpl makePredicateInternal(AtomImpl atom) { + PredicateImpl newInternalPredicate = PredicateImpl.getInstance(atom.getPredicate().getName(), atom.getPredicate().getArity(), true); return new BasicAtom(newInternalPredicate, atom.getTerms()); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java index 36cba1580..71e25e96a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.PredicateImpl; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; @@ -47,11 +47,11 @@ public class StratifiedEvaluation extends ProgramTransformation> predicateDefiningRules; + private Map> predicateDefiningRules; - private Map> modifiedInLastEvaluationRun = new HashMap<>(); + private Map> modifiedInLastEvaluationRun = new HashMap<>(); - private List additionalFacts = new ArrayList<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. + private List additionalFacts = new ArrayList<>(); // 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; @@ -66,15 +66,15 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { predicateDefiningRules = inputProgram.getPredicateDefiningRules(); // Set up list of atoms which are known to be true - these will be expand by the evaluation. - Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); - for (Map.Entry> entry : knownFacts.entrySet()) { + Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); + for (Map.Entry> entry : knownFacts.entrySet()) { workingMemory.initialize(entry.getKey()); workingMemory.addInstances(entry.getKey(), true, entry.getValue()); } // Create working memories for all predicates occurring in each rule. for (InternalRule nonGroundRule : inputProgram.getRulesById().values()) { - for (Predicate predicate : nonGroundRule.getOccurringPredicates()) { + for (PredicateImpl predicate : nonGroundRule.getOccurringPredicates()) { workingMemory.initialize(predicate); } } @@ -165,7 +165,7 @@ private void prepareInitialEvaluation(Set rulesToEvaluate) { modifiedInLastEvaluationRun = new HashMap<>(); for (InternalRule rule : rulesToEvaluate) { // Register rule head instances. - Predicate headPredicate = rule.getHeadAtom().getPredicate(); + PredicateImpl headPredicate = rule.getHeadAtom().getPredicate(); IndexedInstanceStorage headInstances = workingMemory.get(headPredicate, true); modifiedInLastEvaluationRun.putIfAbsent(headPredicate, new LinkedHashSet<>()); if (headInstances != null) { @@ -173,7 +173,7 @@ private void prepareInitialEvaluation(Set rulesToEvaluate) { } // Register positive body literal instances. for (Literal lit : rule.getPositiveBody()) { - Predicate bodyPredicate = lit.getPredicate(); + PredicateImpl bodyPredicate = lit.getPredicate(); IndexedInstanceStorage bodyInstances = workingMemory.get(bodyPredicate, true); modifiedInLastEvaluationRun.putIfAbsent(bodyPredicate, new LinkedHashSet<>()); if (bodyInstances != null) { @@ -309,13 +309,13 @@ private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { Set recursiveRules = new HashSet<>(); // Collect all predicates occurring in heads of rules of the given component. - Set headPredicates = new HashSet<>(); + Set headPredicates = new HashSet<>(); for (Node node : comp.getNodes()) { headPredicates.add(node.getPredicate()); } // Check each predicate whether its defining rules depend on some of the head predicates, i.e., whether there is a // cycle. - for (Predicate headPredicate : headPredicates) { + for (PredicateImpl headPredicate : headPredicates) { HashSet definingRules = predicateDefiningRules.get(headPredicate); if (definingRules == null) { // Predicate only occurs in facts, skip. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java index f7590b7d5..17d9957cf 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java @@ -27,13 +27,12 @@ */ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.program.NormalProgram; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Unifier; @@ -107,7 +106,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { return rule; } - List rewrittenBody = new ArrayList<>(rule.getBody()); + List rewrittenBody = new ArrayList<>(rule.getBody()); NormalHead rewrittenHead = rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()); // Use substitution for actual replacement. @@ -122,22 +121,22 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { replacementSubstitution.put(variableToReplace, replacementVariable); } // Replace/Substitute in each literal every term where one of the common variables occurs. - Iterator bodyIterator = rewrittenBody.iterator(); + Iterator bodyIterator = rewrittenBody.iterator(); while (bodyIterator.hasNext()) { - Literal literal = bodyIterator.next(); + LiteralImpl literal = bodyIterator.next(); if (equalitiesToRemove.contains(literal)) { bodyIterator.remove(); } for (int i = 0; i < literal.getTerms().size(); i++) { - Term replaced = literal.getTerms().get(i).substitute(replacementSubstitution); + TermImpl replaced = literal.getTerms().get(i).substitute(replacementSubstitution); literal.getTerms().set(i, replaced); } } // Replace variables in head. if (rewrittenHead != null) { - Atom headAtom = rewrittenHead.getAtom(); + AtomImpl headAtom = rewrittenHead.getAtom(); for (int i = 0; i < headAtom.getTerms().size(); i++) { - Term replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); + TermImpl replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); headAtom.getTerms().set(i, replaced); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java index c0f422695..05dd90522 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java @@ -26,6 +26,7 @@ package at.ac.tuwien.kr.alpha.solver; import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; import java.util.ArrayList; import java.util.Collections; @@ -34,7 +35,7 @@ import java.util.Map; /** - * Counts the number of ground atoms stored for each type (i.e., subclass of {@link Atom}. + * Counts the number of ground atoms stored for each type (i.e., subclass of {@link AtomImpl}. * For every atom, only the counter for one class (the most specific one) is incremented, * not the counters for more general classes of which the atom is also an instance. */ @@ -42,7 +43,7 @@ public class AtomCounter { private final Map, Integer> countByType = new HashMap<>(); - public void add(Atom atom) { + public void add(AtomImpl atom) { countByType.compute(atom.getClass(), (k, v) -> (v == null) ? 1 : v + 1); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java index 168f6daa8..edf3423fc 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java @@ -25,9 +25,6 @@ */ package at.ac.tuwien.kr.alpha.solver; -import java.util.Arrays; -import java.util.stream.Collectors; - /** * Offers methods to estimate the effect of propagating binary nogoods. */ @@ -37,42 +34,19 @@ public interface BinaryNoGoodPropagationEstimation { * Uses {@code strategy} to estimate the number of direct consequences of propagating binary nogoods after assigning * {@code truth} to {@code atom}. * - * If {@code strategy} is {@link Strategy#BinaryNoGoodPropagation}, {@code truth} is assigned to {@code atom}, + * If {@code strategy} is {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation}, {@code truth} is assigned to {@code atom}, * only binary nogoods are propagated, a backtrack is executed, and the number of atoms that have been assigned * additionally during this process is returned. * - * If {@code strategy} is {@link Strategy#CountBinaryWatches}, on the other hand, the number of binary watches on + * If {@code strategy} is {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches}, on the other hand, the number of binary watches on * the literal given by {@code atom} and {@code truth} is returned. * * @param atom the atom to estimate effects for * @param truth gives, together with {@code atom}, a literal to estimate effects for - * @param strategy the strategy to use for estimation. If {@link Strategy#BinaryNoGoodPropagation} is given but - * no binary nogoods exist, {@link Strategy#CountBinaryWatches} will be used instead. + * @param strategy the strategy to use for estimation. If {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation} is given but + * no binary nogoods exist, {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches} will be used instead. * @return an estimate on the effects of propagating binary nogoods after assigning {@code truth} to {@code atom}. */ - int estimate(int atom, boolean truth, Strategy strategy); - - /** - * Strategies to estimate the amount of influence of a literal. - */ - public enum Strategy { - /** - * Counts binary watches involving the literal under consideration - */ - CountBinaryWatches, - - /** - * Assigns true to the literal under consideration, then does propagation only on binary nogoods - * and counts how many other atoms are assigned during this process, then backtracks - */ - BinaryNoGoodPropagation; - - /** - * @return a comma-separated list of names of known heuristics - */ - public static String listAllowedValues() { - return Arrays.stream(values()).map(Strategy::toString).collect(Collectors.joining(", ")); - } - } + int estimate(int atom, boolean truth, BinaryNoGoodPropagationEstimationStrategy strategy); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java index a98d2c508..20b5e332a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java @@ -36,6 +36,8 @@ import static at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; import static at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,10 +56,6 @@ import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.config.SystemConfig; @@ -367,13 +365,13 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { } // For RuleAtoms in toJustify the corresponding ground body contains BasicAtoms that have been assigned FALSE in the closing. // First, translate RuleAtom back to NonGroundRule + Substitution. - String ruleId = (String) ((ConstantTerm)atom.getTerms().get(0)).getObject(); + String ruleId = (String) ((ConstantTermImpl)atom.getTerms().get(0)).getObject(); InternalRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); - String substitution = (String) ((ConstantTerm)atom.getTerms().get(1)).getObject(); + String substitution = (String) ((ConstantTermImpl)atom.getTerms().get(1)).getObject(); Substitution groundingSubstitution = Substitution.fromString(substitution); // Find ground literals in the body that have been assigned false and justify those. - for (Literal bodyLiteral : nonGroundRule.getBody()) { - Atom groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); + for (LiteralImpl bodyLiteral : nonGroundRule.getBody()) { + AtomImpl groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); if (groundAtom instanceof ComparisonAtom || analyzingGrounder.isFact(groundAtom)) { // Facts and ComparisonAtoms are always true, no justification needed. continue; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java index e2f256c5d..125b70976 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java @@ -816,7 +816,7 @@ private void clearAlphaWatchList(int literal) { } @Override - public int estimate(int atom, boolean truth, Strategy strategy) { + public int estimate(int atom, boolean truth, BinaryNoGoodPropagationEstimationStrategy strategy) { switch (strategy) { case BinaryNoGoodPropagation: if (hasBinaryNoGoods) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java index e84f9b0a1..87afa8c6a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java @@ -37,54 +37,6 @@ public final class BranchingHeuristicFactory { - /** - * The available domain-independent heuristics. - * Some are deprecated because they perform poorly and have not been improved for some time, - * however the code is kept for now so that it stays compatible when interfaces are refactored. - */ - public enum Heuristic { - NAIVE, - BERKMIN, - BERKMINLITERAL, - @Deprecated - DD, - @Deprecated - DD_SUM, - @Deprecated - DD_AVG, - @Deprecated - DD_MAX, - @Deprecated - DD_MIN, - @Deprecated - DD_PYRO, - @Deprecated - GDD, - @Deprecated - GDD_SUM, - @Deprecated - GDD_AVG, - @Deprecated - GDD_MAX, - @Deprecated - GDD_MIN, - @Deprecated - GDD_PYRO, - @Deprecated - ALPHA_ACTIVE_RULE, - @Deprecated - ALPHA_HEAD_MBT, - VSIDS, - GDD_VSIDS; - - /** - * @return a comma-separated list of names of known heuristics - */ - public static String listAllowedValues() { - return Arrays.stream(values()).map(Heuristic::toString).collect(Collectors.joining(", ")); - } - } - public static BranchingHeuristic getInstance(HeuristicsConfiguration heuristicsConfiguration, Grounder grounder, WritableAssignment assignment, ChoiceManager choiceManager, Random random) { BranchingHeuristic heuristicWithoutReplay = getInstanceWithoutReplay(heuristicsConfiguration, grounder, assignment, choiceManager, random); List replayChoices = heuristicsConfiguration.getReplayChoices(); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java index e579d2871..b2d8b194e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java @@ -26,7 +26,7 @@ package at.ac.tuwien.kr.alpha.solver.heuristics; import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.solver.ChoiceManager; import java.util.Random; @@ -46,11 +46,11 @@ */ public class DependencyDrivenVSIDS extends VSIDS { - public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { super(assignment, choiceManager, new HeapOfActiveChoicePoints(decayPeriod, decayFactor, choiceManager), momsStrategy); } - public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, Random random, BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, Random random, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, random, momsStrategy); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java index 858b9ec91..45f9faf43 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java @@ -28,6 +28,7 @@ import at.ac.tuwien.kr.alpha.common.NoGood; import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.solver.ChoiceInfluenceManager; import at.ac.tuwien.kr.alpha.solver.ChoiceManager; import org.slf4j.Logger; @@ -273,7 +274,7 @@ public void callbackOnChanged(int atom, boolean active) { } } - public void setMOMsStrategy(BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + public void setMOMsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { if (moms != null) { moms.setStrategy(momsStrategy); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java index 160283324..26d3d74a4 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java @@ -25,8 +25,7 @@ */ package at.ac.tuwien.kr.alpha.solver.heuristics; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation.Strategy; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import java.util.List; @@ -36,14 +35,14 @@ public class HeuristicsConfiguration { private Heuristic heuristic; - private Strategy momsStrategy; + private BinaryNoGoodPropagationEstimationStrategy momsStrategy; private List replayChoices; /** * @param heuristic * @param momsStrategy * @param replayChoices */ - public HeuristicsConfiguration(Heuristic heuristic, Strategy momsStrategy, List replayChoices) { + public HeuristicsConfiguration(Heuristic heuristic, BinaryNoGoodPropagationEstimationStrategy momsStrategy, List replayChoices) { super(); this.heuristic = heuristic; this.momsStrategy = momsStrategy; @@ -67,14 +66,14 @@ public void setHeuristic(Heuristic heuristic) { /** * @return the momsStrategy */ - public Strategy getMomsStrategy() { + public BinaryNoGoodPropagationEstimationStrategy getMomsStrategy() { return momsStrategy; } /** * @param momsStrategy the momsStrategy to set */ - public void setMomsStrategy(Strategy momsStrategy) { + public void setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { this.momsStrategy = momsStrategy; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java index 8e68582b6..b1ee79ccf 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java @@ -25,8 +25,7 @@ */ package at.ac.tuwien.kr.alpha.solver.heuristics; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import java.util.List; @@ -36,7 +35,7 @@ public class HeuristicsConfigurationBuilder { private Heuristic heuristic; - private BinaryNoGoodPropagationEstimation.Strategy momsStrategy; + private BinaryNoGoodPropagationEstimationStrategy momsStrategy; private List replayChoices; /** @@ -50,7 +49,7 @@ public HeuristicsConfigurationBuilder setHeuristic(Heuristic heuristic) { /** * @param momsStrategy the momsStrategy to set */ - public HeuristicsConfigurationBuilder setMomsStrategy(BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + public HeuristicsConfigurationBuilder setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { this.momsStrategy = momsStrategy; return this; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java index fd49def05..223cb7ad7 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java @@ -26,7 +26,7 @@ package at.ac.tuwien.kr.alpha.solver.heuristics; import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation.Strategy; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; /** * The well-known MOMs (Maximum Occurrences in clauses of Minimum size) heuristic @@ -34,17 +34,17 @@ * This implementation is inspired by the MOMs implementation in clasp * but differs from it in several ways, e.g.: *

      - *
    • The default strategy is {@link Strategy#CountBinaryWatches}, not {@link Strategy#BinaryNoGoodPropagation}.
    • - *
    • {@link Strategy#BinaryNoGoodPropagation} does not do only one iteration of propagation, but exhaustive propagation.
    • + *
    • The default strategy is {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches}, not {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation}.
    • + *
    • {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation} does not do only one iteration of propagation, but exhaustive propagation.
    • *
    * */ public class MOMs { - static final Strategy DEFAULT_STRATEGY = Strategy.CountBinaryWatches; + static final BinaryNoGoodPropagationEstimationStrategy DEFAULT_STRATEGY = BinaryNoGoodPropagationEstimationStrategy.CountBinaryWatches; private BinaryNoGoodPropagationEstimation bnpEstimation; - private Strategy strategy = DEFAULT_STRATEGY; + private BinaryNoGoodPropagationEstimationStrategy strategy = DEFAULT_STRATEGY; public MOMs(BinaryNoGoodPropagationEstimation bnpEstimation) { super(); @@ -61,7 +61,7 @@ public double getScore(Integer atom) { return ((s1 * s2) << 10) + s1 + s2; } - public void setStrategy(Strategy strategy) { + public void setStrategy(BinaryNoGoodPropagationEstimationStrategy strategy) { this.strategy = strategy != null ? strategy : DEFAULT_STRATEGY; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java index 16b5f0daa..7b8b60232 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java @@ -27,7 +27,7 @@ import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.solver.ThriceTruth; import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProvider; @@ -86,18 +86,18 @@ public class VSIDS implements ActivityBasedBranchingHeuristic { */ protected final MultiValuedMap headToBodies = new HashSetValuedHashMap<>(); - protected VSIDS(Assignment assignment, ChoiceManager choiceManager, HeapOfActiveAtoms heapOfActiveAtoms, BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + protected VSIDS(Assignment assignment, ChoiceManager choiceManager, HeapOfActiveAtoms heapOfActiveAtoms, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { this.assignment = assignment; this.choiceManager = choiceManager; this.heapOfActiveAtoms = heapOfActiveAtoms; this.heapOfActiveAtoms.setMOMsStrategy(momsStrategy); } - public VSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + public VSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { this(assignment, choiceManager, new HeapOfActiveAtoms(decayPeriod, decayFactor, choiceManager), momsStrategy); } - public VSIDS(Assignment assignment, ChoiceManager choiceManager, BinaryNoGoodPropagationEstimation.Strategy momsStrategy) { + public VSIDS(Assignment assignment, ChoiceManager choiceManager, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, momsStrategy); } From 2ae8d14d0027d26d183cd552e055560a0b20e636 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 4 Dec 2020 10:10:16 +0100 Subject: [PATCH 006/111] intermediate commit --- .../main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java index ddec9604a..6772ba6f3 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java @@ -4,6 +4,7 @@ * Copyright (c) 2016, the Alpha Team. */ public class PredicateImpl implements Comparable, Predicate { + private static final Interner INTERNER = new Interner<>(); private final String name; From 725f45eca92aeefeaab18330280f29d8ecbe4eb1 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 14 Dec 2020 16:02:01 +0100 Subject: [PATCH 007/111] WIP: separate inheritance hierarchies for core- and api-types --- .../kr/alpha/api/externals/Externals.java | 3 +- .../kr/alpha/common/AnswerSetBuilder.java | 12 ++-- .../ac/tuwien/kr/alpha/common/AtomStore.java | 10 +-- .../tuwien/kr/alpha/common/AtomStoreImpl.java | 26 +++---- .../kr/alpha/common/BasicAnswerSet.java | 9 +-- .../kr/alpha/common/ComparisonOperator.java | 4 +- ...{PredicateImpl.java => CorePredicate.java} | 24 ++++--- .../common/SimpleAnswerSetFormatter.java | 2 +- .../kr/alpha/common/atoms/AggregateAtom.java | 18 ++--- .../alpha/common/atoms/AggregateLiteral.java | 4 +- .../kr/alpha/common/atoms/BasicAtom.java | 20 +++--- .../kr/alpha/common/atoms/BasicLiteral.java | 4 +- .../kr/alpha/common/atoms/ComparisonAtom.java | 10 +-- .../alpha/common/atoms/ComparisonLiteral.java | 2 +- .../atoms/{AtomImpl.java => CoreAtom.java} | 36 +++++----- .../{LiteralImpl.java => CoreLiteral.java} | 34 ++++----- .../kr/alpha/common/atoms/ExternalAtom.java | 12 ++-- .../alpha/common/atoms/ExternalLiteral.java | 2 +- .../atoms/FixedInterpretationLiteral.java | 4 +- .../atoms/VariableNormalizableAtom.java | 2 +- .../common/depgraph/DependencyGraph.java | 28 ++++---- .../tuwien/kr/alpha/common/depgraph/Node.java | 8 +-- .../alpha/common/program/AbstractProgram.java | 8 +-- .../alpha/common/program/AnalyzedProgram.java | 6 +- .../kr/alpha/common/program/InputProgram.java | 10 +-- .../alpha/common/program/InternalProgram.java | 28 ++++---- .../alpha/common/program/NormalProgram.java | 4 +- .../kr/alpha/common/rule/AbstractRule.java | 30 ++++---- .../kr/alpha/common/rule/BasicRule.java | 5 +- .../kr/alpha/common/rule/InternalRule.java | 29 ++++---- .../kr/alpha/common/rule/NormalRule.java | 19 +++-- .../kr/alpha/common/rule/head/ChoiceHead.java | 10 +-- .../kr/alpha/common/rule/head/NormalHead.java | 8 +-- .../kr/alpha/grounder/AbstractGrounder.java | 6 +- .../kr/alpha/grounder/BridgedGrounder.java | 10 +-- .../alpha/grounder/FactIntervalEvaluator.java | 4 +- .../kr/alpha/grounder/FilteringGrounder.java | 6 +- .../kr/alpha/grounder/GrounderFactory.java | 9 +-- .../grounder/IndexedInstanceStorage.java | 29 ++++---- .../ac/tuwien/kr/alpha/grounder/Instance.java | 4 +- .../kr/alpha/grounder/NaiveGrounder.java | 54 +++++++------- .../kr/alpha/grounder/NoGoodGenerator.java | 24 +++---- .../kr/alpha/grounder/RuleGroundingOrder.java | 13 ++-- .../alpha/grounder/RuleGroundingOrders.java | 41 ++++++----- .../kr/alpha/grounder/Substitution.java | 19 ++--- .../tuwien/kr/alpha/grounder/Unification.java | 8 +-- .../kr/alpha/grounder/WorkingMemory.java | 24 +++---- .../kr/alpha/grounder/atoms/ChoiceAtom.java | 27 ++++--- .../alpha/grounder/atoms/EnumerationAtom.java | 4 +- .../kr/alpha/grounder/atoms/IntervalAtom.java | 12 ++-- .../kr/alpha/grounder/atoms/RuleAtom.java | 18 ++--- .../AbstractLiteralInstantiationStrategy.java | 16 ++--- ...ultLazyGroundingInstantiationStrategy.java | 37 +++++----- .../LiteralInstantiationStrategy.java | 6 +- .../instantiation/LiteralInstantiator.java | 6 +- ...rkingMemoryBasedInstantiationStrategy.java | 11 ++- .../grounder/parser/ParseTreeVisitor.java | 22 +++--- .../structure/AnalyzeUnjustified.java | 72 +++++++++---------- .../kr/alpha/grounder/structure/LitSet.java | 18 ++--- .../CardinalityNormalization.java | 42 ++++++----- .../transformation/ChoiceHeadToNormal.java | 18 ++--- .../transformation/EnumerationRewriting.java | 36 +++++----- .../IntervalTermToIntervalAtom.java | 14 ++-- .../transformation/PredicateInternalizer.java | 12 ++-- .../transformation/StratifiedEvaluation.java | 20 +++--- .../VariableEqualityRemoval.java | 8 +-- .../tuwien/kr/alpha/solver/AtomCounter.java | 6 +- .../tuwien/kr/alpha/solver/DefaultSolver.java | 4 +- 68 files changed, 549 insertions(+), 542 deletions(-) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/{PredicateImpl.java => CorePredicate.java} (74%) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/{AtomImpl.java => CoreAtom.java} (84%) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/{LiteralImpl.java => CoreLiteral.java} (81%) diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java index e03e8530e..028414986 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java @@ -134,7 +134,8 @@ public static > List asFacts(Class classOfExtFa String javaName = classOfExtFacts.getSimpleName(); String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. for (T instance : extFacts) { - retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.PredicateImpl.getInstance(name, 1), ConstantTermImpl.getInstance(instance))); + // TODO use properly wrapped BasicAtoms here + retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.CorePredicate.getInstance(name, 1), ConstantTermImpl.getInstance(instance))); } return retVal; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java index 3ebe7a880..cd43eb146 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java @@ -16,10 +16,10 @@ public class AnswerSetBuilder { private boolean firstInstance = true; private String predicateSymbol; - private PredicateImpl predicate; - private SortedSet predicates = new TreeSet<>(); + private CorePredicate predicate; + private SortedSet predicates = new TreeSet<>(); private SortedSet instances = new TreeSet<>(); - private Map> predicateInstances = new HashMap<>(); + private Map> predicateInstances = new HashMap<>(); public AnswerSetBuilder() { } @@ -37,7 +37,7 @@ public AnswerSetBuilder(AnswerSetBuilder copy) { private void flush() { if (firstInstance) { - predicate = PredicateImpl.getInstance(predicateSymbol, 0); + predicate = CorePredicate.getInstance(predicateSymbol, 0); predicates.add(predicate); predicateInstances.put(predicate, new TreeSet<>(singletonList(new BasicAtom(predicate)))); } else { @@ -65,7 +65,7 @@ public AnswerSetBuilder predicate(String predicateSymbol) { public final > AnswerSetBuilder instance(final T... terms) { if (firstInstance) { firstInstance = false; - predicate = PredicateImpl.getInstance(predicateSymbol, terms.length); + predicate = CorePredicate.getInstance(predicateSymbol, terms.length); predicates.add(predicate); } @@ -83,7 +83,7 @@ public final > AnswerSetBuilder instance(final T... term public AnswerSetBuilder symbolicInstance(String... terms) { if (firstInstance) { firstInstance = false; - predicate = PredicateImpl.getInstance(predicateSymbol, terms.length); + predicate = CorePredicate.getInstance(predicateSymbol, terms.length); predicates.add(predicate); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java index eb5f81434..2581cb11b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java @@ -28,7 +28,7 @@ package at.ac.tuwien.kr.alpha.common; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.solver.AtomCounter; import java.util.Iterator; @@ -59,14 +59,14 @@ public interface AtomStore { * @param atom the atom to translate. * @return the Atom object represented by the int. */ - AtomImpl get(int atom); + CoreAtom get(int atom); /** * Translates an atom represented as Atom object into an int. * @param atom the Atom object to translate. * @return the int representing the Atom object. */ - int get(Atom atom); + int get(CoreAtom atom); /** * If the given ground atom is not already stored, associates it with a new integer (ID) and stores it, else @@ -75,14 +75,14 @@ public interface AtomStore { * @param groundAtom the ground atom to look up in the store. * @return the integer ID of the ground atom, possibly newly assigned. */ - int putIfAbsent(AtomImpl groundAtom); + int putIfAbsent(CoreAtom groundAtom); /** * Returns whether the given ground atom is known to the AtomStore. * @param groundAtom the ground atom to test. * @return true if the ground atom is already associated an integer ID. */ - boolean contains(Atom groundAtom); + boolean contains(CoreAtom groundAtom); String atomToString(int atom); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java index d95771477..67994c90a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java @@ -27,25 +27,25 @@ */ package at.ac.tuwien.kr.alpha.common; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.solver.AtomCounter; +import static at.ac.tuwien.kr.alpha.Util.oops; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import static at.ac.tuwien.kr.alpha.Util.oops; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.solver.AtomCounter; /** * This class stores ground atoms and provides the translation from an (integer) atomId to a (structured) predicate instance. */ public class AtomStoreImpl implements AtomStore { - private final List atomIdsToInternalBasicAtoms = new ArrayList<>(); - private final Map predicateInstancesToAtomIds = new HashMap<>(); + private final List atomIdsToInternalBasicAtoms = new ArrayList<>(); + private final Map predicateInstancesToAtomIds = new HashMap<>(); private final IntIdGenerator atomIdGenerator = new IntIdGenerator(1); private final AtomCounter atomCounter = new AtomCounter(); @@ -57,7 +57,7 @@ public AtomStoreImpl() { } @Override - public int putIfAbsent(AtomImpl groundAtom) { + public int putIfAbsent(CoreAtom groundAtom) { if (!groundAtom.isGround()) { throw new IllegalArgumentException("Atom must be ground: " + groundAtom); } @@ -75,7 +75,7 @@ public int putIfAbsent(AtomImpl groundAtom) { } @Override - public boolean contains(Atom groundAtom) { + public boolean contains(CoreAtom groundAtom) { return predicateInstancesToAtomIds.containsKey(groundAtom); } @@ -90,7 +90,7 @@ public void releaseAtomId(int atomId) { public String printAtomIdTermMapping() { StringBuilder ret = new StringBuilder(); - for (Map.Entry entry : predicateInstancesToAtomIds.entrySet()) { + for (Map.Entry entry : predicateInstancesToAtomIds.entrySet()) { ret.append(entry.getValue()).append(" <-> ").append(entry.getKey().toString()).append(System.lineSeparator()); } return ret.toString(); @@ -112,7 +112,7 @@ public int getMaxAtomId() { } @Override - public AtomImpl get(int atom) { + public CoreAtom get(int atom) { try { return atomIdsToInternalBasicAtoms.get(atom); } catch (IndexOutOfBoundsException e) { @@ -121,7 +121,7 @@ public AtomImpl get(int atom) { } @Override - public int get(Atom atom) { + public int get(CoreAtom atom) { return predicateInstancesToAtomIds.get(atom); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java index 07a4b0203..1bd486460 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java @@ -14,13 +14,14 @@ /** * Copyright (c) 2016, the Alpha Team. */ +// TODO bring this into public non-core API by using something like an "answer-set-view" public class BasicAnswerSet implements AnswerSet { public static final BasicAnswerSet EMPTY = new BasicAnswerSet(emptySortedSet(), emptyMap()); - private final SortedSet predicates; - private final Map> predicateInstances; + private final SortedSet predicates; + private final Map> predicateInstances; - public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { + public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { this.predicates = predicates; this.predicateInstances = predicateInstances; } @@ -47,7 +48,7 @@ public String toString() { } final StringBuilder sb = new StringBuilder("{ "); - for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { + for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { Predicate predicate = iterator.next(); Set instances = getPredicateInstances(predicate); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java index c0b762cbe..b9a61571a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java @@ -33,7 +33,7 @@ public ComparisonOperator getNegation() { throw oops("Unknown binary operator encountered, cannot negate it"); } - public PredicateImpl predicate() { - return PredicateImpl.getInstance(this.asString, 2); + public CorePredicate predicate() { + return CorePredicate.getInstance(this.asString, 2); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java similarity index 74% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java index 6772ba6f3..670241c1c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/PredicateImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java @@ -1,34 +1,36 @@ package at.ac.tuwien.kr.alpha.common; /** - * Copyright (c) 2016, the Alpha Team. + * A predicate as used by the Alpha solver internally. + * + * Copyright (c) 2016-2020, the Alpha Team. */ -public class PredicateImpl implements Comparable, Predicate { +public class CorePredicate implements Comparable { - private static final Interner INTERNER = new Interner<>(); + private static final Interner INTERNER = new Interner<>(); private final String name; private final int arity; private final boolean internal; private final boolean solverInternal; - protected PredicateImpl(String name, int arity, boolean internal, boolean solverInternal) { + protected CorePredicate(String name, int arity, boolean internal, boolean solverInternal) { this.name = name; this.arity = arity; this.internal = internal; this.solverInternal = solverInternal; } - public static PredicateImpl getInstance(String symbol, int arity) { + public static CorePredicate getInstance(String symbol, int arity) { return getInstance(symbol, arity, false, false); } - public static PredicateImpl getInstance(String symbol, int arity, boolean internal) { + public static CorePredicate getInstance(String symbol, int arity, boolean internal) { return getInstance(symbol, arity, internal, false); } - public static PredicateImpl getInstance(String symbol, int arity, boolean internal, boolean solverInternal) { - return INTERNER.intern(new PredicateImpl(symbol, arity, internal, solverInternal)); + public static CorePredicate getInstance(String symbol, int arity, boolean internal, boolean solverInternal) { + return INTERNER.intern(new CorePredicate(symbol, arity, internal, solverInternal)); } @Override @@ -45,11 +47,11 @@ public boolean equals(Object o) { return true; } - if (!(o instanceof PredicateImpl)) { + if (!(o instanceof CorePredicate)) { return false; } - PredicateImpl predicate = (PredicateImpl) o; + CorePredicate predicate = (CorePredicate) o; if (arity != predicate.arity) { return false; @@ -80,7 +82,7 @@ public boolean isSolverInternal() { } @Override - public int compareTo(Predicate other) { + public int compareTo(CorePredicate other) { int result = getName().compareTo(other.getName()); if (result != 0) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java index 0a655658c..f705ca4be 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java @@ -18,7 +18,7 @@ public SimpleAnswerSetFormatter(String atomSeparator) { @Override public String format(AnswerSet answerSet) { List predicateInstanceStrings = new ArrayList<>(); - for (PredicateImpl p : answerSet.getPredicates()) { + for (CorePredicate p : answerSet.getPredicates()) { SortedSet instances; if ((instances = answerSet.getPredicateInstances(p)) == null || instances.isEmpty()) { predicateInstanceStrings.add(p.getName()); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java index 49bda0c52..17fe8b7ba 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java @@ -28,7 +28,7 @@ package at.ac.tuwien.kr.alpha.common.atoms; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; @@ -41,7 +41,7 @@ import static at.ac.tuwien.kr.alpha.Util.join; import static at.ac.tuwien.kr.alpha.Util.oops; -public class AggregateAtom extends AtomImpl { +public class AggregateAtom extends CoreAtom { private final ComparisonOperator lowerBoundOperator; private final TermImpl lowerBoundTerm; @@ -88,12 +88,12 @@ public List getTerms() { } @Override - public AtomImpl withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for aggregate atoms!"); } @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { throw oops("Aggregate atom cannot report predicate."); } @@ -194,9 +194,9 @@ public enum AGGREGATEFUNCTION { public static class AggregateElement { final List elementTerms; - final List elementLiterals; + final List elementLiterals; - public AggregateElement(List elementTerms, List elementLiterals) { + public AggregateElement(List elementTerms, List elementLiterals) { this.elementTerms = elementTerms; this.elementLiterals = elementLiterals; } @@ -205,7 +205,7 @@ public List getElementTerms() { return elementTerms; } - public List getElementLiterals() { + public List getElementLiterals() { return elementLiterals; } @@ -215,7 +215,7 @@ public boolean isGround() { return false; } } - for (Literal elementLiteral : elementLiterals) { + for (CoreLiteral elementLiteral : elementLiterals) { if (!elementLiteral.isGround()) { return false; } @@ -230,7 +230,7 @@ public List getOccurringVariables() { occurringVariables.add((VariableTerm) term); } } - for (LiteralImpl literal : elementLiterals) { + for (CoreLiteral literal : elementLiterals) { occurringVariables.addAll(literal.getBindingVariables()); occurringVariables.addAll(literal.getNonBindingVariables()); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java index 068232033..594eb7e49 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java @@ -11,7 +11,7 @@ /** * Copyright (c) 2018, the Alpha Team. */ -public class AggregateLiteral extends LiteralImpl { +public class AggregateLiteral extends CoreLiteral { public AggregateLiteral(AggregateAtom atom, boolean positive) { super(atom, positive); } @@ -27,7 +27,7 @@ public AggregateLiteral negate() { } /** - * @see AtomImpl#substitute(Substitution) + * @see CoreAtom#substitute(Substitution) */ @Override public AggregateLiteral substitute(Substitution substitution) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java index 1fedbd4ac..dc3b4f40a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; @@ -42,8 +42,8 @@ /** * Represents ordinary ASP atoms. */ -public class BasicAtom extends AtomImpl implements VariableNormalizableAtom { - private final PredicateImpl predicate; +public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { + private final CorePredicate predicate; private final List terms; private final boolean ground; @@ -53,7 +53,7 @@ public class BasicAtom extends AtomImpl implements VariableNormalizableAtom { * @param predicate * @param terms */ - public BasicAtom(PredicateImpl predicate, List terms) { + public BasicAtom(CorePredicate predicate, List terms) { this.predicate = predicate; this.terms = terms; @@ -68,16 +68,16 @@ public BasicAtom(PredicateImpl predicate, List terms) { this.ground = ground; } - public BasicAtom(PredicateImpl predicate, TermImpl... terms) { + public BasicAtom(CorePredicate predicate, TermImpl... terms) { this(predicate, Arrays.asList(terms)); } - public BasicAtom(PredicateImpl predicate) { + public BasicAtom(CorePredicate predicate) { this(predicate, Collections.emptyList()); } @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return predicate; } @@ -105,7 +105,7 @@ public BasicAtom normalizeVariables(String prefix, int counterStartingValue) { } @Override - public LiteralImpl toLiteral(boolean positive) { + public CoreLiteral toLiteral(boolean positive) { return new BasicLiteral(this, positive); } @@ -120,7 +120,7 @@ public String toString() { } @Override - public int compareTo(Atom o) { + public int compareTo(CoreAtom o) { if (this.terms.size() != o.getTerms().size()) { return this.terms.size() - o.getTerms().size(); } @@ -161,7 +161,7 @@ public int hashCode() { } @Override - public AtomImpl withTerms(List terms) { + public CoreAtom withTerms(List terms) { return new BasicAtom(predicate, terms); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java index 306d97e87..f65d03c5e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java @@ -40,7 +40,7 @@ * * Copyright (c) 2017-2018, the Alpha Team. */ -public class BasicLiteral extends LiteralImpl { +public class BasicLiteral extends CoreLiteral { public BasicLiteral(BasicAtom atom, boolean positive) { super(atom, positive); @@ -60,7 +60,7 @@ public BasicLiteral negate() { } /** - * @see AtomImpl#substitute(Substitution) + * @see CoreAtom#substitute(Substitution) */ @Override public BasicLiteral substitute(Substitution substitution) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java index bcd3991ab..4a0b2cec6 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java @@ -28,7 +28,7 @@ package at.ac.tuwien.kr.alpha.common.atoms; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; @@ -40,8 +40,8 @@ /** * Represents a builtin comparison atom according to the standard. */ -public class ComparisonAtom extends AtomImpl implements VariableNormalizableAtom { - private final PredicateImpl predicate; +public class ComparisonAtom extends CoreAtom implements VariableNormalizableAtom { + private final CorePredicate predicate; final ComparisonOperator operator; private final List terms; @@ -56,7 +56,7 @@ public ComparisonAtom(TermImpl term1, TermImpl term2, ComparisonOperator operato } @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return predicate; } @@ -121,7 +121,7 @@ public ComparisonAtom normalizeVariables(String prefix, int counterStartingValue } @Override - public AtomImpl withTerms(List terms) { + public CoreAtom withTerms(List terms) { return new ComparisonAtom(terms, operator); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java index 0aa65d6f4..edb3655e7 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java @@ -67,7 +67,7 @@ public ComparisonLiteral negate() { } /** - * @see AtomImpl#substitute(Substitution) + * @see CoreAtom#substitute(Substitution) */ @Override public ComparisonLiteral substitute(Substitution substitution) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AtomImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java similarity index 84% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AtomImpl.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java index 7e8578e6a..0cb3cb3ea 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AtomImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java @@ -27,21 +27,20 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import at.ac.tuwien.kr.alpha.grounder.Unifier; -import java.util.List; -import java.util.Set; - /** * An Atom is the common superclass of all representations of ASP atoms used by Alpha. */ -public abstract class AtomImpl implements Atom { +public abstract class CoreAtom implements Comparable{ /** * Creates a new Atom that represents this Atom, but has the given term list instead. @@ -49,7 +48,7 @@ public abstract class AtomImpl implements Atom { * @param terms the terms to set. * @return a new Atom with the given terms set. */ - public abstract AtomImpl withTerms(List terms); + public abstract CoreAtom withTerms(List terms); /** * Returns the set of all variables occurring in the Atom. @@ -65,26 +64,29 @@ public Set getOccurringVariables() { * @param substitution the variable substitution to apply. * @return the atom resulting from the application of the substitution. */ - public abstract AtomImpl substitute(Substitution substitution); + public abstract CoreAtom substitute(Substitution substitution); - @Override public abstract List getTerms(); - @Override - public abstract PredicateImpl getPredicate(); + public abstract CorePredicate getPredicate(); + /** + * Returns whether this atom is ground, i.e., variable-free. + * + * @return true iff the terms of this atom contain no {@link VariableTerm}. + */ + public abstract boolean isGround(); + /** * Creates a non-negated literal containing this atom. */ - @Override - public LiteralImpl toLiteral() { + public CoreLiteral toLiteral() { return toLiteral(true); } - @Override - public abstract LiteralImpl toLiteral(boolean positive); + public abstract CoreLiteral toLiteral(boolean positive); - public AtomImpl renameVariables(String newVariablePrefix) { + public CoreAtom renameVariables(String newVariablePrefix) { Unifier renamingSubstitution = new Unifier(); int counter = 0; for (VariableTerm variable : getOccurringVariables()) { @@ -94,7 +96,7 @@ public AtomImpl renameVariables(String newVariablePrefix) { } @Override - public int compareTo(Atom o) { + public int compareTo(CoreAtom o) { if (o == null) { return 1; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java similarity index 81% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralImpl.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java index e702dab0b..55a0a7cfe 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017-2018, the Alpha Team. + * Copyright (c) 2017-2020, the Alpha Team. * All rights reserved. *

    * Additional changes made by Siemens. @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; @@ -37,34 +37,31 @@ import java.util.Set; /** - * A potentially negated {@link AtomImpl} + * A potentially negated {@link CoreAtom} * * Copyright (c) 2017-2018, the Alpha Team. */ -public abstract class LiteralImpl implements Literal { +public abstract class CoreLiteral { - protected final AtomImpl atom; + protected final CoreAtom atom; protected final boolean positive; - public LiteralImpl(AtomImpl atom, boolean positive) { + public CoreLiteral(CoreAtom atom, boolean positive) { this.atom = atom; this.positive = positive; } - @Override - public AtomImpl getAtom() { + public CoreAtom getAtom() { return atom; } - @Override public boolean isNegated() { return !positive; } - @Override - public abstract LiteralImpl negate(); + public abstract CoreLiteral negate(); - public abstract LiteralImpl substitute(Substitution substitution); + public abstract CoreLiteral substitute(Substitution substitution); public abstract Set getBindingVariables(); @@ -78,25 +75,22 @@ public Set getOccurringVariables() { } /** - * @see AtomImpl#getPredicate() + * @see CoreAtom#getPredicate() */ - @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return atom.getPredicate(); } /** - * @see AtomImpl#getTerms() + * @see CoreAtom#getTerms() */ - @Override public List getTerms() { return atom.getTerms(); } /** - * @see AtomImpl#isGround() + * @see CoreAtom#isGround() */ - @Override public boolean isGround() { return atom.isGround(); } @@ -115,7 +109,7 @@ public boolean equals(Object o) { return false; } - LiteralImpl that = (LiteralImpl) o; + CoreLiteral that = (CoreLiteral) o; return atom.equals(that.atom) && positive == that.positive; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java index d3e0781de..5e02e916e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; @@ -39,15 +39,15 @@ import static at.ac.tuwien.kr.alpha.Util.join; -public class ExternalAtom extends AtomImpl implements VariableNormalizableAtom { +public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { private final List input; private final List output; - protected final PredicateImpl predicate; + protected final CorePredicate predicate; protected final PredicateInterpretation interpretation; - public ExternalAtom(PredicateImpl predicate, PredicateInterpretation interpretation, List input, List output) { + public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { if (predicate == null) { throw new IllegalArgumentException("predicate must not be null!"); } @@ -71,7 +71,7 @@ public boolean hasOutput() { } @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return predicate; } @@ -132,7 +132,7 @@ public String toString() { } @Override - public AtomImpl withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for external atoms!"); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java index d2dc3ef6a..bef994f6f 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java @@ -56,7 +56,7 @@ public ExternalLiteral negate() { } /** - * @see AtomImpl#substitute(Substitution) + * @see CoreAtom#substitute(Substitution) */ @Override public ExternalLiteral substitute(Substitution substitution) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java index c01f11c94..fc318944e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java @@ -38,9 +38,9 @@ * atoms. * Copyright (c) 2017-2018, the Alpha Team. */ -public abstract class FixedInterpretationLiteral extends LiteralImpl { +public abstract class FixedInterpretationLiteral extends CoreLiteral { - public FixedInterpretationLiteral(AtomImpl atom, boolean positive) { + public FixedInterpretationLiteral(CoreAtom atom, boolean positive) { super(atom, positive); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java index 9b891ef38..7c63cf0b9 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java @@ -15,6 +15,6 @@ public interface VariableNormalizableAtom { * @return the Atom where all variables are renamed and enumerated * left-to-right. */ - AtomImpl normalizeVariables(String prefix, int counterStartingValue); + CoreAtom normalizeVariables(String prefix, int counterStartingValue); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java index 41117fa9c..395daeb4a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.common.depgraph; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import org.slf4j.Logger; @@ -40,7 +40,7 @@ /** * Internal representation of an {@link at.ac.tuwien.kr.alpha.common.program.InternalProgram}'s dependency graph. The dependency graph tracks dependencies - * between rules of a program. Each {@link Node} of the graph represents a {@link PredicateImpl} occurring in the program. A node has an incoming {@link Edge} for + * between rules of a program. Each {@link Node} of the graph represents a {@link CorePredicate} occurring in the program. A node has an incoming {@link Edge} for * every {@link Literal} in some rule body that depends on it, i.e. the predicate of the literal in question is the same as that of the node. The "sign" flag of * an {@link Edge} indicates whether the dependency is a positive or negative one, i.e. if the atom in question is preceded by a "not". * @@ -60,9 +60,9 @@ public final class DependencyGraph { */ private final Map> adjacencyMap; - private final Map nodesByPredicate; + private final Map nodesByPredicate; - private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { + private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { this.adjacencyMap = adjacencyMap; this.nodesByPredicate = nodesByPredicate; } @@ -71,7 +71,7 @@ public static DependencyGraph buildDependencyGraph(Map no return new DependencyGraph.Builder(nonGroundRules.values()).build(); } - public Node getNodeForPredicate(PredicateImpl p) { + public Node getNodeForPredicate(CorePredicate p) { return nodesByPredicate.get(p); } @@ -87,7 +87,7 @@ private static class Builder { private Collection rules; private Map> adjacentNodesMap = new HashMap<>(); - private Map nodesByPredicate = new HashMap<>(); + private Map nodesByPredicate = new HashMap<>(); private Builder(Collection rules) { this.rules = rules; @@ -98,7 +98,7 @@ private DependencyGraph build() { for (InternalRule rule : rules) { LOGGER.debug("Processing rule: {}", rule); Node headNode = handleRuleHead(rule); - for (LiteralImpl literal : rule.getBody()) { + for (CoreLiteral literal : rule.getBody()) { LOGGER.trace("Processing rule body literal: {}", literal); if (literal instanceof FixedInterpretationLiteral) { LOGGER.trace("Ignoring FixedInterpretationLiteral {}", literal); @@ -114,7 +114,7 @@ private Node handleRuleHead(InternalRule rule) { LOGGER.trace("Processing head of rule: {}", rule); Node headNode; if (rule.isConstraint()) { - PredicateImpl pred = generateConstraintDummyPredicate(); + CorePredicate pred = generateConstraintDummyPredicate(); headNode = new Node(pred); List dependencies = new ArrayList<>(); dependencies.add(new Edge(headNode, false)); @@ -124,8 +124,8 @@ private Node handleRuleHead(InternalRule rule) { adjacentNodesMap.put(headNode, dependencies); nodesByPredicate.put(pred, headNode); } else { - AtomImpl head = rule.getHeadAtom(); - PredicateImpl pred = head.getPredicate(); + CoreAtom head = rule.getHeadAtom(); + CorePredicate pred = head.getPredicate(); if (!nodesByPredicate.containsKey(pred)) { headNode = new Node(pred); adjacentNodesMap.put(headNode, new ArrayList<>()); @@ -137,10 +137,10 @@ private Node handleRuleHead(InternalRule rule) { return headNode; } - private void handleRuleBodyLiteral(Node headNode, LiteralImpl lit) { + private void handleRuleBodyLiteral(Node headNode, CoreLiteral lit) { List dependants; Node bodyNode; - PredicateImpl bodyPred = lit.getPredicate(); + CorePredicate bodyPred = lit.getPredicate(); if (!nodesByPredicate.containsKey(bodyPred)) { LOGGER.trace("Creating new node for bodyPred {}", bodyPred); dependants = new ArrayList<>(); @@ -160,8 +160,8 @@ private void handleRuleBodyLiteral(Node headNode, LiteralImpl lit) { nodesByPredicate.put(bodyPred, bodyNode); } - private PredicateImpl generateConstraintDummyPredicate() { - return PredicateImpl.getInstance(String.format(DependencyGraph.Builder.CONSTRAINT_PREDICATE_FORMAT, ++constraintNumber), 0); + private CorePredicate generateConstraintDummyPredicate() { + return CorePredicate.getInstance(String.format(DependencyGraph.Builder.CONSTRAINT_PREDICATE_FORMAT, ++constraintNumber), 0); } } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java index 5a5ebf76f..f7f041aba 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.common.depgraph; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; /** * A node in a dependency graph. One node references exactly one predicate. This means that all rule heads deriving the @@ -36,9 +36,9 @@ */ public class Node { - private final PredicateImpl predicate; + private final CorePredicate predicate; - public Node(PredicateImpl predicate) { + public Node(CorePredicate predicate) { this.predicate = predicate; } @@ -64,7 +64,7 @@ public String getLabel() { return predicate.toString(); } - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return predicate; } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java index cbccf4802..83b1fe45e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.common.program; import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.rule.AbstractRule; import at.ac.tuwien.kr.alpha.common.rule.head.Head; import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; @@ -18,10 +18,10 @@ public abstract class AbstractProgram> { private final List rules; - private final List facts; + private final List facts; private final InlineDirectives inlineDirectives; - public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { this.rules = rules; this.facts = facts; this.inlineDirectives = inlineDirectives; @@ -31,7 +31,7 @@ public List getRules() { return Collections.unmodifiableList(rules); } - public List getFacts() { + public List getFacts() { return Collections.unmodifiableList(facts); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java index d89254a56..6a7437c36 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.common.program; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; import at.ac.tuwien.kr.alpha.common.depgraph.StronglyConnectedComponentsAlgorithm; @@ -21,14 +21,14 @@ public class AnalyzedProgram extends InternalProgram { private final DependencyGraph dependencyGraph; private final ComponentGraph componentGraph; - public AnalyzedProgram(List rules, List facts) { + public AnalyzedProgram(List rules, List facts) { super(rules, facts); dependencyGraph = DependencyGraph.buildDependencyGraph(getRulesById()); componentGraph = buildComponentGraph(dependencyGraph); } public static AnalyzedProgram analyzeNormalProgram(NormalProgram prog) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); return new AnalyzedProgram(rulesAndFacts.left, rulesAndFacts.right); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java index ea0ed8f22..3bb1d8190 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java @@ -28,7 +28,7 @@ package at.ac.tuwien.kr.alpha.common.program; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; @@ -45,7 +45,7 @@ public class InputProgram extends AbstractProgram implements Program public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectives()); - public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } @@ -67,7 +67,7 @@ public static Builder builder(InputProgram prog) { public static class Builder { private List rules = new ArrayList<>(); - private List facts = new ArrayList<>(); + private List facts = new ArrayList<>(); private InlineDirectives inlineDirectives = new InlineDirectives(); public Builder(InputProgram prog) { @@ -90,12 +90,12 @@ public Builder addRule(BasicRule r) { return this; } - public Builder addFacts(List facts) { + public Builder addFacts(List facts) { this.facts.addAll(facts); return this; } - public Builder addFact(AtomImpl fact) { + public Builder addFact(CoreAtom fact) { this.facts.add(fact); return this; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java index ba9468b0f..dd8f88f53 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java @@ -1,8 +1,8 @@ package at.ac.tuwien.kr.alpha.common.program; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.grounder.FactIntervalEvaluator; @@ -20,19 +20,19 @@ */ public class InternalProgram extends AbstractProgram { - private final Map> predicateDefiningRules = new LinkedHashMap<>(); - private final Map> factsByPredicate = new LinkedHashMap<>(); + private final Map> predicateDefiningRules = new LinkedHashMap<>(); + private final Map> factsByPredicate = new LinkedHashMap<>(); private final Map rulesById = new LinkedHashMap<>(); - public InternalProgram(List rules, List facts) { + public InternalProgram(List rules, List facts) { super(rules, facts, null); recordFacts(facts); recordRules(rules); } - static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { + static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { List internalRules = new ArrayList<>(); - List facts = new ArrayList<>(normalProgram.getFacts()); + List facts = new ArrayList<>(normalProgram.getFacts()); for (NormalRule r : normalProgram.getRules()) { if (r.getBody().isEmpty()) { if (!r.getHead().isGround()) { @@ -47,14 +47,14 @@ static ImmutablePair, List> internalizeRu } public static InternalProgram fromNormalProgram(NormalProgram normalProgram) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); return new InternalProgram(rulesAndFacts.left, rulesAndFacts.right); } - private void recordFacts(List facts) { - for (AtomImpl fact : facts) { + private void recordFacts(List facts) { + for (CoreAtom fact : facts) { List tmpInstances = FactIntervalEvaluator.constructFactInstances(fact); - PredicateImpl tmpPredicate = fact.getPredicate(); + CorePredicate tmpPredicate = fact.getPredicate(); factsByPredicate.putIfAbsent(tmpPredicate, new LinkedHashSet<>()); factsByPredicate.get(tmpPredicate).addAll(tmpInstances); } @@ -69,16 +69,16 @@ private void recordRules(List rules) { } } - private void recordDefiningRule(PredicateImpl headPredicate, InternalRule rule) { + private void recordDefiningRule(CorePredicate headPredicate, InternalRule rule) { predicateDefiningRules.putIfAbsent(headPredicate, new LinkedHashSet<>()); predicateDefiningRules.get(headPredicate).add(rule); } - public Map> getPredicateDefiningRules() { + public Map> getPredicateDefiningRules() { return Collections.unmodifiableMap(predicateDefiningRules); } - public Map> getFactsByPredicate() { + public Map> getFactsByPredicate() { return Collections.unmodifiableMap(factsByPredicate); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java index f102c2b4f..d6d1b18e9 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java @@ -4,7 +4,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; @@ -16,7 +16,7 @@ */ public class NormalProgram extends AbstractProgram { - public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java index 012da514d..a4c41973e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java @@ -1,17 +1,17 @@ package at.ac.tuwien.kr.alpha.common.rule; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import org.apache.commons.collections4.SetUtils; - 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.Util; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.head.Head; + /** * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) * @@ -22,14 +22,14 @@ public abstract class AbstractRule { private final H head; - private final Set bodyLiteralsPositive; - private final Set bodyLiteralsNegative; + private final Set bodyLiteralsPositive; + private final Set bodyLiteralsNegative; - public AbstractRule(H head, List body) { + public AbstractRule(H head, List body) { this.head = head; - Set positiveBody = new LinkedHashSet<>(); - Set negativeBody = new LinkedHashSet<>(); - for (LiteralImpl bodyLiteral : body) { + Set positiveBody = new LinkedHashSet<>(); + Set negativeBody = new LinkedHashSet<>(); + for (CoreLiteral bodyLiteral : body) { if (bodyLiteral.isNegated()) { negativeBody.add(bodyLiteral); } else { @@ -94,15 +94,15 @@ public H getHead() { return head; } - public Set getBody() { + public Set getBody() { return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); } - public Set getPositiveBody() { + public Set getPositiveBody() { return this.bodyLiteralsPositive; } - public Set getNegativeBody() { + public Set getNegativeBody() { return this.bodyLiteralsNegative; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java index 84660bf52..db05e1164 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java @@ -29,8 +29,7 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.head.Head; /** @@ -39,7 +38,7 @@ */ public class BasicRule extends AbstractRule { - public BasicRule(Head head, List body) { + public BasicRule(Head head, List body) { super(head, body); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java index f41a1cab5..ace3930f3 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java @@ -27,16 +27,15 @@ */ package at.ac.tuwien.kr.alpha.common.rule; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; -import com.google.common.annotations.VisibleForTesting; - import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import com.google.common.annotations.VisibleForTesting; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; @@ -53,11 +52,11 @@ public class InternalRule extends NormalRule { private final int ruleId; - private final List occurringPredicates; + private final List occurringPredicates; private final RuleGroundingOrders groundingOrders; - public InternalRule(NormalHead head, List body) { + public InternalRule(NormalHead head, List body) { super(head, body); if (body.isEmpty()) { throw new IllegalArgumentException( @@ -70,7 +69,7 @@ public InternalRule(NormalHead head, List body) { this.occurringPredicates.add(this.getHeadAtom().getPredicate()); } - for (LiteralImpl literal : body) { + for (CoreLiteral literal : body) { if (literal instanceof AggregateLiteral) { throw new IllegalArgumentException("AggregateLiterals aren't supported in InternalRules! (lit: " + literal.toString() + ")"); } @@ -103,9 +102,9 @@ public static InternalRule fromNormalRule(NormalRule rule) { */ public InternalRule renameVariables(String newVariablePostfix) { List occurringVariables = new ArrayList<>(); - AtomImpl headAtom = this.getHeadAtom(); + CoreAtom headAtom = this.getHeadAtom(); occurringVariables.addAll(headAtom.getOccurringVariables()); - for (LiteralImpl literal : this.getBody()) { + for (CoreLiteral literal : this.getBody()) { occurringVariables.addAll(literal.getOccurringVariables()); } Unifier variableReplacement = new Unifier(); @@ -113,9 +112,9 @@ public InternalRule renameVariables(String newVariablePostfix) { final String newVariableName = occurringVariable.toString() + newVariablePostfix; variableReplacement.put(occurringVariable, VariableTerm.getInstance(newVariableName)); } - AtomImpl renamedHeadAtom = headAtom.substitute(variableReplacement); - ArrayList renamedBody = new ArrayList<>(this.getBody().size()); - for (LiteralImpl literal : this.getBody()) { + CoreAtom renamedHeadAtom = headAtom.substitute(variableReplacement); + ArrayList renamedBody = new ArrayList<>(this.getBody().size()); + for (CoreLiteral literal : this.getBody()) { renamedBody.add(literal.substitute(variableReplacement)); } return new InternalRule(new NormalHead(renamedHeadAtom), renamedBody); @@ -125,7 +124,7 @@ public InternalRule renameVariables(String newVariablePostfix) { * Returns the predicates occurring in this rule. * @return a list of all predicates occurring in the rule (may contain duplicates and builtin atoms). */ - public List getOccurringPredicates() { + public List getOccurringPredicates() { return this.occurringPredicates; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java index fe94e3a70..db9f8ac7e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java @@ -1,14 +1,13 @@ package at.ac.tuwien.kr.alpha.common.rule; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; - import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; + /** * 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. @@ -17,12 +16,12 @@ */ public class NormalRule extends AbstractRule { - public NormalRule(NormalHead head, List body) { + public NormalRule(NormalHead head, List body) { super(head, body); } public static NormalRule fromBasicRule(BasicRule rule) { - AtomImpl headAtom = null; + CoreAtom 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()); @@ -36,7 +35,7 @@ public boolean isGround() { if (!isConstraint() && !this.getHead().isGround()) { return false; } - for (Literal bodyElement : this.getBody()) { + for (CoreLiteral bodyElement : this.getBody()) { if (!bodyElement.isGround()) { return false; } @@ -44,7 +43,7 @@ public boolean isGround() { return true; } - public AtomImpl getHeadAtom() { + public CoreAtom getHeadAtom() { return this.isConstraint() ? null : this.getHead().getAtom(); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java index 5dc261490..6a43cb24d 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java @@ -1,9 +1,9 @@ package at.ac.tuwien.kr.alpha.common.rule.head; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.terms.Term; import java.util.List; @@ -25,10 +25,10 @@ public class ChoiceHead extends Head { private final ComparisonOperator upperOp; public static class ChoiceElement { - public final AtomImpl choiceAtom; - public final List conditionLiterals; + public final CoreAtom choiceAtom; + public final List conditionLiterals; - public ChoiceElement(AtomImpl choiceAtom, List conditionLiterals) { + public ChoiceElement(CoreAtom choiceAtom, List conditionLiterals) { this.choiceAtom = choiceAtom; this.conditionLiterals = conditionLiterals; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java index 3e0a01b0e..650eadbc2 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.common.rule.head; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; /** * Represents a normal head, i.e., a head that is an Atom. @@ -8,9 +8,9 @@ */ public class NormalHead extends Head { - private final AtomImpl atom; + private final CoreAtom atom; - public NormalHead(AtomImpl atom) { + public NormalHead(CoreAtom atom) { this.atom = atom; } @@ -19,7 +19,7 @@ public boolean isGround() { return atom.isGround(); } - public AtomImpl getAtom() { + public CoreAtom getAtom() { return atom; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java index 6a2b04039..f37739534 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.grounder; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; /** * Copyright (c) 2016, the Alpha Team. */ public abstract class AbstractGrounder implements Grounder { - protected final java.util.function.Predicate filter; + protected final java.util.function.Predicate filter; - protected AbstractGrounder(java.util.function.Predicate filter) { + protected AbstractGrounder(java.util.function.Predicate filter) { this.filter = filter; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java index 0be02b2e8..98b18eb5b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java @@ -1,18 +1,18 @@ package at.ac.tuwien.kr.alpha.grounder; +import java.util.HashSet; +import java.util.Set; + import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; -import java.util.HashSet; -import java.util.Set; - public abstract class BridgedGrounder extends AbstractGrounder { protected final Bridge[] bridges; - protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { + protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { super(filter); this.bridges = bridges; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java index bd34ef18e..05b5a6c3e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.grounder; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.*; import java.util.ArrayList; @@ -19,7 +19,7 @@ public class FactIntervalEvaluator { * @param fact the fact potentially containing intervals. * @return all instances stemming from unfolding the intervals. */ - public static List constructFactInstances(AtomImpl fact) { + public static List constructFactInstances(CoreAtom fact) { // Construct instance(s) from the fact. int arity = fact.getPredicate().getArity(); TermImpl[] currentTerms = new TermImpl[arity]; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java index 73424f16c..03aac3274 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.grounder; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; /** * Copyright (c) 2016, the Alpha Team. */ public abstract class FilteringGrounder implements Grounder { - protected final java.util.function.Predicate filter; + protected final java.util.function.Predicate filter; - protected FilteringGrounder(java.util.function.Predicate filter) { + protected FilteringGrounder(java.util.function.Predicate filter) { this.filter = filter; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java index 8e29f999b..a24c9c8a8 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java @@ -28,14 +28,15 @@ package at.ac.tuwien.kr.alpha.grounder; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.config.InputConfig; import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; public final class GrounderFactory { - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + public static Grounder getInstance(String name, InternalProgram 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); @@ -43,11 +44,11 @@ public static Grounder getInstance(String name, InternalProgram program, AtomSto throw new IllegalArgumentException("Unknown grounder requested."); } - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { return getInstance(name, program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); } - + public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, boolean debugInternalChecks) { return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, new GrounderHeuristicsConfiguration(), debugInternalChecks); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java index ad2fc3d43..83bd539ca 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java @@ -36,8 +36,8 @@ import java.util.Map; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.Term; /** @@ -47,7 +47,7 @@ * Copyright (c) 2016-2020, the Alpha Team. */ public class IndexedInstanceStorage { - private final PredicateImpl predicate; + private final CorePredicate predicate; private final boolean positive; /** @@ -62,7 +62,7 @@ public class IndexedInstanceStorage { private final ArrayList recentlyAddedInstances = new ArrayList<>(); - public IndexedInstanceStorage(PredicateImpl predicate, boolean positive) { + public IndexedInstanceStorage(CorePredicate predicate, boolean positive) { this.predicate = predicate; this.positive = positive; @@ -72,7 +72,7 @@ public IndexedInstanceStorage(PredicateImpl predicate, boolean positive) { } } - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return predicate; } @@ -83,7 +83,7 @@ public void markRecentlyAddedInstancesDone() { public void addIndexPosition(int position) { if (position < 0 || position > predicate.getArity() - 1) { throw new RuntimeException("Requested to create indices for attribute out of range." + - "IndexedInstanceStorage: " + this + " requested indices position: " + position); + "IndexedInstanceStorage: " + this + " requested indices position: " + position); } // Add index indices.set(position, new LinkedHashMap<>()); @@ -99,13 +99,14 @@ public void addIndexPosition(int position) { public void removeIndexPosition(int position) { if (position < 0 || position > predicate.getArity() - 1) { throw new RuntimeException("Requested to create indices for attribute out of range." + - "IndexedInstanceStorage: " + this + " requested indices position: " + position); + "IndexedInstanceStorage: " + this + " requested indices position: " + position); } indices.set(position, null); } /** * Returns whether an instance is already contained in the storage. + * * @param instance the instance to check for containment. * @return true if the instance is already contained in the storage. */ @@ -116,8 +117,8 @@ public boolean containsInstance(Instance instance) { public void addInstance(Instance instance) { if (instance.terms.size() != predicate.getArity()) { throw new RuntimeException("Instance length does not match arity of IndexedInstanceStorage: " + - "instance size: " + instance.terms.size() - + "IndexedInstanceStorage: " + this); + "instance size: " + instance.terms.size() + + "IndexedInstanceStorage: " + this); } instances.add(instance); recentlyAddedInstances.add(instance); @@ -129,7 +130,7 @@ public void addInstance(Instance instance) { } posIndex.putIfAbsent(instance.terms.get(i), new ArrayList<>()); ArrayList matchingInstancesAtPos = posIndex.get(instance.terms.get(i)); - matchingInstancesAtPos.add(instance); // Add instance + matchingInstancesAtPos.add(instance); // Add instance } } @@ -145,7 +146,7 @@ public void removeInstance(Instance instance) { continue; } ArrayList matchingInstancesAtPos = posIndex.get(instance.terms.get(i)); - matchingInstancesAtPos.remove(instance); // Remove instance + matchingInstancesAtPos.remove(instance); // Remove instance // If there are no more instances having the term at the current position, // remove the entry from the hash. @@ -163,6 +164,7 @@ public List getRecentlyAddedInstances() { /** * Returns a list of all instances having the given term at the given position. Returns null if no such * instances exist. + * * @param term * @param position * @return @@ -176,8 +178,7 @@ public List getInstancesMatchingAtPosition(Term term, int position) { return matchingInstances == null ? Collections.emptyList() : matchingInstances; } - - private int getMostSelectiveGroundTermPosition(Atom atom) { + private int getMostSelectiveGroundTermPosition(CoreAtom atom) { int smallestNumberOfInstances = Integer.MAX_VALUE; int mostSelectiveTermPosition = -1; for (int i = 0; i < atom.getTerms().size(); i++) { @@ -198,7 +199,7 @@ private int getMostSelectiveGroundTermPosition(Atom atom) { return mostSelectiveTermPosition; } - public List getInstancesFromPartiallyGroundAtom(Atom substitute) { + public List getInstancesFromPartiallyGroundAtom(CoreAtom substitute) { // For selection of the instances, find ground term on which to select. int firstGroundTermPosition = getMostSelectiveGroundTermPosition(substitute); // Select matching instances, select all if no ground term was found. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java index 1242e0243..3e623193d 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java @@ -6,7 +6,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; @@ -26,7 +26,7 @@ public Instance(List terms) { this.terms = terms; } - public static Instance fromAtom(AtomImpl atom) { + public static Instance fromAtom(CoreAtom atom) { if (!atom.isGround()) { throw Util.oops("Cannot create instance from non-ground atom " + atom.toString()); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java index 1d54b8c78..aa457df0b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java @@ -65,12 +65,12 @@ public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGr private final InternalProgram program; private final AnalyzeUnjustified analyzeUnjustified; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private final Map> rulesUsingPredicateWorkingMemory = new HashMap<>(); private final Map knownNonGroundRules; private ArrayList fixedRules = new ArrayList<>(); - private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); + private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); private final boolean debugInternalChecks; private final GrounderHeuristicsConfiguration heuristicsConfiguration; @@ -88,7 +88,7 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, bridges); } - NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { super(filter, bridges); this.atomStore = atomStore; this.heuristicsConfiguration = heuristicsConfiguration; @@ -118,8 +118,8 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur private void initializeFactsAndRules() { // Initialize all facts. - for (AtomImpl fact : program.getFacts()) { - final PredicateImpl predicate = fact.getPredicate(); + for (CoreAtom fact : program.getFacts()) { + final CorePredicate predicate = fact.getPredicate(); // Record predicate workingMemory.initialize(predicate); @@ -133,7 +133,7 @@ private void initializeFactsAndRules() { // Initialize rules and constraints in working memory. for (InternalRule nonGroundRule : program.getRulesById().values()) { // Create working memories for all predicates occurring in the rule. - for (PredicateImpl predicate : nonGroundRule.getOccurringPredicates()) { + for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { // FIXME: this also contains interval/builtin predicates that are not needed. workingMemory.initialize(predicate); } @@ -145,7 +145,7 @@ private void initializeFactsAndRules() { } // Register each starting literal at the corresponding working memory. - for (LiteralImpl literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { + for (CoreLiteral literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { registerLiteralAtWorkingMemory(literal, nonGroundRule); } } @@ -156,14 +156,14 @@ private Set getRulesWithUniqueHead() { // Record all unique rule heads. final Set uniqueGroundRulePerGroundHead = new HashSet<>(); - for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { + for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { if (headDefiningRules.getValue().size() != 1) { continue; } InternalRule nonGroundRule = headDefiningRules.getValue().iterator().next(); // Check that all variables of the body also occur in the head (otherwise grounding is not unique). - AtomImpl headAtom = nonGroundRule.getHeadAtom(); + CoreAtom headAtom = nonGroundRule.getHeadAtom(); // Rule is not guaranteed unique if there are facts for it. HashSet potentialFacts = factsFromProgram.get(headAtom.getPredicate()); @@ -174,7 +174,7 @@ private Set getRulesWithUniqueHead() { // Collect head and body variables. HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); HashSet occurringVariablesBody = new HashSet<>(); - for (LiteralImpl lit : nonGroundRule.getPositiveBody()) { + for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { occurringVariablesBody.addAll(lit.getBindingVariables()); } occurringVariablesBody.removeAll(occurringVariablesHead); @@ -191,7 +191,7 @@ private Set getRulesWithUniqueHead() { * Registers a starting literal of a NonGroundRule at its corresponding working memory. * @param nonGroundRule the rule in which the literal occurs. */ - private void registerLiteralAtWorkingMemory(LiteralImpl literal, InternalRule nonGroundRule) { + private void registerLiteralAtWorkingMemory(CoreLiteral literal, InternalRule nonGroundRule) { if (literal.isNegated()) { throw new RuntimeException("Literal to register is negated. Should not happen."); } @@ -202,13 +202,13 @@ private void registerLiteralAtWorkingMemory(LiteralImpl literal, InternalRule no @Override public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { - Map> predicateInstances = new LinkedHashMap<>(); - SortedSet knownPredicates = new TreeSet<>(); + Map> predicateInstances = new LinkedHashMap<>(); + SortedSet knownPredicates = new TreeSet<>(); // Iterate over all true atomIds, computeNextAnswerSet instances from atomStore and add them if not filtered. for (int trueAtom : trueAtoms) { - final Atom atom = atomStore.get(trueAtom); - PredicateImpl predicate = atom.getPredicate(); + final CoreAtom atom = atomStore.get(trueAtom); + CorePredicate predicate = atom.getPredicate(); // Skip atoms over internal predicates. if (predicate.isInternal()) { @@ -222,13 +222,13 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { knownPredicates.add(predicate); predicateInstances.putIfAbsent(predicate, new TreeSet<>()); - Set instances = predicateInstances.get(predicate); + Set instances = predicateInstances.get(predicate); instances.add(atom); } // Add true atoms from facts. - for (Map.Entry> facts : factsFromProgram.entrySet()) { - PredicateImpl factPredicate = facts.getKey(); + for (Map.Entry> facts : factsFromProgram.entrySet()) { + CorePredicate factPredicate = facts.getKey(); // Skip atoms over internal predicates. if (factPredicate.isInternal()) { continue; @@ -244,7 +244,7 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { knownPredicates.add(factPredicate); predicateInstances.putIfAbsent(factPredicate, new TreeSet<>()); for (Instance factInstance : facts.getValue()) { - SortedSet instances = predicateInstances.get(factPredicate); + SortedSet instances = predicateInstances.get(factPredicate); instances.add(new BasicAtom(factPredicate, factInstance.terms)); } } @@ -263,7 +263,7 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { protected HashMap bootstrap() { final HashMap groundNogoods = new LinkedHashMap<>(); - for (PredicateImpl predicate : factsFromProgram.keySet()) { + for (CorePredicate predicate : factsFromProgram.keySet()) { // Instead of generating NoGoods, add instance to working memories directly. workingMemory.addInstances(predicate, true, factsFromProgram.get(predicate)); } @@ -288,7 +288,7 @@ public Map getNoGoods(Assignment currentAssignment) { // Compute new ground rule (evaluate joins with newly changed atoms) for (IndexedInstanceStorage modifiedWorkingMemory : workingMemory.modified()) { // Skip predicates solely used in the solver which do not occur in rules. - PredicateImpl workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); + CorePredicate workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); if (workingMemoryPredicate.isSolverInternal()) { continue; } @@ -331,7 +331,7 @@ public Map getNoGoods(Assignment currentAssignment) { } workingMemory.reset(); - for (AtomImpl removeAtom : removeAfterObtainingNewNoGoods) { + for (CoreAtom removeAtom : removeAfterObtainingNewNoGoods) { final IndexedInstanceStorage storage = workingMemory.get(removeAtom, true); Instance instance = new Instance(removeAtom.getTerms()); if (storage.containsInstance(instance)) { @@ -475,7 +475,7 @@ private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder grounding //@formatter:on private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, Substitution partialSubstitution) { - LiteralImpl currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); + CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); if (currentLiteral == null) { LOGGER.trace("No more literals found in grounding order, therefore stopping binding!"); return BindingResult.singleton(partialSubstitution, originalTolerance - remainingTolerance); @@ -583,7 +583,7 @@ public Set justifyAtom(int atomToJustify, Assignment currentAssignment) /** * Checks that every nogood not marked as {@link NoGoodInterface.Type#INTERNAL} contains only - * atoms which are not {@link PredicateImpl#isSolverInternal()} (except {@link RuleAtom}s, which are allowed). + * atoms which are not {@link CorePredicate#isSolverInternal()} (except {@link RuleAtom}s, which are allowed). * * @param newNoGoods */ @@ -591,7 +591,7 @@ private void checkTypesOfNoGoods(Collection newNoGoods) { for (NoGood noGood : newNoGoods) { if (noGood.getType() != NoGoodInterface.Type.INTERNAL) { for (int literal : noGood) { - Atom atom = atomStore.get(atomOf(literal)); + CoreAtom atom = atomStore.get(atomOf(literal)); if (atom.getPredicate().isSolverInternal() && !(atom instanceof RuleAtom)) { throw oops("NoGood containing atom of internal predicate " + atom + " is " + noGood.getType() + " instead of INTERNAL"); } @@ -602,9 +602,9 @@ private void checkTypesOfNoGoods(Collection newNoGoods) { private static class FirstBindingAtom { final InternalRule rule; - final Literal startingLiteral; + final CoreLiteral startingLiteral; - FirstBindingAtom(InternalRule rule, Literal startingLiteral) { + FirstBindingAtom(InternalRule rule, CoreLiteral startingLiteral) { this.rule = rule; this.startingLiteral = startingLiteral; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java index aea9a8fd4..69996e2e6 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java @@ -42,11 +42,11 @@ import at.ac.tuwien.kr.alpha.common.AtomStore; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; @@ -59,11 +59,11 @@ public class NoGoodGenerator { private final AtomStore atomStore; private final ChoiceRecorder choiceRecorder; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private final InternalProgram programAnalysis; private final Set uniqueGroundRulePerGroundHead; - NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { + NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { this.atomStore = atomStore; this.choiceRecorder = recorder; this.factsFromProgram = factsFromProgram; @@ -96,7 +96,7 @@ List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundR final List result = new ArrayList<>(); - final AtomImpl groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); + final CoreAtom groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); final int headId = atomStore.putIfAbsent(groundHeadAtom); // Prepare atom representing the rule body. @@ -141,8 +141,8 @@ List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundR List collectNegLiterals(final InternalRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsNegative = new ArrayList<>(); - for (LiteralImpl lit : nonGroundRule.getNegativeBody()) { - AtomImpl groundAtom = lit.getAtom().substitute(substitution); + for (CoreLiteral lit : nonGroundRule.getNegativeBody()) { + CoreAtom groundAtom = lit.getAtom().substitute(substitution); final Set factInstances = factsFromProgram.get(groundAtom.getPredicate()); @@ -163,7 +163,7 @@ List collectNegLiterals(final InternalRule nonGroundRule, final Substit private List collectPosLiterals(final InternalRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsPositive = new ArrayList<>(); - for (LiteralImpl lit : nonGroundRule.getPositiveBody()) { + for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { if (lit instanceof FixedInterpretationLiteral) { // TODO: conversion of atom to literal is ugly. NonGroundRule could manage atoms instead of literals, cf. FIXME there // Atom has fixed interpretation, hence was checked earlier that it @@ -171,13 +171,13 @@ private List collectPosLiterals(final InternalRule nonGroundRule, final // FixedInterpretationAtoms need not be shown to the solver, skip it. continue; } - final AtomImpl atom = lit.getAtom(); + final CoreAtom atom = lit.getAtom(); // Skip the special enumeration atom. if (atom instanceof EnumerationAtom) { continue; } - final AtomImpl groundAtom = atom.substitute(substitution); + final CoreAtom groundAtom = atom.substitute(substitution); // Consider facts to eliminate ground atoms from the generated nogoods that are always true // and eliminate nogoods that are always satisfied due to facts. @@ -197,7 +197,7 @@ private List collectPosLiterals(final InternalRule nonGroundRule, final return bodyLiteralsPositive; } - private boolean existsRuleWithPredicateInHead(final PredicateImpl predicate) { + private boolean existsRuleWithPredicateInHead(final CorePredicate predicate) { final HashSet definingRules = programAnalysis.getPredicateDefiningRules().get(predicate); return definingRules != null && !definingRules.isEmpty(); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java index ee30ac7a1..a3a7c16d7 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java @@ -28,8 +28,7 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; /** @@ -37,13 +36,13 @@ */ public class RuleGroundingOrder { - private Literal startingLiteral; - private List otherLiterals; + private CoreLiteral startingLiteral; + private List otherLiterals; private int positionLastVarBound; private int stopBindingAtOrderPosition; private final boolean ground; - RuleGroundingOrder(Literal startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { + RuleGroundingOrder(CoreLiteral startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { super(); this.startingLiteral = startingLiteral; this.otherLiterals = otherLiterals; @@ -67,7 +66,7 @@ private RuleGroundingOrder(RuleGroundingOrder otherRuleGroundingOrder) { * @param orderPosition zero-based index into list of literals except the starting literal * @return the literal at the given position, or {@code null} if it is already known that this literal is not able to yield new bindings */ - public LiteralImpl getLiteralAtOrderPosition(int orderPosition) { + public CoreLiteral getLiteralAtOrderPosition(int orderPosition) { if (orderPosition >= stopBindingAtOrderPosition) { return null; } @@ -126,7 +125,7 @@ public void considerUntilCurrentEnd() { this.stopBindingAtOrderPosition = this.otherLiterals.size(); } - public Literal getStartingLiteral() { + public CoreLiteral getStartingLiteral() { return this.startingLiteral; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java index f37d43f74..a3e022aa3 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java @@ -38,8 +38,7 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; @@ -63,9 +62,9 @@ */ public class RuleGroundingOrders { private final InternalRule internalRule; - HashMap groundingOrders; - private HashMap literalSelectivity; - private List startingLiterals; + HashMap groundingOrders; + private HashMap literalSelectivity; + private List startingLiterals; private final boolean fixedGroundingInstantiation; private RuleGroundingOrder fixedGroundingOrder; @@ -80,7 +79,7 @@ public RuleGroundingOrders(InternalRule internalRule) { private void resetLiteralSelectivity() { // Set selectivity of all literals to 1.0f. - for (LiteralImpl literal : internalRule.getBody()) { + for (CoreLiteral literal : internalRule.getBody()) { literalSelectivity.put(literal, 1.0f); } } @@ -90,8 +89,8 @@ private void resetLiteralSelectivity() { * @return true iff the rule has a fixed ground instantiation. */ private boolean computeStartingLiterals() { - LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); - LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); + LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); + LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); // If the rule is ground, every body literal is a starting literal and the ground instantiation is fixed. if (internalRule.isGround()) { @@ -100,7 +99,7 @@ private boolean computeStartingLiterals() { } // Check each literal in the rule body whether it is eligible. - for (LiteralImpl literal : internalRule.getBody()) { + for (CoreLiteral literal : internalRule.getBody()) { // Only literals that need no variables already bound can start grounding. if (literal.getNonBindingVariables().size() != 0) { continue; @@ -128,15 +127,15 @@ private boolean computeStartingLiterals() { } } - public List getStartingLiterals() { + public List getStartingLiterals() { return Collections.unmodifiableList(startingLiterals); } - public void updateLiteralSelectivity(Literal literal, int numGivenTuples, int numObtainedTuples) { + public void updateLiteralSelectivity(CoreLiteral literal, int numGivenTuples, int numObtainedTuples) { // TODO: add old selectivity (with a decay factor) and new selectivity. } - public RuleGroundingOrder orderStartingFrom(Literal startingLiteral) { + public RuleGroundingOrder orderStartingFrom(CoreLiteral startingLiteral) { return groundingOrders.get(startingLiteral); } @@ -160,18 +159,18 @@ public void computeGroundingOrders() { return; } // Compute grounding orders for all positive BasicAtoms. - for (LiteralImpl literal : startingLiterals) { + for (CoreLiteral literal : startingLiterals) { computeGroundingOrder(literal); } } - private void computeGroundingOrder(LiteralImpl startingLiteral) { - Set bodyLiterals = internalRule.getBody(); + private void computeGroundingOrder(CoreLiteral startingLiteral) { + Set bodyLiterals = internalRule.getBody(); HashSet boundVariables = new HashSet<>(); boundVariables.addAll(startingLiteral.getBindingVariables()); - LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); + LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); remainingLiterals.remove(startingLiteral); - ArrayList literalsOrder; + ArrayList literalsOrder; if (fixedGroundingInstantiation) { literalsOrder = new ArrayList<>(bodyLiterals.size()); literalsOrder.add(startingLiteral); @@ -182,7 +181,7 @@ private void computeGroundingOrder(LiteralImpl startingLiteral) { int position = 0; int positionLastVarBound = -1; while (!remainingLiterals.isEmpty()) { - LiteralImpl nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); + CoreLiteral nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); if (nextGroundingLiteral == null) { throw new RuntimeException("Could not find a grounding order for rule " + internalRule + " with starting literal: " + startingLiteral + ". Rule is not safe."); } @@ -200,13 +199,13 @@ private void computeGroundingOrder(LiteralImpl startingLiteral) { groundingOrders.put(startingLiteral, new RuleGroundingOrder(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); } - private LiteralImpl selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { + private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { Float bestSelectivity = Float.MAX_VALUE; - LiteralImpl bestLiteral = null; + CoreLiteral bestLiteral = null; boolean bestLiteralSharesVariables = false; // Find the best literal whose nonbinding variables are already bound and whose selectivity is highest. // To avoid cross products, select those first that have some of their variables already bound. - for (LiteralImpl literal : remainingLiterals) { + for (CoreLiteral literal : remainingLiterals) { if (!boundVariables.containsAll(literal.getNonBindingVariables())) { // Only consider literals whose nonbinding variables are already bound. continue; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java index 73fa3727b..876005862 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java @@ -27,11 +27,7 @@ */ package at.ac.tuwien.kr.alpha.grounder; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.*; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; +import static at.ac.tuwien.kr.alpha.Util.oops; import java.util.List; import java.util.Map; @@ -39,7 +35,14 @@ import java.util.Set; import java.util.TreeMap; -import static at.ac.tuwien.kr.alpha.Util.oops; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; public class Substitution { @@ -68,7 +71,7 @@ public Substitution(Substitution clone) { this(new TreeMap<>(clone.substitution)); } - public static Substitution specializeSubstitution(Literal literal, Instance instance, Substitution substitution) { + public static Substitution specializeSubstitution(CoreLiteral literal, Instance instance, Substitution substitution) { return specializeSubstitution(literal.getAtom(), instance, substitution); } @@ -153,7 +156,7 @@ boolean unifyTerms(Term termNonGround, TermImpl termGround, Substitution partial * parameter substitution already is a unifier, it is returned. If the unifying substitution is an * extension of the input substitution, a new substitution will be returned. */ - public static Substitution specializeSubstitution(Atom atom, Instance instance, Substitution substitution) { + public static Substitution specializeSubstitution(CoreAtom atom, Instance instance, Substitution substitution) { return new SpecializationHelper().unify(atom.getTerms(), instance, substitution); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java index 1303e3dec..4c1c795fd 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java @@ -28,7 +28,7 @@ package at.ac.tuwien.kr.alpha.grounder; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; @@ -42,7 +42,7 @@ */ public class Unification { - public static Unifier unifyAtoms(AtomImpl left, AtomImpl right) { + public static Unifier unifyAtoms(CoreAtom left, CoreAtom right) { return unifyAtoms(left, right, false); } @@ -52,11 +52,11 @@ public static Unifier unifyAtoms(AtomImpl left, AtomImpl right) { * @param specific the specific Atom. * @return a Unifier sigma such that specific == general.substitute(sigma), returns null if no such sigma exists. */ - public static Unifier instantiate(AtomImpl general, AtomImpl specific) { + public static Unifier instantiate(CoreAtom general, CoreAtom specific) { return unifyAtoms(specific, general, true); } - private static Unifier unifyAtoms(AtomImpl left, AtomImpl right, boolean keepLeftAsIs) { + private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLeftAsIs) { Set leftOccurringVariables = left.getOccurringVariables(); Set rightOccurringVaribles = right.getOccurringVariables(); boolean leftSmaller = leftOccurringVariables.size() < rightOccurringVaribles.size(); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java index ca7b89b90..b5ba106f2 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java @@ -34,19 +34,19 @@ import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; public class WorkingMemory { - protected HashMap> workingMemory = new HashMap<>(); + protected HashMap> workingMemory = new HashMap<>(); private HashSet modifiedWorkingMemories = new LinkedHashSet<>(); - public boolean contains(PredicateImpl predicate) { + public boolean contains(CorePredicate predicate) { return workingMemory.containsKey(predicate); } - public void initialize(PredicateImpl predicate) { + public void initialize(CorePredicate predicate) { if (workingMemory.containsKey(predicate)) { return; } @@ -62,15 +62,15 @@ public void initialize(PredicateImpl predicate) { workingMemory.put(predicate, new ImmutablePair<>(pos, neg)); } - public IndexedInstanceStorage get(Literal literal) { + public IndexedInstanceStorage get(CoreLiteral literal) { return get(literal.getAtom(), !literal.isNegated()); } - public IndexedInstanceStorage get(Atom atom, boolean value) { + public IndexedInstanceStorage get(CoreAtom atom, boolean value) { return get(atom.getPredicate(), value); } - public IndexedInstanceStorage get(PredicateImpl predicate, boolean value) { + public IndexedInstanceStorage get(CorePredicate predicate, boolean value) { ImmutablePair pair = workingMemory.get(predicate); if (value) { return pair.getLeft(); @@ -79,11 +79,11 @@ public IndexedInstanceStorage get(PredicateImpl predicate, boolean value) { } } - public void addInstance(Atom atom, boolean value) { + public void addInstance(CoreAtom atom, boolean value) { addInstance(atom.getPredicate(), value, new Instance(atom.getTerms())); } - public void addInstance(PredicateImpl predicate, boolean value, Instance instance) { + public void addInstance(CorePredicate predicate, boolean value, Instance instance) { IndexedInstanceStorage storage = get(predicate, value); if (!storage.containsInstance(instance)) { @@ -92,7 +92,7 @@ public void addInstance(PredicateImpl predicate, boolean value, Instance instanc } } - public void addInstances(PredicateImpl predicate, boolean value, Iterable instances) { + public void addInstances(CorePredicate predicate, boolean value, Iterable instances) { IndexedInstanceStorage storage = get(predicate, value); for (Instance instance : instances) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java index 080451244..d9cbb8edb 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java @@ -32,29 +32,28 @@ import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; -public class ChoiceAtom extends AtomImpl { +public class ChoiceAtom extends CoreAtom { - public static final PredicateImpl ON = PredicateImpl.getInstance("ChoiceOn", 1, true, true); - public static final PredicateImpl OFF = PredicateImpl.getInstance("ChoiceOff", 1, true, true); + public static final CorePredicate ON = CorePredicate.getInstance("ChoiceOn", 1, true, true); + public static final CorePredicate OFF = CorePredicate.getInstance("ChoiceOff", 1, true, true); - private final PredicateImpl predicate; + private final CorePredicate predicate; private final List terms; - private ChoiceAtom(PredicateImpl predicate, Term term) { + private ChoiceAtom(CorePredicate predicate, Term term) { this.predicate = predicate; this.terms = Collections.singletonList(term); } - private ChoiceAtom(PredicateImpl predicate, int id) { + private ChoiceAtom(CorePredicate predicate, int id) { this(predicate, ConstantTerm.getInstance(Integer.toString(id))); } @@ -67,7 +66,7 @@ public static ChoiceAtom off(int id) { } @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return predicate; } @@ -83,12 +82,12 @@ public boolean isGround() { } @Override - public Literal toLiteral(boolean negated) { + public CoreLiteral toLiteral(boolean negated) { throw new UnsupportedOperationException("ChoiceAtom cannot be literalized"); } @Override - public AtomImpl substitute(Substitution substitution) { + public CoreAtom substitute(Substitution substitution) { return this; } @@ -98,7 +97,7 @@ public String toString() { } @Override - public AtomImpl withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("Changing terms is not supported for ChoiceAtoms!"); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java index 18da329e9..0c0128798 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java @@ -5,7 +5,7 @@ import java.util.HashMap; import java.util.List; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; @@ -24,7 +24,7 @@ * Copyright (c) 2017, the Alpha Team. */ public class EnumerationAtom extends BasicAtom { - public static final PredicateImpl ENUMERATION_PREDICATE = PredicateImpl.getInstance("_Enumeration", 3); + public static final CorePredicate ENUMERATION_PREDICATE = CorePredicate.getInstance("_Enumeration", 3); private static final HashMap> ENUMERATIONS = new HashMap<>(); public EnumerationAtom(List terms) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java index 830ee4567..582b6497c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java @@ -33,9 +33,9 @@ import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; @@ -54,8 +54,8 @@ * * Copyright (c) 2017, the Alpha Team. */ -public class IntervalAtom extends AtomImpl implements VariableNormalizableAtom { - private static final PredicateImpl PREDICATE = PredicateImpl.getInstance("_interval", 2, true); +public class IntervalAtom extends CoreAtom implements VariableNormalizableAtom { + private static final CorePredicate PREDICATE = CorePredicate.getInstance("_interval", 2, true); private final List terms; @@ -64,7 +64,7 @@ public IntervalAtom(IntervalTerm intervalTerm, Term intervalRepresentingVariable } @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return PREDICATE; } @@ -132,7 +132,7 @@ public IntervalAtom normalizeVariables(String prefix, int counterStartingValue) } @Override - public AtomImpl withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("IntervalAtoms do not support setting of terms!"); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java index 87a219210..05e664c65 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java @@ -27,11 +27,11 @@ */ package at.ac.tuwien.kr.alpha.grounder.atoms; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; @@ -47,8 +47,8 @@ * Atoms corresponding to rule bodies use this predicate, first term is rule number, * second is a term containing variable substitutions. */ -public class RuleAtom extends AtomImpl { - public static final PredicateImpl PREDICATE = PredicateImpl.getInstance("_R_", 2, true, true); +public class RuleAtom extends CoreAtom { + public static final CorePredicate PREDICATE = CorePredicate.getInstance("_R_", 2, true, true); private final List> terms; @@ -69,7 +69,7 @@ public RuleAtom(InternalRule nonGroundRule, Substitution substitution) { } @Override - public PredicateImpl getPredicate() { + public CorePredicate getPredicate() { return PREDICATE; } @@ -85,12 +85,12 @@ public boolean isGround() { } @Override - public LiteralImpl toLiteral(boolean positive) { + public CoreLiteral toLiteral(boolean positive) { throw new UnsupportedOperationException("RuleAtom cannot be literalized"); } @Override - public AtomImpl substitute(Substitution substitution) { + public CoreAtom substitute(Substitution substitution) { return this; } @@ -119,7 +119,7 @@ public String toString() { } @Override - public AtomImpl withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("RuleAtoms do not support setting of terms!"); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java index 82eac356c..79026fdcc 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -52,7 +52,7 @@ public abstract class AbstractLiteralInstantiationStrategy implements LiteralIns * literals is determined using the abstract method {@link AbstractLiteralInstantiationStrategy#getAssignmentStatusForAtom(Atom)}. */ @Override - public final AssignmentStatus getTruthForGroundLiteral(LiteralImpl groundLiteral) { + public final AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral) { if (groundLiteral.isNegated()) { return this.getAssignmentStatusForNegatedGroundLiteral(groundLiteral); } @@ -69,8 +69,8 @@ public final AssignmentStatus getTruthForGroundLiteral(LiteralImpl groundLiteral * {@link AbstractLiteralInstantiationStrategy#assignmentStatusAccepted(AssignmentStatus)}. */ @Override - public final List> getAcceptedSubstitutions(LiteralImpl lit, Substitution partialSubstitution) { - Atom atom = lit.getAtom(); + public final List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution) { + CoreAtom atom = lit.getAtom(); Iterable groundInstances = this.computeCandidateInstances(atom); return this.buildSubstitutionsFromInstances(atom, groundInstances, partialSubstitution); } @@ -84,7 +84,7 @@ public final List> getAcceptedSubs * @param partiallyGroundAtom a partially ground atom for which to find fitting ground instances * @return a list of candidate instances */ - protected abstract Iterable computeCandidateInstances(Atom partiallyGroundAtom); + protected abstract Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom); /** * Based on a list of candidate instances (see {@link AbstractLiteralInstantiationStrategy#computeCandidateInstances(Atom)}), create a list @@ -96,12 +96,12 @@ public final List> getAcceptedSubs * @param partialSubstitution * @return */ - protected final List> buildSubstitutionsFromInstances(Atom atomToSubstitute, + protected final List> buildSubstitutionsFromInstances(CoreAtom atomToSubstitute, Iterable candidateInstances, Substitution partialSubstitution) { List> retVal = new ArrayList<>(); // Filter for only instances unifying with partialSubsitution, i.e. "where all joins work out". Substitution currentInstanceSubstitution; - AtomImpl atomForCurrentInstance; + CoreAtom atomForCurrentInstance; for (Instance instance : candidateInstances) { currentInstanceSubstitution = Substitution.specializeSubstitution(atomToSubstitute, instance, partialSubstitution); if (currentInstanceSubstitution == null) { @@ -122,9 +122,9 @@ protected final List> buildSubstit return retVal; } - protected abstract AssignmentStatus getAssignmentStatusForAtom(AtomImpl atom); + protected abstract AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom); - protected abstract AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(Literal negatedGroundLiteral); + protected abstract AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral); protected abstract boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java index 950b06ea2..21f30e40b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java @@ -31,10 +31,10 @@ import at.ac.tuwien.kr.alpha.Util; import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; import at.ac.tuwien.kr.alpha.grounder.Instance; import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; @@ -46,7 +46,8 @@ * Implementation of {@link AbstractLiteralInstantiationStrategy} designed for use in {@link NaiveGrounder}. * * The instantiation strategy shares a {@link WorkingMemory}, an {@link AtomStore}, an {@link Assignment}, a {@link Map} of atoms that were - * facts of the currently grounded program, as well as a list of {@link AtomImpl}s that should be lazily deleted from the working memory, with + * facts of the currently grounded program, as well as a list of {@link CoreAtom}s that should be lazily deleted from the working memory, + * with * the grounder. * * The working memory and the facts map are maintained by the grounder and are being read by @@ -55,10 +56,12 @@ * are added by the instantiation strategy. The {@link Assignment} reflects the {@link Solver}s "current view of the world". It is used by * {@link DefaultLazyGroundingInstantiationStrategy} to determine {@link AssignmentStatus}es for atoms. * - * A specialty of this implementation is that - since deletion of obsolete {@link AtomImpl}s from {@link NaiveGrounder}s {@link WorkingMemory} + * A specialty of this implementation is that - since deletion of obsolete {@link CoreAtom}s from {@link NaiveGrounder}s + * {@link WorkingMemory} * happens lazily (i.e. at the end of each run of {@link NaiveGrounder#getNoGoods(Assignment)}) - it maintains a set of "stale" atoms that * is shared with the grounder. Specifically, whenever {@link DefaultLazyGroundingInstantiationStrategy#getAssignmentStatusForAtom(Atom)} - * determines that an {@link AtomImpl} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link AtomImpl} is added to + * determines that an {@link CoreAtom} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link CoreAtom} is + * added to * the stale atom set, which in turn is processed by the grounder, which then deletes the respective atoms from the working memory. * * Copyright (c) 2020, the Alpha Team. @@ -68,25 +71,25 @@ public class DefaultLazyGroundingInstantiationStrategy extends AbstractLiteralIn private WorkingMemory workingMemory; private AtomStore atomStore; private Assignment currentAssignment; - private LinkedHashSet staleWorkingMemoryEntries; - private Map> facts; + private LinkedHashSet staleWorkingMemoryEntries; + private Map> facts; public DefaultLazyGroundingInstantiationStrategy(WorkingMemory workingMemory, AtomStore atomStore, - Map> facts) { + Map> facts) { this.workingMemory = workingMemory; this.atomStore = atomStore; this.facts = facts; } @Override - protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) { + protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { IndexedInstanceStorage instanceStorage = this.workingMemory.get(partiallyGroundAtom, true); return instanceStorage.getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); } //@formatter:off /** - * Computes the {@link AssignmentStatus} for a given {@link AtomImpl} a. + * Computes the {@link AssignmentStatus} for a given {@link CoreAtom} a. * * The atom a is {@link AssignmentStatus#TRUE} iff *

      @@ -98,12 +101,12 @@ protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) * An atom is {@link AssignmentStatus#UNASSIGNED} iff it has no {@link ThriceTruth} assigned to it in the current assignment. * An atom is {@link AssignmentStatus#FALSE} iff it is assigned {@link ThriceTruth#FALSE} in the current assignment by the {@link Solver}. * - * Whenever an {@link AtomImpl} is found to be UNASSIGNED or FALSE, - * that {@link AtomImpl} is added to the stale atom set for later deletion from working memory by the grounder. + * Whenever an {@link CoreAtom} is found to be UNASSIGNED or FALSE, + * that {@link CoreAtom} is added to the stale atom set for later deletion from working memory by the grounder. */ //@formatter:on @Override - protected AssignmentStatus getAssignmentStatusForAtom(AtomImpl atom) { + protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { if (this.currentAssignment == null || this.isFact(atom)) { // currentAssignment == null is a legitimate case, grounder may be in bootstrap // and will call bindNextAtom with null assignment in that case. @@ -131,7 +134,7 @@ protected AssignmentStatus getAssignmentStatusForAtom(AtomImpl atom) { return retVal; } - private boolean isFact(AtomImpl atom) { + private boolean isFact(CoreAtom atom) { if (this.facts.get(atom.getPredicate()) == null) { return false; } else { @@ -140,7 +143,7 @@ private boolean isFact(AtomImpl atom) { } @Override - protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(Literal negatedGroundLiteral) { + protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { return AssignmentStatus.TRUE; } @@ -167,7 +170,7 @@ public void setCurrentAssignment(Assignment currentAssignment) { this.currentAssignment = currentAssignment; } - public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { + public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { this.staleWorkingMemoryEntries = staleWorkingMemoryEntries; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java index 54e3dbd43..5a8489f77 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java @@ -27,7 +27,7 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import org.apache.commons.lang3.tuple.ImmutablePair; import at.ac.tuwien.kr.alpha.common.atoms.Literal; @@ -47,7 +47,7 @@ public interface LiteralInstantiationStrategy { * @param groundLiteral a ground {@link Literal} for which to compute an {@link AssignmentStatus} * @return the current {@link AssignmentStatus} for the given literal according to the rules of this {@link LiteralInstantiationStrategy} */ - AssignmentStatus getTruthForGroundLiteral(LiteralImpl groundLiteral); + AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral); /** * Computes {@link Substitution}s that yield ground instances for a given literal and starting substitution along with the @@ -60,6 +60,6 @@ public interface LiteralInstantiationStrategy { * @param partialSubstitution a (possibly empty) substitution to use as a starting point * @return a list of substitutions along with the assignment status of the respective ground atoms */ - List> getAcceptedSubstitutions(LiteralImpl lit, Substitution partialSubstitution); + List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java index aaae8cff4..607f3ac63 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java @@ -70,7 +70,7 @@ public LiteralInstantiator(LiteralInstantiationStrategy instantiationStrategy) { * @param partialSubstitution a substitution that serves as a starting point. May be empty. * @return a {@link LiteralInstantiationResult} containing ground substitutions - if any exist - along with some metadata for the grounder */ - public LiteralInstantiationResult instantiateLiteral(LiteralImpl lit, Substitution partialSubstitution) { + public LiteralInstantiationResult instantiateLiteral(CoreLiteral lit, Substitution partialSubstitution) { LOGGER.trace("Instantiating literal: {}", lit); if (lit instanceof FixedInterpretationLiteral) { return this.instantiateFixedInterpretationLiteral((FixedInterpretationLiteral) lit, partialSubstitution); @@ -130,10 +130,10 @@ private LiteralInstantiationResult instantiateEnumerationLiteral(EnumerationLite * @param lit * @param partialSubstitution */ - private LiteralInstantiationResult instantiateBasicLiteral(LiteralImpl lit, Substitution partialSubstitution) { + private LiteralInstantiationResult instantiateBasicLiteral(CoreLiteral lit, Substitution partialSubstitution) { LOGGER.trace("Instantiating basic literal: {}", lit); List> substitutions; - LiteralImpl substitutedLiteral = lit.substitute(partialSubstitution); + CoreLiteral substitutedLiteral = lit.substitute(partialSubstitution); LOGGER.trace("Substituted literal is {}", substitutedLiteral); if (substitutedLiteral.isGround()) { LOGGER.trace("Literal {} is already ground, checking truth", substitutedLiteral); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java index a243a8091..3f98f3695 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java @@ -25,9 +25,8 @@ */ package at.ac.tuwien.kr.alpha.grounder.instantiation; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.grounder.Instance; import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; @@ -48,17 +47,17 @@ public WorkingMemoryBasedInstantiationStrategy(WorkingMemory workingMemory) { } @Override - protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) { + protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { return this.workingMemory.get(partiallyGroundAtom, true).getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); } @Override - protected AssignmentStatus getAssignmentStatusForAtom(AtomImpl atom) { + protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { return this.workingMemory.get(atom, true).containsInstance(Instance.fromAtom(atom)) ? AssignmentStatus.TRUE : AssignmentStatus.FALSE; } @Override - protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(Literal negatedGroundLiteral) { + protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { return this.getAssignmentStatusForAtom(negatedGroundLiteral.getAtom()) == AssignmentStatus.TRUE ? AssignmentStatus.FALSE : AssignmentStatus.TRUE; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java index c0c814330..5c837987f 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java @@ -33,7 +33,7 @@ import at.ac.tuwien.kr.alpha.common.AnswerSet; import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.common.program.InputProgram; @@ -99,11 +99,11 @@ public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { @Override public AnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { - SortedSet predicates = new TreeSet<>(); - Map> predicateInstances = new TreeMap<>(); + SortedSet predicates = new TreeSet<>(); + Map> predicateInstances = new TreeMap<>(); for (ASPCore2Parser.Classical_literalContext classicalLiteralContext : ctx.classical_literal()) { - AtomImpl atom = visitClassical_literal(classicalLiteralContext); + CoreAtom atom = visitClassical_literal(classicalLiteralContext); predicates.add(atom.getPredicate()); predicateInstances.compute(atom.getPredicate(), (k, v) -> { @@ -252,9 +252,9 @@ public ChoiceHead.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elemen } @Override - public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { + public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { // naf_literals : naf_literal (COMMA naf_literals)?; - List literals; + List literals; if (ctx.naf_literals() != null) { literals = visitNaf_literals(ctx.naf_literals()); } else { @@ -272,13 +272,13 @@ public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationCon } @Override - public List visitBody(ASPCore2Parser.BodyContext ctx) { + public List visitBody(ASPCore2Parser.BodyContext ctx) { // body : ( naf_literal | aggregate ) (COMMA body)?; if (ctx == null) { return emptyList(); } - final List literals = new ArrayList<>(); + final List literals = new ArrayList<>(); do { if (ctx.naf_literal() != null) { literals.add(visitNaf_literal(ctx.naf_literal())); @@ -427,7 +427,7 @@ public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) } @Override - public LiteralImpl visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { + public CoreLiteral visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { // naf_literal : NAF? (external_atom | classical_literal | builtin_atom); boolean isCurrentLiteralNegated = ctx.NAF() != null; if (ctx.builtin_atom() != null) { @@ -448,7 +448,7 @@ public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext } final List terms = visitTerms(ctx.terms()); - return new BasicAtom(PredicateImpl.getInstance(ctx.ID().getText(), terms.size()), terms); + return new BasicAtom(CorePredicate.getInstance(ctx.ID().getText(), terms.size()), terms); } @Override @@ -529,7 +529,7 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) List outputTerms = visitTerms(ctx.output); return new ExternalAtom( - PredicateImpl.getInstance(predicateName, outputTerms.size()), + CorePredicate.getInstance(predicateName, outputTerms.size()), interpretation, visitTerms(ctx.input), outputTerms diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java index 4a965260d..cfa094681 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java @@ -2,7 +2,7 @@ import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; @@ -26,22 +26,22 @@ public class AnalyzeUnjustified { private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeUnjustified.class); private final InternalProgram programAnalysis; private final AtomStore atomStore; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private int renamingCounter; private int padDepth; - public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { + public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { this.programAnalysis = programAnalysis; this.atomStore = atomStore; this.factsFromProgram = factsFromProgram; padDepth = 0; } - private Map> assignedAtoms; + private Map> assignedAtoms; public Set analyze(int atomToJustify, Assignment currentAssignment) { padDepth = 0; - AtomImpl atom = atomStore.get(atomToJustify); + CoreAtom atom = atomStore.get(atomToJustify); if (!(atom instanceof BasicAtom)) { throw oops("Starting atom must be a BasicAtom, but received: " + atom + " of type: " + atom.getClass()); } @@ -58,7 +58,7 @@ public Set analyze(int atomToJustify, Assignment currentAssignment) { if (truth == null) { continue; } - AtomImpl assignedAtom = atomStore.get(i); + CoreAtom assignedAtom = atomStore.get(i); assignedAtoms.putIfAbsent(assignedAtom.getPredicate(), new ArrayList<>()); assignedAtoms.get(assignedAtom.getPredicate()).add(assignedAtom); } @@ -93,7 +93,7 @@ private Set analyze(BasicAtom atom, Assignment currentAssignment) { private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment) { padDepth += 2; log("Begin explainUnjust(): {}", x); - AtomImpl p = x.getAtom(); + CoreAtom p = x.getAtom(); ReturnExplainUnjust ret = new ReturnExplainUnjust(); @@ -103,8 +103,8 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment rulesLoop: for (RuleAndUnifier ruleUnifier : rulesUnifyingWithP) { Unifier sigma = ruleUnifier.unifier; - Set bodyR = ruleUnifier.ruleBody; - AtomImpl sigmaHr = ruleUnifier.originalHead.substitute(sigma); + Set bodyR = ruleUnifier.ruleBody; + CoreAtom sigmaHr = ruleUnifier.originalHead.substitute(sigma); log("Considering now: {}", ruleUnifier); Set vN = new LinkedHashSet<>(x.getComplementSubstitutions()); for (Unifier sigmaN : vN) { @@ -125,15 +125,15 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment log("Adapting N to N'. Original N is {}", vN); log("Adapted N' is {}", vNp); log("Searching for falsified negated literals in the body: {}", bodyR); - for (LiteralImpl lit : bodyR) { + for (CoreLiteral lit : bodyR) { if (!lit.isNegated()) { continue; } - AtomImpl lb = lit.getAtom().substitute(sigma); + CoreAtom lb = lit.getAtom().substitute(sigma); log("Found: {}, searching falsifying ground instances of {} (with unifier from the head) now.", lit, lb); AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(lb.getPredicate()); while (assignedAtomsOverPredicate.hasNext()) { - AtomImpl lg = assignedAtomsOverPredicate.next(); + CoreAtom lg = assignedAtomsOverPredicate.next(); log("Considering: {}", lg); if (atomStore.contains(lg)) { int atomId = atomStore.get(lg); @@ -167,8 +167,8 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment } } - List bodyPos = new ArrayList<>(); - for (LiteralImpl literal : bodyR) { + List bodyPos = new ArrayList<>(); + for (CoreLiteral literal : bodyR) { if (!literal.isNegated()) { bodyPos.add(literal); } @@ -181,7 +181,7 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment return ret; } - private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { + private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { padDepth += 2; log("Begin UnjustCoverFixed()"); log("Finding unjustified body literals in: {} / {} excluded {}", vB, vY, vN); @@ -199,10 +199,10 @@ private Set unjustCover(List vB, Set vY, Set vYp = new LinkedHashSet<>(); @@ -210,7 +210,7 @@ private Set unjustCover(List vB, Set vY, Set unjustCover(List vB, Set vY, Set unjustCover(List vB, Set vY, Set occurringVariables = new ArrayList<>(variablesOccurringInSigma); occurringVariables.addAll(sigmaN.getMappedVariables()); - BasicAtom genericAtom = new BasicAtom(PredicateImpl.getInstance("_", occurringVariables.size(), true), occurringVariables); - AtomImpl genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); + BasicAtom genericAtom = new BasicAtom(CorePredicate.getInstance("_", occurringVariables.size(), true), occurringVariables); + CoreAtom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); if (Unification.instantiate(genericSubstituted, genericAtom.substitute(sigma)) != null) { log("Atom {} is excluded by: {} via {}", genericSubstituted, sigmaN, sigma); continue atomLoop; @@ -259,7 +259,7 @@ private Set unjustCover(List vB, Set vY, Set newB = new ArrayList<>(vB); + ArrayList newB = new ArrayList<>(vB); newB.remove(chosenLiteralPos); ret.addAll(unjustCover(newB, vYp, vN, currentAssignment)); log("Literal set(s) to treat: {}", ret); @@ -278,20 +278,20 @@ private String pad(String string) { return sb.toString(); } - private AssignedAtomsIterator getAssignedAtomsOverPredicate(PredicateImpl predicate) { + private AssignedAtomsIterator getAssignedAtomsOverPredicate(CorePredicate predicate) { // Find more substitutions, consider currentAssignment. - List assignedAtoms = this.assignedAtoms.get(predicate); + List assignedAtoms = this.assignedAtoms.get(predicate); // Consider instances from facts. LinkedHashSet factsOverPredicate = factsFromProgram.get(predicate); return new AssignedAtomsIterator(predicate, assignedAtoms, factsOverPredicate); } - private static class AssignedAtomsIterator implements Iterator { - private final PredicateImpl predicate; - private final Iterator assignedAtomsIterator; + private static class AssignedAtomsIterator implements Iterator { + private final CorePredicate predicate; + private final Iterator assignedAtomsIterator; private final Iterator factsIterator; - public AssignedAtomsIterator(PredicateImpl predicate, List assignedAtoms, Set facts) { + public AssignedAtomsIterator(CorePredicate predicate, List assignedAtoms, Set facts) { this.predicate = predicate; this.assignedAtomsIterator = assignedAtoms == null ? Collections.emptyIterator() : assignedAtoms.iterator(); this.factsIterator = facts == null ? Collections.emptyIterator() : facts.iterator(); @@ -303,7 +303,7 @@ public boolean hasNext() { } @Override - public AtomImpl next() { + public CoreAtom next() { if (assignedAtomsIterator.hasNext()) { return assignedAtomsIterator.next(); } @@ -314,10 +314,10 @@ public AtomImpl next() { } } - private List rulesHeadUnifyingWith(AtomImpl p) { + private List rulesHeadUnifyingWith(CoreAtom p) { List rulesWithUnifier = new ArrayList<>(); - PredicateImpl predicate = p.getPredicate(); + CorePredicate predicate = p.getPredicate(); ArrayList definingRulesAndFacts = new ArrayList<>(); // Get facts over the same predicate. @@ -336,8 +336,8 @@ private List rulesHeadUnifyingWith(AtomImpl p) { } for (FactOrNonGroundRule factOrNonGroundRule : definingRulesAndFacts) { boolean isNonGroundRule = factOrNonGroundRule.nonGroundRule != null; - Set renamedBody; - AtomImpl headAtom; + Set renamedBody; + CoreAtom headAtom; if (isNonGroundRule) { // First rename all variables in the rule. InternalRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++); @@ -375,11 +375,11 @@ private static class ReturnExplainUnjust { } private static class RuleAndUnifier { - final Set ruleBody; + final Set ruleBody; final Unifier unifier; - final AtomImpl originalHead; + final CoreAtom originalHead; - private RuleAndUnifier(Set ruleBody, Unifier unifier, AtomImpl originalHead) { + private RuleAndUnifier(Set ruleBody, Unifier unifier, CoreAtom originalHead) { this.ruleBody = ruleBody; this.unifier = unifier; this.originalHead = originalHead; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java index 24de12007..4cc542a8b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.grounder.structure; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; import at.ac.tuwien.kr.alpha.grounder.Unifier; import at.ac.tuwien.kr.alpha.grounder.Unification; @@ -17,14 +17,14 @@ * Copyright (c) 2018, the Alpha Team. */ public class LitSet { - private final AtomImpl atom; + private final CoreAtom atom; private final Set complementSubstitutions; private final int hashCode; - private final AtomImpl normalizedLiteral; + private final CoreAtom normalizedLiteral; private final Set normalizedSubstitutions; private static int litSetCounter = 1; - LitSet(AtomImpl atom, Set complementSubstitutions) { + LitSet(CoreAtom atom, Set complementSubstitutions) { this.atom = atom.renameVariables("_AS" + litSetCounter++); this.complementSubstitutions = new HashSet<>(); for (Unifier complementSubstitution : complementSubstitutions) { @@ -49,8 +49,8 @@ public class LitSet { * @param normalizedAtom * @return */ - private Unifier normalizeSubstitution(AtomImpl originalAtom, Unifier substitution, AtomImpl normalizedAtom) { - AtomImpl substitutedLiteral = originalAtom.substitute(substitution); + private Unifier normalizeSubstitution(CoreAtom originalAtom, Unifier substitution, CoreAtom normalizedAtom) { + CoreAtom substitutedLiteral = originalAtom.substitute(substitution); return Unification.instantiate(normalizedAtom, substitutedLiteral); } @@ -67,7 +67,7 @@ public boolean coversNothing() { return false; } - public AtomImpl getAtom() { + public CoreAtom getAtom() { return atom; } @@ -119,7 +119,7 @@ private int computeHashCode() { return result; } - private AtomImpl computeNormalized(Atom atom, String prefix) { + private CoreAtom computeNormalized(Atom atom, String prefix) { if (atom instanceof VariableNormalizableAtom) { return ((VariableNormalizableAtom) atom).normalizeVariables(prefix, 0); } else { @@ -134,7 +134,7 @@ private Set computeNormalizedSubstitutions() { // Unifier may still contain variables in the right-hand side, those have to be normalized, too. Atom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); // Apply substitution and normalize all remaining variables, i.e., those appearing at the right-hand side of the substitution. - AtomImpl normalized = computeNormalized(appliedSub, "_X"); + CoreAtom normalized = computeNormalized(appliedSub, "_X"); // Compute final substitution from normalized atom to the one where also variables are normalized. Unifier normalizedSubstitution = new Unifier(Unification.instantiate(normalizedLiteral, normalized)); ret.add(normalizedSubstitution); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java index f58a09fad..f6181822f 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java @@ -1,25 +1,31 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; + import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import at.ac.tuwien.kr.alpha.grounder.Unifier; import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; - /** * Copyright (c) 2017-2020, the Alpha Team. */ @@ -98,7 +104,7 @@ public InputProgram apply(InputProgram inputProgram) { BasicRule tmpEnumRule = PredicateInternalizer.makePredicatesInternal(parse( "sorting_network_input_number(A, I) :- sorting_network_input(A, X).")).getRules().get(0); EnumerationAtom enumerationAtom = new EnumerationAtom(parse("sorting_network_index(A, X, I).").getFacts().get(0).getTerms()); - List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); + List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); enumerationRuleBody.add(enumerationAtom.toLiteral()); BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); programBuilder.addRule(enumerationRule); @@ -116,7 +122,7 @@ public InputProgram apply(InputProgram inputProgram) { */ private boolean rewritingNecessary(InputProgram program) { for (BasicRule rule : program.getRules()) { - for (Literal lit : rule.getBody()) { + for (CoreLiteral lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.COUNT) { @@ -152,14 +158,14 @@ private List rewriteAggregatesInRule(BasicRule rule) { final BasicAtom lowerBoundAtom = (BasicAtom) PredicateInternalizer .makePredicatesInternal(parse("sorting_network_bound(aggregate_arguments(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - ArrayList aggregateOutputAtoms = new ArrayList<>(); + ArrayList aggregateOutputAtoms = new ArrayList<>(); int aggregatesInRule = 0; // Only needed for limited rewriting. ArrayList additionalRules = new ArrayList<>(); - List rewrittenBody = new ArrayList<>(rule.getBody()); + List rewrittenBody = new ArrayList<>(rule.getBody()); - for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { - Literal bodyElement = iterator.next(); + for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { + CoreLiteral bodyElement = iterator.next(); // Skip non-aggregates. if (!(bodyElement instanceof AggregateLiteral)) { continue; @@ -210,7 +216,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementSubstitution); - List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); + List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); // If there are global variables used inside the aggregate, add original rule body // (minus the aggregate itself) to input rule. @@ -223,7 +229,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create lower bound for the aggregate. BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateSubstitution); - List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. + List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); } @@ -233,11 +239,11 @@ private List rewriteAggregatesInRule(BasicRule rule) { return additionalRules; } - static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { + static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { // Hacky way to get all global variables: take all variables inside the aggregate that occur also in the // rest of the rule. HashSet occurringVariables = new LinkedHashSet<>(); - for (Literal element : ruleBody) { + for (CoreLiteral element : ruleBody) { if (element instanceof AggregateLiteral) { continue; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java index 50bf0b9a0..48a5330ed 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; @@ -76,8 +76,8 @@ public InputProgram apply(InputProgram inputProgram) { // Create two guessing rules for each choiceElement. // Construct common body to both rules. - AtomImpl head = choiceElement.choiceAtom; - List ruleBody = new ArrayList<>(rule.getBody()); + CoreAtom head = choiceElement.choiceAtom; + List ruleBody = new ArrayList<>(rule.getBody()); ruleBody.addAll(choiceElement.conditionLiterals); if (containsIntervalTerms(head)) { @@ -85,20 +85,20 @@ public InputProgram apply(InputProgram inputProgram) { } // Construct head atom for the choice. - PredicateImpl headPredicate = head.getPredicate(); + CorePredicate headPredicate = head.getPredicate(); - PredicateImpl negPredicate = PredicateImpl.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); + CorePredicate negPredicate = CorePredicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); List headTerms = new ArrayList<>(head.getTerms()); headTerms.add(0, ConstantTermImpl.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for // classical negative atoms. - AtomImpl negHead = new BasicAtom(negPredicate, headTerms); + CoreAtom negHead = new BasicAtom(negPredicate, headTerms); // Construct two guessing rules. - List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); + List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); guessingRuleBodyWithNegHead.add(new BasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); additionalRules.add(new BasicRule(new NormalHead(negHead), guessingRuleBodyWithNegHead)); - List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); + List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); guessingRuleBodyWithHead.add(new BasicAtom(negPredicate, headTerms).toLiteral(false)); additionalRules.add(new BasicRule(new NormalHead(head), guessingRuleBodyWithHead)); @@ -109,7 +109,7 @@ public InputProgram apply(InputProgram inputProgram) { .addInlineDirectives(inputProgram.getInlineDirectives()).build(); } - private static boolean containsIntervalTerms(Atom atom) { + private static boolean containsIntervalTerms(CoreAtom atom) { for (Term term : atom.getTerms()) { if (IntervalTerm.termContainsIntervalTerm(term)) { return true; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java index e65dc928c..54b78535c 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java @@ -1,21 +1,21 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; +import static at.ac.tuwien.kr.alpha.Util.oops; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import static at.ac.tuwien.kr.alpha.Util.oops; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; /** * Rewrites the ordinary atom whose name is given in the input program by the enumeration directive #enum_atom_is into @@ -33,7 +33,7 @@ public InputProgram apply(InputProgram inputProgram) { // Directive not set, nothing to rewrite. return inputProgram; } - PredicateImpl enumPredicate = PredicateImpl.getInstance(enumDirective, 3); + CorePredicate enumPredicate = CorePredicate.getInstance(enumDirective, 3); InputProgram.Builder programBuilder = InputProgram.builder().addInlineDirectives(inputProgram.getInlineDirectives()); @@ -45,15 +45,15 @@ public InputProgram apply(InputProgram inputProgram) { return programBuilder.build(); } - private void checkFactsAreEnumerationFree(List srcFacts, PredicateImpl enumPredicate) { - for (Atom fact : srcFacts) { + private void checkFactsAreEnumerationFree(List srcFacts, CorePredicate enumPredicate) { + for (CoreAtom fact : srcFacts) { if (fact.getPredicate().equals(enumPredicate)) { throw oops("Atom declared as enumeration atom by directive occurs in a fact: " + fact); } } } - private List rewriteRules(List srcRules, PredicateImpl enumPredicate) { + private List rewriteRules(List srcRules, CorePredicate enumPredicate) { List rewrittenRules = new ArrayList<>(); for (BasicRule rule : srcRules) { if (rule.getHead() != null && !(rule.getHead() instanceof NormalHead)) { @@ -62,11 +62,11 @@ private List rewriteRules(List srcRules, PredicateImpl enu 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()); - Iterator rit = modifiedBodyLiterals.iterator(); - LinkedList rewrittenLiterals = new LinkedList<>(); + List modifiedBodyLiterals = new ArrayList<>(rule.getBody()); + Iterator rit = modifiedBodyLiterals.iterator(); + LinkedList rewrittenLiterals = new LinkedList<>(); while (rit.hasNext()) { - Literal literal = rit.next(); + CoreLiteral literal = rit.next(); if (!(literal instanceof BasicLiteral)) { continue; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java index 9a185316e..4aefc6db1 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java @@ -28,9 +28,9 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.LiteralImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.program.NormalProgram; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; @@ -59,9 +59,9 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { // Collect all intervals and replace them with variables. Map intervalReplacements = new LinkedHashMap<>(); - List rewrittenBody = new ArrayList<>(); + List rewrittenBody = new ArrayList<>(); - for (LiteralImpl literal : rule.getBody()) { + for (CoreLiteral literal : rule.getBody()) { rewrittenBody.add(rewriteLiteral(literal, intervalReplacements)); } NormalHead rewrittenHead = rule.isConstraint() ? null : @@ -82,8 +82,8 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { /** * Replaces every IntervalTerm by a new variable and returns a mapping of the replaced VariableTerm -> IntervalTerm. */ - private static LiteralImpl rewriteLiteral(LiteralImpl lit, Map intervalReplacement) { - AtomImpl atom = lit.getAtom(); + private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { + CoreAtom atom = lit.getAtom(); List termList = new ArrayList<>(atom.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { @@ -102,7 +102,7 @@ private static LiteralImpl rewriteLiteral(LiteralImpl lit, Map newBody = new ArrayList<>(); - for (LiteralImpl bodyElement : rule.getBody()) { + List newBody = new ArrayList<>(); + for (CoreLiteral bodyElement : rule.getBody()) { // Only rewrite BasicAtoms. if (bodyElement instanceof BasicLiteral) { newBody.add(makePredicateInternal(bodyElement.getAtom()).toLiteral()); @@ -52,8 +52,8 @@ private static BasicRule makePredicateInternal(BasicRule rule) { return new BasicRule(newHead, newBody); } - private static AtomImpl makePredicateInternal(AtomImpl atom) { - PredicateImpl newInternalPredicate = PredicateImpl.getInstance(atom.getPredicate().getName(), atom.getPredicate().getArity(), true); + private static CoreAtom makePredicateInternal(CoreAtom atom) { + CorePredicate newInternalPredicate = CorePredicate.getInstance(atom.getPredicate().getName(), atom.getPredicate().getArity(), true); return new BasicAtom(newInternalPredicate, atom.getTerms()); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java index 71e25e96a..a9d66cb6b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.PredicateImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; @@ -47,9 +47,9 @@ public class StratifiedEvaluation extends ProgramTransformation> predicateDefiningRules; + private Map> predicateDefiningRules; - private Map> modifiedInLastEvaluationRun = new HashMap<>(); + private Map> modifiedInLastEvaluationRun = new HashMap<>(); private List additionalFacts = new ArrayList<>(); // 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. @@ -66,15 +66,15 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { predicateDefiningRules = inputProgram.getPredicateDefiningRules(); // Set up list of atoms which are known to be true - these will be expand by the evaluation. - Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); - for (Map.Entry> entry : knownFacts.entrySet()) { + Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); + for (Map.Entry> entry : knownFacts.entrySet()) { workingMemory.initialize(entry.getKey()); workingMemory.addInstances(entry.getKey(), true, entry.getValue()); } // Create working memories for all predicates occurring in each rule. for (InternalRule nonGroundRule : inputProgram.getRulesById().values()) { - for (PredicateImpl predicate : nonGroundRule.getOccurringPredicates()) { + for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { workingMemory.initialize(predicate); } } @@ -165,7 +165,7 @@ private void prepareInitialEvaluation(Set rulesToEvaluate) { modifiedInLastEvaluationRun = new HashMap<>(); for (InternalRule rule : rulesToEvaluate) { // Register rule head instances. - PredicateImpl headPredicate = rule.getHeadAtom().getPredicate(); + CorePredicate headPredicate = rule.getHeadAtom().getPredicate(); IndexedInstanceStorage headInstances = workingMemory.get(headPredicate, true); modifiedInLastEvaluationRun.putIfAbsent(headPredicate, new LinkedHashSet<>()); if (headInstances != null) { @@ -173,7 +173,7 @@ private void prepareInitialEvaluation(Set rulesToEvaluate) { } // Register positive body literal instances. for (Literal lit : rule.getPositiveBody()) { - PredicateImpl bodyPredicate = lit.getPredicate(); + CorePredicate bodyPredicate = lit.getPredicate(); IndexedInstanceStorage bodyInstances = workingMemory.get(bodyPredicate, true); modifiedInLastEvaluationRun.putIfAbsent(bodyPredicate, new LinkedHashSet<>()); if (bodyInstances != null) { @@ -309,13 +309,13 @@ private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { Set recursiveRules = new HashSet<>(); // Collect all predicates occurring in heads of rules of the given component. - Set headPredicates = new HashSet<>(); + Set headPredicates = new HashSet<>(); for (Node node : comp.getNodes()) { headPredicates.add(node.getPredicate()); } // Check each predicate whether its defining rules depend on some of the head predicates, i.e., whether there is a // cycle. - for (PredicateImpl headPredicate : headPredicates) { + for (CorePredicate headPredicate : headPredicates) { HashSet definingRules = predicateDefiningRules.get(headPredicate); if (definingRules == null) { // Predicate only occurs in facts, skip. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java index 17d9957cf..ff1c13b37 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java @@ -106,7 +106,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { return rule; } - List rewrittenBody = new ArrayList<>(rule.getBody()); + List rewrittenBody = new ArrayList<>(rule.getBody()); NormalHead rewrittenHead = rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()); // Use substitution for actual replacement. @@ -121,9 +121,9 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { replacementSubstitution.put(variableToReplace, replacementVariable); } // Replace/Substitute in each literal every term where one of the common variables occurs. - Iterator bodyIterator = rewrittenBody.iterator(); + Iterator bodyIterator = rewrittenBody.iterator(); while (bodyIterator.hasNext()) { - LiteralImpl literal = bodyIterator.next(); + CoreLiteral literal = bodyIterator.next(); if (equalitiesToRemove.contains(literal)) { bodyIterator.remove(); } @@ -134,7 +134,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { } // Replace variables in head. if (rewrittenHead != null) { - AtomImpl headAtom = rewrittenHead.getAtom(); + CoreAtom headAtom = rewrittenHead.getAtom(); for (int i = 0; i < headAtom.getTerms().size(); i++) { TermImpl replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); headAtom.getTerms().set(i, replaced); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java index 05dd90522..3ff48ed66 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java @@ -26,7 +26,7 @@ package at.ac.tuwien.kr.alpha.solver; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.AtomImpl; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import java.util.ArrayList; import java.util.Collections; @@ -35,7 +35,7 @@ import java.util.Map; /** - * Counts the number of ground atoms stored for each type (i.e., subclass of {@link AtomImpl}. + * Counts the number of ground atoms stored for each type (i.e., subclass of {@link CoreAtom}. * For every atom, only the counter for one class (the most specific one) is incremented, * not the counters for more general classes of which the atom is also an instance. */ @@ -43,7 +43,7 @@ public class AtomCounter { private final Map, Integer> countByType = new HashMap<>(); - public void add(AtomImpl atom) { + public void add(CoreAtom atom) { countByType.compute(atom.getClass(), (k, v) -> (v == null) ? 1 : v + 1); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java index 20b5e332a..7873ab386 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java @@ -370,8 +370,8 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { String substitution = (String) ((ConstantTermImpl)atom.getTerms().get(1)).getObject(); Substitution groundingSubstitution = Substitution.fromString(substitution); // Find ground literals in the body that have been assigned false and justify those. - for (LiteralImpl bodyLiteral : nonGroundRule.getBody()) { - AtomImpl groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); + for (CoreLiteral bodyLiteral : nonGroundRule.getBody()) { + CoreAtom groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); if (groundAtom instanceof ComparisonAtom || analyzingGrounder.isFact(groundAtom)) { // Facts and ComparisonAtoms are always true, no justification needed. continue; From af4d78c88ad13c5073c32b42ad81d42140e85138 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 18 Dec 2020 15:56:37 +0100 Subject: [PATCH 008/111] WIP: let core components only depend on core API (not dependent on public API) --- .../kr/alpha/api/externals/Externals.java | 4 +- .../kr/alpha/common/AnswerSetBuilder.java | 10 ++-- .../kr/alpha/common/atoms/AggregateAtom.java | 39 ++++++------ .../alpha/common/atoms/AggregateLiteral.java | 10 ++-- .../kr/alpha/common/atoms/BasicAtom.java | 23 ++++--- .../kr/alpha/common/atoms/BasicLiteral.java | 6 +- .../kr/alpha/common/atoms/ComparisonAtom.java | 16 ++--- .../alpha/common/atoms/ComparisonLiteral.java | 54 +++++++++-------- .../kr/alpha/common/atoms/CoreAtom.java | 11 ++-- .../kr/alpha/common/atoms/CoreLiteral.java | 4 +- .../kr/alpha/common/atoms/ExternalAtom.java | 28 ++++----- .../alpha/common/atoms/ExternalLiteral.java | 34 +++++------ .../alpha/common/program/AbstractProgram.java | 6 +- .../kr/alpha/common/terms/ArithmeticTerm.java | 46 +++++++------- ...antTermImpl.java => CoreConstantTerm.java} | 30 +++++----- .../terms/{TermImpl.java => CoreTerm.java} | 22 +++---- .../kr/alpha/common/terms/FunctionTerm.java | 34 +++++------ .../kr/alpha/common/terms/IntervalTerm.java | 20 +++---- .../tuwien/kr/alpha/common/terms/Terms.java | 10 ++-- .../kr/alpha/common/terms/VariableTerm.java | 12 ++-- .../alpha/grounder/FactIntervalEvaluator.java | 12 ++-- .../grounder/IndexedInstanceStorage.java | 16 ++--- .../ac/tuwien/kr/alpha/grounder/Instance.java | 9 ++- .../kr/alpha/grounder/NaiveGrounder.java | 60 +++++++++++++------ .../grounder/ProgramAnalyzingGrounder.java | 12 ++-- .../kr/alpha/grounder/Substitution.java | 27 ++++----- .../tuwien/kr/alpha/grounder/Unification.java | 16 ++--- .../ac/tuwien/kr/alpha/grounder/Unifier.java | 21 ++++--- .../kr/alpha/grounder/atoms/ChoiceAtom.java | 15 +++-- .../alpha/grounder/atoms/EnumerationAtom.java | 18 +++--- .../grounder/atoms/EnumerationLiteral.java | 14 ++--- .../kr/alpha/grounder/atoms/IntervalAtom.java | 16 +++-- .../alpha/grounder/atoms/IntervalLiteral.java | 28 +++++---- .../kr/alpha/grounder/atoms/RuleAtom.java | 25 ++++---- .../grounder/parser/ParseTreeVisitor.java | 44 +++++++------- .../grounder/parser/ProgramPartParser.java | 6 +- .../structure/AnalyzeUnjustified.java | 12 ++-- .../kr/alpha/grounder/structure/LitSet.java | 15 +++-- .../CardinalityNormalization.java | 24 ++++---- .../transformation/ChoiceHeadToNormal.java | 6 +- .../IntervalTermToIntervalAtom.java | 25 ++++---- .../transformation/PredicateInternalizer.java | 12 ++-- .../transformation/StratifiedEvaluation.java | 53 ++++++++-------- .../transformation/SumNormalization.java | 46 +++++++------- .../VariableEqualityRemoval.java | 27 +++++---- .../tuwien/kr/alpha/solver/AtomCounter.java | 4 +- .../tuwien/kr/alpha/solver/DefaultSolver.java | 28 +++++---- 47 files changed, 519 insertions(+), 491 deletions(-) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/{ConstantTermImpl.java => CoreConstantTerm.java} (75%) rename core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/{TermImpl.java => CoreTerm.java} (81%) diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java index 028414986..0bb017067 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java @@ -30,7 +30,7 @@ import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.*; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import org.reflections.Reflections; import org.reflections.scanners.MethodAnnotationsScanner; @@ -135,7 +135,7 @@ public static > List asFacts(Class classOfExtFa String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. for (T instance : extFacts) { // TODO use properly wrapped BasicAtoms here - retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.CorePredicate.getInstance(name, 1), ConstantTermImpl.getInstance(instance))); + retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.CorePredicate.getInstance(name, 1), CoreConstantTerm.getInstance(instance))); } return retVal; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java index cd43eb146..e7c091951 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java @@ -3,9 +3,9 @@ import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import java.util.*; import java.util.stream.Collectors; @@ -71,9 +71,9 @@ public final > AnswerSetBuilder instance(final T... term // Note that usage of terms does not pollute the heap, // since we are only reading, not writing. - List termList = Stream + List termList = Stream .of(terms) - .map(ConstantTermImpl::getInstance) + .map(CoreConstantTerm::getInstance) .collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); @@ -87,7 +87,7 @@ public AnswerSetBuilder symbolicInstance(String... terms) { predicates.add(predicate); } - List termList = Stream.of(terms).map(ConstantTermImpl::getSymbolicInstance).collect(Collectors.toList()); + List termList = Stream.of(terms).map(CoreConstantTerm::getSymbolicInstance).collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); return this; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java index 17fe8b7ba..f37e0acc8 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java @@ -27,30 +27,29 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import static at.ac.tuwien.kr.alpha.Util.join; +import static at.ac.tuwien.kr.alpha.Util.oops; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import static at.ac.tuwien.kr.alpha.Util.join; -import static at.ac.tuwien.kr.alpha.Util.oops; +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; public class AggregateAtom extends CoreAtom { private final ComparisonOperator lowerBoundOperator; - private final TermImpl lowerBoundTerm; + private final CoreTerm lowerBoundTerm; private final ComparisonOperator upperBoundOperator; - private final Term upperBoundTerm; + private final CoreTerm upperBoundTerm; private final AGGREGATEFUNCTION aggregatefunction; private final List aggregateElements; - public AggregateAtom(ComparisonOperator lowerBoundOperator, TermImpl lowerBoundTerm, ComparisonOperator upperBoundOperator, Term upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { + public AggregateAtom(ComparisonOperator lowerBoundOperator, CoreTerm lowerBoundTerm, ComparisonOperator upperBoundOperator, CoreTerm upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { this.lowerBoundOperator = lowerBoundOperator; this.lowerBoundTerm = lowerBoundTerm; this.upperBoundOperator = upperBoundOperator; @@ -83,12 +82,12 @@ public AggregateLiteral toLiteral(boolean positive) { } @Override - public List getTerms() { + public List getTerms() { throw oops("Aggregate atom cannot report terms."); } @Override - public CoreAtom withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for aggregate atoms!"); } @@ -165,7 +164,7 @@ public ComparisonOperator getLowerBoundOperator() { return lowerBoundOperator; } - public TermImpl getLowerBoundTerm() { + public CoreTerm getLowerBoundTerm() { return lowerBoundTerm; } @@ -173,7 +172,7 @@ public ComparisonOperator getUpperBoundOperator() { return upperBoundOperator; } - public Term getUpperBoundTerm() { + public CoreTerm getUpperBoundTerm() { return upperBoundTerm; } @@ -193,15 +192,15 @@ public enum AGGREGATEFUNCTION { } public static class AggregateElement { - final List elementTerms; + final List elementTerms; final List elementLiterals; - public AggregateElement(List elementTerms, List elementLiterals) { + public AggregateElement(List elementTerms, List elementLiterals) { this.elementTerms = elementTerms; this.elementLiterals = elementLiterals; } - public List getElementTerms() { + public List getElementTerms() { return elementTerms; } @@ -210,7 +209,7 @@ public List getElementLiterals() { } public boolean isGround() { - for (Term elementTerm : elementTerms) { + for (CoreTerm elementTerm : elementTerms) { if (!elementTerm.isGround()) { return false; } @@ -225,7 +224,7 @@ public boolean isGround() { public List getOccurringVariables() { List occurringVariables = new LinkedList<>(); - for (Term term : elementTerms) { + for (CoreTerm term : elementTerms) { if (term instanceof VariableTerm) { occurringVariables.add((VariableTerm) term); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java index 594eb7e49..a2d6123cc 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java @@ -1,13 +1,13 @@ package at.ac.tuwien.kr.alpha.common.atoms; +import java.util.HashSet; +import java.util.Set; + import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; -import java.util.HashSet; -import java.util.Set; - /** * Copyright (c) 2018, the Alpha Team. */ @@ -53,7 +53,7 @@ public Set getNonBindingVariables() { throw new UnsupportedOperationException(); } - private static VariableTerm boundBindingVariable(ComparisonOperator op, Term bound, boolean positive) { + private static VariableTerm boundBindingVariable(ComparisonOperator op, CoreTerm bound, boolean positive) { boolean isNormalizedEquality = op == ComparisonOperator.EQ && positive || op == ComparisonOperator.NE && !positive; if (isNormalizedEquality && bound instanceof VariableTerm) { return (VariableTerm) bound; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java index dc3b4f40a..746abc051 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java @@ -27,24 +27,23 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import static at.ac.tuwien.kr.alpha.Util.join; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import static at.ac.tuwien.kr.alpha.Util.join; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; /** * Represents ordinary ASP atoms. */ public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { private final CorePredicate predicate; - private final List terms; + private final List terms; private final boolean ground; /** @@ -53,12 +52,12 @@ public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { * @param predicate * @param terms */ - public BasicAtom(CorePredicate predicate, List terms) { + public BasicAtom(CorePredicate predicate, List terms) { this.predicate = predicate; this.terms = terms; boolean ground = true; - for (Term term : terms) { + for (CoreTerm term : terms) { if (!term.isGround()) { ground = false; break; @@ -68,7 +67,7 @@ public BasicAtom(CorePredicate predicate, List terms) { this.ground = ground; } - public BasicAtom(CorePredicate predicate, TermImpl... terms) { + public BasicAtom(CorePredicate predicate, CoreTerm... terms) { this(predicate, Arrays.asList(terms)); } @@ -82,7 +81,7 @@ public CorePredicate getPredicate() { } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -100,7 +99,7 @@ public BasicAtom substitute(Substitution substitution) { @Override public BasicAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = TermImpl.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); return new BasicAtom(predicate, renamedTerms); } @@ -161,7 +160,7 @@ public int hashCode() { } @Override - public CoreAtom withTerms(List terms) { + public CoreAtom withTerms(List terms) { return new BasicAtom(predicate, terms); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java index f65d03c5e..173e9befc 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; @@ -79,7 +79,7 @@ public Set getBindingVariables() { return Collections.emptySet(); } Set bindingVariables = new HashSet<>(); - for (TermImpl term : atom.getTerms()) { + for (CoreTerm term : atom.getTerms()) { bindingVariables.addAll(term.getOccurringVariables()); } return bindingVariables; @@ -97,7 +97,7 @@ public Set getNonBindingVariables() { return Collections.emptySet(); } Set nonbindingVariables = new HashSet<>(); - for (TermImpl term : atom.getTerms()) { + for (CoreTerm term : atom.getTerms()) { nonbindingVariables.addAll(term.getOccurringVariables()); } return nonbindingVariables; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java index 4a0b2cec6..c94b8e231 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java @@ -30,7 +30,7 @@ import at.ac.tuwien.kr.alpha.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import java.util.Arrays; @@ -43,15 +43,15 @@ public class ComparisonAtom extends CoreAtom implements VariableNormalizableAtom { private final CorePredicate predicate; final ComparisonOperator operator; - private final List terms; + private final List terms; - private ComparisonAtom(List terms, ComparisonOperator operator) { + private ComparisonAtom(List terms, ComparisonOperator operator) { this.terms = terms; this.operator = operator; this.predicate = operator.predicate(); } - public ComparisonAtom(TermImpl term1, TermImpl term2, ComparisonOperator operator) { + public ComparisonAtom(CoreTerm term1, CoreTerm term2, ComparisonOperator operator) { this(Arrays.asList(term1, term2), operator); } @@ -61,7 +61,7 @@ public CorePredicate getPredicate() { } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -72,7 +72,7 @@ public boolean isGround() { @Override public ComparisonAtom substitute(Substitution substitution) { - List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); + List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); return new ComparisonAtom(substitutedTerms, operator); } @@ -116,12 +116,12 @@ public int hashCode() { @Override public ComparisonAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = TermImpl.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); return new ComparisonAtom(renamedTerms.get(0), renamedTerms.get(1), operator); } @Override - public CoreAtom withTerms(List terms) { + public CoreAtom withTerms(List terms) { return new ComparisonAtom(terms, operator); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java index edb3655e7..836cd21be 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java @@ -27,14 +27,20 @@ */ package at.ac.tuwien.kr.alpha.common.atoms; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.*; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import static at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm.evaluateGroundTerm; -import java.util.*; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; -import static at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm.evaluateGroundTerm; +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; /** * Contains a potentially negated {@link ComparisonAtom}. @@ -74,14 +80,14 @@ public ComparisonLiteral substitute(Substitution substitution) { return new ComparisonLiteral(getAtom().substitute(substitution), positive); } - private boolean assignable(Term term) { + private boolean assignable(CoreTerm term) { return isNormalizedEquality && term instanceof VariableTerm; } @Override public Set getBindingVariables() { - final Term left = getTerms().get(0); - final Term right = getTerms().get(1); + final CoreTerm left = getTerms().get(0); + final CoreTerm right = getTerms().get(1); if (assignable(left) && assignable(right)) { // In case this is "X = Y" or "not X != Y" then both sides are binding given that the other is. // In this case non-binding and binding variables cannot be reported accurately, in fact, the double variable could be compiled away. @@ -98,8 +104,8 @@ public Set getBindingVariables() { @Override public Set getNonBindingVariables() { - final TermImpl left = getTerms().get(0); - final TermImpl right = getTerms().get(1); + final CoreTerm left = getTerms().get(0); + final CoreTerm right = getTerms().get(1); HashSet occurringVariables = new HashSet<>(); List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); @@ -121,17 +127,17 @@ public Set getNonBindingVariables() { @Override public List getSatisfyingSubstitutions(Substitution partialSubstitution) { // Treat case where this is just comparison with all variables bound by partialSubstitution. - final TermImpl left = getAtom().getTerms().get(0).substitute(partialSubstitution); - final TermImpl right = getAtom().getTerms().get(1).substitute(partialSubstitution); + final CoreTerm left = getAtom().getTerms().get(0).substitute(partialSubstitution); + final CoreTerm right = getAtom().getTerms().get(1).substitute(partialSubstitution); final boolean leftAssigning = assignable(left); final boolean rightAssigning = assignable(right); if (!leftAssigning && !rightAssigning) { // No assignment (variables are bound by partialSubstitution), thus evaluate comparison only. - TermImpl leftEvaluatedSubstitute = evaluateTerm(left); + CoreTerm leftEvaluatedSubstitute = evaluateTerm(left); if (leftEvaluatedSubstitute == null) { return Collections.emptyList(); } - Term rightEvaluatedSubstitute = evaluateTerm(right); + CoreTerm rightEvaluatedSubstitute = evaluateTerm(right); if (rightEvaluatedSubstitute == null) { return Collections.emptyList(); } @@ -143,7 +149,7 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit } // Treat case that this is X = t or t = X. VariableTerm variable = null; - TermImpl expression = null; + CoreTerm expression = null; if (leftAssigning) { variable = (VariableTerm) left; expression = right; @@ -152,15 +158,15 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit variable = (VariableTerm) right; expression = left; } - TermImpl groundTerm = expression.substitute(partialSubstitution); - TermImpl resultTerm = null; + CoreTerm groundTerm = expression.substitute(partialSubstitution); + CoreTerm resultTerm = null; // Check if the groundTerm is an arithmetic expression and evaluate it if so. if (groundTerm instanceof ArithmeticTerm) { Integer result = evaluateGroundTerm(groundTerm); if (result == null) { return Collections.emptyList(); } - resultTerm = ConstantTermImpl.getInstance(result); + resultTerm = CoreConstantTerm.getInstance(result); } else { // Ground term is another term (constant, or function term). resultTerm = groundTerm; @@ -171,24 +177,24 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit } public boolean isLeftOrRightAssigning() { - final Term left = getTerms().get(0); - final Term right = getTerms().get(1); + final CoreTerm left = getTerms().get(0); + final CoreTerm right = getTerms().get(1); return isNormalizedEquality && (assignable(left) && right.isGround() || assignable(right) && left.isGround()); } - private TermImpl evaluateTerm(TermImpl term) { + private CoreTerm evaluateTerm(CoreTerm term) { // Evaluate arithmetics. if (term instanceof ArithmeticTerm) { Integer result = ArithmeticTerm.evaluateGroundTerm(term); if (result == null) { return null; } - return ConstantTermImpl.getInstance(result); + return CoreConstantTerm.getInstance(result); } return term; } - private boolean compare(TermImpl x, Term y) { + private boolean compare(CoreTerm x, CoreTerm y) { final int comparisonResult = x.compareTo(y); ComparisonOperator operator = isNegated() ? getAtom().operator.getNegation() : getAtom().operator; switch (operator) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java index 0cb3cb3ea..d8fe2ee7e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java @@ -31,8 +31,7 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import at.ac.tuwien.kr.alpha.grounder.Unifier; @@ -48,7 +47,7 @@ public abstract class CoreAtom implements Comparable{ * @param terms the terms to set. * @return a new Atom with the given terms set. */ - public abstract CoreAtom withTerms(List terms); + public abstract CoreAtom withTerms(List terms); /** * Returns the set of all variables occurring in the Atom. @@ -66,7 +65,7 @@ public Set getOccurringVariables() { */ public abstract CoreAtom substitute(Substitution substitution); - public abstract List getTerms(); + public abstract List getTerms(); public abstract CorePredicate getPredicate(); @@ -101,8 +100,8 @@ public int compareTo(CoreAtom o) { return 1; } - final List aTerms = this.getTerms(); - final List bTerms = o.getTerms(); + final List aTerms = this.getTerms(); + final List bTerms = o.getTerms(); if (aTerms.size() != bTerms.size()) { return Integer.compare(aTerms.size(), bTerms.size()); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java index 55a0a7cfe..b87bafc64 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java @@ -28,7 +28,7 @@ package at.ac.tuwien.kr.alpha.common.atoms; import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import org.apache.commons.collections4.SetUtils; @@ -84,7 +84,7 @@ public CorePredicate getPredicate() { /** * @see CoreAtom#getTerms() */ - public List getTerms() { + public List getTerms() { return atom.getTerms(); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java index 5e02e916e..50a62cf63 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java @@ -30,7 +30,7 @@ import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import java.util.Collections; @@ -41,13 +41,13 @@ public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { - private final List input; - private final List output; + private final List input; + private final List output; protected final CorePredicate predicate; protected final PredicateInterpretation interpretation; - public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { + public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { if (predicate == null) { throw new IllegalArgumentException("predicate must not be null!"); } @@ -79,27 +79,27 @@ public PredicateInterpretation getInterpretation() { return interpretation; } - public List getInput() { + public List getInput() { return Collections.unmodifiableList(input); } - public List getOutput() { + public List getOutput() { return Collections.unmodifiableList(output); } @Override - public List getTerms() { + public List getTerms() { return input; } @Override public boolean isGround() { - for (Term t : input) { + for (CoreTerm t : input) { if (!t.isGround()) { return false; } } - for (Term t : output) { + for (CoreTerm t : output) { if (!t.isGround()) { return false; } @@ -109,8 +109,8 @@ public boolean isGround() { @Override public ExternalAtom 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()); + 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 ExternalAtom(predicate, interpretation, substitutedInput, substitutedOutput); } @@ -132,7 +132,7 @@ public String toString() { } @Override - public CoreAtom withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for external atoms!"); } @@ -172,8 +172,8 @@ public boolean equals(Object obj) { @Override public ExternalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedInput = TermImpl.renameTerms(this.input, prefix + "_IN_", counterStartingValue); - List renamedOutput = TermImpl.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); + List renamedInput = CoreTerm.renameTerms(this.input, prefix + "_IN_", counterStartingValue); + List renamedOutput = CoreTerm.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); return new ExternalAtom(this.predicate, this.interpretation, renamedInput, renamedOutput); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java index bef994f6f..29dfffed6 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java @@ -73,11 +73,11 @@ public Set getBindingVariables() { return Collections.emptySet(); } - List output = getAtom().getOutput(); + List output = getAtom().getOutput(); Set binding = new HashSet<>(output.size()); - for (Term out : output) { + for (CoreTerm out : output) { if (out instanceof VariableTerm) { binding.add((VariableTerm) out); } @@ -88,20 +88,20 @@ public Set getBindingVariables() { @Override public Set getNonBindingVariables() { - List input = getAtom().getInput(); - List output = getAtom().getOutput(); + 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 (TermImpl term : input) { + for (CoreTerm term : input) { nonbindingVariables.addAll(term.getOccurringVariables()); } // If the external atom is negative, then all variables of input and output are // non-binding. if (!positive) { - for (Term out : output) { + for (CoreTerm out : output) { if (out instanceof VariableTerm) { nonbindingVariables.add((VariableTerm) out); } @@ -113,15 +113,15 @@ public Set getNonBindingVariables() { @Override public List getSatisfyingSubstitutions(Substitution partialSubstitution) { - List input = getAtom().getInput(); - List substitutes = new ArrayList<>(input.size()); + List input = getAtom().getInput(); + List substitutes = new ArrayList<>(input.size()); // In preparation for evaluating the external atom, set the input values according // to the partial substitution supplied by the grounder. - for (TermImpl t : input) { + for (CoreTerm t : input) { substitutes.add(t.substitute(partialSubstitution)); } - Set>> results = getAtom().getInterpretation().evaluate(substitutes); + Set>> results = getAtom().getInterpretation().evaluate(substitutes); if (results == null) { throw new NullPointerException("Predicate " + getPredicate().getName() + " returned null. It must return a Set."); } @@ -154,10 +154,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) { - List externalAtomOutTerms = this.getAtom().getOutput(); + 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))) { @@ -176,10 +176,10 @@ private boolean isNegatedLiteralSatisfied(Set>> e 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) { + List externalAtomOutputTerms = this.getAtom().getOutput(); + for (List> bindings : outputs) { if (bindings.size() < externalAtomOutputTerms.size()) { throw new RuntimeException( "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() @@ -188,7 +188,7 @@ private List buildSubstitutionsForOutputs(Substitution partialSubs Substitution ith = new Substitution(partialSubstitution); boolean skip = false; for (int i = 0; i < externalAtomOutputTerms.size(); i++) { - Term out = externalAtomOutputTerms.get(i); + CoreTerm out = externalAtomOutputTerms.get(i); if (out instanceof VariableTerm) { ith.put((VariableTerm) out, bindings.get(i)); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java index 83b1fe45e..0043b5e7b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java @@ -18,10 +18,10 @@ public abstract class AbstractProgram> { private final List rules; - private final List facts; + private final List facts; private final InlineDirectives inlineDirectives; - public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { this.rules = rules; this.facts = facts; this.inlineDirectives = inlineDirectives; @@ -31,7 +31,7 @@ public List getRules() { return Collections.unmodifiableList(rules); } - public List getFacts() { + public List getFacts() { return Collections.unmodifiableList(facts); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java index 3e8786fc0..3c6d525c0 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java @@ -39,23 +39,23 @@ * This class represents an arithmetic expression occurring as a term. * Copyright (c) 2017-2019, the Alpha Team. */ -public class ArithmeticTerm extends TermImpl { +public class ArithmeticTerm extends CoreTerm { private static final Interner INTERNER = new Interner<>(); - protected final TermImpl left; + protected final CoreTerm left; private final ArithmeticOperator arithmeticOperator; - private final TermImpl right; + private final CoreTerm right; - private ArithmeticTerm(TermImpl left, ArithmeticOperator arithmeticOperator, TermImpl right) { + private ArithmeticTerm(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { this.left = left; this.arithmeticOperator = arithmeticOperator; this.right = right; } - public static TermImpl getInstance(TermImpl left, ArithmeticOperator arithmeticOperator, TermImpl right) { + public static CoreTerm getInstance(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { // Evaluate ground arithmetic terms immediately and return result. if (left.isGround() && right.isGround()) { Integer result = new ArithmeticTerm(left, arithmeticOperator, right).evaluateExpression(); - return ConstantTermImpl.getInstance(result); + return CoreConstantTerm.getInstance(result); } return INTERNER.intern(new ArithmeticTerm(left, arithmeticOperator, right)); } @@ -74,35 +74,35 @@ public List getOccurringVariables() { } @Override - public TermImpl substitute(Substitution substitution) { + public CoreTerm substitute(Substitution substitution) { return getInstance(left.substitute(substitution), arithmeticOperator, right.substitute(substitution)); } @Override - public TermImpl renameVariables(String renamePrefix) { + public CoreTerm renameVariables(String renamePrefix) { return getInstance(left.renameVariables(renamePrefix), arithmeticOperator, right.renameVariables(renamePrefix)); } @Override - public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { - TermImpl normalizedLeft = left.normalizeVariables(renamePrefix, counter); - TermImpl normalizedRight = right.normalizeVariables(renamePrefix, counter); + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); + CoreTerm normalizedRight = right.normalizeVariables(renamePrefix, counter); return ArithmeticTerm.getInstance(normalizedLeft, arithmeticOperator, normalizedRight); } - public static Integer evaluateGroundTerm(Term term) { + public static Integer evaluateGroundTerm(CoreTerm term) { if (!term.isGround()) { throw new RuntimeException("Cannot evaluate arithmetic term since it is not ground: " + term); } return evaluateGroundTermHelper(term); } - private static Integer evaluateGroundTermHelper(Term term) { - if (term instanceof ConstantTerm - && ((ConstantTermImpl) term).getObject() instanceof Integer) { + private static Integer evaluateGroundTermHelper(CoreTerm term) { + if (term instanceof CoreConstantTerm + && ((CoreConstantTerm) term).getObject() instanceof Integer) { // Extract integer from the constant. - return (Integer) ((ConstantTermImpl) term).getObject(); + return (Integer) ((CoreConstantTerm) term).getObject(); } else if (term instanceof ArithmeticTerm) { return ((ArithmeticTerm) term).evaluateExpression(); } else { @@ -196,16 +196,16 @@ public Integer eval(Integer left, Integer right) { public static class MinusTerm extends ArithmeticTerm { - private MinusTerm(TermImpl term) { + private MinusTerm(CoreTerm term) { super(term, null, null); } - public static TermImpl getInstance(TermImpl term) { + public static CoreTerm getInstance(CoreTerm term) { // Evaluate ground arithmetic terms immediately and return result. if (term.isGround()) { Integer result = evaluateGroundTermHelper(term) * -1; - return ConstantTermImpl.getInstance(result); + return CoreConstantTerm.getInstance(result); } return INTERNER.intern(new MinusTerm(term)); } @@ -226,18 +226,18 @@ public List getOccurringVariables() { } @Override - public TermImpl substitute(Substitution substitution) { + public CoreTerm substitute(Substitution substitution) { return getInstance(left.substitute(substitution)); } @Override - public TermImpl renameVariables(String renamePrefix) { + public CoreTerm renameVariables(String renamePrefix) { return getInstance(left.renameVariables(renamePrefix)); } @Override - public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { - TermImpl normalizedLeft = left.normalizeVariables(renamePrefix, counter); + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); return MinusTerm.getInstance(normalizedLeft); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTermImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java similarity index 75% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTermImpl.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java index 1f421c2e4..dd64324dc 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTermImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java @@ -9,25 +9,25 @@ /** * Copyright (c) 2016-2020, the Alpha Team. */ -public class ConstantTermImpl> extends TermImpl implements ConstantTerm { - private static final Interner> INTERNER = new Interner<>(); +public class CoreConstantTerm> extends CoreTerm { + private static final Interner> INTERNER = new Interner<>(); private final T object; private final boolean symbolic; - private ConstantTermImpl(T object, boolean symbolic) { + private CoreConstantTerm(T object, boolean symbolic) { this.object = object; this.symbolic = symbolic; } @SuppressWarnings("unchecked") - public static > ConstantTermImpl getInstance(T symbol) { - return (ConstantTermImpl) INTERNER.intern(new ConstantTermImpl<>(symbol, false)); + public static > CoreConstantTerm getInstance(T symbol) { + return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, false)); } @SuppressWarnings("unchecked") - public static > ConstantTermImpl getSymbolicInstance(String symbol) { - return (ConstantTermImpl) INTERNER.intern(new ConstantTermImpl<>(symbol, true)); + public static > CoreConstantTerm getSymbolicInstance(String symbol) { + return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, true)); } @Override @@ -41,7 +41,7 @@ public List getOccurringVariables() { } @Override - public TermImpl substitute(Substitution substitution) { + public CoreTerm substitute(Substitution substitution) { return this; } @@ -67,7 +67,7 @@ public boolean equals(Object o) { return false; } - ConstantTermImpl that = (ConstantTermImpl) o; + CoreConstantTerm that = (CoreConstantTerm) o; if (this.symbolic != that.symbolic) { return false; } @@ -86,7 +86,7 @@ public int hashCode() { * Establishes "priority" for ordering of constant terms depending on the type * of the corresponding object according to ASP-Core-2.03c. */ - private static final int priority(final Class clazz, ConstantTermImpl term) { + private static final int priority(final Class clazz, CoreConstantTerm term) { if (clazz.equals(Integer.class)) { return 1; } else if (clazz.equals(String.class)) { @@ -97,16 +97,16 @@ private static final int priority(final Class clazz, ConstantTermImpl term @Override @SuppressWarnings("unchecked") - public int compareTo(Term o) { + public int compareTo(CoreTerm o) { if (this == o) { return 0; } - if (!(o instanceof ConstantTermImpl)) { + if (!(o instanceof CoreConstantTerm)) { return super.compareTo(o); } - ConstantTermImpl other = (ConstantTermImpl) o; + CoreConstantTerm other = (CoreConstantTerm) o; // We will perform an unchecked cast. // Because of type erasure, we cannot know the exact type @@ -138,13 +138,13 @@ public int compareTo(Term o) { } @Override - public TermImpl renameVariables(String renamePrefix) { + public CoreTerm renameVariables(String renamePrefix) { // Constant contains no variables, hence stays the same. return this; } @Override - public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { return this; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/TermImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java similarity index 81% rename from core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/TermImpl.java rename to core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java index 793016361..7f740aa37 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/TermImpl.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java @@ -31,7 +31,7 @@ * Copyright (c) 2016-2020, the Alpha Team. */ //@formatter:on -public abstract class TermImpl implements Term { +public abstract class CoreTerm implements Comparable { public abstract List getOccurringVariables(); @@ -41,9 +41,9 @@ public abstract class TermImpl implements Term { * @param substitution the variable substitution to apply. * @return the non-substitute term where all variable substitutions have been applied. */ - public abstract TermImpl substitute(Substitution substitution); + public abstract CoreTerm substitute(Substitution substitution); - private static int priority(Term term) { + private static int priority(CoreTerm term) { final Class clazz = term.getClass(); if (clazz.equals(ConstantTerm.class)) { return 1; @@ -56,19 +56,21 @@ private static int priority(Term term) { } @Override - public int compareTo(Term o) { + public int compareTo(CoreTerm o) { return o == null ? 1 : Integer.compare(priority(this), priority(o)); } + public abstract boolean isGround(); + /** * Rename all variables occurring in this Term by prefixing their name. * * @param renamePrefix the name to prefix all occurring variables. * @return the term with all variables renamed. */ - public abstract TermImpl renameVariables(String renamePrefix); + public abstract CoreTerm renameVariables(String renamePrefix); - public abstract TermImpl normalizeVariables(String renamePrefix, RenameCounter counter); + public abstract CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter); public static class RenameCounter { int counter; @@ -80,10 +82,10 @@ public RenameCounter(int startingValue) { } } - public static List renameTerms(List terms, String prefix, int counterStartingValue) { - List renamedTerms = new ArrayList<>(terms.size()); - TermImpl.RenameCounter renameCounter = new TermImpl.RenameCounter(counterStartingValue); - for (TermImpl term : terms) { + public static List renameTerms(List terms, String prefix, int counterStartingValue) { + List renamedTerms = new ArrayList<>(terms.size()); + CoreTerm.RenameCounter renameCounter = new CoreTerm.RenameCounter(counterStartingValue); + for (CoreTerm term : terms) { renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); } return renamedTerms; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java index 6a51c8778..e2529258a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java @@ -10,14 +10,14 @@ /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class FunctionTerm extends TermImpl { +public class FunctionTerm extends CoreTerm { private static final Interner INTERNER = new Interner<>(); private final String symbol; - private final List terms; + private final List terms; private final boolean ground; - private FunctionTerm(String symbol, List terms) { + private FunctionTerm(String symbol, List terms) { if (symbol == null) { throw new IllegalArgumentException(); } @@ -26,7 +26,7 @@ private FunctionTerm(String symbol, List terms) { this.terms = Collections.unmodifiableList(terms); boolean ground = true; - for (Term term : terms) { + for (CoreTerm term : terms) { if (!term.isGround()) { ground = false; break; @@ -35,15 +35,15 @@ private FunctionTerm(String symbol, List terms) { this.ground = ground; } - public static FunctionTerm getInstance(String functionSymbol, List termList) { + public static FunctionTerm getInstance(String functionSymbol, List termList) { return INTERNER.intern(new FunctionTerm(functionSymbol, termList)); } - public static FunctionTerm getInstance(String functionSymbol, TermImpl... terms) { + public static FunctionTerm getInstance(String functionSymbol, CoreTerm... terms) { return getInstance(functionSymbol, Arrays.asList(terms)); } - public List getTerms() { + public List getTerms() { return terms; } @@ -59,7 +59,7 @@ public boolean isGround() { @Override public List getOccurringVariables() { LinkedList vars = new LinkedList<>(); - for (TermImpl term : terms) { + for (CoreTerm term : terms) { vars.addAll(term.getOccurringVariables()); } return vars; @@ -67,8 +67,8 @@ public List getOccurringVariables() { @Override public FunctionTerm substitute(Substitution substitution) { - List groundTermList = new ArrayList<>(terms.size()); - for (TermImpl term : terms) { + List groundTermList = new ArrayList<>(terms.size()); + for (CoreTerm term : terms) { groundTermList.add(term.substitute(substitution)); } return FunctionTerm.getInstance(symbol, groundTermList); @@ -106,7 +106,7 @@ public int hashCode() { } @Override - public int compareTo(Term o) { + public int compareTo(CoreTerm o) { if (this == o) { return 0; } @@ -138,18 +138,18 @@ public int compareTo(Term o) { } @Override - public TermImpl renameVariables(String renamePrefix) { - List renamedTerms = new ArrayList<>(terms.size()); - for (TermImpl term : terms) { + public CoreTerm renameVariables(String renamePrefix) { + List renamedTerms = new ArrayList<>(terms.size()); + for (CoreTerm term : terms) { renamedTerms.add(term.renameVariables(renamePrefix)); } return FunctionTerm.getInstance(symbol, renamedTerms); } @Override - public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { - List normalizedTerms = new ArrayList<>(terms.size()); - for (TermImpl term : terms) { + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + List normalizedTerms = new ArrayList<>(terms.size()); + for (CoreTerm term : terms) { normalizedTerms.add(term.normalizeVariables(renamePrefix, counter)); } return FunctionTerm.getInstance(symbol, normalizedTerms); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java index 2736ebf58..3a801e7a8 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java @@ -13,17 +13,17 @@ * An IntervalTerm is a meta-term and the grounder must replace it with its corresponding set of facts or rules. * Copyright (c) 2017, the Alpha Team. */ -public class IntervalTerm extends TermImpl { +public class IntervalTerm extends CoreTerm { private static final Interner INTERNER = new Interner<>(); - private final TermImpl lowerBoundTerm; - private final TermImpl upperBoundTerm; + private final CoreTerm lowerBoundTerm; + private final CoreTerm upperBoundTerm; private final int lowerBound; private final int upperBound; private final boolean ground; - private IntervalTerm(TermImpl lowerBound, TermImpl upperBound) { + private IntervalTerm(CoreTerm lowerBound, CoreTerm upperBound) { if (lowerBound == null || upperBound == null) { throw new IllegalArgumentException(); } @@ -42,7 +42,7 @@ private IntervalTerm(TermImpl lowerBound, TermImpl upperBound) { } } - public static IntervalTerm getInstance(TermImpl lowerBound, TermImpl upperBound) { + public static IntervalTerm getInstance(CoreTerm lowerBound, CoreTerm upperBound) { return INTERNER.intern(new IntervalTerm(lowerBound, upperBound)); } @@ -114,17 +114,17 @@ public int hashCode() { } @Override - public int compareTo(Term o) { + public int compareTo(CoreTerm o) { throw new UnsupportedOperationException("Intervals cannot be compared."); } @Override - public TermImpl renameVariables(String renamePrefix) { + public CoreTerm renameVariables(String renamePrefix) { return new IntervalTerm(lowerBoundTerm.renameVariables(renamePrefix), upperBoundTerm.renameVariables(renamePrefix)); } @Override - public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { return IntervalTerm.getInstance( lowerBoundTerm.normalizeVariables(renamePrefix, counter), upperBoundTerm.normalizeVariables(renamePrefix, counter)); @@ -135,7 +135,7 @@ public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { * @param term the term to test * @return true iff an IntervalTerm occurs in term. */ - public static boolean termContainsIntervalTerm(Term term) { + public static boolean termContainsIntervalTerm(CoreTerm term) { if (term instanceof IntervalTerm) { return true; } else if (term instanceof FunctionTerm) { @@ -147,7 +147,7 @@ public static boolean termContainsIntervalTerm(Term term) { public static boolean functionTermContainsIntervals(FunctionTerm functionTerm) { // Test whether a function term contains an interval term (recursively). - for (Term term : functionTerm.getTerms()) { + for (CoreTerm term : functionTerm.getTerms()) { if (term instanceof IntervalTerm) { return true; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java index 07d628121..7ba67d17a 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java @@ -4,9 +4,9 @@ import java.util.List; /** - * Convenience methods for {@link TermImpl}s. The methods provided here are an + * Convenience methods for {@link CoreTerm}s. The methods provided here are an * attempt to avoid repeating commonly used code snippets, like wrapping sets of - * values in {@link TermImpl}s and creating lists of those terms, etc. + * values in {@link CoreTerm}s and creating lists of those terms, etc. * * Copyright (c) 2020, the Alpha Team. */ @@ -22,10 +22,10 @@ private Terms() { } @SafeVarargs - public static > List> asTermList(T... values) { - List> retVal = new ArrayList<>(); + public static > List> asTermList(T... values) { + List> retVal = new ArrayList<>(); for (T value : values) { - retVal.add(ConstantTermImpl.getInstance(value)); + retVal.add(CoreConstantTerm.getInstance(value)); } return retVal; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java index 904f7f3a4..0fd29c5e8 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java @@ -10,7 +10,7 @@ /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class VariableTerm extends TermImpl { +public class VariableTerm extends CoreTerm { private static final Interner INTERNER = new Interner<>(); private static final String ANONYMOUS_VARIABLE_PREFIX = "_"; @@ -41,8 +41,8 @@ public List getOccurringVariables() { } @Override - public TermImpl substitute(Substitution substitution) { - TermImpl groundTerm = substitution.eval(this); + public CoreTerm substitute(Substitution substitution) { + CoreTerm groundTerm = substitution.eval(this); if (groundTerm == null) { // If variable is not substituted, keep term as is. return this; @@ -76,7 +76,7 @@ public int hashCode() { } @Override - public int compareTo(Term o) { + public int compareTo(CoreTerm o) { if (this == o) { return 0; } @@ -90,12 +90,12 @@ public int compareTo(Term o) { } @Override - public TermImpl renameVariables(String renamePrefix) { + public CoreTerm renameVariables(String renamePrefix) { return VariableTerm.getInstance(renamePrefix + variableName); } @Override - public TermImpl normalizeVariables(String renamePrefix, RenameCounter counter) { + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { VariableTerm renamedThis = counter.renamedVariables.get(this); if (renamedThis != null) { return renamedThis; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java index 05b5a6c3e..7f762c773 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java @@ -22,11 +22,11 @@ public class FactIntervalEvaluator { public static List constructFactInstances(CoreAtom fact) { // Construct instance(s) from the fact. int arity = fact.getPredicate().getArity(); - TermImpl[] currentTerms = new TermImpl[arity]; + CoreTerm[] currentTerms = new CoreTerm[arity]; boolean containsIntervals = false; // Check if instance contains intervals at all. for (int i = 0; i < arity; i++) { - TermImpl term = fact.getTerms().get(i); + CoreTerm term = fact.getTerms().get(i); currentTerms[i] = term; if (term instanceof IntervalTerm) { containsIntervals = true; @@ -43,11 +43,11 @@ public static List constructFactInstances(CoreAtom fact) { return unrollInstances(currentTerms, 0); } - private static List unrollInstances(TermImpl[] currentTerms, int currentPosition) { + private static List unrollInstances(CoreTerm[] currentTerms, int currentPosition) { if (currentPosition == currentTerms.length) { return Collections.singletonList(new Instance(currentTerms)); } - Term currentTerm = currentTerms[currentPosition]; + CoreTerm currentTerm = currentTerms[currentPosition]; if (!(currentTerm instanceof IntervalTerm)) { return unrollInstances(currentTerms, currentPosition + 1); } @@ -58,8 +58,8 @@ private static List unrollInstances(TermImpl[] currentTerms, int curre int upper = ((IntervalTerm) currentTerm).getUpperBound(); for (int i = lower; i <= upper; i++) { - TermImpl[] clonedTerms = currentTerms.clone(); - clonedTerms[currentPosition] = ConstantTermImpl.getInstance(i); + CoreTerm[] clonedTerms = currentTerms.clone(); + clonedTerms[currentPosition] = CoreConstantTerm.getInstance(i); instances.addAll(unrollInstances(clonedTerms, currentPosition + 1)); } return instances; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java index 83bd539ca..578596886 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; /** * A storage for instances with a certain arity, where each position of the instance can be indexed. @@ -58,7 +58,7 @@ public class IndexedInstanceStorage { /** * For each position, a mapping of termIds to list of instances with this termId at the corresponding position */ - private final ArrayList>> indices = new ArrayList<>(); + private final ArrayList>> indices = new ArrayList<>(); private final ArrayList recentlyAddedInstances = new ArrayList<>(); @@ -124,7 +124,7 @@ public void addInstance(Instance instance) { recentlyAddedInstances.add(instance); // Add instance to all indices. for (int i = 0; i < indices.size(); i++) { - HashMap> posIndex = indices.get(i); + HashMap> posIndex = indices.get(i); if (posIndex == null) { continue; } @@ -141,7 +141,7 @@ public void removeInstance(Instance instance) { } // Remove from all indices for (int i = 0; i < indices.size(); i++) { - HashMap> posIndex = indices.get(i); + HashMap> posIndex = indices.get(i); if (posIndex == null) { continue; } @@ -169,8 +169,8 @@ public List getRecentlyAddedInstances() { * @param position * @return */ - public List getInstancesMatchingAtPosition(Term term, int position) { - Map> indexForPosition = indices.get(position); + public List getInstancesMatchingAtPosition(CoreTerm term, int position) { + Map> indexForPosition = indices.get(position); if (indexForPosition == null) { throw new RuntimeException("IndexedInstanceStorage queried for position " + position + " which is not indexed."); } @@ -182,7 +182,7 @@ private int getMostSelectiveGroundTermPosition(CoreAtom atom) { int smallestNumberOfInstances = Integer.MAX_VALUE; int mostSelectiveTermPosition = -1; for (int i = 0; i < atom.getTerms().size(); i++) { - Term testTerm = atom.getTerms().get(i); + CoreTerm testTerm = atom.getTerms().get(i); if (testTerm.isGround()) { ArrayList instancesMatchingTest = indices.get(i).get(testTerm); if (instancesMatchingTest == null) { @@ -204,7 +204,7 @@ public List getInstancesFromPartiallyGroundAtom(CoreAtom substitute) { int firstGroundTermPosition = getMostSelectiveGroundTermPosition(substitute); // Select matching instances, select all if no ground term was found. if (firstGroundTermPosition != -1) { - Term firstGroundTerm = substitute.getTerms().get(firstGroundTermPosition); + CoreTerm firstGroundTerm = substitute.getTerms().get(firstGroundTermPosition); return getInstancesMatchingAtPosition(firstGroundTerm, firstGroundTermPosition); } else { return new ArrayList<>(getAllInstances()); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java index 3e623193d..9897b5a03 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java @@ -7,8 +7,7 @@ import at.ac.tuwien.kr.alpha.Util; import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; /** * An instance is a positional association of terms, e.g., representing a variable substitution, or a ground instance of @@ -16,13 +15,13 @@ * Copyright (c) 2016, the Alpha Team. */ public class Instance { - public final List terms; + public final List terms; - public Instance(TermImpl... terms) { + public Instance(CoreTerm... terms) { this(Arrays.asList(terms)); } - public Instance(List terms) { + public Instance(List terms) { this.terms = terms; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java index aa457df0b..cb19e5cb3 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java @@ -27,9 +27,40 @@ */ package at.ac.tuwien.kr.alpha.grounder; +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +import java.util.ArrayList; +import java.util.Collection; +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.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.*; -import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.IntIterator; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; @@ -37,17 +68,12 @@ import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.instantiation.*; +import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; +import at.ac.tuwien.kr.alpha.grounder.instantiation.BindingResult; +import at.ac.tuwien.kr.alpha.grounder.instantiation.DefaultLazyGroundingInstantiationStrategy; +import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; +import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; import at.ac.tuwien.kr.alpha.grounder.structure.AnalyzeUnjustified; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; /** * A semi-naive grounder. @@ -556,7 +582,7 @@ public InternalRule getNonGroundRule(Integer ruleId) { } @Override - public boolean isFact(Atom atom) { + public boolean isFact(CoreAtom atom) { LinkedHashSet instances = factsFromProgram.get(atom.getPredicate()); if (instances == null) { return false; @@ -565,11 +591,11 @@ public boolean isFact(Atom atom) { } @Override - public Set justifyAtom(int atomToJustify, Assignment currentAssignment) { - Set literals = analyzeUnjustified.analyze(atomToJustify, currentAssignment); + public Set justifyAtom(int atomToJustify, Assignment currentAssignment) { + Set literals = analyzeUnjustified.analyze(atomToJustify, currentAssignment); // Remove facts from justification before handing it over to the solver. - for (Iterator iterator = literals.iterator(); iterator.hasNext(); ) { - Literal literal = iterator.next(); + for (Iterator iterator = literals.iterator(); iterator.hasNext(); ) { + CoreLiteral literal = iterator.next(); if (literal.isNegated()) { continue; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java index 0ff1f153e..ec99f727d 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java @@ -1,12 +1,12 @@ package at.ac.tuwien.kr.alpha.grounder; +import java.util.Set; + import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import java.util.Set; - /** * Copyright (c) 2017, the Alpha Team. */ @@ -18,14 +18,14 @@ public interface ProgramAnalyzingGrounder extends Grounder { * @param currentAssignment the current assignment. * @return a set of literals who jointly imply the atomToJustify not being TRUE. */ - Set justifyAtom(int atomToJustify, Assignment currentAssignment); + Set justifyAtom(int atomToJustify, Assignment currentAssignment); /** * Returns true iff the given atom is known to the grounder as a fact (hence not occurring in any assignment). * @param atom the atom. * @return true iff atom is a fact. */ - boolean isFact(Atom atom); + boolean isFact(CoreAtom atom); /** * Returns the NonGroundRule identified by the given id. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java index 876005862..7cc35a992 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java @@ -38,9 +38,8 @@ import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; @@ -49,14 +48,14 @@ public class Substitution { private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); public static final Substitution EMPTY_SUBSTITUTION = new Substitution() { @Override - public > Term put(VariableTerm variableTerm, TermImpl groundTerm) { + public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { throw oops("Should not be called on EMPTY_SUBSTITUTION"); } }; - protected TreeMap substitution; + protected TreeMap substitution; - private Substitution(TreeMap substitution) { + private Substitution(TreeMap substitution) { if (substitution == null) { throw oops("Substitution is null."); } @@ -81,7 +80,7 @@ public static Substitution specializeSubstitution(CoreLiteral literal, Instance private static class SpecializationHelper { Substitution updatedSubstitution; // Is null for as long as the given partial substitution is not extended, afterwards holds the updated/extended/specialized substitution. - Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { + Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { for (int i = 0; i < termList.size(); i++) { if (!unifyTerms(termList.get(i), instance.terms.get(i), partialSubstitution)) { return null; @@ -94,7 +93,7 @@ Substitution unify(List termList, Instance instance, Substitutio return updatedSubstitution; } - boolean unifyTerms(Term termNonGround, TermImpl termGround, Substitution partialSubstitution) { + boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution partialSubstitution) { if (termNonGround == termGround) { // Both terms are either the same constant or the same variable term return true; @@ -105,7 +104,7 @@ boolean unifyTerms(Term termNonGround, TermImpl termGround, Substitution partial VariableTerm variableTerm = (VariableTerm) termNonGround; // Left term is variable, bind it to the right term. Use original substitution if it has // not been cloned yet. - Term bound = (updatedSubstitution == null ? partialSubstitution : updatedSubstitution).eval(variableTerm); // Get variable binding, either from input substitution if it has not been updated yet, or from the cloned/updated substitution. + CoreTerm bound = (updatedSubstitution == null ? partialSubstitution : updatedSubstitution).eval(variableTerm); // Get variable binding, either from input substitution if it has not been updated yet, or from the cloned/updated substitution. if (bound != null) { // Variable is already bound, return true if binding is the same as the current ground term. return termGround == bound; @@ -161,20 +160,20 @@ public static Substitution specializeSubstitution(CoreAtom atom, Instance instan } /** - * This method should be used to obtain the {@link TermImpl} to be used in place of a given {@link VariableTerm} under this substitution. + * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTerm} under this substitution. * * @param variableTerm the variable term to substitute, if possible * @return a constant term if the substitution contains the given variable, {@code null} otherwise. */ - public TermImpl eval(VariableTerm variableTerm) { + public CoreTerm eval(VariableTerm variableTerm) { return this.substitution.get(variableTerm); } - public > Term put(VariableTerm variableTerm, TermImpl groundTerm) { + public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { if (!groundTerm.isGround()) { throw oops("Right-hand term is not ground."); } - Term alreadyAssigned = substitution.get(variableTerm); + CoreTerm alreadyAssigned = substitution.get(variableTerm); if (alreadyAssigned != null && alreadyAssigned != groundTerm) { throw oops("Variable is already assigned to another term."); } @@ -203,7 +202,7 @@ public Set getMappedVariables() { public String toString() { final StringBuilder ret = new StringBuilder("{"); boolean isFirst = true; - for (Map.Entry e : substitution.entrySet()) { + for (Map.Entry e : substitution.entrySet()) { if (isFirst) { isFirst = false; } else { @@ -222,7 +221,7 @@ public static Substitution fromString(String substitution) { for (String assignment : assignments) { String[] keyVal = assignment.split("->"); VariableTerm variable = VariableTerm.getInstance(keyVal[0]); - TermImpl assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); + CoreTerm assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); ret.put(variable, assignedTerm); } return ret; diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java index 4c1c795fd..a188d7adf 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java @@ -30,7 +30,7 @@ import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import java.util.Set; @@ -72,8 +72,8 @@ private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLef return null; } for (int i = 0; i < left.getPredicate().getArity(); i++) { - final TermImpl leftTerm = left.getTerms().get(i); - final TermImpl rightTerm = right.getTerms().get(i); + final CoreTerm leftTerm = left.getTerms().get(i); + final CoreTerm rightTerm = right.getTerms().get(i); if (!unifyTerms(leftTerm, rightTerm, mgu, keepLeftAsIs)) { return null; } @@ -81,9 +81,9 @@ private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLef return mgu; } - private static boolean unifyTerms(TermImpl left, TermImpl right, Unifier currentSubstitution, boolean keepLeftAsIs) { - final TermImpl leftSubs = left.substitute(currentSubstitution); - final TermImpl rightSubs = right.substitute(currentSubstitution); + private static boolean unifyTerms(CoreTerm left, CoreTerm right, Unifier currentSubstitution, boolean keepLeftAsIs) { + final CoreTerm leftSubs = left.substitute(currentSubstitution); + final CoreTerm rightSubs = right.substitute(currentSubstitution); if (leftSubs == rightSubs) { return true; } @@ -103,8 +103,8 @@ private static boolean unifyTerms(TermImpl left, TermImpl right, Unifier current return false; } for (int i = 0; i < leftFunction.getTerms().size(); i++) { - final TermImpl leftTerm = leftFunction.getTerms().get(i); - final TermImpl rightTerm = rightFunction.getTerms().get(i); + final CoreTerm leftTerm = leftFunction.getTerms().get(i); + final CoreTerm rightTerm = rightFunction.getTerms().get(i); if (!unifyTerms(leftTerm, rightTerm, currentSubstitution, keepLeftAsIs)) { return false; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java index 3e326e1b1..92a3df759 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java @@ -9,8 +9,7 @@ import java.util.Set; import java.util.TreeMap; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; /** @@ -22,7 +21,7 @@ public class Unifier extends Substitution { private final TreeMap> rightHandVariableOccurrences; - private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { + private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { if (substitution == null) { throw oops("Substitution is null."); } @@ -44,7 +43,7 @@ public Unifier(Substitution clone) { public Unifier extendWith(Substitution extension) { - for (Map.Entry extensionVariable : extension.substitution.entrySet()) { + for (Map.Entry extensionVariable : extension.substitution.entrySet()) { this.put(extensionVariable.getKey(), extensionVariable.getValue()); } return this; @@ -57,7 +56,7 @@ public Unifier extendWith(Substitution extension) { @Override public Set getMappedVariables() { Set ret = new HashSet<>(); - for (Map.Entry substitution : substitution.entrySet()) { + for (Map.Entry substitution : substitution.entrySet()) { ret.add(substitution.getKey()); ret.addAll(substitution.getValue().getOccurringVariables()); } @@ -66,7 +65,7 @@ public Set getMappedVariables() { @Override - public > Term put(VariableTerm variableTerm, TermImpl term) { + public > CoreTerm put(VariableTerm variableTerm, CoreTerm term) { // If term is not ground, store it for right-hand side reverse-lookup. if (!term.isGround()) { for (VariableTerm rightHandVariable : term.getOccurringVariables()) { @@ -75,7 +74,7 @@ public > Term put(VariableTerm variableTerm, TermImpl te } } // Note: We're destroying type information here. - Term ret = substitution.put(variableTerm, term); + CoreTerm ret = substitution.put(variableTerm, term); // Check if the just-assigned variable occurs somewhere in the right-hand side already. List rightHandOccurrences = rightHandVariableOccurrences.get(variableTerm); @@ -83,7 +82,7 @@ public > Term put(VariableTerm variableTerm, TermImpl te // Replace all occurrences on the right-hand side with the just-assigned term. for (VariableTerm rightHandOccurrence : rightHandOccurrences) { // Substitute the right hand where this assigned variable occurs with the new value and store it. - TermImpl previousRightHand = substitution.get(rightHandOccurrence); + CoreTerm previousRightHand = substitution.get(rightHandOccurrence); if (previousRightHand == null) { // Variable does not occur on the lef-hand side, skip. continue; @@ -107,16 +106,16 @@ public > Term put(VariableTerm variableTerm, TermImpl te public static Unifier mergeIntoLeft(Unifier left, Unifier right) { // Note: we assume both substitutions are free of chains, i.e., no A->B, B->C but A->C, B->C. Unifier ret = new Unifier(left); - for (Map.Entry mapping : right.substitution.entrySet()) { + for (Map.Entry mapping : right.substitution.entrySet()) { VariableTerm variable = mapping.getKey(); - TermImpl term = mapping.getValue(); + CoreTerm term = mapping.getValue(); // If variable is unset, simply add. if (!ret.isVariableSet(variable)) { ret.put(variable, term); continue; } // Variable is already set. - Term setTerm = ret.eval(variable); + CoreTerm setTerm = ret.eval(variable); if (setTerm instanceof VariableTerm) { // Variable maps to another variable in left. // Add a new mapping of the setTerm variable into our right-assigned term. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java index d9cbb8edb..3ce4e494e 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java @@ -35,9 +35,8 @@ import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; public class ChoiceAtom extends CoreAtom { @@ -46,15 +45,15 @@ public class ChoiceAtom extends CoreAtom { public static final CorePredicate OFF = CorePredicate.getInstance("ChoiceOff", 1, true, true); private final CorePredicate predicate; - private final List terms; + private final List terms; - private ChoiceAtom(CorePredicate predicate, Term term) { + private ChoiceAtom(CorePredicate predicate, CoreTerm term) { this.predicate = predicate; this.terms = Collections.singletonList(term); } private ChoiceAtom(CorePredicate predicate, int id) { - this(predicate, ConstantTerm.getInstance(Integer.toString(id))); + this(predicate, CoreConstantTerm.getInstance(Integer.toString(id))); } public static ChoiceAtom on(int id) { @@ -71,7 +70,7 @@ public CorePredicate getPredicate() { } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -97,7 +96,7 @@ public String toString() { } @Override - public CoreAtom withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("Changing terms is not supported for ChoiceAtoms!"); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java index 0c0128798..80d310fad 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java @@ -7,8 +7,8 @@ import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; @@ -25,9 +25,9 @@ */ public class EnumerationAtom extends BasicAtom { public static final CorePredicate ENUMERATION_PREDICATE = CorePredicate.getInstance("_Enumeration", 3); - private static final HashMap> ENUMERATIONS = new HashMap<>(); + private static final HashMap> ENUMERATIONS = new HashMap<>(); - public EnumerationAtom(List terms) { + public EnumerationAtom(List terms) { super(ENUMERATION_PREDICATE, terms); if (terms.size() != 3) { throw new RuntimeException("EnumerationAtom must have arity three. Given terms are of wrong size: " + terms); @@ -41,9 +41,9 @@ public static void resetEnumerations() { ENUMERATIONS.clear(); } - private Integer getEnumerationIndex(Term identifier, Term enumerationTerm) { + private Integer getEnumerationIndex(CoreTerm identifier, CoreTerm enumerationTerm) { ENUMERATIONS.putIfAbsent(identifier, new HashMap<>()); - HashMap enumeratedTerms = ENUMERATIONS.get(identifier); + HashMap enumeratedTerms = ENUMERATIONS.get(identifier); Integer assignedInteger = enumeratedTerms.get(enumerationTerm); if (assignedInteger == null) { int enumerationIndex = enumeratedTerms.size() + 1; @@ -64,14 +64,14 @@ private Integer getEnumerationIndex(Term identifier, Term enumerationTerm) { * @return a new substitution where the third term of the enumeration atom is bound to an integer. */ public Substitution addEnumerationIndexToSubstitution(Substitution substitution) { - Term idTerm = this.getTerms().get(0).substitute(substitution); - Term enumerationTerm = this.getTerms().get(1).substitute(substitution); + CoreTerm idTerm = this.getTerms().get(0).substitute(substitution); + CoreTerm enumerationTerm = this.getTerms().get(1).substitute(substitution); if (!enumerationTerm.isGround()) { throw new RuntimeException("Enumeration term is not ground after substitution. Should not happen."); } Integer enumerationIndex = getEnumerationIndex(idTerm, enumerationTerm); Substitution retVal = new Substitution(substitution); - retVal.put((VariableTerm) getTerms().get(2), ConstantTerm.getInstance(enumerationIndex)); + retVal.put((VariableTerm) getTerms().get(2), CoreConstantTerm.getInstance(enumerationIndex)); return retVal; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java index ae19a9e15..99c1735fd 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.grounder.atoms; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - import java.util.Collections; import java.util.HashSet; import java.util.Set; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + /** * Copyright (c) 2018, the Alpha Team. */ @@ -41,8 +41,8 @@ public Set getBindingVariables() { @Override public Set getNonBindingVariables() { Set ret = new HashSet<>(2); - Term idTerm = getTerms().get(0); - Term enumTerm = getTerms().get(1); + CoreTerm idTerm = getTerms().get(0); + CoreTerm enumTerm = getTerms().get(1); if (idTerm instanceof VariableTerm) { ret.add((VariableTerm) idTerm); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java index 582b6497c..5d1b96580 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java @@ -34,12 +34,10 @@ import java.util.List; import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.grounder.Substitution; /** @@ -57,9 +55,9 @@ public class IntervalAtom extends CoreAtom implements VariableNormalizableAtom { private static final CorePredicate PREDICATE = CorePredicate.getInstance("_interval", 2, true); - private final List terms; + private final List terms; - public IntervalAtom(IntervalTerm intervalTerm, Term intervalRepresentingVariable) { + public IntervalAtom(IntervalTerm intervalTerm, CoreTerm intervalRepresentingVariable) { this.terms = Arrays.asList(intervalTerm, intervalRepresentingVariable); } @@ -69,13 +67,13 @@ public CorePredicate getPredicate() { } @Override - public List getTerms() { + public List getTerms() { return terms; } @Override public boolean isGround() { - for (Term t : this.terms) { + for (CoreTerm t : this.terms) { if (!t.isGround()) { return false; } @@ -127,12 +125,12 @@ public IntervalAtom substitute(Substitution substitution) { @Override public IntervalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = TermImpl.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); return new IntervalAtom((IntervalTerm) renamedTerms.get(0), renamedTerms.get(1)); } @Override - public CoreAtom withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("IntervalAtoms do not support setting of terms!"); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java index f055e86b7..5b6505c5f 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java @@ -27,18 +27,20 @@ */ package at.ac.tuwien.kr.alpha.grounder.atoms; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import com.google.common.collect.Sets; + import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; -import com.google.common.collect.Sets; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; /** * @see IntervalAtom @@ -61,26 +63,26 @@ public IntervalLiteral negate() { private List getIntervalSubstitutions(Substitution partialSubstitution) { List substitutions = new ArrayList<>(); - List terms = getTerms(); - Term intervalRepresentingVariable = terms.get(1); + List terms = getTerms(); + CoreTerm intervalRepresentingVariable = terms.get(1); IntervalTerm intervalTerm = (IntervalTerm) terms.get(0); // Check whether intervalRepresentingVariable is bound already. if (intervalRepresentingVariable instanceof VariableTerm) { // Still a variable, generate all elements in the interval. for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) { Substitution ith = new Substitution(partialSubstitution); - ith.put((VariableTerm) intervalRepresentingVariable, ConstantTerm.getInstance(i)); + ith.put((VariableTerm) intervalRepresentingVariable, CoreConstantTerm.getInstance(i)); substitutions.add(ith); } return substitutions; } else { // The intervalRepresentingVariable is bound already, check if it is in the interval. if (!(intervalRepresentingVariable instanceof ConstantTerm) - || !(((ConstantTerm) intervalRepresentingVariable).getObject() instanceof Integer)) { + || !(((CoreConstantTerm) intervalRepresentingVariable).getObject() instanceof Integer)) { // Term is not bound to an integer constant, not in the interval. return Collections.emptyList(); } - Integer integer = (Integer) ((ConstantTerm) intervalRepresentingVariable).getObject(); + Integer integer = (Integer) ((CoreConstantTerm) intervalRepresentingVariable).getObject(); if (intervalTerm.getLowerBound() <= integer && integer <= intervalTerm.getUpperBound()) { return Collections.singletonList(partialSubstitution); } @@ -90,7 +92,7 @@ private List getIntervalSubstitutions(Substitution partialSubstitu @Override public Set getBindingVariables() { - Term term = getTerms().get(1); + CoreTerm term = getTerms().get(1); if (term instanceof VariableTerm) { return Collections.singleton((VariableTerm) term); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java index 05e664c65..cbe2f5a66 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java @@ -27,22 +27,19 @@ */ package at.ac.tuwien.kr.alpha.grounder.atoms; +import static at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm.getInstance; + +import java.util.Arrays; +import java.util.List; + import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; -import java.util.Arrays; -import java.util.List; - -import static at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl.getInstance; - /** * Atoms corresponding to rule bodies use this predicate, first term is rule number, * second is a term containing variable substitutions. @@ -50,9 +47,9 @@ public class RuleAtom extends CoreAtom { public static final CorePredicate PREDICATE = CorePredicate.getInstance("_R_", 2, true, true); - private final List> terms; + private final List> terms; - private RuleAtom(List> terms) { + private RuleAtom(List> terms) { if (terms.size() != 2) { throw new IllegalArgumentException(); } @@ -74,7 +71,7 @@ public CorePredicate getPredicate() { } @Override - public List getTerms() { + public List getTerms() { return Arrays.asList(terms.get(0), terms.get(1)); } @@ -119,7 +116,7 @@ public String toString() { } @Override - public CoreAtom withTerms(List terms) { + public CoreAtom withTerms(List terms) { throw new UnsupportedOperationException("RuleAtoms do not support setting of terms!"); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java index 5c837987f..3571d961b 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java @@ -295,12 +295,12 @@ public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { // aggregate : NAF? (lt=term lop=binop)? aggregate_function CURLY_OPEN aggregate_elements CURLY_CLOSE (uop=binop ut=term)?; boolean isPositive = ctx.NAF() == null; - TermImpl lt = null; + CoreTerm lt = null; ComparisonOperator lop = null; Term ut = null; ComparisonOperator uop = null; if (ctx.lt != null) { - lt = (TermImpl) visit(ctx.lt); + lt = (CoreTerm) visit(ctx.lt); lop = visitBinop(ctx.lop); } if (ctx.ut != null) { @@ -357,16 +357,16 @@ public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { // ground_term : ID | QUOTED_STRING | MINUS? NUMBER; if (ctx.ID() != null) { - return ConstantTermImpl.getSymbolicInstance(ctx.ID().getText()); + return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); } else if (ctx.QUOTED_STRING() != null) { String quotedString = ctx.QUOTED_STRING().getText(); - return ConstantTermImpl.getInstance(quotedString.substring(1, quotedString.length() - 1)); + return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); } else { int multiplier = 1; if (ctx.MINUS() != null) { multiplier = -1; } - return ConstantTermImpl.getInstance(multiplier * Integer.parseInt(ctx.NUMBER().getText())); + return CoreConstantTerm.getInstance(multiplier * Integer.parseInt(ctx.NUMBER().getText())); } } @@ -420,8 +420,8 @@ public ComparisonOperator visitBinop(ASPCore2Parser.BinopContext ctx) { public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { // builtin_atom : term binop term; return new ComparisonAtom( - (TermImpl) visit(ctx.term(0)), - (TermImpl) visit(ctx.term(1)), + (CoreTerm) visit(ctx.term(0)), + (CoreTerm) visit(ctx.term(1)), visitBinop(ctx.binop()) ); } @@ -447,21 +447,21 @@ public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext throw notSupported(ctx); } - final List terms = visitTerms(ctx.terms()); + final List terms = visitTerms(ctx.terms()); return new BasicAtom(CorePredicate.getInstance(ctx.ID().getText(), terms.size()), terms); } @Override - public List visitTerms(ASPCore2Parser.TermsContext ctx) { + public List visitTerms(ASPCore2Parser.TermsContext ctx) { // terms : term (COMMA terms)?; if (ctx == null) { return emptyList(); } - final List terms = new ArrayList<>(); + final List terms = new ArrayList<>(); do { ASPCore2Parser.TermContext term = ctx.term(); - terms.add((TermImpl) visit(term)); + terms.add((CoreTerm) visit(term)); } while ((ctx = ctx.terms()) != null); return terms; @@ -469,18 +469,18 @@ public List visitTerms(ASPCore2Parser.TermsContext ctx) { @Override public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { - return ConstantTermImpl.getInstance(Integer.parseInt(ctx.NUMBER().getText())); + return CoreConstantTerm.getInstance(Integer.parseInt(ctx.NUMBER().getText())); } @Override public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { - return ConstantTermImpl.getSymbolicInstance(ctx.ID().getText()); + return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); } @Override public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { String quotedString = ctx.QUOTED_STRING().getText().replace("\\\"", "\""); - return ConstantTermImpl.getInstance(quotedString.substring(1, quotedString.length() - 1)); + return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); } @Override @@ -526,7 +526,7 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) throw new IllegalArgumentException("Unknown interpretation name encountered: " + predicateName); } - List outputTerms = visitTerms(ctx.output); + List outputTerms = visitTerms(ctx.output); return new ExternalAtom( CorePredicate.getInstance(predicateName, outputTerms.size()), @@ -542,15 +542,15 @@ public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) ASPCore2Parser.IntervalContext ictx = ctx.interval(); String lowerText = ictx.lower.getText(); String upperText = ictx.upper.getText(); - TermImpl lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? ConstantTermImpl.getInstance(Integer.parseInt(lowerText)) : VariableTerm.getInstance(lowerText); - TermImpl upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? ConstantTermImpl.getInstance(Integer.parseInt(upperText)) : VariableTerm.getInstance(upperText); + CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) : VariableTerm.getInstance(lowerText); + CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) : VariableTerm.getInstance(upperText); return IntervalTerm.getInstance(lower, upper); } @Override public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { // | MINUS term - return ArithmeticTerm.MinusTerm.getInstance((TermImpl) visit(ctx.term())); + return ArithmeticTerm.MinusTerm.getInstance((CoreTerm) visit(ctx.term())); } @Override @@ -558,26 +558,26 @@ public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArit // | term (TIMES | DIV | MODULO) term ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; - return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), op, (TermImpl) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); } @Override public Object visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { // | term (PLUS | MINUS) term ArithmeticTerm.ArithmeticOperator op = ctx.PLUS() != null ? ArithmeticTerm.ArithmeticOperator.PLUS : ArithmeticTerm.ArithmeticOperator.MINUS; - return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), op, (TermImpl) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); } @Override public Object visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { // | term POWER term ArithmeticTerm.ArithmeticOperator op = ArithmeticTerm.ArithmeticOperator.POWER; - return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), op, (TermImpl) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); } @Override public Object visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { // | term BITXOR term - return ArithmeticTerm.getInstance((TermImpl) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (TermImpl) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (CoreTerm) visit(ctx.term(1))); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java index 9dc07e1c6..a7cc0f152 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java @@ -32,7 +32,7 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; @@ -48,9 +48,9 @@ public class ProgramPartParser { private final ParseTreeVisitor visitor = new ParseTreeVisitor(Collections.emptyMap(), true); - public TermImpl parseTerm(String s) { + public CoreTerm parseTerm(String s) { final ASPCore2Parser parser = getASPCore2Parser(s); - return (TermImpl)parse(parser.term()); + return (CoreTerm)parse(parser.term()); } public BasicAtom parseBasicAtom(String s) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java index cfa094681..52be979bb 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java @@ -6,7 +6,7 @@ import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Instance; import at.ac.tuwien.kr.alpha.grounder.Unification; @@ -39,7 +39,7 @@ public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, private Map> assignedAtoms; - public Set analyze(int atomToJustify, Assignment currentAssignment) { + public Set analyze(int atomToJustify, Assignment currentAssignment) { padDepth = 0; CoreAtom atom = atomStore.get(atomToJustify); if (!(atom instanceof BasicAtom)) { @@ -65,9 +65,9 @@ public Set analyze(int atomToJustify, Assignment currentAssignment) { return analyze((BasicAtom) atom, currentAssignment); } - private Set analyze(BasicAtom atom, Assignment currentAssignment) { + private Set analyze(BasicAtom atom, Assignment currentAssignment) { log(pad("Starting analyze, current assignment is: {}"), currentAssignment); - LinkedHashSet vL = new LinkedHashSet<>(); + LinkedHashSet vL = new LinkedHashSet<>(); LinkedHashSet vToDo = new LinkedHashSet<>(Collections.singleton(new LitSet(atom, new LinkedHashSet<>()))); LinkedHashSet vDone = new LinkedHashSet<>(); while (!vToDo.isEmpty()) { @@ -233,7 +233,7 @@ private Set unjustCover(List vB, Set vY, Set variablesOccurringInSigma = sigma.getMappedVariables(); if (Unification.instantiate(bSigmaY, bSigma) != null) { for (Unifier sigmaN : vN) { - ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); + ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); occurringVariables.addAll(sigmaN.getMappedVariables()); BasicAtom genericAtom = new BasicAtom(CorePredicate.getInstance("_", occurringVariables.size(), true), occurringVariables); CoreAtom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); @@ -365,7 +365,7 @@ private void log(String msg, Object... refs) { } private static class ReturnExplainUnjust { - Set vL; + Set vL; Set vToDo; ReturnExplainUnjust() { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java index 4cc542a8b..e599f42b8 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java @@ -1,17 +1,16 @@ package at.ac.tuwien.kr.alpha.grounder.structure; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; -import at.ac.tuwien.kr.alpha.grounder.Unifier; -import at.ac.tuwien.kr.alpha.grounder.Unification; +import static at.ac.tuwien.kr.alpha.Util.oops; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; -import static at.ac.tuwien.kr.alpha.Util.oops; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; +import at.ac.tuwien.kr.alpha.grounder.Unification; +import at.ac.tuwien.kr.alpha.grounder.Unifier; /** * Copyright (c) 2018, the Alpha Team. @@ -119,7 +118,7 @@ private int computeHashCode() { return result; } - private CoreAtom computeNormalized(Atom atom, String prefix) { + private CoreAtom computeNormalized(CoreAtom atom, String prefix) { if (atom instanceof VariableNormalizableAtom) { return ((VariableNormalizableAtom) atom).normalizeVariables(prefix, 0); } else { @@ -132,7 +131,7 @@ private Set computeNormalizedSubstitutions() { for (Unifier substitution : complementSubstitutions) { Unifier preNormalizedSubstitution = normalizeSubstitution(atom, substitution, normalizedLiteral); // Unifier may still contain variables in the right-hand side, those have to be normalized, too. - Atom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); + CoreAtom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); // Apply substitution and normalize all remaining variables, i.e., those appearing at the right-hand side of the substitution. CoreAtom normalized = computeNormalized(appliedSub, "_X"); // Compute final substitution from normalized atom to the one where also variables are normalized. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java index f6181822f..5ff468496 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java @@ -11,15 +11,13 @@ import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Substitution; import at.ac.tuwien.kr.alpha.grounder.Unifier; @@ -192,13 +190,13 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Prepare aggregate parameters. aggregateCount++; Substitution aggregateSubstitution = new Unifier(); - Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); + Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), ConstantTerm.getInstance(aggregateCount)); + aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier - ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); - globalVariableTermlist.add(ConstantTermImpl.getInstance(aggregateCount)); + ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); + globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); } aggregateSubstitution.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); @@ -209,7 +207,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create input to sorting network from aggregate elements. for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. - List elementTerms = aggregateElement.getElementTerms(); + List elementTerms = aggregateElement.getElementTerms(); FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); Substitution elementSubstitution = new Unifier(aggregateSubstitution); elementSubstitution.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); @@ -239,10 +237,10 @@ private List rewriteAggregatesInRule(BasicRule rule) { return additionalRules; } - static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { + static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { // Hacky way to get all global variables: take all variables inside the aggregate that occur also in the // rest of the rule. - HashSet occurringVariables = new LinkedHashSet<>(); + HashSet occurringVariables = new LinkedHashSet<>(); for (CoreLiteral element : ruleBody) { if (element instanceof AggregateLiteral) { continue; @@ -250,8 +248,8 @@ static Collection getGlobalVariables(List ruleBody, Aggregate occurringVariables.addAll(element.getBindingVariables()); occurringVariables.addAll(element.getNonBindingVariables()); } - LinkedHashSet globalVariables = new LinkedHashSet<>(); - for (Term aggVariable : aggregateAtom.getAggregateVariables()) { + LinkedHashSet globalVariables = new LinkedHashSet<>(); + for (CoreTerm aggVariable : aggregateAtom.getAggregateVariables()) { if (occurringVariables.contains(aggVariable)) { globalVariables.add(aggVariable); } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java index 48a5330ed..8dfe872e0 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java @@ -88,8 +88,8 @@ public InputProgram apply(InputProgram inputProgram) { CorePredicate headPredicate = head.getPredicate(); CorePredicate negPredicate = CorePredicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); - List headTerms = new ArrayList<>(head.getTerms()); - headTerms.add(0, ConstantTermImpl.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for + List headTerms = new ArrayList<>(head.getTerms()); + headTerms.add(0, CoreConstantTerm.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for // classical negative atoms. CoreAtom negHead = new BasicAtom(negPredicate, headTerms); @@ -110,7 +110,7 @@ public InputProgram apply(InputProgram inputProgram) { } private static boolean containsIntervalTerms(CoreAtom atom) { - for (Term term : atom.getTerms()) { + for (CoreTerm term : atom.getTerms()) { if (IntervalTerm.termContainsIntervalTerm(term)) { return true; } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java index 4aefc6db1..0307133cf 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java @@ -27,21 +27,22 @@ */ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.program.NormalProgram; import at.ac.tuwien.kr.alpha.common.rule.NormalRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalAtom; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - /** * Rewrites all interval terms in a rule into a new variable and an IntervalAtom. * @@ -84,10 +85,10 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { */ private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { CoreAtom atom = lit.getAtom(); - List termList = new ArrayList<>(atom.getTerms()); + List termList = new ArrayList<>(atom.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { - Term term = termList.get(i); + CoreTerm term = termList.get(i); if (term instanceof IntervalTerm) { VariableTerm replacementVariable = VariableTerm.getInstance(INTERVAL_VARIABLE_PREFIX + intervalReplacement.size()); intervalReplacement.put(replacementVariable, (IntervalTerm) term); @@ -109,10 +110,10 @@ private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { - List termList = new ArrayList<>(functionTerm.getTerms()); + List termList = new ArrayList<>(functionTerm.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { - Term term = termList.get(i); + CoreTerm term = termList.get(i); if (term instanceof IntervalTerm) { VariableTerm replacementVariable = VariableTerm.getInstance("_Interval" + intervalReplacement.size()); intervalReplacement.put(replacementVariable, (IntervalTerm) term); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java index 74fe4e363..956296bdd 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java @@ -1,16 +1,18 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import java.util.ArrayList; +import java.util.List; + import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.head.Head; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import java.util.ArrayList; -import java.util.List; - /** * * Rewrites all predicates of a given Program such that they are internal and hence hidden from answer sets. diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java index a9d66cb6b..4c7b470ef 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java @@ -1,9 +1,25 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import org.apache.commons.collections4.SetUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; import at.ac.tuwien.kr.alpha.common.depgraph.Node; @@ -21,21 +37,6 @@ import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; import at.ac.tuwien.kr.alpha.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy; -import org.apache.commons.collections4.SetUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Stack; /** * Evaluates the stratifiable part of a given (analyzed) ASP program. @@ -51,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 List additionalFacts = new ArrayList<>(); // 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; @@ -172,7 +173,7 @@ private void prepareInitialEvaluation(Set rulesToEvaluate) { modifiedInLastEvaluationRun.get(headPredicate).addAll(headInstances.getAllInstances()); } // Register positive body literal instances. - for (Literal lit : rule.getPositiveBody()) { + for (CoreLiteral lit : rule.getPositiveBody()) { CorePredicate bodyPredicate = lit.getPredicate(); IndexedInstanceStorage bodyInstances = workingMemory.get(bodyPredicate, true); modifiedInLastEvaluationRun.putIfAbsent(bodyPredicate, new LinkedHashSet<>()); @@ -202,17 +203,17 @@ private List calculateSatisfyingSubstitutionsForRule(InternalRule return calcSubstitutionsWithGroundingOrder(fixedGroundingOrder, Collections.singletonList(new Substitution())); } - List startingLiterals = groundingOrders.getStartingLiterals(); + List startingLiterals = groundingOrders.getStartingLiterals(); // Check only one starting literal if indicated by the parameter. if (!checkAllStartingLiterals) { // If this is the first evaluation run, it suffices to start from the first starting literal only. - Literal lit = startingLiterals.get(0); + CoreLiteral lit = startingLiterals.get(0); return calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), substituteFromRecentlyAddedInstances(lit)); } // Ground from all starting literals. List groundSubstitutions = new ArrayList<>(); // Collection of full ground substitutions for the given rule. - for (Literal lit : startingLiterals) { + for (CoreLiteral lit : startingLiterals) { List substitutionsForStartingLiteral = calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), substituteFromRecentlyAddedInstances(lit)); groundSubstitutions.addAll(substitutionsForStartingLiteral); @@ -229,7 +230,7 @@ private List calculateSatisfyingSubstitutionsForRule(InternalRule * @return valid ground substitutions for the literal based on the recently added instances (i.e. instances derived in * the last evaluation run). */ - private List substituteFromRecentlyAddedInstances(Literal lit) { + private List substituteFromRecentlyAddedInstances(CoreLiteral lit) { List retVal = new ArrayList<>(); Set instances = modifiedInLastEvaluationRun.get(lit.getPredicate()); if (instances == null) { @@ -268,7 +269,7 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde } // In case the full grounding order has been worked on, all current substitutions are full substitutions, add them to // result. - Literal currentLiteral = groundingOrder.getLiteralAtOrderPosition(currentOrderPosition); + CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(currentOrderPosition); if (currentLiteral == null) { fullSubstitutions.addAll(currentSubstitutions); currentSubstitutions.clear(); @@ -296,7 +297,7 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde } private void fireRule(InternalRule rule, Substitution substitution) { - Atom newAtom = rule.getHeadAtom().substitute(substitution); + CoreAtom newAtom = rule.getHeadAtom().substitute(substitution); if (!newAtom.isGround()) { throw new IllegalStateException("Trying to fire rule " + rule.toString() + " with incompatible substitution " + substitution.toString()); } @@ -324,7 +325,7 @@ private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { // Note: here we assume that all rules defining a predicate belong to the same SC component. for (InternalRule rule : definingRules) { boolean isRuleRecursive = false; - for (Literal lit : rule.getPositiveBody()) { + for (CoreLiteral lit : rule.getPositiveBody()) { if (headPredicates.contains(lit.getPredicate())) { // The rule body contains a predicate that is defined in the same // component, the rule is therefore part of a cyclic dependency within diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java index c6435794d..c12827fa7 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java @@ -1,27 +1,27 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; +import static at.ac.tuwien.kr.alpha.grounder.transformation.PredicateInternalizer.makePredicatesInternal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.program.InputProgram; import at.ac.tuwien.kr.alpha.common.rule.BasicRule; import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.grounder.Unifier; import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import static at.ac.tuwien.kr.alpha.grounder.transformation.PredicateInternalizer.makePredicatesInternal; - /** * Rewrites #sum aggregates into normal rules. * Note: Currently only works for a restricted form. @@ -62,7 +62,7 @@ public InputProgram apply(InputProgram inputProgram) { // The enumeration rule is: "input_number_with_first(A, I, F) :- input_with_first(A, X, F), _index(A, X, I)." BasicRule tmpEnumRule = makePredicatesInternal(parse("input_number_with_first(A, I, F) :- input_with_first(A, X, F).")).getRules().get(0); EnumerationAtom enumerationAtom = new EnumerationAtom(parse("index(A, X, I).").getFacts().get(0).getTerms()); - List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); + List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); enumerationRuleBody.add(enumerationAtom.toLiteral()); BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); prgBuilder.addRule(enumerationRule); @@ -78,7 +78,7 @@ public InputProgram apply(InputProgram inputProgram) { */ private boolean rewritingNecessary(InputProgram program) { for (BasicRule rule : program.getRules()) { - for (Literal lit : rule.getBody()) { + for (CoreLiteral lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.SUM) { @@ -117,13 +117,13 @@ private List rewriteAggregatesInRule(BasicRule rule) { final BasicAtom lowerBoundAtom = (BasicAtom) makePredicatesInternal(parse( "bound(aggregate(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - ArrayList aggregateOutputAtoms = new ArrayList<>(); + ArrayList aggregateOutputAtoms = new ArrayList<>(); int aggregatesInRule = 0; // Only needed for limited rewriting. ArrayList additionalRules = new ArrayList<>(); - List rewrittenBody = new ArrayList<>(rule.getBody()); - for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { - Literal bodyElement = iterator.next(); + List rewrittenBody = new ArrayList<>(rule.getBody()); + for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { + CoreLiteral bodyElement = iterator.next(); // Skip non-aggregates. if (!(bodyElement instanceof AggregateLiteral)) { continue; @@ -149,13 +149,13 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Prepare aggregate parameters. aggregateCount++; Unifier aggregateUnifier = new Unifier(); - Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); + Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), ConstantTerm.getInstance(aggregateCount)); + aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier - ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); - globalVariableTermlist.add(ConstantTerm.getInstance(aggregateCount)); + ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); + globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); } aggregateUnifier.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); @@ -166,7 +166,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create input to sorting network from aggregate elements. for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. - List elementTerms = aggregateElement.getElementTerms(); + List elementTerms = aggregateElement.getElementTerms(); FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); Unifier elementUnifier = new Unifier(aggregateUnifier); elementUnifier.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); @@ -174,7 +174,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementUnifier); - List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); + List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); // If there are global variables used inside the aggregate, add original rule body (minus the aggregate itself) to input rule. if (!globalVariables.isEmpty()) { @@ -186,7 +186,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create lower bound for the aggregate. BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateUnifier); - List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. + List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); } if (aggregatesInRule > 0) { diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java index ff1c13b37..7a86941fc 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java @@ -27,15 +27,6 @@ */ package at.ac.tuwien.kr.alpha.grounder.transformation; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.TermImpl; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Unifier; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -46,6 +37,16 @@ import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.common.rule.NormalRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Unifier; + /** * Removes variable equalities from rules by replacing one variable with the other. * @@ -65,8 +66,8 @@ public NormalProgram apply(NormalProgram inputProgram) { private NormalRule findAndReplaceVariableEquality(NormalRule rule) { // Collect all equal variables. HashMap> variableToEqualVariables = new LinkedHashMap<>(); - HashSet equalitiesToRemove = new HashSet<>(); - for (Literal bodyElement : rule.getBody()) { + HashSet equalitiesToRemove = new HashSet<>(); + for (CoreLiteral bodyElement : rule.getBody()) { if (!(bodyElement instanceof ComparisonLiteral)) { continue; } @@ -128,7 +129,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { bodyIterator.remove(); } for (int i = 0; i < literal.getTerms().size(); i++) { - TermImpl replaced = literal.getTerms().get(i).substitute(replacementSubstitution); + CoreTerm replaced = literal.getTerms().get(i).substitute(replacementSubstitution); literal.getTerms().set(i, replaced); } } @@ -136,7 +137,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { if (rewrittenHead != null) { CoreAtom headAtom = rewrittenHead.getAtom(); for (int i = 0; i < headAtom.getTerms().size(); i++) { - TermImpl replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); + CoreTerm replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); headAtom.getTerms().set(i, replaced); } } diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java index 3ff48ed66..506dddbcd 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java @@ -41,7 +41,7 @@ */ public class AtomCounter { - private final Map, Integer> countByType = new HashMap<>(); + private final Map, Integer> countByType = new HashMap<>(); public void add(CoreAtom atom) { countByType.compute(atom.getClass(), (k, v) -> (v == null) ? 1 : v + 1); @@ -60,7 +60,7 @@ public int getNumberOfAtoms(Class type) { */ public String getStatsByType() { List statsList = new ArrayList<>(); - for (Map.Entry, Integer> entry : countByType.entrySet()) { + for (Map.Entry, Integer> entry : countByType.entrySet()) { statsList.add(entry.getKey().getSimpleName() + ": " + entry.getValue()); } Collections.sort(statsList); diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java index 7873ab386..34560c693 100644 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java +++ b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java @@ -36,11 +36,6 @@ import static at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; import static at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTermImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; @@ -52,12 +47,19 @@ import java.util.Set; import java.util.function.Consumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import at.ac.tuwien.kr.alpha.common.AnswerSet; import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.config.SystemConfig; import at.ac.tuwien.kr.alpha.grounder.Grounder; import at.ac.tuwien.kr.alpha.grounder.ProgramAnalyzingGrounder; @@ -302,7 +304,7 @@ private boolean justifyMbtAndBacktrack() { LOGGER.debug("Searching for justification of {} / {}", atomToJustify, atomStore.atomToString(atomToJustify)); LOGGER.debug("Assignment is (TRUE part only): {}", translate(assignment.getTrueAssignments())); } - Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomToJustify, assignment); + Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomToJustify, assignment); NoGood noGood = noGoodFromJustificationReasons(atomToJustify, reasonsForUnjustified); @@ -318,12 +320,12 @@ private boolean justifyMbtAndBacktrack() { return true; } - private NoGood noGoodFromJustificationReasons(int atomToJustify, Set reasonsForUnjustified) { + private NoGood noGoodFromJustificationReasons(int atomToJustify, Set reasonsForUnjustified) { // Turn the justification into a NoGood. int[] reasons = new int[reasonsForUnjustified.size() + 1]; reasons[0] = atomToLiteral(atomToJustify); int arrpos = 1; - for (Literal literal : reasonsForUnjustified) { + for (CoreLiteral literal : reasonsForUnjustified) { reasons[arrpos++] = atomToLiteral(atomStore.get(literal.getAtom()), !literal.isNegated()); } return NoGood.learnt(reasons); @@ -354,7 +356,7 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { ArrayList ruleAtomReplacements = new ArrayList<>(); while (toJustifyIterator.hasNext()) { Integer literal = toJustifyIterator.next(); - Atom atom = atomStore.get(atomOf(literal)); + CoreAtom atom = atomStore.get(atomOf(literal)); if (atom instanceof BasicAtom) { continue; } @@ -365,9 +367,9 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { } // For RuleAtoms in toJustify the corresponding ground body contains BasicAtoms that have been assigned FALSE in the closing. // First, translate RuleAtom back to NonGroundRule + Substitution. - String ruleId = (String) ((ConstantTermImpl)atom.getTerms().get(0)).getObject(); + String ruleId = (String) ((CoreConstantTerm)atom.getTerms().get(0)).getObject(); InternalRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); - String substitution = (String) ((ConstantTermImpl)atom.getTerms().get(1)).getObject(); + String substitution = (String) ((CoreConstantTerm)atom.getTerms().get(1)).getObject(); Substitution groundingSubstitution = Substitution.fromString(substitution); // Find ground literals in the body that have been assigned false and justify those. for (CoreLiteral bodyLiteral : nonGroundRule.getBody()) { @@ -388,7 +390,7 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { toJustify.addAll(ruleAtomReplacements); for (Integer literalToJustify : toJustify) { LOGGER.debug("Searching for justification(s) of {} / {}", toJustify, atomStore.atomToString(atomOf(literalToJustify))); - Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomOf(literalToJustify), assignment); + Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomOf(literalToJustify), assignment); NoGood noGood = noGoodFromJustificationReasons(atomOf(literalToJustify), reasonsForUnjustified); int noGoodID = grounder.register(noGood); obtained.put(noGoodID, noGood); From 2a456289fa2338a02a1895a6c8da68cda62d4845 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 19 Dec 2020 18:45:39 +0100 Subject: [PATCH 009/111] adapt module names, add module alpha-solver --- alpha-api/build.gradle | 11 + .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 4 + .../kr/alpha/api/externals/Predicate.java | 27 + .../api/mapper/AnswerSetToObjectMapper.java | 41 + .../api/mapper/AnswerSetToWorkbookMapper.java | 137 +++ .../ac/tuwien/kr/alpha/common/AnswerSet.java | 13 + .../ac/tuwien/kr/alpha/common/Predicate.java | 7 + .../ac/tuwien/kr/alpha/common/atoms/Atom.java | 29 + .../tuwien/kr/alpha/common/atoms/Literal.java | 20 + .../BindingPredicateInterpretation.java | 9 + .../PredicateInterpretation.java | 46 + .../kr/alpha/common/program/Program.java | 4 + .../ac/tuwien/kr/alpha/common/rules/Head.java | 4 + .../ac/tuwien/kr/alpha/common/rules/Rule.java | 4 + .../kr/alpha/common/terms/ConstantTerm.java | 4 + .../ac/tuwien/kr/alpha/common/terms/Term.java | 5 + .../tuwien/kr/alpha/config/AlphaConfig.java | 27 + .../tuwien/kr/alpha/config/InputConfig.java | 170 +++ .../tuwien/kr/alpha/config/SystemConfig.java | 258 +++++ .../GrounderHeuristicsConfiguration.java | 148 +++ ...ryNoGoodPropagationEstimationStrategy.java | 27 + .../kr/alpha/solver/heuristics/Heuristic.java | 52 + alpha-cli-app/build.gradle | 40 + .../kr/alpha/AnswerSetToXlsxWriter.java | 60 + .../main/java/at/ac/tuwien/kr/alpha/Main.java | 234 ++++ .../kr/alpha/config/CliOptionHandler.java | 11 + .../kr/alpha/config/CommandLineParser.java | 482 ++++++++ alpha-cli-app/src/main/resources/logback.xml | 15 + alpha-core/build.gradle | 57 + .../at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 | 90 ++ .../at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 | 50 + .../tuwien/kr/alpha/CustomErrorListener.java | 28 + .../main/java/at/ac/tuwien/kr/alpha/Util.java | 121 ++ .../kr/alpha/api/externals/Externals.java | 143 +++ .../externals/stdlib/AspStandardLibrary.java | 214 ++++ .../kr/alpha/common/AnswerSetBuilder.java | 99 ++ .../kr/alpha/common/AnswerSetFormatter.java | 6 + .../ac/tuwien/kr/alpha/common/Assignment.java | 184 +++ .../ac/tuwien/kr/alpha/common/AtomStore.java | 120 ++ .../tuwien/kr/alpha/common/AtomStoreImpl.java | 132 +++ .../kr/alpha/common/BasicAnswerSet.java | 117 ++ .../kr/alpha/common/ComparisonOperator.java | 39 + .../tuwien/kr/alpha/common/CorePredicate.java | 107 ++ .../tuwien/kr/alpha/common/IntIterator.java | 20 + .../ac/tuwien/kr/alpha/common/Interner.java | 26 + .../ac/tuwien/kr/alpha/common/Literals.java | 83 ++ .../at/ac/tuwien/kr/alpha/common/NoGood.java | 288 +++++ .../kr/alpha/common/NoGoodInterface.java | 95 ++ .../common/SimpleAnswerSetFormatter.java | 33 + .../at/ac/tuwien/kr/alpha/common/Truth.java | 10 + .../kr/alpha/common/atoms/AggregateAtom.java | 269 +++++ .../alpha/common/atoms/AggregateLiteral.java | 64 ++ .../kr/alpha/common/atoms/BasicAtom.java | 166 +++ .../kr/alpha/common/atoms/BasicLiteral.java | 105 ++ .../kr/alpha/common/atoms/ComparisonAtom.java | 128 +++ .../alpha/common/atoms/ComparisonLiteral.java | 218 ++++ .../kr/alpha/common/atoms/CoreAtom.java | 132 +++ .../kr/alpha/common/atoms/CoreLiteral.java | 122 ++ .../kr/alpha/common/atoms/ExternalAtom.java | 180 +++ .../alpha/common/atoms/ExternalLiteral.java | 209 ++++ .../atoms/FixedInterpretationLiteral.java | 62 + .../atoms/VariableNormalizableAtom.java | 20 + .../alpha/common/depgraph/ComponentGraph.java | 201 ++++ .../common/depgraph/DependencyGraph.java | 167 +++ .../depgraph/DepthFirstSearchAlgorithm.java | 117 ++ .../tuwien/kr/alpha/common/depgraph/Edge.java | 79 ++ .../tuwien/kr/alpha/common/depgraph/Node.java | 70 ++ .../depgraph/StratificationAlgorithm.java | 126 +++ .../StronglyConnectedComponentsAlgorithm.java | 118 ++ .../BinaryPredicateInterpretation.java | 50 + .../BindingMethodPredicateInterpretation.java | 97 ++ .../IntPredicateInterpretation.java | 48 + .../LongPredicateInterpretation.java | 48 + .../MethodPredicateInterpretation.java | 81 ++ .../NonBindingPredicateInterpretation.java | 78 ++ .../PredicateInterpretationImpl.java | 12 + .../SuppliedPredicateInterpretation.java | 51 + .../UnaryPredicateInterpretation.java | 46 + .../common/graphio/ComponentGraphWriter.java | 101 ++ .../common/graphio/DependencyGraphWriter.java | 98 ++ .../alpha/common/program/AbstractProgram.java | 52 + .../alpha/common/program/AnalyzedProgram.java | 48 + .../kr/alpha/common/program/InputProgram.java | 117 ++ .../alpha/common/program/InternalProgram.java | 89 ++ .../alpha/common/program/NormalProgram.java | 31 + .../kr/alpha/common/program/Programs.java | 23 + .../kr/alpha/common/rule/AbstractRule.java | 128 +++ .../kr/alpha/common/rule/BasicRule.java | 45 + .../kr/alpha/common/rule/InternalRule.java | 139 +++ .../kr/alpha/common/rule/NormalRule.java | 50 + .../kr/alpha/common/rule/head/ChoiceHead.java | 147 +++ .../common/rule/head/DisjunctiveHead.java | 66 ++ .../kr/alpha/common/rule/head/Head.java | 19 + .../kr/alpha/common/rule/head/NormalHead.java | 61 + .../kr/alpha/common/terms/ArithmeticTerm.java | 268 +++++ .../alpha/common/terms/CoreConstantTerm.java | 154 +++ .../kr/alpha/common/terms/CoreTerm.java | 100 ++ .../kr/alpha/common/terms/FunctionTerm.java | 157 +++ .../kr/alpha/common/terms/IntervalTerm.java | 160 +++ .../tuwien/kr/alpha/common/terms/Terms.java | 33 + .../kr/alpha/common/terms/VariableTerm.java | 108 ++ .../kr/alpha/grounder/AbstractGrounder.java | 18 + .../kr/alpha/grounder/BridgedGrounder.java | 34 + .../kr/alpha/grounder/ChoiceRecorder.java | 128 +++ .../alpha/grounder/FactIntervalEvaluator.java | 67 ++ .../kr/alpha/grounder/FilteringGrounder.java | 18 + .../ac/tuwien/kr/alpha/grounder/Grounder.java | 82 ++ .../kr/alpha/grounder/GrounderFactory.java | 55 + .../grounder/IndexedInstanceStorage.java | 222 ++++ .../ac/tuwien/kr/alpha/grounder/Instance.java | 57 + .../kr/alpha/grounder/IntIdGenerator.java | 33 + .../kr/alpha/grounder/NaiveGrounder.java | 639 +++++++++++ .../kr/alpha/grounder/NoGoodGenerator.java | 204 ++++ .../kr/alpha/grounder/NogoodRegistry.java | 44 + .../grounder/ProgramAnalyzingGrounder.java | 36 + .../kr/alpha/grounder/RuleGroundingOrder.java | 132 +++ .../alpha/grounder/RuleGroundingOrders.java | 229 ++++ .../kr/alpha/grounder/Substitution.java | 248 ++++ .../tuwien/kr/alpha/grounder/Unification.java | 116 ++ .../ac/tuwien/kr/alpha/grounder/Unifier.java | 134 +++ .../kr/alpha/grounder/WorkingMemory.java | 113 ++ .../kr/alpha/grounder/atoms/ChoiceAtom.java | 140 +++ .../alpha/grounder/atoms/EnumerationAtom.java | 95 ++ .../grounder/atoms/EnumerationLiteral.java | 59 + .../kr/alpha/grounder/atoms/IntervalAtom.java | 136 +++ .../alpha/grounder/atoms/IntervalLiteral.java | 119 ++ .../kr/alpha/grounder/atoms/RuleAtom.java | 122 ++ .../kr/alpha/grounder/bridges/Bridge.java | 12 + .../AbstractLiteralInstantiationStrategy.java | 131 +++ .../instantiation/AssignmentStatus.java | 57 + .../grounder/instantiation/BindingResult.java | 74 ++ ...ultLazyGroundingInstantiationStrategy.java | 177 +++ .../LiteralInstantiationResult.java | 140 +++ .../LiteralInstantiationStrategy.java | 65 ++ .../instantiation/LiteralInstantiator.java | 187 +++ ...rkingMemoryBasedInstantiationStrategy.java | 69 ++ .../grounder/parser/InlineDirectives.java | 34 + .../grounder/parser/ParseTreeVisitor.java | 583 ++++++++++ .../alpha/grounder/parser/ProgramParser.java | 111 ++ .../grounder/parser/ProgramPartParser.java | 80 ++ .../kr/alpha/grounder/rete/TupleIndex.java | 7 + .../kr/alpha/grounder/rete/TupleStore.java | 10 + .../structure/AnalyzeUnjustified.java | 409 +++++++ .../kr/alpha/grounder/structure/LitSet.java | 143 +++ .../CardinalityNormalization.java | 259 +++++ .../transformation/ChoiceHeadToNormal.java | 120 ++ .../transformation/EnumerationRewriting.java | 86 ++ .../IntervalTermToIntervalAtom.java | 157 +++ .../NormalizeProgramTransformation.java | 42 + .../transformation/PredicateInternalizer.java | 61 + .../transformation/ProgramTransformation.java | 12 + .../transformation/StratifiedEvaluation.java | 369 ++++++ .../transformation/SumNormalization.java | 201 ++++ .../VariableEqualityRemoval.java | 146 +++ .../kr/alpha/solver/AbstractSolver.java | 38 + .../ac/tuwien/kr/alpha/solver/Antecedent.java | 17 + .../tuwien/kr/alpha/solver/AtomCounter.java | 70 ++ .../at/ac/tuwien/kr/alpha/solver/Atoms.java | 9 + .../BinaryNoGoodPropagationEstimation.java | 52 + .../ac/tuwien/kr/alpha/solver/Checkable.java | 12 + .../at/ac/tuwien/kr/alpha/solver/Choice.java | 64 ++ .../alpha/solver/ChoiceInfluenceManager.java | 235 ++++ .../tuwien/kr/alpha/solver/ChoiceManager.java | 325 ++++++ .../tuwien/kr/alpha/solver/ConflictCause.java | 26 + .../tuwien/kr/alpha/solver/DefaultSolver.java | 599 ++++++++++ .../alpha/solver/LearnedNoGoodDeletion.java | 116 ++ .../kr/alpha/solver/NaiveNoGoodStore.java | 231 ++++ .../tuwien/kr/alpha/solver/NaiveSolver.java | 432 +++++++ .../tuwien/kr/alpha/solver/NoGoodCounter.java | 129 +++ .../tuwien/kr/alpha/solver/NoGoodStore.java | 58 + .../alpha/solver/NoGoodStoreAlphaRoaming.java | 1003 +++++++++++++++++ .../kr/alpha/solver/PerformanceLog.java | 73 ++ .../kr/alpha/solver/ShallowAntecedent.java | 33 + .../at/ac/tuwien/kr/alpha/solver/Solver.java | 27 + .../tuwien/kr/alpha/solver/SolverFactory.java | 76 ++ .../solver/SolverMaintainingStatistics.java | 68 ++ .../tuwien/kr/alpha/solver/ThriceTruth.java | 77 ++ .../kr/alpha/solver/TrailAssignment.java | 783 +++++++++++++ .../tuwien/kr/alpha/solver/WatchedNoGood.java | 213 ++++ .../kr/alpha/solver/WritableAssignment.java | 97 ++ .../ActivityBasedBranchingHeuristic.java | 42 + .../heuristics/AlphaActiveRuleHeuristic.java | 61 + .../AlphaHeadMustBeTrueHeuristic.java | 68 ++ .../heuristics/AlphaRandomSignHeuristic.java | 65 ++ .../kr/alpha/solver/heuristics/BerkMin.java | 280 +++++ .../solver/heuristics/BerkMinLiteral.java | 82 ++ .../solver/heuristics/BranchingHeuristic.java | 84 ++ .../heuristics/BranchingHeuristicFactory.java | 94 ++ .../ChainedBranchingHeuristics.java | 125 ++ .../heuristics/DependencyDrivenHeuristic.java | 361 ++++++ .../DependencyDrivenPyroHeuristic.java | 64 ++ .../heuristics/DependencyDrivenVSIDS.java | 70 ++ .../GeneralizedDependencyDrivenHeuristic.java | 91 ++ ...eralizedDependencyDrivenPyroHeuristic.java | 65 ++ .../solver/heuristics/HeapOfActiveAtoms.java | 283 +++++ .../heuristics/HeapOfActiveChoicePoints.java | 110 ++ .../heuristics/HeuristicsConfiguration.java | 98 ++ .../HeuristicsConfigurationBuilder.java | 69 ++ .../kr/alpha/solver/heuristics/MOMs.java | 68 ++ .../solver/heuristics/NaiveHeuristic.java | 75 ++ .../solver/heuristics/ReplayHeuristic.java | 90 ++ .../kr/alpha/solver/heuristics/VSIDS.java | 252 +++++ .../activity/AvgBodyActivityProvider.java | 43 + .../activity/BodyActivityProvider.java | 52 + .../activity/BodyActivityProviderFactory.java | 56 + .../activity/DefaultBodyActivityProvider.java | 43 + .../activity/MaxBodyActivityProvider.java | 43 + .../activity/MinBodyActivityProvider.java | 43 + .../activity/SumBodyActivityProvider.java | 43 + .../learning/GroundConflictNoGoodLearner.java | 361 ++++++ .../solver/learning/ResolutionSequence.java | 7 + alpha-solver/build.gradle | 10 + .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 228 ++++ settings.gradle | 2 +- 214 files changed, 24621 insertions(+), 1 deletion(-) create mode 100644 alpha-api/build.gradle create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java create mode 100644 alpha-cli-app/build.gradle create mode 100644 alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java create mode 100644 alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java create mode 100644 alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java create mode 100644 alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java create mode 100644 alpha-cli-app/src/main/resources/logback.xml create mode 100644 alpha-core/build.gradle create mode 100644 alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 create mode 100644 alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/Util.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java create mode 100644 alpha-solver/build.gradle create mode 100644 alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java diff --git a/alpha-api/build.gradle b/alpha-api/build.gradle new file mode 100644 index 000000000..105ea638a --- /dev/null +++ b/alpha-api/build.gradle @@ -0,0 +1,11 @@ +plugins { + id 'alpha.java-library-conventions' +} + +dependencies { + implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7' + implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' + implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' + implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' +} + 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 new file mode 100644 index 000000000..a267fc6f4 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.api; + +public interface Alpha { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java new file mode 100644 index 000000000..928f2cf99 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java @@ -0,0 +1,27 @@ +package at.ac.tuwien.kr.alpha.api.externals; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used for discovery of method that represent + * external predicates at runtime. + * + * In order to have your method detected by Alpha, annotate it + * with this annotation and call {@link Externals#scan}. + * + * @see Externals#scan + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Predicate { + /** + * The name of the predicate that will be used to refer to + * the annotated method. If it is the empty string (which + * is also the default value), then the name of the annotated + * method will be used. + */ + String name() default ""; +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java new file mode 100644 index 000000000..8f745e556 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.api.mapper; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; + +/** + * Copyright (c) 2020, the Alpha Team. + * + * Interface definition for an adapter that maps from an {@link AnswerSet} to an instance of the implementation's generic type T. + * + * @param the type to which to map answer sets + */ +public interface AnswerSetToObjectMapper { + + T mapFromAnswerSet(AnswerSet answerSet); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java new file mode 100644 index 000000000..4b7af303a --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.api.mapper; + +import java.util.List; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +/** + * Implementation of {@link AnswerSetToObjectMapper} that generates an office open xml workbook ("excel file") from a given answer set. + * + * Copyright (c) 2020, the Alpha Team. + */ +public class AnswerSetToWorkbookMapper implements AnswerSetToObjectMapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(AnswerSetToWorkbookMapper.class); + + /** + * Creates an xlsx workbook containing all the atoms from the given {@link AnswerSet} with one sheet per predicate. All predicates with arity 0 are listed + * in a special sheet called "flags". Caution, potential resource leak: note that the returned workbook needs to be closed by the caller once it has been + * processed (written to file etc). + */ + @Override + public Workbook mapFromAnswerSet(AnswerSet answerSet) { + LOGGER.debug("Start mapping answer set to workbook"); + Workbook workbook = new XSSFWorkbook(); + // create cell style for header cells + CellStyle headerStyle = this.createHeaderStyle(workbook); + + // first, create a worksheet for 0-arity predicates + Sheet flags = this.createSheetWithHeader(workbook, headerStyle, "Flags", "Flags"); + Sheet currentPredicateSheet; + String[] headerContent; + for (Predicate pred : answerSet.getPredicates()) { + if (pred.getArity() == 0) { + this.writeAtomToSheet(flags, answerSet.getPredicateInstances(pred).first()); + } else { + headerContent = new String[pred.getArity()]; + for (int i = 0; i < headerContent.length; i++) { + headerContent[i] = "Attribute " + Integer.toString(i + 1); + } + currentPredicateSheet = this.createSheetWithHeader(workbook, headerStyle, pred.getName() + "_" + pred.getArity(), headerContent); + for (Atom atom : answerSet.getPredicateInstances(pred)) { + this.writeAtomToSheet(currentPredicateSheet, atom); + } + } + } + return workbook; + } + + private void writeAtomToSheet(Sheet sheet, Atom atom) { + int rownum = -1; + if (sheet.getLastRowNum() == 0 && sheet.getRow(0) == null) { + // sheet is empty, start at row zero + rownum = 0; + } else { + rownum = sheet.getLastRowNum() + 1; + } + Row atomRow = sheet.createRow(rownum); + List terms = atom.getTerms(); + Cell currCell; + if (terms.isEmpty()) { + // 0-arity atom + currCell = atomRow.createCell(0); + currCell.setCellValue(atom.getPredicate().getName()); + sheet.autoSizeColumn(0); + } else { + for (int i = 0; i < terms.size(); i++) { + currCell = atomRow.createCell(i); + currCell.setCellValue(terms.get(i).toString()); + sheet.autoSizeColumn(i); + } + } + } + + private CellStyle createHeaderStyle(Workbook workbook) { + CellStyle headerStyle = workbook.createCellStyle(); + Font headerFont = workbook.createFont(); + headerFont.setFontHeightInPoints((short) 11); + headerFont.setBold(true); // (short) 0x74c4f2 + headerStyle.setFont(headerFont); + headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + return headerStyle; + } + + private Sheet createSheetWithHeader(Workbook wb, CellStyle headerStyle, String sheetName, String... headerContent) { + Sheet retVal = wb.createSheet(sheetName); + Row headerRow = retVal.createRow(0); + Cell cell; + for (int i = 0; i < headerContent.length; i++) { + cell = headerRow.createCell(i); + cell.setCellStyle(headerStyle); + cell.setCellValue(headerContent[i]); + } + return retVal; + } + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java new file mode 100644 index 000000000..11c98b9e6 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java @@ -0,0 +1,13 @@ +package at.ac.tuwien.kr.alpha.common; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; + +import java.util.SortedSet; + +public interface AnswerSet extends Comparable { + SortedSet getPredicates(); + + SortedSet getPredicateInstances(Predicate predicate); + + boolean isEmpty(); +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java new file mode 100644 index 000000000..28d5811e4 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java @@ -0,0 +1,7 @@ +package at.ac.tuwien.kr.alpha.common; + +public interface Predicate extends Comparable { + String getName(); + + int getArity(); +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java new file mode 100644 index 000000000..41bf3da32 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java @@ -0,0 +1,29 @@ +package at.ac.tuwien.kr.alpha.common.atoms; + +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; + +public interface Atom extends Comparable { + Predicate getPredicate(); + + List getTerms(); + + /** + * Returns whether this atom is ground, i.e., variable-free. + * + * @return true iff the terms of this atom contain no {@link VariableTerm}. + */ + boolean isGround(); + + Literal toLiteral(); + + /** + * Creates a literal containing this atom which will be negated if {@code positive} is {@code false}. + * + * @param positive the polarity of the resulting literal. + * @return a literal that is positive iff the given parameter is true. + */ + Literal toLiteral(boolean positive); +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java new file mode 100644 index 000000000..12b583fd2 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java @@ -0,0 +1,20 @@ +package at.ac.tuwien.kr.alpha.common.atoms; + +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; + +public interface Literal { + Atom getAtom(); + + boolean isNegated(); + + Literal negate(); + + Predicate getPredicate(); + + List getTerms(); + + boolean isGround(); +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java new file mode 100644 index 000000000..e354d35a5 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java @@ -0,0 +1,9 @@ +package at.ac.tuwien.kr.alpha.common.fixedinterpretations; + +/** + * This interface is used to mark predicate interpretations that might generate + * new bindings. + */ +@FunctionalInterface +public interface BindingPredicateInterpretation extends PredicateInterpretation { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java new file mode 100644 index 000000000..96f454b8e --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; +import java.util.Set; + +import static java.util.Collections.*; + +@FunctionalInterface +public interface PredicateInterpretation { + 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); +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java new file mode 100644 index 000000000..4327a4c0e --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.program; + +public interface Program { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java new file mode 100644 index 000000000..0b16a5ecf --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.rules; + +public interface Head { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java new file mode 100644 index 000000000..35778c7fb --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.rules; + +public interface Rule { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java new file mode 100644 index 000000000..795680347 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +public interface ConstantTerm> { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java new file mode 100644 index 000000000..9aae02494 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +public interface Term extends Comparable { + boolean isGround(); +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java new file mode 100644 index 000000000..86fbf473a --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java @@ -0,0 +1,27 @@ +package at.ac.tuwien.kr.alpha.config; + +/** + * Wrapper type for AlphaConfig and InputConfig. + */ +public class AlphaConfig { + + private SystemConfig systemConfig; + private InputConfig inputConfig; + + public SystemConfig getSystemConfig() { + return this.systemConfig; + } + + public void setSystemConfig(SystemConfig alphaConfig) { + this.systemConfig = alphaConfig; + } + + public InputConfig getInputConfig() { + return this.inputConfig; + } + + public void setInputConfig(InputConfig inputConfig) { + this.inputConfig = inputConfig; + } + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java new file mode 100644 index 000000000..12e5d3167 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java @@ -0,0 +1,170 @@ +package at.ac.tuwien.kr.alpha.config; + +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; + +import java.util.*; + +public class InputConfig { + + public static final java.util.function.Predicate DEFAULT_FILTER = p -> true; + public static final boolean DEFAULT_LITERATE = false; + public static final int DEFAULT_NUM_ANSWER_SETS = 0; + public static final boolean DEFAULT_WRITE_DEPENDENCY_GRAPH = false; + public static final String DEFAULT_DEPGRAPH_TARGET_FILE = "depgraph.dot"; + public static final boolean DEFAULT_WRITE_COMPONENT_GRAPH = false; + public static final String DEFAULT_COMPGRAPH_TARGET_FILE = "compgraph.dot"; + public static final boolean DEFAULT_WRITE_PREPROCESSED_PROG = false; + public static final String DEFAULT_PREPROC_TARGET_FILE = "input.preproc.asp"; + public static final String PREPROC_STDOUT_PATH = "---"; // indicator preprocessed program should be written to stdout + public static final boolean DEFAULT_WRITE_XLSX = false; + public static final String DEFAULT_XLSX_OUTFILE_PATH = "alphaAnswerSet"; // current directory, files named "alphaAnswerSet.{num}.{ext}" + + private List aspStrings = new ArrayList<>(); + private List files = new ArrayList<>(); + private boolean literate = InputConfig.DEFAULT_LITERATE; + private int numAnswerSets = InputConfig.DEFAULT_NUM_ANSWER_SETS; + private Set desiredPredicates = new HashSet<>(); + private boolean writeDependencyGraph = InputConfig.DEFAULT_WRITE_DEPENDENCY_GRAPH; + private String depgraphPath = InputConfig.DEFAULT_DEPGRAPH_TARGET_FILE; + private boolean writeComponentGraph = InputConfig.DEFAULT_WRITE_COMPONENT_GRAPH; + private String compgraphPath = InputConfig.DEFAULT_COMPGRAPH_TARGET_FILE; + private boolean writePreprocessed = InputConfig.DEFAULT_WRITE_PREPROCESSED_PROG; + private String preprocessedPath = InputConfig.DEFAULT_PREPROC_TARGET_FILE; + // TODO: standard library externals are NOT always loaded, but this was the case before introducing modules + private Map predicateMethods = new HashMap<>(); // Externals.getStandardLibraryExternals(); + private boolean writeAnswerSetsAsXlsx = InputConfig.DEFAULT_WRITE_XLSX; + private String answerSetFileOutputPath; + + public static InputConfig forString(String str) { + InputConfig retVal = new InputConfig(); + retVal.aspStrings.add(str); + return retVal; + } + + public List getAspStrings() { + return this.aspStrings; + } + + public void setAspStrings(List aspStrings) { + this.aspStrings = aspStrings; + } + + public boolean isLiterate() { + return this.literate; + } + + public void setLiterate(boolean literate) { + this.literate = literate; + } + + public int getNumAnswerSets() { + return this.numAnswerSets; + } + + public void setNumAnswerSets(int numAnswerSets) { + this.numAnswerSets = numAnswerSets; + } + + public java.util.function.Predicate getFilter() { + return this.desiredPredicates.isEmpty() ? InputConfig.DEFAULT_FILTER : p -> this.desiredPredicates.contains(p.getName()); + } + + public Map getPredicateMethods() { + return this.predicateMethods; + } + + public void addPredicateMethods(Map predicateMethods) { + for (Map.Entry entry : predicateMethods.entrySet()) { + if (this.predicateMethods.containsKey(entry.getKey())) { + throw new IllegalArgumentException("Input config already contains a predicate interpretation with name " + entry.getKey()); + } + this.predicateMethods.put(entry.getKey(), entry.getValue()); + } + } + + public void addPredicateMethod(String name, PredicateInterpretation interpretation) { + this.predicateMethods.put(name, interpretation); + } + + public List getFiles() { + return this.files; + } + + public void setFiles(List files) { + this.files = files; + } + + public Set getDesiredPredicates() { + return this.desiredPredicates; + } + + public void setDesiredPredicates(Set desiredPredicates) { + this.desiredPredicates = desiredPredicates; + } + + public boolean isWriteDependencyGraph() { + return this.writeDependencyGraph; + } + + public void setWriteDependencyGraph(boolean writeDependencyGraph) { + this.writeDependencyGraph = writeDependencyGraph; + } + + public boolean isWriteComponentGraph() { + return this.writeComponentGraph; + } + + public void setWriteComponentGraph(boolean writeComponentGraph) { + this.writeComponentGraph = writeComponentGraph; + } + + public boolean isWritePreprocessed() { + return this.writePreprocessed; + } + + public void setWritePreprocessed(boolean writePreprocessed) { + this.writePreprocessed = writePreprocessed; + } + + public String getDepgraphPath() { + return this.depgraphPath; + } + + public void setDepgraphPath(String depgraphPath) { + this.depgraphPath = depgraphPath; + } + + public String getCompgraphPath() { + return this.compgraphPath; + } + + public void setCompgraphPath(String compgraphPath) { + this.compgraphPath = compgraphPath; + } + + public String getPreprocessedPath() { + return this.preprocessedPath; + } + + public void setPreprocessedPath(String preprocessedPath) { + this.preprocessedPath = preprocessedPath; + } + + public boolean isWriteAnswerSetsAsXlsx() { + return this.writeAnswerSetsAsXlsx; + } + + public void setWriteAnswerSetsAsXlsx(boolean writeAnswerSetsAsXslx) { + this.writeAnswerSetsAsXlsx = writeAnswerSetsAsXslx; + } + + public String getAnswerSetFileOutputPath() { + return this.answerSetFileOutputPath; + } + + public void setAnswerSetFileOutputPath(String answerSetFileOutputPath) { + this.answerSetFileOutputPath = answerSetFileOutputPath; + } + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java new file mode 100644 index 000000000..4f38c37ba --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java @@ -0,0 +1,258 @@ +/** + * Copyright (c) 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.config; + +import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class SystemConfig { + + // Note: Defining constants for default values here rather than just + // 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; + public static final boolean DEFAULT_DEBUG_INTERNAL_CHECKS = false; + public static final boolean DEFAULT_USE_NORMALIZATION_GRID = 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; + public static final boolean DEFAULT_GROUNDER_ACCUMULATOR_ENABLED = false; + public static final String DEFAULT_ATOM_SEPARATOR = ", "; + + private String grounderName = SystemConfig.DEFAULT_GROUNDER_NAME; + private String solverName = SystemConfig.DEFAULT_SOLVER_NAME; + private String nogoodStoreName = SystemConfig.DEFAULT_NOGOOD_STORE_NAME; + private boolean deterministic = SystemConfig.DEFAULT_DETERMINISTIC; + private long seed = SystemConfig.DEFAULT_SEED; + private boolean debugInternalChecks = SystemConfig.DEFAULT_DEBUG_INTERNAL_CHECKS; + private Heuristic branchingHeuristic = SystemConfig.DEFAULT_BRANCHING_HEURISTIC; + private BinaryNoGoodPropagationEstimationStrategy momsStrategy = SystemConfig.DEFAULT_MOMS_STRATEGY; + private boolean quiet = SystemConfig.DEFAULT_QUIET; + private boolean printStats = SystemConfig.DEFAULT_PRINT_STATS; + private boolean disableJustificationSearch = SystemConfig.DEFAULT_DISABLE_JUSTIFICATION_SEARCH; + private boolean useNormalizationGrid = SystemConfig.DEFAULT_USE_NORMALIZATION_GRID; + private boolean sortAnswerSets = SystemConfig.DEFAULT_SORT_ANSWER_SETS; + private List replayChoices = SystemConfig.DEFAULT_REPLAY_CHOICES; + private boolean evaluateStratifiedPart = SystemConfig.DEFAULT_STRATIFIED_EVALUATION; + private boolean disableNoGoodDeletion = SystemConfig.DEFAULT_DISABLE_NOGOOD_DELETION; + private String grounderToleranceConstraints = DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS; + private String grounderToleranceRules = DEFAULT_GROUNDER_TOLERANCE_RULES; + private boolean grounderAccumulatorEnabled = DEFAULT_GROUNDER_ACCUMULATOR_ENABLED; + private String atomSeparator = DEFAULT_ATOM_SEPARATOR; + + public String getGrounderName() { + return this.grounderName; + } + + public void setGrounderName(String grounderName) { + this.grounderName = grounderName; + } + + public String getSolverName() { + return this.solverName; + } + + public void setSolverName(String solverName) { + this.solverName = solverName; + } + + public String getNogoodStoreName() { + return this.nogoodStoreName; + } + + public void setNogoodStoreName(String nogoodStoreName) { + this.nogoodStoreName = nogoodStoreName; + } + + public boolean isDeterministic() { + return this.deterministic; + } + + public void setDeterministic(boolean deterministic) { + this.deterministic = deterministic; + } + + public long getSeed() { + return this.seed; + } + + public void setSeed(long seed) { + this.seed = seed; + } + + public boolean isDebugInternalChecks() { + return this.debugInternalChecks; + } + + public void setDebugInternalChecks(boolean debugInternalChecks) { + this.debugInternalChecks = debugInternalChecks; + } + + public Heuristic getBranchingHeuristic() { + return this.branchingHeuristic; + } + + public void setBranchingHeuristic(Heuristic branchingHeuristic) { + this.branchingHeuristic = branchingHeuristic; + } + + public void setBranchingHeuristicName(String branchingHeuristicName) { + this.branchingHeuristic = Heuristic.valueOf(branchingHeuristicName.replace("-", "_").toUpperCase()); + } + + public BinaryNoGoodPropagationEstimationStrategy getMomsStrategy() { + return momsStrategy; + } + + public void setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + this.momsStrategy = momsStrategy; + } + + public void setMomsStrategyName(String momsStrategyName) { + this.momsStrategy = BinaryNoGoodPropagationEstimationStrategy.valueOf(momsStrategyName); + } + + public boolean isQuiet() { + return this.quiet; + } + + public void setQuiet(boolean quiet) { + this.quiet = quiet; + } + + public boolean isPrintStats() { + return this.printStats; + } + + public void setPrintStats(boolean printStats) { + this.printStats = printStats; + } + + public boolean isDisableJustificationSearch() { + return this.disableJustificationSearch; + } + + public void setDisableJustificationSearch(boolean disableJustificationSearch) { + this.disableJustificationSearch = disableJustificationSearch; + } + + public boolean isUseNormalizationGrid() { + return this.useNormalizationGrid; + } + + public void setUseNormalizationGrid(boolean useNormalizationGrid) { + this.useNormalizationGrid = useNormalizationGrid; + } + + public boolean isSortAnswerSets() { + return this.sortAnswerSets; + } + + public void setSortAnswerSets(boolean sortAnswerSets) { + this.sortAnswerSets = sortAnswerSets; + } + + public List getReplayChoices() { + return replayChoices; + } + + public void setReplayChoices(List replayChoices) { + this.replayChoices = replayChoices; + } + + 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; + } + + public void setDisableNoGoodDeletion(boolean disableNoGoodDeletion) { + this.disableNoGoodDeletion = disableNoGoodDeletion; + } + + public String getGrounderToleranceConstraints() { + return grounderToleranceConstraints; + } + + public void setGrounderToleranceConstraints(String grounderToleranceConstraints) { + this.grounderToleranceConstraints = grounderToleranceConstraints; + } + + public String getGrounderToleranceRules() { + return grounderToleranceRules; + } + + public void setGrounderToleranceRules(String grounderToleranceRules) { + this.grounderToleranceRules = grounderToleranceRules; + } + + public boolean isGrounderAccumulatorEnabled() { + return grounderAccumulatorEnabled; + } + + public void setGrounderAccumulatorEnabled(boolean grounderAccumulatorEnabled) { + this.grounderAccumulatorEnabled = grounderAccumulatorEnabled; + } + + public String getAtomSeparator() { + return this.atomSeparator; + } + + public void setAtomSeparator(String atomSeparator) { + this.atomSeparator = atomSeparator; + } +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java new file mode 100644 index 000000000..9348af476 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2019 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.grounder.heuristics; + +/** + * Contains configuration parameters for heuristics used by {@link at.ac.tuwien.kr.alpha.grounder.Grounder}s. + * + * Both parameters {@link #toleranceConstraints} and {@link #toleranceRules} are interpreted as follows: + * A rule (or constraint) is grounded if the following conditions are satisfied: + *

        + *
      • All variables in the rule are bound (either by positive body literals that are already + * satisfied, or because the whole rule is ground).
      • + *
      • No atom occurring positively in the body is assigned F.
      • + *
      • No atom occurring negatively in the body is true as a fact. + * (Note: The rule is still grounded if an atom occurring negatively in the body is assigned true without + * being a fact, because the alternative would necessitate triggering re-grounding during backtracking.)
      • + *
      • At most {@code N} atoms occurring positively in the body are still unassigned.
      • + *
      + * + * The parameter {@link #toleranceConstraints} specifies {@code N} for constraints, while {@link #toleranceRules} + * specifies {@code N} for all other rules. Infinity is represented by the value {@code -1}. + * The default value for both parameters is {@code 0}, which means that only those rules and constraints are + * grounded whose positive body is already satisfied. + * + * The additional parameter {@link #accumulatorEnabled} is a switch for the accumulator grounding strategy + * which disables the removal of instances from the grounder memory in certain cases. + * + */ +public class GrounderHeuristicsConfiguration { + + public static final String STRICT_STRING = "strict"; + public static final int STRICT_INT = 0; + public static final String PERMISSIVE_STRING = "permissive"; + public static final int PERMISSIVE_INT = -1; + + private int toleranceConstraints; + private int toleranceRules; + private boolean accumulatorEnabled; + + public GrounderHeuristicsConfiguration() { + super(); + this.toleranceConstraints = STRICT_INT; + this.toleranceRules = STRICT_INT; + } + + /** + * @param toleranceConstraints + * @param toleranceRules + */ + private GrounderHeuristicsConfiguration(int toleranceConstraints, int toleranceRules) { + super(); + this.toleranceConstraints = toleranceConstraints; + this.toleranceRules = toleranceRules; + } + + /** + * @return the tolerance for constraints + */ + public int getToleranceConstraints() { + return toleranceConstraints; + } + + /** + * @return the tolerance for rules that are not constraints + */ + public int getToleranceRules() { + return toleranceRules; + } + + /** + * @param ruleIsConstraint {@code true} iff the parameter for constraints shall be returned + * @return {@link #getToleranceConstraints()} if {@code ruleIsConstraint}, otherwise {@link #getToleranceRules()} + */ + public int getTolerance(boolean ruleIsConstraint) { + return ruleIsConstraint ? getToleranceConstraints() : getToleranceRules(); + } + + /** + * @param ruleIsConstraint {@code true} iff the parameter for constraints shall be returned + * @return {@code true} iff the tolerance is not 0 + */ + public boolean isPermissive(boolean ruleIsConstraint) { + return getTolerance(ruleIsConstraint) != STRICT_INT; + } + + public boolean isAccumulatorEnabled() { + return accumulatorEnabled; + } + + public void setAccumulatorEnabled(boolean accumulatorEnabled) { + this.accumulatorEnabled = accumulatorEnabled; + } + + public static GrounderHeuristicsConfiguration strict() { + return new GrounderHeuristicsConfiguration(STRICT_INT, STRICT_INT); + } + + public static GrounderHeuristicsConfiguration permissive() { + return new GrounderHeuristicsConfiguration(PERMISSIVE_INT, PERMISSIVE_INT); + } + + public static GrounderHeuristicsConfiguration getInstance(int toleranceConstraints, int toleranceRules) { + return new GrounderHeuristicsConfiguration(toleranceConstraints, toleranceRules); + } + + public static GrounderHeuristicsConfiguration getInstance(String toleranceConstraints, String toleranceRules) { + return getInstance(parseTolerance(toleranceConstraints), parseTolerance(toleranceRules)); + } + + private static int parseTolerance(String tolerance) { + if (STRICT_STRING.equalsIgnoreCase(tolerance)) { + return STRICT_INT; + } else if (PERMISSIVE_STRING.equalsIgnoreCase(tolerance)) { + return PERMISSIVE_INT; + } else { + return Integer.parseInt(tolerance); + } + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "(toleranceConstraints=" + toleranceConstraints + ",toleranceRules=" + toleranceRules + ",disableInstanceRemoval=" + accumulatorEnabled + ")"; + } + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java new file mode 100644 index 000000000..bf3ad5242 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java @@ -0,0 +1,27 @@ +package at.ac.tuwien.kr.alpha.solver; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * Strategies to estimate the amount of influence of a literal. + */ +public enum BinaryNoGoodPropagationEstimationStrategy { + /** + * Counts binary watches involving the literal under consideration + */ + CountBinaryWatches, + + /** + * Assigns true to the literal under consideration, then does propagation only on binary nogoods + * and counts how many other atoms are assigned during this process, then backtracks + */ + BinaryNoGoodPropagation; + + /** + * @return a comma-separated list of names of known heuristics + */ + public static String listAllowedValues() { + return Arrays.stream(values()).map(BinaryNoGoodPropagationEstimationStrategy::toString).collect(Collectors.joining(", ")); + } +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java new file mode 100644 index 000000000..f9aa16953 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java @@ -0,0 +1,52 @@ +package at.ac.tuwien.kr.alpha.solver.heuristics; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * The available domain-independent heuristics. + * Some are deprecated because they perform poorly and have not been improved for some time, + * however the code is kept for now so that it stays compatible when interfaces are refactored. + */ +public enum Heuristic { + NAIVE, + BERKMIN, + BERKMINLITERAL, + @Deprecated + DD, + @Deprecated + DD_SUM, + @Deprecated + DD_AVG, + @Deprecated + DD_MAX, + @Deprecated + DD_MIN, + @Deprecated + DD_PYRO, + @Deprecated + GDD, + @Deprecated + GDD_SUM, + @Deprecated + GDD_AVG, + @Deprecated + GDD_MAX, + @Deprecated + GDD_MIN, + @Deprecated + GDD_PYRO, + @Deprecated + ALPHA_ACTIVE_RULE, + @Deprecated + ALPHA_HEAD_MBT, + VSIDS, + GDD_VSIDS; + + /** + * @return a comma-separated list of names of known heuristics + */ + public static String listAllowedValues() { + return Arrays.stream(values()).map(Heuristic::toString).collect(Collectors.joining(", ")); + } +} diff --git a/alpha-cli-app/build.gradle b/alpha-cli-app/build.gradle new file mode 100644 index 000000000..907a683a9 --- /dev/null +++ b/alpha-cli-app/build.gradle @@ -0,0 +1,40 @@ +plugins { + id 'alpha.java-application-conventions' +} + +dependencies { + implementation project(':alpha-core') + implementation project(':alpha-api') + + implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' +} + +def mainClassName = 'at.ac.tuwien.kr.alpha.Main' + +application { + mainClass = mainClassName +} + +task bundledJar(type: Jar) { + manifest { + attributes 'Main-Class': mainClassName + } + + from { + configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } + + archiveFileName = "${project.name}-bundled.jar" + + /* + * In order to make sure we don't overwrite NOTICE and LICENSE files coming from dependency + * jars with each other, number them while copying + */ + int i = 1 + rename { name -> (name.equals("NOTICE.txt") || name.equals("NOTICE")) ? "NOTICE." + (i++) + ".txt" : null } + + int j = 1 + rename { name -> (name.equals("LICENSE.txt") || name.equals("LICENSE")) ? "LICENSE." + (j++) + ".txt" : null } + + with jar +} diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java new file mode 100644 index 000000000..fc61c4b9b --- /dev/null +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java @@ -0,0 +1,60 @@ +package at.ac.tuwien.kr.alpha; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.function.BiConsumer; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToObjectMapper; +import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToWorkbookMapper; +import at.ac.tuwien.kr.alpha.common.AnswerSet; + +public class AnswerSetToXlsxWriter implements BiConsumer { + + private String targetBasePath; + private AnswerSetToObjectMapper answerSetMapper; + + public AnswerSetToXlsxWriter(String targetBasePath) { + this.targetBasePath = targetBasePath; + this.answerSetMapper = new AnswerSetToWorkbookMapper(); + } + + @Override + public void accept(Integer num, AnswerSet as) { + try { + Path outputPath = Paths.get(this.targetBasePath + "." + num + ".xlsx"); + OutputStream os = Files.newOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); + Workbook wb = this.answerSetMapper.mapFromAnswerSet(as); + wb.write(os); + wb.close(); + os.close(); + System.out.println("Answer set written to file " + outputPath.toString()); + } catch (IOException ex) { + System.err.println("Failed writing answer set as xlsx file! (" + ex.getMessage() + ")"); + } + } + + public static void writeUnsatInfo(Path path) throws IOException { + Workbook workbook = new XSSFWorkbook(); + // first, create a worksheet for 0-arity predicates + Sheet sheet = workbook.createSheet("Unsatisfiable"); + Row row = sheet.createRow(0); + Cell cell = row.createCell(0); + cell.setCellValue("Input is unsatisfiable - No answer sets!"); + sheet.autoSizeColumn(0); + OutputStream os = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); + workbook.write(os); + workbook.close(); + os.close(); + } + +} 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 new file mode 100644 index 000000000..da7d22a12 --- /dev/null +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2016-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; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AnswerSetFormatter; +import at.ac.tuwien.kr.alpha.common.SimpleAnswerSetFormatter; +import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.common.graphio.ComponentGraphWriter; +import at.ac.tuwien.kr.alpha.common.graphio.DependencyGraphWriter; +import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.config.AlphaConfig; +import at.ac.tuwien.kr.alpha.config.CommandLineParser; +import at.ac.tuwien.kr.alpha.config.InputConfig; +import at.ac.tuwien.kr.alpha.solver.Solver; +import at.ac.tuwien.kr.alpha.solver.SolverMaintainingStatistics; +import org.antlr.v4.runtime.RecognitionException; +import org.apache.commons.cli.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Paths; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Main entry point for Alpha. + */ +public class Main { + + private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); + + private static final String ALPHA_CALL_SYNTAX = "java -jar alpha-bundled.jar" + System.lineSeparator() + "java -jar alpha.jar"; + + public static void main(String[] args) { + CommandLineParser commandLineParser = new CommandLineParser(Main.ALPHA_CALL_SYNTAX, (msg) -> Main.exitWithMessage(msg, 0)); + AlphaConfig cfg = null; + try { + cfg = commandLineParser.parseCommandLine(args); + } catch (ParseException ex) { + System.err.println("Invalid usage: " + ex.getMessage()); + Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); + } + + AlphaImpl alpha = new AlphaImpl(cfg.getSystemConfig()); + + InputProgram program = null; + try { + program = alpha.readProgram(cfg.getInputConfig()); + } catch (RecognitionException e) { + // In case a recognition exception occurred, parseVisit will + // already have printed an error message, so we just exit + // at this point without further logging. + System.exit(1); + } catch (FileNotFoundException e) { + Main.bailOut(e.getMessage()); + } catch (IOException e) { + Main.bailOut("Failed to parse program.", e); + } + + NormalProgram normalized = alpha.normalizeProgram(program); + InternalProgram preprocessed; + InputConfig inputCfg = cfg.getInputConfig(); + if (!(inputCfg.isWriteDependencyGraph() || inputCfg.isWriteComponentGraph())) { + LOGGER.debug("Not writing dependency or component graphs, starting preprocessing..."); + preprocessed = alpha.performProgramPreprocessing(InternalProgram.fromNormalProgram(normalized)); + } else { + LOGGER.debug("Performing program analysis in preparation for writing dependency and/or component graph file..."); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalized); + if (cfg.getInputConfig().isWriteDependencyGraph()) { + Main.writeDependencyGraph(analyzed.getDependencyGraph(), cfg.getInputConfig().getDepgraphPath()); + } + if (cfg.getInputConfig().isWriteComponentGraph()) { + Main.writeComponentGraph(analyzed.getComponentGraph(), cfg.getInputConfig().getCompgraphPath()); + } + preprocessed = alpha.performProgramPreprocessing(analyzed); + } + if (cfg.getInputConfig().isWritePreprocessed()) { + Main.writeInternalProgram(preprocessed, cfg.getInputConfig().getPreprocessedPath()); + } + Main.computeAndConsumeAnswerSets(alpha, cfg.getInputConfig(), preprocessed); + } + + /** + * Writes the given {@link DependencyGraph} to the destination passed as the second parameter + * + * @param dg the dependency graph to write + * @param path the path to write the graph to + */ + private static void writeDependencyGraph(DependencyGraph dg, String path) { + DependencyGraphWriter depGraphWriter = new DependencyGraphWriter(); + try (FileOutputStream os = new FileOutputStream(new File(path))) { + depGraphWriter.writeAsDot(dg, os); + } catch (IOException ex) { + Main.bailOut("Error writing dependency graph: " + ex.getMessage()); + } + } + + /** + * Writes the given {@link ComponentGraph} to the destination passed as the second parameter + * + * @param cg the component graph to write + * @param path the path to write the graph to + */ + private static void writeComponentGraph(ComponentGraph cg, String path) { + ComponentGraphWriter compGraphWriter = new ComponentGraphWriter(); + try (FileOutputStream os = new FileOutputStream(new File(path))) { + compGraphWriter.writeAsDot(cg, os); + } catch (IOException ex) { + Main.bailOut("Error writing component graph: " + ex.getMessage()); + } + + } + + /** + * Writes the given {@link InternalProgram} to the destination passed as the second parameter + * + * @param prg the program to write + * @param path the path to write the program to + */ + private static void writeInternalProgram(InternalProgram prg, String path) { + LOGGER.debug("Writing preprocessed program to {}", path); + PrintStream ps; + try { + if (path.equals(InputConfig.PREPROC_STDOUT_PATH)) { + ps = System.out; + } else { + ps = new PrintStream(new File(path)); + } + ps.println(prg.toString()); + } catch (IOException ex) { + LOGGER.error("Failed writing preprocessed program file", ex); + Main.bailOut("Failed writing preprocessed program file " + ex.getMessage()); + } + } + + private static void computeAndConsumeAnswerSets(AlphaImpl alpha, InputConfig inputCfg, InternalProgram program) { + Solver solver = alpha.prepareSolverFor(program, inputCfg.getFilter()); + Stream stream = solver.stream(); + if (alpha.getConfig().isSortAnswerSets()) { + stream = stream.sorted(); + } + + int limit = inputCfg.getNumAnswerSets(); + if (limit > 0) { + stream = stream.limit(limit); + } + + if (!alpha.getConfig().isQuiet()) { + AtomicInteger counter = new AtomicInteger(0); + final BiConsumer answerSetHandler; + final AnswerSetFormatter fmt = new SimpleAnswerSetFormatter(alpha.getConfig().getAtomSeparator()); + BiConsumer stdoutPrinter = (n, as) -> { + System.out.println("Answer set " + Integer.toString(n) + ":" + System.lineSeparator() + fmt.format(as)); + }; + if (inputCfg.isWriteAnswerSetsAsXlsx()) { + BiConsumer xlsxWriter = new AnswerSetToXlsxWriter(inputCfg.getAnswerSetFileOutputPath()); + answerSetHandler = stdoutPrinter.andThen(xlsxWriter); + } else { + answerSetHandler = stdoutPrinter; + } + stream.forEach(as -> { + int cnt = counter.incrementAndGet(); + answerSetHandler.accept(cnt, as); + }); + if (counter.get() == 0) { + System.out.println("UNSATISFIABLE"); + if (inputCfg.isWriteAnswerSetsAsXlsx()) { + try { + AnswerSetToXlsxWriter.writeUnsatInfo(Paths.get(inputCfg.getAnswerSetFileOutputPath() + ".UNSAT.xlsx")); + } catch (IOException ex) { + System.err.println("Failed writing unsat file!"); + } + } + } else { + System.out.println("SATISFIABLE"); + } + } else { + // Note: Even though we are not consuming the result, we will still compute + // answer sets. + stream.collect(Collectors.toList()); + } + if (alpha.getConfig().isPrintStats()) { + ((SolverMaintainingStatistics) solver).printStatistics(); + } + } + + private static void exitWithMessage(String msg, int exitCode) { + System.out.println(msg); + System.exit(exitCode); + } + + private static void bailOut(String format, Object... arguments) { + LOGGER.error(format, arguments); + System.exit(1); + } + +} diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java new file mode 100644 index 000000000..054f01654 --- /dev/null +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java @@ -0,0 +1,11 @@ +package at.ac.tuwien.kr.alpha.config; + +import org.apache.commons.cli.Option; +import org.apache.commons.cli.ParseException; + +@FunctionalInterface +public interface CliOptionHandler { + + void handleOption(Option opt, T dest) throws ParseException; + +} diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java new file mode 100644 index 000000000..dca1d5d90 --- /dev/null +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java @@ -0,0 +1,482 @@ +/** + * Copyright (c) 2016-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.config; + +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +/** + * Parses given argument lists (as passed when Alpha is called from command line) into {@link SystemConfig}s and + * {@link InputConfig}s. + * + */ +public class CommandLineParser { + + private static final Logger LOGGER = LoggerFactory.getLogger(CommandLineParser.class); + + //@formatter:off + /* + * Whenever a new command line option is added, perform the following steps: + * 1. Add it as a constant option below. + * 2. Add the constant option into the Options "CLI_OPTS" in the static initializer. + * 3. Add a handler method for it and add the respective map entry in initializeGlobalOptionHandlers + * or initializeInputOptionHandlers with a method reference to the handler. + */ + + // "special", i.e. non-configuration options + private static final Option OPT_HELP = Option.builder("h").longOpt("help").hasArg(false).desc("shows this help").build(); + + // input-specific options + private static final Option OPT_INPUT = Option.builder("i").longOpt("input").hasArg(true).argName("file").type(FileInputStream.class) + .desc("read ASP program from this file").build(); + private static final Option OPT_NUM_ANSWER_SETS = Option.builder("n").longOpt("numAS").hasArg(true).argName("number").type(Integer.class) + .desc("the number of answer sets to compute (default: compute all)").build(); + private static final Option OPT_FILTER = Option.builder("f").longOpt("filter").hasArg(true).argName("filter").valueSeparator(',') + .desc("predicates to show when printing answer sets").build(); + private static final Option OPT_ASPSTRING = Option.builder("str").longOpt("aspstring").hasArg(true).argName("program").type(String.class) + .desc("provide the asp program as a string").build(); + private static final Option OPT_LITERATE = Option.builder("l").longOpt("literate") + .desc("enable literate programming mode (default: " + InputConfig.DEFAULT_LITERATE + ")").build(); + private static final Option OPT_WRITE_PREPROCESSED = Option.builder("wpp").longOpt("writePreprocessedProgram").hasArg(true).argName("target") + .desc("write the internal program that is passed into the solver after transformations to a file. Writing to STDOUT is possible by setting target to: " + InputConfig.PREPROC_STDOUT_PATH).build(); + private static final Option OPT_WRITE_DEPGRAPH = Option.builder("wdg").longOpt("writeDependencyGraph").hasArg(true).argName("target") + .desc("Write a dot file with the input program's dependency graph").build(); + private static final Option OPT_WRITE_COMPGRAPH = Option.builder("wcg").longOpt("writeComponentGraph").hasArg(true).argName("target") + .desc("Write a dot file with the input program's component graph").build(); + private static final Option OPT_WRITE_XSLX = Option.builder("wx").longOpt("write-xlsx").hasArg(true).argName("path").type(String.class) + .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("dbg").longOpt("DebugEnableInternalChecks") + .desc("run additional (time-consuming) safety checks (default: " + SystemConfig.DEFAULT_DEBUG_INTERNAL_CHECKS + ")").build(); + private static final Option OPT_BRANCHING_HEURISTIC = Option.builder("b").longOpt("branchingHeuristic").hasArg(true).argName("heuristic") + .desc("the branching heuristic to use (default: " + SystemConfig.DEFAULT_BRANCHING_HEURISTIC.name() + ")").build(); + private static final Option OPT_MOMS_STRATEGY = Option.builder("ms").longOpt("momsStrategy").hasArg(true).argName("strategy") + .desc("strategy for mom's heuristic (CountBinaryWatches or BinaryNoGoodPropagation, default: " + SystemConfig.DEFAULT_MOMS_STRATEGY.name() + ")") + .build(); + private static final Option OPT_REPLAY_CHOICES = Option.builder("rc").longOpt("replayChoices").hasArg().argName("choices") + .desc("comma-separated list of choices to be replayed (each choice is represented by a signed integer whose absolute value designates an atom ID and whose sign designates a truth value)") + .build(); + private static final Option OPT_QUIET = Option.builder("q").longOpt("quiet").desc("do not print answer sets (default: " + SystemConfig.DEFAULT_QUIET) + .build(); + private static final Option OPT_STATS = Option.builder("st").longOpt("stats").desc("print statistics (default: " + SystemConfig.DEFAULT_PRINT_STATS + ")") + .build(); + private static final Option OPT_NO_JUSTIFICATION = Option.builder("dj").longOpt("disableJustifications") + .desc("disable the search for justifications on must-be-true assigned atoms in the solver (default: " + + SystemConfig.DEFAULT_DISABLE_JUSTIFICATION_SEARCH + ")") + .build(); + private static final Option OPT_NORMALIZATION_GRID = Option.builder("ng").longOpt("normalizationCountingGrid") + .desc("use counting grid normalization instead of sorting circuit for #count (default: " + SystemConfig.DEFAULT_USE_NORMALIZATION_GRID + ")") + .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 + ")") + .build(); + private static final Option OPT_GROUNDER_TOLERANCE_CONSTRAINTS = Option.builder("gtc").longOpt("grounderToleranceConstraints") + .desc("grounder tolerance for constraints (default: " + SystemConfig.DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS + ")") + .hasArg().argName("tolerance") + .build(); + private static final Option OPT_GROUNDER_TOLERANCE_RULES = Option.builder("gtr").longOpt("grounderToleranceRules") + .desc("grounder tolerance for rules (default: " + SystemConfig.DEFAULT_GROUNDER_TOLERANCE_RULES + ")") + .hasArg().argName("tolerance") + .build(); + private static final Option OPT_GROUNDER_ACCUMULATOR_ENABLED = Option.builder("acc").longOpt("enableAccumulator") + .desc("activates the accumulator grounding strategy by disabling removal of instances from grounder memory in certain cases (default: " + + SystemConfig.DEFAULT_GROUNDER_ACCUMULATOR_ENABLED + ")") + .build(); + private static final Option OPT_OUTPUT_ATOM_SEPARATOR = Option.builder("sep").longOpt("atomSeparator").hasArg(true).argName("separator") + .desc("a character (sequence) to use as separator for atoms in printed answer sets (default: " + + SystemConfig.DEFAULT_ATOM_SEPARATOR + ")") + .build(); + //@formatter:on + + private static final Options CLI_OPTS = new Options(); + + static { + /* + * Below code adds all options defined above to CLI_OPTS - needed for parsing + */ + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_HELP); + + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NUM_ANSWER_SETS); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_FILTER); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_LITERATE); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_INPUT); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_ASPSTRING); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_XSLX); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_PREPROCESSED); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_DEPGRAPH); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_COMPGRAPH); + + 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); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_MOMS_STRATEGY); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_REPLAY_CHOICES); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_QUIET); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_STATS); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NO_JUSTIFICATION); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NORMALIZATION_GRID); + + 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); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER_ACCUMULATOR_ENABLED); + CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_OUTPUT_ATOM_SEPARATOR); + } + + /* + * Below maps map commandline options to handler methods. If a new option is added, the appropriate put into the map + * must be added in the constructor + */ + private final Map> globalOptionHandlers = new HashMap<>(); + private final Map> inputOptionHandlers = new HashMap<>(); + private Consumer abortAction; + private String cmdSyntax; + + /** + * Creates a new CommandLineParser. The abortAction described below is passed into the constructor + * externally in order to avoid strongly coupling this class to any other part of the application. Especially an + * abortAction - which likely will include some call like System.exit({state}) - should not be specified by utility + * classes themselves, but rather by the application's main class. + * + * @param cmdLineSyntax a string describing the basic call syntax for the application binary, e.g. "java -jar + * somejar.jar" + * @param abortAction a Consumer that is called when option parsing is aborted, as is the case + * when the "help" option is encountered. + * It expects a string parameter, which is a message accompanying the abort + */ + public CommandLineParser(String cmdLineSyntax, Consumer abortAction) { + this.cmdSyntax = cmdLineSyntax; + this.abortAction = abortAction; + this.initializeGlobalOptionHandlers(); + this.initializeInputOptionHandlers(); + } + + private void initializeGlobalOptionHandlers() { + /* + * below put invocations are used to "register" the handler methods for each commandline option + */ + // 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); + this.globalOptionHandlers.put(CommandLineParser.OPT_MOMS_STRATEGY.getOpt(), this::handleMomsStrategy); + this.globalOptionHandlers.put(CommandLineParser.OPT_REPLAY_CHOICES.getOpt(), this::handleReplayChoices); + this.globalOptionHandlers.put(CommandLineParser.OPT_QUIET.getOpt(), this::handleQuiet); + this.globalOptionHandlers.put(CommandLineParser.OPT_STATS.getOpt(), this::handleStats); + this.globalOptionHandlers.put(CommandLineParser.OPT_NO_JUSTIFICATION.getOpt(), this::handleNoJustification); + this.globalOptionHandlers.put(CommandLineParser.OPT_NORMALIZATION_GRID.getOpt(), this::handleNormalizationGrid); + 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); + this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER_ACCUMULATOR_ENABLED.getOpt(), this::handleGrounderNoInstanceRemoval); + this.globalOptionHandlers.put(CommandLineParser.OPT_OUTPUT_ATOM_SEPARATOR.getOpt(), this::handleAtomSeparator); + } + + private void initializeInputOptionHandlers() { + this.inputOptionHandlers.put(CommandLineParser.OPT_NUM_ANSWER_SETS.getOpt(), this::handleNumAnswerSets); + this.inputOptionHandlers.put(CommandLineParser.OPT_INPUT.getOpt(), this::handleInput); + this.inputOptionHandlers.put(CommandLineParser.OPT_FILTER.getOpt(), this::handleFilters); + this.inputOptionHandlers.put(CommandLineParser.OPT_ASPSTRING.getOpt(), this::handleAspString); + this.inputOptionHandlers.put(CommandLineParser.OPT_LITERATE.getOpt(), this::handleLiterate); + this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_XSLX.getOpt(), this::handleWriteXlsx); + this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_PREPROCESSED.getOpt(), this::handleWritePreprocessed); + this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_DEPGRAPH.getOpt(), this::handleWriteDepgraph); + this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_COMPGRAPH.getOpt(), this::handleWriteCompgraph); + } + + public AlphaConfig parseCommandLine(String[] args) throws ParseException { + CommandLine commandLine = new DefaultParser().parse(CommandLineParser.CLI_OPTS, args); + if (commandLine.getArgs().length > 0) { + throw new ParseException("Positional arguments { " + StringUtils.join(args, ' ') + " } are invalid!"); + } + AlphaConfig retVal = new AlphaConfig(); + SystemConfig sysConf = new SystemConfig(); + InputConfig inputConf = new InputConfig(); + if (commandLine.hasOption(CommandLineParser.OPT_HELP.getOpt())) { + LOGGER.debug("Found help option!"); + this.handleHelp(); + } else { + this.validate(commandLine); + } + for (Option opt : commandLine.getOptions()) { + this.handleOption(opt, sysConf, inputConf); + } + retVal.setSystemConfig(sysConf); + retVal.setInputConfig(inputConf); + return retVal; + } + + private void handleOption(Option opt, SystemConfig sysConf, InputConfig inputConf) throws ParseException { + CliOptionHandler globalOptionHandler; + CliOptionHandler inputOptionHandler; + globalOptionHandler = this.globalOptionHandlers.get(opt.getOpt()); + if (globalOptionHandler != null) { + globalOptionHandler.handleOption(opt, sysConf); + } else { + inputOptionHandler = this.inputOptionHandlers.get(opt.getOpt()); + if (inputOptionHandler != null) { + inputOptionHandler.handleOption(opt, inputConf); + } else { + throw new ParseException("Cannot handle option: " + opt.getOpt()); + } + } + } + + public String getUsageMessage() { + HelpFormatter formatter = new HelpFormatter(); + // Unfortunately, commons-cli does not offer a method of simply rendering a help + // message into a string, therefore the ByteArrayOutputStream.. + ByteArrayOutputStream helpBuffer = new ByteArrayOutputStream(); + PrintWriter pw = new PrintWriter(helpBuffer); + formatter.printHelp(pw, HelpFormatter.DEFAULT_WIDTH, this.cmdSyntax, "", CommandLineParser.CLI_OPTS, HelpFormatter.DEFAULT_LEFT_PAD, + HelpFormatter.DEFAULT_DESC_PAD, ""); + pw.flush(); + return helpBuffer.toString(); + } + + private void validate(CommandLine commandLine) throws ParseException { + if (!commandLine.hasOption(CommandLineParser.OPT_INPUT.getOpt()) && !commandLine.hasOption(CommandLineParser.OPT_ASPSTRING.getOpt())) { + throw new ParseException("Missing input source - need to specifiy either a file (" + CommandLineParser.OPT_INPUT.getOpt() + ") or a string (" + + CommandLineParser.OPT_ASPSTRING.getOpt() + " - or both)!"); + } + } + + private void handleNumAnswerSets(Option opt, InputConfig cfg) { + String optVal = opt.getValue(); + int limit; + if (optVal != null) { + limit = Integer.valueOf(optVal); + cfg.setNumAnswerSets(limit); + } else { + cfg.setNumAnswerSets(InputConfig.DEFAULT_NUM_ANSWER_SETS); + } + } + + private void handleHelp() { + this.abortAction.accept(this.getUsageMessage()); + } + + private void handleInput(Option opt, InputConfig cfg) { + String optVal = opt.getValue().trim(); + 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)); + } + + private void handleNogoodStore(Option opt, SystemConfig cfg) { + cfg.setNogoodStoreName(opt.getValue(SystemConfig.DEFAULT_NOGOOD_STORE_NAME)); + } + + private void handleFilters(Option opt, InputConfig cfg) { + String pred = opt.getValue().trim(); + cfg.getDesiredPredicates().add(pred); + } + + private void handleAspString(Option opt, InputConfig cfg) { + String optVal = opt.getValue().trim(); + cfg.getAspStrings().add(optVal); + } + + private void handleSort(Option opt, SystemConfig cfg) { + cfg.setSortAnswerSets(true); + } + + 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) { + seed = Long.valueOf(optVal); + cfg.setSeed(seed); + } else { + cfg.setSeed(SystemConfig.DEFAULT_SEED); + } + } + + private void handleInternalChecks(Option opt, SystemConfig cfg) { + cfg.setDebugInternalChecks(true); + } + + private void handleBranchingHeuristic(Option opt, SystemConfig cfg) throws ParseException { + String branchingHeuristicName = opt.getValue(SystemConfig.DEFAULT_BRANCHING_HEURISTIC.name()); + try { + cfg.setBranchingHeuristicName(branchingHeuristicName); + } catch (IllegalArgumentException e) { + throw new ParseException( + "Unknown branching heuristic: " + branchingHeuristicName + ". Please try one of the following: " + Heuristic.listAllowedValues()); + } + } + + private void handleMomsStrategy(Option opt, SystemConfig cfg) throws ParseException { + String momsStrategyName = opt.getValue(SystemConfig.DEFAULT_MOMS_STRATEGY.name()); + try { + cfg.setMomsStrategyName(momsStrategyName); + } catch (IllegalArgumentException e) { + throw new ParseException("Unknown mom's strategy: " + momsStrategyName + ". Please try one of the following: " + + BinaryNoGoodPropagationEstimationStrategy.listAllowedValues()); + } + } + + private void handleReplayChoices(Option opt, SystemConfig cfg) throws ParseException { + String replayChoices = opt.getValue(SystemConfig.DEFAULT_REPLAY_CHOICES.toString()); + try { + cfg.setReplayChoices(replayChoices); + } catch (NumberFormatException e) { + throw new ParseException("Cannot parse list of signed integers indicating choices to be replayed: " + replayChoices); + } + } + + private void handleQuiet(Option opt, SystemConfig cfg) { + cfg.setQuiet(true); + } + + private void handleLiterate(Option opt, InputConfig cfg) { + cfg.setLiterate(true); + } + + private void handleWriteXlsx(Option opt, InputConfig cfg) { + cfg.setWriteAnswerSetsAsXlsx(true); + String outputPath = opt.getValue(InputConfig.DEFAULT_XLSX_OUTFILE_PATH); + cfg.setAnswerSetFileOutputPath(outputPath); + } + + private void handleStats(Option opt, SystemConfig cfg) { + cfg.setPrintStats(true); + } + + private void handleNoJustification(Option opt, SystemConfig cfg) { + cfg.setDisableJustificationSearch(true); + } + + private void handleNormalizationGrid(Option opt, SystemConfig cfg) { + cfg.setUseNormalizationGrid(true); + } + + private void handleDisableStratifedEval(Option opt, SystemConfig cfg) { + cfg.setEvaluateStratifiedPart(false); + } + + private void handleWritePreprocessed(Option opt, InputConfig cfg) { + cfg.setWritePreprocessed(true); + String preprocessedPath = opt.getValue(InputConfig.DEFAULT_PREPROC_TARGET_FILE); + cfg.setPreprocessedPath(preprocessedPath); + } + + private void handleWriteDepgraph(Option opt, InputConfig cfg) { + cfg.setWriteDependencyGraph(true); + String depgraphPath = opt.getValue(InputConfig.DEFAULT_DEPGRAPH_TARGET_FILE); + cfg.setDepgraphPath(depgraphPath); + } + + private void handleWriteCompgraph(Option opt, InputConfig cfg) { + cfg.setWriteComponentGraph(true); + String compgraphPath = opt.getValue(InputConfig.DEFAULT_COMPGRAPH_TARGET_FILE); + cfg.setCompgraphPath(compgraphPath); + } + + private void handleNoNoGoodDeletion(Option opt, SystemConfig cfg) { + cfg.setDisableNoGoodDeletion(true); + } + + private void handleGrounderToleranceConstraints(Option opt, SystemConfig cfg) { + String grounderToleranceConstraints = opt.getValue(SystemConfig.DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS); + cfg.setGrounderToleranceConstraints(grounderToleranceConstraints); + } + + private void handleGrounderToleranceRules(Option opt, SystemConfig cfg) { + String grounderToleranceRules = opt.getValue(SystemConfig.DEFAULT_GROUNDER_TOLERANCE_RULES); + cfg.setGrounderToleranceRules(grounderToleranceRules); + } + + private void handleGrounderNoInstanceRemoval(Option opt, SystemConfig cfg) { + cfg.setGrounderAccumulatorEnabled(true); + } + + private void handleAtomSeparator(Option opt, SystemConfig cfg) { + cfg.setAtomSeparator(StringEscapeUtils.unescapeJava(opt.getValue(SystemConfig.DEFAULT_ATOM_SEPARATOR))); + } + +} diff --git a/alpha-cli-app/src/main/resources/logback.xml b/alpha-cli-app/src/main/resources/logback.xml new file mode 100644 index 000000000..379c1c22e --- /dev/null +++ b/alpha-cli-app/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + %5relative %.-1level %20.20logger %msg %n + + + + + + + + + + diff --git a/alpha-core/build.gradle b/alpha-core/build.gradle new file mode 100644 index 000000000..292152bba --- /dev/null +++ b/alpha-core/build.gradle @@ -0,0 +1,57 @@ +plugins { + id 'antlr' + id 'alpha.java-library-conventions' +} + + +def antlrVersion = '4.7' + +/* The following configuration directive is a work-around for a fault in the Gradle + * ANTLR plugin. It would require both antlr4 and antlr4-runtime at compile time and + * at run time, which unnecessarily bloats our JARs. Only antlr4-runtime is needed. + * We therefore remove this extension of antlr dependencies being compile dependencies + * and reintroduce them on our own. + */ +configurations { + implementation { + extendsFrom = extendsFrom.findAll { it != configurations.antlr } + } +} + +dependencies { + + // We need to give the ANTLR Plugin a hint. + antlr group: 'org.antlr', name: 'antlr4', version: "${antlrVersion}" + + // Re-introduce antlr4-runtime as compile dependency. + implementation group: 'org.antlr', name: 'antlr4-runtime', version: "${antlrVersion}" +} + +tasks.withType(AntlrTask) { + // See https://github.com/antlr/antlr4/blob/master/doc/tool-options.md + arguments += [ + "-visitor", + "-no-listener", + "-long-messages", + "-package", "at.ac.tuwien.kr.alpha.antlr", + "-Werror", + "-Xlog", + "-lib", "src/main/antlr/at/ac/tuwien/kr/alpha/antlr" + ] +} + +jacocoTestReport { + reports { + xml.enabled = true + } + + // NOTE: Contents of the antlr subpackage are autogenerated (see configuration of + // AntlrTasks above). It does not make sense to include them in our coverage + // report. + afterEvaluate { + getClassDirectories().setFrom(files(classDirectories.files.collect { + fileTree(dir: it, exclude: "at/ac/tuwien/kr/alpha/antlr/**") + })) + } +} + diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 new file mode 100644 index 000000000..aeca5cc2d --- /dev/null +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 @@ -0,0 +1,90 @@ +grammar ASPCore2; + +import ASPLexer; + +/* The ASP-Core-2 grammar in ANTLR v4 based on + * 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). + */ + +program : statements? query? EOF; + +statements : statement+; + +query : classical_literal QUERY_MARK; + +statement : head DOT # statement_fact + | CONS body DOT # statement_constraint + | head CONS body DOT # statement_rule + | WCONS body? DOT SQUARE_OPEN weight_at_level SQUARE_CLOSE # statement_weightConstraint + | directive # statement_directive; // NOT Core2 syntax. + +head : disjunction | choice; + +body : ( naf_literal | aggregate ) (COMMA body)?; + +disjunction : classical_literal (OR disjunction)?; + +choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; + +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_elements : aggregate_element (SEMICOLON aggregate_elements)?; + +aggregate_element : basic_terms? (COLON naf_literals?)?; + +aggregate_function : AGGREGATE_COUNT | AGGREGATE_MAX | AGGREGATE_MIN | AGGREGATE_SUM; + +weight_at_level : term (AT term)? (COMMA terms)?; + +naf_literals : naf_literal (COMMA naf_literals)?; + +naf_literal : NAF? (external_atom | classical_literal | builtin_atom); + +classical_literal : MINUS? ID (PAREN_OPEN terms PAREN_CLOSE)?; + +builtin_atom : term binop term; + +binop : EQUAL | UNEQUAL | LESS | GREATER | LESS_OR_EQ | GREATER_OR_EQ; + +terms : term (COMMA terms)?; + +term : ID # term_const + | ID (PAREN_OPEN terms? PAREN_CLOSE) # term_func + | NUMBER # term_number + | QUOTED_STRING # term_string + | VARIABLE # term_variable + | ANONYMOUS_VARIABLE # term_anonymousVariable + | PAREN_OPEN term PAREN_CLOSE # term_parenthesisedTerm + | interval # term_interval // Syntax extension. + | MINUS term # term_minusArithTerm + | term POWER term # term_powerArithTerm + | term (TIMES | DIV | MODULO) term # term_timesdivmodArithTerm + | term (PLUS | MINUS) term # term_plusminusArithTerm + | term BITXOR term # term_bitxorArithTerm + ; + +interval : lower = (NUMBER | VARIABLE) DOT DOT upper = (NUMBER | VARIABLE); // NOT Core2 syntax, but widespread + +external_atom : MINUS? AMPERSAND ID (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; // NOT Core2 syntax. + +directive : directive_enumeration; // NOT Core2 syntax, allows solver specific directives. Further directives shall be added here. + +directive_enumeration : SHARP 'enumeration_predicate_is' ID DOT; // NOT Core2 syntax, used for aggregate translation. + +basic_terms : basic_term (COMMA basic_terms)? ; + +basic_term : ground_term | variable_term; + +ground_term : /*SYMBOLIC_CONSTANT*/ ID | QUOTED_STRING | MINUS? NUMBER; + +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 diff --git a/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 new file mode 100644 index 000000000..a900ca342 --- /dev/null +++ b/alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 @@ -0,0 +1,50 @@ +lexer grammar ASPLexer; + +ANONYMOUS_VARIABLE : '_'; +DOT : '.'; +COMMA : ','; +QUERY_MARK : '?'; +COLON : ':'; +SEMICOLON : ';'; +OR : '|'; +NAF : 'not'; +CONS : ':-'; +WCONS : ':~'; +PLUS : '+'; +MINUS : '-'; +TIMES : '*'; +DIV : '/'; +POWER : '**'; +MODULO : '\\'; +BITXOR : '^'; +AT : '@'; +SHARP : '#'; // NOT Core2 syntax but gringo +AMPERSAND : '&'; +QUOTE : '"'; + +PAREN_OPEN : '('; +PAREN_CLOSE : ')'; +SQUARE_OPEN : '['; +SQUARE_CLOSE : ']'; +CURLY_OPEN : '{'; +CURLY_CLOSE : '}'; +EQUAL : '='; +UNEQUAL : '<>' | '!='; +LESS : '<'; +GREATER : '>'; +LESS_OR_EQ : '<='; +GREATER_OR_EQ : '>='; + +AGGREGATE_COUNT : '#count'; +AGGREGATE_MAX : '#max'; +AGGREGATE_MIN : '#min'; +AGGREGATE_SUM : '#sum'; + +ID : ('a'..'z') ( 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' )*; +VARIABLE : ('A'..'Z') ( 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' )*; +NUMBER : '0' | ('1'..'9') ('0'..'9')*; +QUOTED_STRING : QUOTE ( '\\"' | . )*? QUOTE; + +COMMENT : '%' ~[\r\n]* -> channel(HIDDEN); +MULTI_LINE_COMMEN : '%*' .*? '*%' -> channel(HIDDEN); +BLANK : [ \t\r\n\f]+ -> channel(HIDDEN); \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java new file mode 100644 index 000000000..29b9adf3f --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java @@ -0,0 +1,28 @@ +package at.ac.tuwien.kr.alpha; + +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +public class CustomErrorListener extends BaseErrorListener { + RecognitionException recognitionException; + + private final String fileName; + + public CustomErrorListener(String fileName) { + this.fileName = fileName; + } + + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { + super.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e); + + System.err.println(fileName + ":" + line + ":" + charPositionInLine + ": " + msg); + + this.recognitionException = e; + } + + public RecognitionException getRecognitionException() { + return recognitionException; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/Util.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/Util.java new file mode 100644 index 000000000..b8e9efde0 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/Util.java @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2016, 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; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.StandardCharsets; +import java.util.AbstractMap; +import java.util.Iterator; +import java.util.Map; +import java.util.SortedSet; +import java.util.StringJoiner; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class Util { + private static final String LITERATE_INDENT = " "; + + public static Map.Entry entry(K key, V value) { + return new AbstractMap.SimpleEntry<>(key, value); + } + + public static Collector, ?, Map> entriesToMap() { + return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue); + } + + public static String join(String prefix, Iterable iterable, String suffix) { + return join(prefix, iterable, ", ", suffix); + } + + public static String join(String prefix, Iterable iterable, String delimiter, String suffix) { + StringJoiner joiner = new StringJoiner(delimiter, prefix, suffix); + for (E element : iterable) { + joiner.add(element.toString()); + } + return joiner.toString(); + } + + public static > int compareSortedSets(SortedSet a, SortedSet b) { + if (a.size() != b.size()) { + return a.size() - b.size(); + } + + if (a.isEmpty() && b.isEmpty()) { + return 0; + } + + final Iterator ita = a.iterator(); + final Iterator itb = b.iterator(); + + do { + final int result = ita.next().compareTo(itb.next()); + + if (result != 0) { + return result; + } + } while (ita.hasNext() && itb.hasNext()); + + return 0; + } + + public static RuntimeException oops(String message, Exception e) { + return new RuntimeException(message + "! Should not happen.", e); + } + + public static RuntimeException oops(String message) { + // We do not call oops(String, Exception) here to not bloat the stack trace. + return new RuntimeException(message + "! Should not happen."); + } + + public static RuntimeException oops() { + return oops("Reached fatal state"); + } + + public static Stream literate(Stream input) { + return input.map(l -> { + if (l.startsWith(LITERATE_INDENT)) { + return l.substring(LITERATE_INDENT.length()); + } + return "% " + l; + }); + } + + public static ReadableByteChannel streamToChannel(Stream lines) throws IOException { + return Channels.newChannel(new ByteArrayInputStream(lines.collect(Collectors.joining(System.lineSeparator())).getBytes(StandardCharsets.UTF_8))); + } + + public static int arrayGrowthSize(int oldSize) { + // Growth factor is 1.5. + return oldSize + (oldSize >> 1); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java new file mode 100644 index 000000000..0bb017067 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.api.externals; + +import at.ac.tuwien.kr.alpha.api.externals.stdlib.AspStandardLibrary; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.*; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import org.reflections.Reflections; +import org.reflections.scanners.MethodAnnotationsScanner; + +import java.lang.reflect.Method; +import java.util.*; + +public final class Externals { + + // Private constructor since this is a utility class. + private Externals() { + + } + + /** + * Returns a map of external definitions making up the "standard library" of + * externals that are always available in programs for Alpha. + * This method scans all predicate-annotated methods in the package holding the + * class {@link AspStandardLibrary}. + */ + public static Map getStandardLibraryExternals() { + return Externals.scan(AspStandardLibrary.class.getPackage()); + } + + public static Map scan(Package basePackage) { + Reflections reflections = new Reflections(basePackage.getName(), new MethodAnnotationsScanner()); + Set methods = reflections.getMethodsAnnotatedWith(Predicate.class); + return Externals.scanMethods(methods); + } + + public static Map scan(Class classWithPredicateMethods) { + Method[] methods = classWithPredicateMethods.getMethods(); + Set predicateMethods = new HashSet<>(); + for (Method method : methods) { + if (method.isAnnotationPresent(Predicate.class)) { + predicateMethods.add(method); + } + } + return Externals.scanMethods(predicateMethods); + } + + private static Map scanMethods(Iterable methods) { + Map retVal = new HashMap<>(); + String name; + for (Method method : methods) { + name = method.getAnnotation(Predicate.class).name(); + if (name.isEmpty()) { + name = method.getName(); + } + retVal.put(name, Externals.processPredicateMethod(method)); + } + return retVal; + } + + public static PredicateInterpretation processPredicateMethod(Method method) { + if (method.getReturnType().equals(boolean.class)) { + return new MethodPredicateInterpretation(method); + } + + if (method.getGenericReturnType().getTypeName().startsWith(PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX)) { + return new BindingMethodPredicateInterpretation(method); + } + + throw new IllegalArgumentException("Passed method has unexpected return type. Should be either boolean or start with " + + PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX + "."); + } + + public static PredicateInterpretation processPredicate(java.util.function.Predicate predicate) { + return new UnaryPredicateInterpretation<>(predicate); + } + + public static PredicateInterpretation processPredicate(java.util.function.IntPredicate predicate) { + return new IntPredicateInterpretation(predicate); + } + + public static PredicateInterpretation processPredicate(java.util.function.LongPredicate predicate) { + return new LongPredicateInterpretation(predicate); + } + + public static PredicateInterpretation processPredicate(java.util.function.BiPredicate predicate) { + return new BinaryPredicateInterpretation<>(predicate); + } + + public static PredicateInterpretation processPredicate(java.util.function.Supplier>>> supplier) { + return new SuppliedPredicateInterpretation(supplier); + } + + /** + * Converts a collection of objects to facts. + * Every item in the collection is wrapped in a {@link ConstantTerm}, which is the argument of a unary predicate whose + * symbol is the class name of the given class (i.e. the declared type of objects inside the collection), modified to + * start with a lower-case letter. + * + * @param the type of the objects to use as facts + * @param classOfExtFacts the {@link Class} object of the value type + * @param extFacts a {@link Collection} of objects of type classOfExtFacts + * @return a list of {@link Atom}s. + */ + public static > List asFacts(Class classOfExtFacts, Collection extFacts) { + // Use Class as parameter here, taking simple name from first element might not give desired result if it is a subtype. + List retVal = new ArrayList<>(); + String javaName = classOfExtFacts.getSimpleName(); + String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. + for (T instance : extFacts) { + // TODO use properly wrapped BasicAtoms here + retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.CorePredicate.getInstance(name, 1), CoreConstantTerm.getInstance(instance))); + } + return retVal; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java new file mode 100644 index 000000000..973e738de --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java @@ -0,0 +1,214 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.api.externals.stdlib; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.externals.Predicate; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Terms; + +/** + * Collection of methods that can be used as external atoms from ASP programs. + * Provides commonly used functionality such as basic string operations, + * datetime handling etc. + * + * All functions exposed by this class are guaranteed to be stateless and + * side-effect free. + * + * Copyright (c) 2020, the Alpha Team. + */ +public final class AspStandardLibrary { + + private AspStandardLibrary() { + throw new AssertionError(this.getClass().getSimpleName() + " is a non-instantiable utility class!"); + } + + /** + * Parses a string representing a datetime without time-zone and returns the + * year, month, day, hours, minutes and seconds as separate symbolic integer + * terms. + * Example: + * + *

      +	 * 		A valid ground instance of the atom &stdlib_datetime_parse[DTSTR, "dd.mm.yyyy hh:MM:ss"](YEAR, MONTH, DAY, HOUR, MIN, SEC)
      +	 * 		would be: &stdlib_datetime_parse["20.05.2020 01:19:13", "dd.mm.yyyy hh:MM:ss"](2020, 5, 20, 1, 19, 13)
      +	 * 
      + * + * Timezones are not supported by this function. Datetime values are parsed + * using {@link LocalDateTime.parse}. + * + * @param datetime a string representing a datetime without time zone + * information + * @param format a format string that is accepted by {@link DateTimeFormatter} + * @return a 6-value integer tuple of format (YEAR, MONTH, DAY, HOUR, MIN, SEC) + */ + @Predicate(name = "stdlib_datetime_parse") + public static Set>> datetimeParse(String dtstr, String format) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + LocalDateTime datetime = LocalDateTime.parse(dtstr, formatter); + List> terms = Terms.asTermList( + datetime.getYear(), datetime.getMonth().getValue(), datetime.getDayOfMonth(), + datetime.getHour(), datetime.getMinute(), datetime.getSecond()); + return Collections.singleton(terms); + } + + /** + * Compares two datetimes and returns true iff the first datetime (dt1) is + * before the second datetime (dt2). Both datetimes are represented as six + * integers each, referring to years, months, days, hours, minutes and seconds + * respectively. + * + * @param dt1Year the year field for dt1 + * @param dt1Month the month field for dt1 + * @param dt1Day the day field for dt1 + * @param dt1Hour the hour field for dt1 + * @param dt1Minute the minute field for dt1 + * @param dt1Second the second field for dt1 + * @param dt2Year the year field for dt2 + * @param dt2Month the month field for dt2 + * @param dt2Day the day field for dt2 + * @param dt2Hour the hour field for dt2 + * @param dt2Minute the minute field for dt2 + * @param dt2Second the second field for dt2 + * @return true if dt1 is before dt2 in time, false otherwise + */ + @Predicate(name = "stdlib_datetime_is_before") + public static boolean datetimeIsBefore(int dt1Year, int dt1Month, int dt1Day, int dt1Hour, int dt1Minute, int dt1Second, + int dt2Year, int dt2Month, int dt2Day, int dt2Hour, int dt2Minute, int dt2Second) { + LocalDateTime dt1 = LocalDateTime.of(dt1Year, dt1Month, dt1Day, dt1Hour, dt1Minute, dt1Second); + LocalDateTime dt2 = LocalDateTime.of(dt2Year, dt2Month, dt2Day, dt2Hour, dt2Minute, dt2Second); + return dt1.isBefore(dt2); + } + + /** + * Compares two datetimes and returns true iff the first datetime (dt1) is + * equal to the second datetime (dt2). Both datetimes are represented as six + * integers each, referring to years, months, days, hours, minutes and seconds + * respectively. + * + * @param dt1Year the year field for dt1 + * @param dt1Month the month field for dt1 + * @param dt1Day the day field for dt1 + * @param dt1Hour the hour field for dt1 + * @param dt1Minute the minute field for dt1 + * @param dt1Second the second field for dt1 + * @param dt2Year the year field for dt2 + * @param dt2Month the month field for dt2 + * @param dt2Day the day field for dt2 + * @param dt2Hour the hour field for dt2 + * @param dt2Minute the minute field for dt2 + * @param dt2Second the second field for dt2 + * @return true if dt1 is equal to dt2, false otherwise + */ + @Predicate(name = "stdlib_datetime_is_equal") + public static boolean datetimeIsEqual(int dt1Year, int dt1Month, int dt1Day, int dt1Hour, int dt1Minute, int dt1Second, + int dt2Year, int dt2Month, int dt2Day, int dt2Hour, int dt2Minute, int dt2Second) { + LocalDateTime dt1 = LocalDateTime.of(dt1Year, dt1Month, dt1Day, dt1Hour, dt1Minute, dt1Second); + LocalDateTime dt2 = LocalDateTime.of(dt2Year, dt2Month, dt2Day, dt2Hour, dt2Minute, dt2Second); + return dt1.isEqual(dt2); + } + + /** + * Compares two datetimes and returns true iff the first datetime (dt1) is + * before or equal to the second datetime (dt2). Both datetimes are represented + * as six integers each, referring to years, months, days, hours, minutes and seconds + * respectively. + * + * @param dt1Year the year field for dt1 + * @param dt1Month the month field for dt1 + * @param dt1Day the day field for dt1 + * @param dt1Hour the hour field for dt1 + * @param dt1Minute the minute field for dt1 + * @param dt1Second the second field for dt1 + * @param dt2Year the year field for dt2 + * @param dt2Month the month field for dt2 + * @param dt2Day the day field for dt2 + * @param dt2Hour the hour field for dt2 + * @param dt2Minute the minute field for dt2 + * @param dt2Second the second field for dt2 + * @return true if dt1 is before dt2 in time or both dt1 and dt2 denote the same + * point in time, false otherwise + */ + @Predicate(name = "stdlib_datetime_is_before_or_equal") + public static boolean datetimeIsBeforeOrEqual(int dt1Year, int dt1Month, int dt1Day, int dt1Hour, int dt1Minute, int dt1Second, + int dt2Year, int dt2Month, int dt2Day, int dt2Hour, int dt2Minute, int dt2Second) { + LocalDateTime dt1 = LocalDateTime.of(dt1Year, dt1Month, dt1Day, dt1Hour, dt1Minute, dt1Second); + LocalDateTime dt2 = LocalDateTime.of(dt2Year, dt2Month, dt2Day, dt2Hour, dt2Minute, dt2Second); + return dt1.isBefore(dt2) || dt1.isEqual(dt2); + } + + /** + * Formats a datetime value represented using six integers as a string according + * to the given pattern. Valid format trings are those accepted by + * {@link DateTimeFormatter.ofPattern}. + * + * @param year + * @param month + * @param day + * @param hours + * @param minutes + * @param seconds + * @param format + * @return a string representing the given datetime in the format specified by + * the format string + */ + @Predicate(name = "stdlib_datetime_to_string") + public static Set>> datetimeToString(int year, int month, int day, int hours, int minutes, int seconds, String format) { + LocalDateTime datetime = LocalDateTime.of(year, month, day, hours, minutes, seconds); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + return Collections.singleton(Terms.asTermList(formatter.format(datetime))); + } + + /** + * Checks whether the given string matches the given regex. + */ + @Predicate(name = "stdlib_string_matches_regex") + public static boolean stringMatchesRegex(String str, String regex) { + return str.matches(regex); + } + + /** + * Returns the length of the given string + */ + @Predicate(name = "stdlib_string_length") + public static Set>> stringLength(String str) { + return Collections.singleton(Terms.asTermList(str.length())); + } + + /** + * Concatenates the two given strings + */ + @Predicate(name = "stdlib_string_concat") + public static Set>> stringConcat(String s1, String s2) { + return Collections.singleton(Terms.asTermList(s1 + s2)); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java new file mode 100644 index 000000000..e7c091951 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java @@ -0,0 +1,99 @@ +package at.ac.tuwien.kr.alpha.common; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.Collections.singletonList; + +public class AnswerSetBuilder { + private boolean firstInstance = true; + private String predicateSymbol; + private CorePredicate predicate; + private SortedSet predicates = new TreeSet<>(); + private SortedSet instances = new TreeSet<>(); + private Map> predicateInstances = new HashMap<>(); + + public AnswerSetBuilder() { + } + + public AnswerSetBuilder(AnswerSetBuilder copy) { + this.firstInstance = copy.firstInstance; + this.predicateSymbol = copy.predicateSymbol; + this.predicate = copy.predicate; + this.predicates = new TreeSet<>(copy.predicates); + this.instances = new TreeSet<>(copy.instances); + this.predicateInstances = new HashMap<>(copy.predicateInstances); + this.predicateInstances = copy.predicateInstances.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new TreeSet<>(e.getValue()))); + } + + private void flush() { + if (firstInstance) { + predicate = CorePredicate.getInstance(predicateSymbol, 0); + predicates.add(predicate); + predicateInstances.put(predicate, new TreeSet<>(singletonList(new BasicAtom(predicate)))); + } else { + SortedSet atoms = predicateInstances.get(predicate); + if (atoms == null) { + predicateInstances.put(predicate, new TreeSet<>(instances)); + } else { + atoms.addAll(instances); + } + } + firstInstance = true; + instances.clear(); + predicate = null; + } + + public AnswerSetBuilder predicate(String predicateSymbol) { + if (this.predicateSymbol != null) { + flush(); + } + this.predicateSymbol = predicateSymbol; + return this; + } + + @SafeVarargs + public final > AnswerSetBuilder instance(final T... terms) { + if (firstInstance) { + firstInstance = false; + predicate = CorePredicate.getInstance(predicateSymbol, terms.length); + predicates.add(predicate); + } + + // Note that usage of terms does not pollute the heap, + // since we are only reading, not writing. + List termList = Stream + .of(terms) + .map(CoreConstantTerm::getInstance) + .collect(Collectors.toList()); + + instances.add(new BasicAtom(predicate, termList)); + return this; + } + + public AnswerSetBuilder symbolicInstance(String... terms) { + if (firstInstance) { + firstInstance = false; + predicate = CorePredicate.getInstance(predicateSymbol, terms.length); + predicates.add(predicate); + } + + List termList = Stream.of(terms).map(CoreConstantTerm::getSymbolicInstance).collect(Collectors.toList()); + instances.add(new BasicAtom(predicate, termList)); + return this; + } + + public BasicAnswerSet build() { + flush(); + return new BasicAnswerSet(predicates, predicateInstances); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java new file mode 100644 index 000000000..8467cc19b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java @@ -0,0 +1,6 @@ +package at.ac.tuwien.kr.alpha.common; + +@FunctionalInterface +public interface AnswerSetFormatter { + T format(AnswerSet answerSet); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java new file mode 100644 index 000000000..d8b4fb7cf --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java @@ -0,0 +1,184 @@ +/** + * 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 + * 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.common; + +import at.ac.tuwien.kr.alpha.solver.Antecedent; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; + +import java.util.Set; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; + +public interface Assignment { + Entry get(int atom); + + /** + * Returns the truth value assigned to an atom. + * @param atom the id of the atom. + * @return the truth value; null if atomId is not assigned. + */ + default ThriceTruth getTruth(int atom) { + final Entry entry = get(atom); + return entry == null ? null : entry.getTruth(); + } + + /** + * Returns the weak decision level of the atom if it is assigned. + * @param atom the atom. + * @return the weak decision level of the atom if it is assigned; otherwise any value may be returned. + */ + int getWeakDecisionLevel(int atom); + + /** + * Returns the strong decision level of the atom. + * @param atom the atom. + * @return the strong decision level of the atom or -1. + */ + int getStrongDecisionLevel(int atom); + + boolean isAssigned(int atom); + + /** + * Returns the NoGood that implied the atom. + * @param atom the atom. + * @return the implying Antecedent. + */ + Antecedent getImpliedBy(int atom); + + /** + * Determines if the given {@code noGood} is undefined in the current assignment. + * + * @param noGood + * @return {@code true} iff at least one literal in {@code noGood} is unassigned. + */ + default boolean isUndefined(NoGood noGood) { + for (Integer literal : noGood) { + if (!isAssigned(atomOf(literal))) { + return true; + } + } + return false; + } + + /** + * Returns an iterator over all newly assigned atoms. New assignments are only returned once. + * @return an iterator over all atoms newly assigned to TRUE or MBT. + */ + IntIterator getNewPositiveAssignmentsIterator(); + + /** + * Returns the new assignments to process. + * @return a Pollable that yields the atoms that were newly assigned. + */ + Pollable getAssignmentsToProcess(); + + /** + * Returns the weak decision level of the atom considering also out-of-order assignments. + * @param atom the atom. + * @return the weakDecisionLevel of the atom if it is not an out-of-order assignment, otherwise the lowest + * decision level at which it will be re-assigned. + */ + int getRealWeakDecisionLevel(int atom); + + interface Pollable { + int peek(); + int remove(); + boolean isEmpty(); + } + + interface Entry { + ThriceTruth getTruth(); + int getAtom(); + int getDecisionLevel(); + Antecedent getImpliedBy(); + + boolean hasPreviousMBT(); + int getMBTDecisionLevel(); + + } + + int getDecisionLevel(); + + default boolean isViolated(int literal) { + final int atom = atomOf(literal); + final ThriceTruth truth = getTruth(atom); + + // For unassigned atoms, any literal is not violated. + return truth != null && isNegated(literal) != truth.toBoolean(); + + } + + default boolean violates(NoGood noGood) { + // Check each NoGood, if it is violated + for (Integer noGoodLiteral : noGood) { + if (!isAssigned(atomOf(noGoodLiteral)) || !isViolated(noGoodLiteral)) { + return false; + } + } + return true; + } + + /** + * Returns all atomIds that are assigned TRUE in the current assignment. + * @return a list of all true assigned atoms. + */ + Set getTrueAssignments(); + + /** + * Reports how many atoms are assigned to must-be-true currently. If this method returns + * zero, the assignment is guaranteed to be free of must-be-true values (i.e. it only + * contains assignments to either true or false). + * @return the count of must-be-true values in the asignment. + */ + int getMBTCount(); + + void backtrack(); + + /** + * Grows all internal data structures to accommodate for all atoms known. + */ + void growForMaxAtomId(); + + /** + * @return the number of atoms assigned since the last decision + */ + int getNumberOfAtomsAssignedSinceLastDecision(); + + /** + * Obtain a BasicAtom that is currently assigned MBT (but not TRUE). + * @return some BasicAtom that is assigned MBT. + */ + int getBasicAtomAssignedMBT(); + + /** + * Assigns all unassigned atoms to FALSE. + * @return true if any atom was assigned. + */ + boolean closeUnassignedAtoms(); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java new file mode 100644 index 000000000..2581cb11b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2016-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.common; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.solver.AtomCounter; + +import java.util.Iterator; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; + +/** + * Translates atoms between integer (solver) and object (grounder) representation. + */ +public interface AtomStore { + + /** + * Returns true whenever the atom is a valid choice point (i.e., it represents a rule body). + * @param atom + * @return + */ + boolean isAtomChoicePoint(int atom); + + /** + * Returns the highest atomId in use. + * @return the highest atomId in use. + */ + int getMaxAtomId(); + + /** + * Translates an atom represented as int into an Atom object. + * @param atom the atom to translate. + * @return the Atom object represented by the int. + */ + CoreAtom get(int atom); + + /** + * Translates an atom represented as Atom object into an int. + * @param atom the Atom object to translate. + * @return the int representing the Atom object. + */ + int get(CoreAtom atom); + + /** + * If the given ground atom is not already stored, associates it with a new integer (ID) and stores it, else + * returns the current associated atom ID. Hence, multiple calls with the same parameter will return the same + * value. + * @param groundAtom the ground atom to look up in the store. + * @return the integer ID of the ground atom, possibly newly assigned. + */ + int putIfAbsent(CoreAtom groundAtom); + + /** + * Returns whether the given ground atom is known to the AtomStore. + * @param groundAtom the ground atom to test. + * @return true if the ground atom is already associated an integer ID. + */ + boolean contains(CoreAtom groundAtom); + + String atomToString(int atom); + + default String literalToString(int literal) { + return (isNegated(literal) ? "-" : "+") + "(" + atomToString(atomOf(literal)) + ")"; + } + + /** + * Prints the NoGood such that literals are structured atoms instead of integers. + * @param noGood the nogood to translate + * @return the string representation of the NoGood. + */ + default String noGoodToString(T noGood) { + StringBuilder sb = new StringBuilder(); + + if (noGood.hasHead()) { + sb.append("*"); + } + sb.append("{"); + + for (Iterator iterator = noGood.iterator(); iterator.hasNext();) { + sb.append(literalToString(iterator.next())); + + if (iterator.hasNext()) { + sb.append(", "); + } + } + + sb.append("}"); + + return sb.toString(); + } + + AtomCounter getAtomCounter(); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java new file mode 100644 index 000000000..67994c90a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java @@ -0,0 +1,132 @@ +/** + * 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 + * 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.common; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.solver.AtomCounter; + +/** + * This class stores ground atoms and provides the translation from an (integer) atomId to a (structured) predicate instance. + */ +public class AtomStoreImpl implements AtomStore { + private final List atomIdsToInternalBasicAtoms = new ArrayList<>(); + private final Map predicateInstancesToAtomIds = new HashMap<>(); + private final IntIdGenerator atomIdGenerator = new IntIdGenerator(1); + private final AtomCounter atomCounter = new AtomCounter(); + + private final List releasedAtomIds = new ArrayList<>(); // contains atomIds ready to be garbage collected if necessary. + + public AtomStoreImpl() { + // Create atomId for falsum (currently not needed, but it gets atomId 0, which cannot represent a negated literal). + atomIdsToInternalBasicAtoms.add(null); + } + + @Override + public int putIfAbsent(CoreAtom groundAtom) { + if (!groundAtom.isGround()) { + throw new IllegalArgumentException("Atom must be ground: " + groundAtom); + } + + Integer id = predicateInstancesToAtomIds.get(groundAtom); + + if (id == null) { + id = atomIdGenerator.getNextId(); + predicateInstancesToAtomIds.put(groundAtom, id); + atomIdsToInternalBasicAtoms.add(id, groundAtom); + atomCounter.add(groundAtom); + } + + return id; + } + + @Override + public boolean contains(CoreAtom groundAtom) { + return predicateInstancesToAtomIds.containsKey(groundAtom); + } + + /** + * Removes the given atom from the AtomStoreImpl. + * @param atomId + */ + public void releaseAtomId(int atomId) { + releasedAtomIds.add(atomId); + // HINT: Additionally removing the terms used in the instance might be beneficial in some cases. + } + + public String printAtomIdTermMapping() { + StringBuilder ret = new StringBuilder(); + for (Map.Entry entry : predicateInstancesToAtomIds.entrySet()) { + ret.append(entry.getValue()).append(" <-> ").append(entry.getKey().toString()).append(System.lineSeparator()); + } + return ret.toString(); + } + + @Override + public String atomToString(int atomId) { + return get(atomId).toString(); + } + + @Override + public boolean isAtomChoicePoint(int atom) { + return get(atom) instanceof RuleAtom; + } + + @Override + public int getMaxAtomId() { + return atomIdsToInternalBasicAtoms.size() - 1; + } + + @Override + public CoreAtom get(int atom) { + try { + return atomIdsToInternalBasicAtoms.get(atom); + } catch (IndexOutOfBoundsException e) { + throw oops("Unknown atom ID encountered: " + atom, e); + } + } + + @Override + public int get(CoreAtom atom) { + return predicateInstancesToAtomIds.get(atom); + } + + @Override + public AtomCounter getAtomCounter() { + return atomCounter; + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java new file mode 100644 index 000000000..1bd486460 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java @@ -0,0 +1,117 @@ +package at.ac.tuwien.kr.alpha.common; + +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySortedSet; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +// TODO bring this into public non-core API by using something like an "answer-set-view" +public class BasicAnswerSet implements AnswerSet { + public static final BasicAnswerSet EMPTY = new BasicAnswerSet(emptySortedSet(), emptyMap()); + + private final SortedSet predicates; + private final Map> predicateInstances; + + public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { + this.predicates = predicates; + this.predicateInstances = predicateInstances; + } + + @Override + public SortedSet getPredicates() { + return predicates; + } + + @Override + public SortedSet getPredicateInstances(Predicate predicate) { + return predicateInstances.get(predicate); + } + + @Override + public boolean isEmpty() { + return predicates.isEmpty(); + } + + @Override + public String toString() { + if (predicates.isEmpty()) { + return "{}"; + } + + final StringBuilder sb = new StringBuilder("{ "); + for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { + Predicate predicate = iterator.next(); + Set instances = getPredicateInstances(predicate); + + if (instances == null || instances.isEmpty()) { + sb.append(predicate.getName()); + continue; + } + + for (Iterator instanceIterator = instances.iterator(); instanceIterator.hasNext();) { + sb.append(instanceIterator.next()); + if (instanceIterator.hasNext()) { + sb.append(", "); + } + } + + if (iterator.hasNext()) { + sb.append(", "); + } + } + sb.append(" }"); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof BasicAnswerSet)) { + return false; + } + + BasicAnswerSet that = (BasicAnswerSet) o; + + if (!predicates.equals(that.predicates)) { + return false; + } + + return predicateInstances.equals(that.predicateInstances); + } + + @Override + public int hashCode() { + return 31 * predicates.hashCode() + predicateInstances.hashCode(); + } + + @Override + public int compareTo(AnswerSet other) { + final SortedSet predicates = this.getPredicates(); + int result = Util.compareSortedSets(predicates, other.getPredicates()); + + if (result != 0) { + return result; + } + + for (Predicate predicate : predicates) { + result = Util.compareSortedSets(this.getPredicateInstances(predicate), other.getPredicateInstances(predicate)); + + if (result != 0) { + return result; + } + } + + return 0; + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java new file mode 100644 index 000000000..b9a61571a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java @@ -0,0 +1,39 @@ +package at.ac.tuwien.kr.alpha.common; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +public enum ComparisonOperator { + EQ("="), + NE("!="), + LT("<"), + GT(">"), + LE("<="), + GE(">="); + + private String asString; + + ComparisonOperator(String asString) { + this.asString = asString; + } + + @Override + public String toString() { + return asString; + } + + public ComparisonOperator getNegation() { + switch (this) { + case EQ: return NE; + case NE: return EQ; + case LT: return GE; + case GT: return LE; + case LE: return GT; + case GE: return LT; + } + throw oops("Unknown binary operator encountered, cannot negate it"); + } + + public CorePredicate predicate() { + return CorePredicate.getInstance(this.asString, 2); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java new file mode 100644 index 000000000..670241c1c --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java @@ -0,0 +1,107 @@ +package at.ac.tuwien.kr.alpha.common; + +/** + * A predicate as used by the Alpha solver internally. + * + * Copyright (c) 2016-2020, the Alpha Team. + */ +public class CorePredicate implements Comparable { + + private static final Interner INTERNER = new Interner<>(); + + private final String name; + private final int arity; + private final boolean internal; + private final boolean solverInternal; + + protected CorePredicate(String name, int arity, boolean internal, boolean solverInternal) { + this.name = name; + this.arity = arity; + this.internal = internal; + this.solverInternal = solverInternal; + } + + public static CorePredicate getInstance(String symbol, int arity) { + return getInstance(symbol, arity, false, false); + } + + public static CorePredicate getInstance(String symbol, int arity, boolean internal) { + return getInstance(symbol, arity, internal, false); + } + + public static CorePredicate getInstance(String symbol, int arity, boolean internal, boolean solverInternal) { + return INTERNER.intern(new CorePredicate(symbol, arity, internal, solverInternal)); + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + arity; + result = 31 * result + (internal ? 1 : 0); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof CorePredicate)) { + return false; + } + + CorePredicate predicate = (CorePredicate) o; + + if (arity != predicate.arity) { + return false; + } + + if (internal != predicate.internal) { + return false; + } + + return name != null ? name.equals(predicate.name) : predicate.name == null; + } + + /** + * Marks internal predicates that should not be shown/printed in answer sets. + * @return true iff this Predicate should be omitted from answer sets. + */ + public boolean isInternal() { + return internal; + } + + /** + * Marks predicates that are used purely for encoding rules by NoGoods in the solver component. Solver internal + * predicates are guaranteed to not occur in any rule bodies and hence are ignored by the grounder. + * @return true iff this Predicate is internal to the solver component. + */ + public boolean isSolverInternal() { + return solverInternal; + } + + @Override + public int compareTo(CorePredicate other) { + int result = getName().compareTo(other.getName()); + + if (result != 0) { + return result; + } + + return Integer.compare(getArity(), other.getArity()); + } + + public String getName() { + return name; + } + + public int getArity() { + return arity; + } + + @Override + public String toString() { + return name + "/" + arity; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java new file mode 100644 index 000000000..0e7c0790e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java @@ -0,0 +1,20 @@ +package at.ac.tuwien.kr.alpha.common; + +/** + * An iterator returning raw int integers instead of Integer objects (for efficiency). + * + * Copyright (c) 2020, the Alpha Team. + */ +public interface IntIterator { + + /** + * @return true if the iterator has more elements. + */ + boolean hasNext(); + + /** + * @return the next int in the iteration. + */ + int next(); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java new file mode 100644 index 000000000..debfa2423 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java @@ -0,0 +1,26 @@ +package at.ac.tuwien.kr.alpha.common; + +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; + +public class Interner { + private WeakHashMap> pool = new WeakHashMap<>(); + + public synchronized T intern(T object) { + T res; + // (The loop is needed to deal with race + // conditions where the GC runs while we are + // accessing the 'pool' map or the 'ref' object.) + do { + WeakReference ref = pool.get(object); + if (ref == null) { + ref = new WeakReference<>(object); + pool.put(object, ref); + res = object; + } else { + res = ref.get(); + } + } while (res == null); + return res; + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java new file mode 100644 index 000000000..8c703a54b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java @@ -0,0 +1,83 @@ +/** + * 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 + * 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.common; + +/** + * Provides methods to convert atoms to literals and vice versa, + * and to obtain and change information on the polarity of a literal. + * A literal is represented by an integer whose least significant bit is + * 1 if the literal is negated and 0 otherwise, and whose other bits + * encode the atom. + */ +public final class Literals { + /** + * Given a literal, returns the corresponding atom. + * @param literal the literal to translate. + * @return the corresponding atom. + */ + public static int atomOf(int literal) { + return literal >> 1; + } + + /** + * A utility to check if a given literal is negated. + * @param literal the literal to check. + * @return {@code true} iff the literal is negated, {@code false} otherwise. + */ + public static boolean isNegated(int literal) { + return (literal & 0x1) == 1; + } + + public static boolean isPositive(int literal) { + return (literal & 0x1) == 0; + } + + public static int negateLiteral(int literal) { + return literal ^ 0x1; + } + + public static int atomToLiteral(int atom, boolean truth) { + return truth ? atomToLiteral(atom) : atomToNegatedLiteral(atom); + } + + public static int atomToLiteral(int atom) { + return atom << 1; + } + + public static int atomToNegatedLiteral(int atom) { + return negateLiteral(atomToLiteral(atom)); + } + + public static int positiveLiteral(int literal) { + return literal & ~0x1; + } + + public static String literalToString(int literal) { + return (isPositive(literal) ? "+" : "-") + atomOf(literal); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java new file mode 100644 index 000000000..84e70cd0e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2016-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.common; + +import at.ac.tuwien.kr.alpha.solver.Antecedent; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.IntStream; + +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.*; + +public class NoGood implements NoGoodInterface, Comparable { + public static final int HEAD = 0; + public static final NoGood UNSAT = new NoGood(); + + protected final int[] literals; + private final boolean head; + private final Type type; + + public NoGood(int... literals) { + this(STATIC, literals, false); + } + + public NoGood(Type type, int... literals) { + this(type, literals, false); + } + + private NoGood(Type type, int[] literals, boolean head) { + this.type = type; + this.head = head; + if (head && !isNegated(literals[0])) { + throw oops("Head is not negative"); + } + + // HINT: this might decrease performance if NoGoods are mostly small. + Arrays.sort(literals, head ? 1 : 0, literals.length); + + int shift = 0; + for (int i = 1; i < literals.length; i++) { + if (literals[i - 1] == literals[i]) { // check for duplicate + shift++; + } + literals[i - shift] = literals[i]; // Remove duplicates in place by shifting remaining literals. + } + + // copy-shrink array if needed. + this.literals = shift <= 0 ? literals : Arrays.copyOf(literals, literals.length - shift); + } + + protected NoGood(NoGood noGood) { + this.literals = noGood.literals.clone(); + this.head = noGood.head; + this.type = noGood.type; + } + + public static NoGood learnt(int... literals) { + return new NoGood(LEARNT, literals); + } + + public static NoGood headFirst(int... literals) { + return headFirst(STATIC, literals); + } + + public static NoGood headFirstInternal(int... literals) { + return headFirst(INTERNAL, literals); + } + + public static NoGood headFirst(Type type, int... literals) { + return new NoGood(type, literals, true); + } + + public static NoGood fact(int literal) { + return headFirst(literal); + } + + public static NoGood support(int headLiteral, int bodyRepresentingLiteral) { + return new NoGood(SUPPORT, headLiteral, negateLiteral(bodyRepresentingLiteral)); + } + + public static NoGood fromConstraint(List posLiterals, List negLiterals) { + return new NoGood(addPosNeg(new int[posLiterals.size() + negLiterals.size()], posLiterals, negLiterals, 0)); + } + + public static NoGood fromBody(List posLiterals, List negLiterals, int bodyRepresentingLiteral) { + return fromBody(STATIC, posLiterals, negLiterals, bodyRepresentingLiteral); + } + + public static NoGood fromBodyInternal(List posLiterals, List negLiterals, int bodyRepresentingLiteral) { + return fromBody(INTERNAL, posLiterals, negLiterals, bodyRepresentingLiteral); + } + + public static NoGood fromBody(Type type, List posLiterals, List negLiterals, int bodyRepresentingLiteral) { + int[] bodyLiterals = new int[posLiterals.size() + negLiterals.size() + 1]; + bodyLiterals[0] = negateLiteral(bodyRepresentingLiteral); + return NoGood.headFirst(type, addPosNeg(bodyLiterals, posLiterals, negLiterals, 1)); + } + + private static int[] addPosNeg(int[] literals, List posLiterals, List negLiterals, int offset) { + int i = offset; + for (Integer literal : posLiterals) { + literals[i++] = literal; + } + for (Integer literal : negLiterals) { + literals[i++] = negateLiteral(literal); + } + return literals; + } + + @Override + public int size() { + return literals.length; + } + + @Override + public Antecedent asAntecedent() { + return new Antecedent() { + + @Override + public int[] getReasonLiterals() { + return NoGood.this.literals; // Beware: returned array must not be modified! + } + + @Override + public void bumpActivity() { + } + + @Override + public void decreaseActivity() { + } + }; + } + + public NoGood withoutHead() { + return new NoGood(type, literals.clone()); + } + + /** + * A shorthand for Literals.positiveLiteral(getLiteral(...)) + */ + public int getPositiveLiteral(int index) { + return positiveLiteral(getLiteral(index)); + } + + @Override + public int getLiteral(int index) { + return literals[index]; + } + + @Override + public boolean hasHead() { + return head; + } + + @Override + public int getHead() { + return getLiteral(HEAD); + } + + @Override + public Type getType() { + return type; + } + + @Override + public Iterator iterator() { + return new Iterator() { + private int i; + + @Override + public boolean hasNext() { + return literals.length > i; + } + + @Override + public Integer next() { + return literals[i++]; + } + }; + } + + public IntStream stream() { + return Arrays.stream(literals); + } + + @Override + public int compareTo(NoGood o) { + if (o == null) { + throw new NullPointerException("Cannot compare against null."); + } + + if (o.head && !head) { + return -1; + } + + if (!o.head && head) { + return +1; + } + + if (o.literals.length > literals.length) { + return -1; + } + + if (o.literals.length < literals.length) { + return +1; + } + + for (int i = 0; i < literals.length; i++) { + if (o.literals[i] > literals[i]) { + return -1; + } + if (o.literals[i] < literals[i]) { + return +1; + } + } + + return 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + NoGood noGood = (NoGood) o; + + return head == noGood.head && Arrays.equals(literals, noGood.literals); + } + + @Override + public int hashCode() { + return 31 * Arrays.hashCode(literals) * (head ? +1 : -1); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + if (head) { + sb.append("*"); + } + + sb.append("{ "); + + for (int literal : literals) { + sb.append(isPositive(literal) ? "+" : "-"); + sb.append(atomOf(literal)); + sb.append(" "); + } + + sb.append("}"); + + return sb.toString(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java new file mode 100644 index 000000000..95157630e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java @@ -0,0 +1,95 @@ +/* + * 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.common; + +import at.ac.tuwien.kr.alpha.solver.Antecedent; + +public interface NoGoodInterface extends Iterable { + + /** + * Returns the literal at the given index. + * @param index the index position within the NoGood. + * @return the literal at the index. + */ + int getLiteral(int index); + + /** + * Returns whether the NoGood has a head. + * @return true if the NoGood has a head. + */ + boolean hasHead(); + + /** + * Returns the head literal of the NoGood, if present. + * @return the head literal if the NoGood has a head, otherwise an arbitrary integer. + */ + int getHead(); + + /** + * Returns the size, i.e., number of literals, in the NoGood. + * @return the size of the NoGood. + */ + int size(); + + default boolean isUnary() { + return size() == 1; + } + + default boolean isBinary() { + return size() == 2; + } + + Antecedent asAntecedent(); + + Type getType(); + + /** + * The possible nogood types + */ + enum Type { + /** + * Unremovable nogood from the input program + */ + STATIC, + + /** + * Removable support nogood from the input program + */ + SUPPORT, + + /** + * Removable nogood learnt from a conflict + */ + LEARNT, + + /** + * Nogood containing solver-internal atoms + */ + INTERNAL, + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java new file mode 100644 index 000000000..f705ca4be --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java @@ -0,0 +1,33 @@ +package at.ac.tuwien.kr.alpha.common; + +import java.util.ArrayList; +import java.util.List; +import java.util.SortedSet; +import java.util.stream.Collectors; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; + +public class SimpleAnswerSetFormatter implements AnswerSetFormatter { + + private final String atomSeparator; + + public SimpleAnswerSetFormatter(String atomSeparator) { + this.atomSeparator = atomSeparator; + } + + @Override + public String format(AnswerSet answerSet) { + List predicateInstanceStrings = new ArrayList<>(); + for (CorePredicate p : answerSet.getPredicates()) { + SortedSet instances; + if ((instances = answerSet.getPredicateInstances(p)) == null || instances.isEmpty()) { + predicateInstanceStrings.add(p.getName()); + } else { + List atomStrings = instances.stream().map((atom) -> atom.toString()).collect(Collectors.toList()); + predicateInstanceStrings.add(String.join(this.atomSeparator, atomStrings)); + } + } + return "{ " + String.join(this.atomSeparator, predicateInstanceStrings) + " }"; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java new file mode 100644 index 000000000..58283a094 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java @@ -0,0 +1,10 @@ +package at.ac.tuwien.kr.alpha.common; + +/** + * Represents truth value that can be converted to a Boolean truth value. + * Copyright (c) 2016, the Alpha Team. + */ +@FunctionalInterface +public interface Truth { + boolean toBoolean(); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java new file mode 100644 index 000000000..f37e0acc8 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java @@ -0,0 +1,269 @@ +/** + * 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. + * + * 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.common.atoms; + +import static at.ac.tuwien.kr.alpha.Util.join; +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +public class AggregateAtom extends CoreAtom { + + private final ComparisonOperator lowerBoundOperator; + private final CoreTerm lowerBoundTerm; + private final ComparisonOperator upperBoundOperator; + private final CoreTerm upperBoundTerm; + private final AGGREGATEFUNCTION aggregatefunction; + private final List aggregateElements; + + public AggregateAtom(ComparisonOperator lowerBoundOperator, CoreTerm lowerBoundTerm, ComparisonOperator upperBoundOperator, CoreTerm upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { + this.lowerBoundOperator = lowerBoundOperator; + this.lowerBoundTerm = lowerBoundTerm; + this.upperBoundOperator = upperBoundOperator; + this.upperBoundTerm = upperBoundTerm; + this.aggregatefunction = aggregatefunction; + this.aggregateElements = aggregateElements; + if (upperBoundOperator != null || lowerBoundOperator != ComparisonOperator.LE || lowerBoundTerm == null) { + throw new UnsupportedOperationException("Aggregate construct not yet supported: " + this); + } + } + + @Override + public boolean isGround() { + for (AggregateElement aggregateElement : aggregateElements) { + if (!aggregateElement.isGround()) { + return false; + } + } + if (lowerBoundTerm != null && !lowerBoundTerm.isGround() + || upperBoundTerm != null && !upperBoundTerm.isGround()) { + return false; + } + return true; + } + + + @Override + public AggregateLiteral toLiteral(boolean positive) { + return new AggregateLiteral(this, positive); + } + + @Override + public List getTerms() { + throw oops("Aggregate atom cannot report terms."); + } + + @Override + public CoreAtom withTerms(List terms) { + throw new UnsupportedOperationException("Editing term list is not supported for aggregate atoms!"); + } + + @Override + public CorePredicate getPredicate() { + throw oops("Aggregate atom cannot report predicate."); + } + + /** + * Returns all variables occurring inside the aggregate, between { ... }. + * @return each variable occurring in some aggregate element. + */ + public List getAggregateVariables() { + List occurringVariables = new LinkedList<>(); + for (AggregateElement aggregateElement : aggregateElements) { + occurringVariables.addAll(aggregateElement.getOccurringVariables()); + } + return occurringVariables; + } + + @Override + public AggregateAtom substitute(Substitution substitution) { + return null; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + AggregateAtom that = (AggregateAtom) o; + + if (lowerBoundOperator != that.lowerBoundOperator) { + return false; + } + if (lowerBoundTerm != null ? !lowerBoundTerm.equals(that.lowerBoundTerm) : that.lowerBoundTerm != null) { + return false; + } + if (upperBoundOperator != that.upperBoundOperator) { + return false; + } + if (upperBoundTerm != null ? !upperBoundTerm.equals(that.upperBoundTerm) : that.upperBoundTerm != null) { + return false; + } + if (aggregateElements != null ? !aggregateElements.equals(that.aggregateElements) : that.aggregateElements != null) { + return false; + } + return aggregatefunction == that.aggregatefunction; + } + + @Override + public String toString() { + String lowerBound = lowerBoundTerm == null ? "" : (lowerBoundTerm.toString() + lowerBoundOperator); + String upperBound = upperBoundTerm == null ? "" : (upperBoundOperator.toString() + upperBoundTerm); + return lowerBound + "#" + aggregatefunction + "{ " + join("", aggregateElements, "; ", "") + " }" + upperBound; + } + + @Override + public int hashCode() { + int result = lowerBoundOperator != null ? lowerBoundOperator.hashCode() : 0; + result = 31 * result + (lowerBoundTerm != null ? lowerBoundTerm.hashCode() : 0); + result = 31 * result + (upperBoundOperator != null ? upperBoundOperator.hashCode() : 0); + result = 31 * result + (upperBoundTerm != null ? upperBoundTerm.hashCode() : 0); + result = 31 * result + (aggregateElements != null ? aggregateElements.hashCode() : 0); + result = 31 * result + (aggregatefunction != null ? aggregatefunction.hashCode() : 0); + return result; + } + + public ComparisonOperator getLowerBoundOperator() { + return lowerBoundOperator; + } + + public CoreTerm getLowerBoundTerm() { + return lowerBoundTerm; + } + + public ComparisonOperator getUpperBoundOperator() { + return upperBoundOperator; + } + + public CoreTerm getUpperBoundTerm() { + return upperBoundTerm; + } + + public AGGREGATEFUNCTION getAggregatefunction() { + return aggregatefunction; + } + + public List getAggregateElements() { + return Collections.unmodifiableList(aggregateElements); + } + + public enum AGGREGATEFUNCTION { + COUNT, + MAX, + MIN, + SUM + } + + public static class AggregateElement { + final List elementTerms; + final List elementLiterals; + + public AggregateElement(List elementTerms, List elementLiterals) { + this.elementTerms = elementTerms; + this.elementLiterals = elementLiterals; + } + + public List getElementTerms() { + return elementTerms; + } + + public List getElementLiterals() { + return elementLiterals; + } + + public boolean isGround() { + for (CoreTerm elementTerm : elementTerms) { + if (!elementTerm.isGround()) { + return false; + } + } + for (CoreLiteral elementLiteral : elementLiterals) { + if (!elementLiteral.isGround()) { + return false; + } + } + return true; + } + + public List getOccurringVariables() { + List occurringVariables = new LinkedList<>(); + for (CoreTerm term : elementTerms) { + if (term instanceof VariableTerm) { + occurringVariables.add((VariableTerm) term); + } + } + for (CoreLiteral literal : elementLiterals) { + occurringVariables.addAll(literal.getBindingVariables()); + occurringVariables.addAll(literal.getNonBindingVariables()); + } + return occurringVariables; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + AggregateElement that = (AggregateElement) o; + + if (elementTerms != null ? !elementTerms.equals(that.elementTerms) : that.elementTerms != null) { + return false; + } + return elementLiterals != null ? elementLiterals.equals(that.elementLiterals) : that.elementLiterals == null; + } + + @Override + public int hashCode() { + int result = elementTerms != null ? elementTerms.hashCode() : 0; + result = 31 * result + (elementLiterals != null ? elementLiterals.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return join("", elementTerms, " : ") + join("", elementLiterals, ""); + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java new file mode 100644 index 000000000..a2d6123cc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java @@ -0,0 +1,64 @@ +package at.ac.tuwien.kr.alpha.common.atoms; + +import java.util.HashSet; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Copyright (c) 2018, the Alpha Team. + */ +public class AggregateLiteral extends CoreLiteral { + public AggregateLiteral(AggregateAtom atom, boolean positive) { + super(atom, positive); + } + + @Override + public AggregateAtom getAtom() { + return (AggregateAtom)atom; + } + + @Override + public AggregateLiteral negate() { + return new AggregateLiteral(getAtom(), !positive); + } + + /** + * @see CoreAtom#substitute(Substitution) + */ + @Override + public AggregateLiteral substitute(Substitution substitution) { + return new AggregateLiteral(getAtom().substitute(substitution), positive); + } + + @Override + public Set getBindingVariables() { + Set bindingVariables = new HashSet<>(); + if (boundBindingVariable(getAtom().getLowerBoundOperator(), getAtom().getLowerBoundTerm(), positive) != null) { + bindingVariables.add((VariableTerm) getAtom().getLowerBoundTerm()); + } + if (boundBindingVariable(getAtom().getUpperBoundOperator(), getAtom().getUpperBoundTerm(), positive) != null) { + bindingVariables.add((VariableTerm) getAtom().getUpperBoundTerm()); + } + return bindingVariables; + } + + @Override + public Set getNonBindingVariables() { + // Note: every local variable that also occurs globally in the rule is a nonBindingVariable, hence an + // aggregate literal alone cannot detect its non-binding (i.e. global) variables. + throw new UnsupportedOperationException(); + } + + private static VariableTerm boundBindingVariable(ComparisonOperator op, CoreTerm bound, boolean positive) { + boolean isNormalizedEquality = op == ComparisonOperator.EQ && positive || op == ComparisonOperator.NE && !positive; + if (isNormalizedEquality && bound instanceof VariableTerm) { + return (VariableTerm) bound; + } + return null; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java new file mode 100644 index 000000000..746abc051 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2016-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.common.atoms; + +import static at.ac.tuwien.kr.alpha.Util.join; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Represents ordinary ASP atoms. + */ +public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { + private final CorePredicate predicate; + private final List terms; + private final boolean ground; + + /** + * Creates a positive BasicAtom over predicate and terms. + * + * @param predicate + * @param terms + */ + public BasicAtom(CorePredicate predicate, List terms) { + this.predicate = predicate; + this.terms = terms; + + boolean ground = true; + for (CoreTerm term : terms) { + if (!term.isGround()) { + ground = false; + break; + } + } + + this.ground = ground; + } + + public BasicAtom(CorePredicate predicate, CoreTerm... terms) { + this(predicate, Arrays.asList(terms)); + } + + public BasicAtom(CorePredicate predicate) { + this(predicate, Collections.emptyList()); + } + + @Override + public CorePredicate getPredicate() { + return predicate; + } + + @Override + public List getTerms() { + return terms; + } + + @Override + public boolean isGround() { + return ground; + } + + @Override + public BasicAtom substitute(Substitution substitution) { + return new BasicAtom(predicate, terms.stream() + .map(t -> t.substitute(substitution)) + .collect(Collectors.toList())); + } + + @Override + public BasicAtom normalizeVariables(String prefix, int counterStartingValue) { + List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); + return new BasicAtom(predicate, renamedTerms); + } + + @Override + public CoreLiteral toLiteral(boolean positive) { + return new BasicLiteral(this, positive); + } + + @Override + public String toString() { + final String prefix = predicate.getName(); + if (terms.isEmpty()) { + return prefix; + } + + return join(prefix + "(", terms, ")"); + } + + @Override + public int compareTo(CoreAtom o) { + if (this.terms.size() != o.getTerms().size()) { + return this.terms.size() - o.getTerms().size(); + } + + int result = this.predicate.compareTo(o.getPredicate()); + + if (result != 0) { + return result; + } + + for (int i = 0; i < terms.size(); i++) { + result = terms.get(i).compareTo(o.getTerms().get(i)); + if (result != 0) { + return result; + } + } + + return 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + BasicAtom that = (BasicAtom) o; + + return predicate.equals(that.predicate) && terms.equals(that.terms); + } + + @Override + public int hashCode() { + return 31 * predicate.hashCode() + terms.hashCode(); + } + + @Override + public CoreAtom withTerms(List terms) { + return new BasicAtom(predicate, terms); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java new file mode 100644 index 000000000..173e9befc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2017-2018, 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.common.atoms; + +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * Contains a potentially negated {@link BasicAtom}. + * + * Copyright (c) 2017-2018, the Alpha Team. + */ +public class BasicLiteral extends CoreLiteral { + + public BasicLiteral(BasicAtom atom, boolean positive) { + super(atom, positive); + } + + @Override + public BasicAtom getAtom() { + return (BasicAtom) atom; + } + + /** + * Returns a new copy of this literal whose {@link Literal#isNegated()} status is inverted + */ + @Override + public BasicLiteral negate() { + return new BasicLiteral(getAtom(), !positive); + } + + /** + * @see CoreAtom#substitute(Substitution) + */ + @Override + public BasicLiteral substitute(Substitution substitution) { + return new BasicLiteral(getAtom().substitute(substitution), positive); + } + + /** + * Set of all variables occurring in the Atom that are potentially binding, i.e., variables in positive atoms. + * + * @return + */ + @Override + public Set getBindingVariables() { + if (!positive) { + // Negative literal has no binding variables. + return Collections.emptySet(); + } + Set bindingVariables = new HashSet<>(); + for (CoreTerm term : atom.getTerms()) { + bindingVariables.addAll(term.getOccurringVariables()); + } + return bindingVariables; + } + + /** + * Set of all variables occurring in the Atom that are never binding, not even in positive atoms, e.g., variables in intervals or built-in atoms. + * + * @return + */ + @Override + public Set getNonBindingVariables() { + if (positive) { + // Positive literal has only binding variables. + return Collections.emptySet(); + } + Set nonbindingVariables = new HashSet<>(); + for (CoreTerm term : atom.getTerms()) { + nonbindingVariables.addAll(term.getOccurringVariables()); + } + return nonbindingVariables; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java new file mode 100644 index 000000000..c94b8e231 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java @@ -0,0 +1,128 @@ +/** + * 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.common.atoms; + +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Represents a builtin comparison atom according to the standard. + */ +public class ComparisonAtom extends CoreAtom implements VariableNormalizableAtom { + private final CorePredicate predicate; + final ComparisonOperator operator; + private final List terms; + + private ComparisonAtom(List terms, ComparisonOperator operator) { + this.terms = terms; + this.operator = operator; + this.predicate = operator.predicate(); + } + + public ComparisonAtom(CoreTerm term1, CoreTerm term2, ComparisonOperator operator) { + this(Arrays.asList(term1, term2), operator); + } + + @Override + public CorePredicate getPredicate() { + return predicate; + } + + @Override + public List getTerms() { + return terms; + } + + @Override + public boolean isGround() { + return terms.get(0).isGround() && terms.get(1).isGround(); + } + + @Override + public ComparisonAtom substitute(Substitution substitution) { + List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); + return new ComparisonAtom(substitutedTerms, operator); + } + + @Override + public ComparisonLiteral toLiteral(boolean positive) { + return new ComparisonLiteral(this, positive); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(terms.get(0)); + sb.append(" "); + sb.append(operator); + sb.append(" "); + sb.append(terms.get(1)); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ComparisonAtom that = (ComparisonAtom) o; + + if (operator != that.operator) { + return false; + } + return terms.equals(that.terms); + } + + @Override + public int hashCode() { + return 31 * (31 * operator.hashCode() + terms.hashCode()); + } + + @Override + public ComparisonAtom normalizeVariables(String prefix, int counterStartingValue) { + List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); + return new ComparisonAtom(renamedTerms.get(0), renamedTerms.get(1), operator); + } + + @Override + public CoreAtom withTerms(List terms) { + return new ComparisonAtom(terms, operator); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java new file mode 100644 index 000000000..836cd21be --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java @@ -0,0 +1,218 @@ +/** + * 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. + * + * 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.common.atoms; + +import static at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm.evaluateGroundTerm; + +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Contains a potentially negated {@link ComparisonAtom}. + */ +public class ComparisonLiteral extends FixedInterpretationLiteral { + private final boolean isNormalizedEquality; + + public ComparisonLiteral(ComparisonAtom atom, boolean positive) { + super(atom, positive); + final ComparisonOperator operator = getAtom().operator; + isNormalizedEquality = (positive && operator == ComparisonOperator.EQ) + || (!positive && operator == ComparisonOperator.NE); + } + + @Override + public ComparisonAtom getAtom() { + return (ComparisonAtom)atom; + } + + public boolean isNormalizedEquality() { + return isNormalizedEquality; + } + + /** + * Returns a new copy of this literal whose {@link Literal#isNegated()} status is inverted + */ + @Override + public ComparisonLiteral negate() { + return new ComparisonLiteral(getAtom(), !positive); + } + + /** + * @see CoreAtom#substitute(Substitution) + */ + @Override + public ComparisonLiteral substitute(Substitution substitution) { + return new ComparisonLiteral(getAtom().substitute(substitution), positive); + } + + private boolean assignable(CoreTerm term) { + return isNormalizedEquality && term instanceof VariableTerm; + } + + @Override + public Set getBindingVariables() { + final CoreTerm left = getTerms().get(0); + final CoreTerm right = getTerms().get(1); + if (assignable(left) && assignable(right)) { + // In case this is "X = Y" or "not X != Y" then both sides are binding given that the other is. + // In this case non-binding and binding variables cannot be reported accurately, in fact, the double variable could be compiled away. + throw new RuntimeException("Builtin equality with left and right side being variables encountered. Should not happen."); + } + if (assignable(left)) { + return Collections.singleton((VariableTerm) left); + } + if (assignable(right)) { + return Collections.singleton((VariableTerm) right); + } + return Collections.emptySet(); + } + + @Override + public Set getNonBindingVariables() { + final CoreTerm left = getTerms().get(0); + final CoreTerm right = getTerms().get(1); + HashSet occurringVariables = new HashSet<>(); + List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); + List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); + if (assignable(left)) { + leftOccurringVariables.remove(left); + } + if (assignable(right)) { + rightOccurringVariables.remove(right); + } + occurringVariables.addAll(leftOccurringVariables); + occurringVariables.addAll(rightOccurringVariables); + if (assignable(left) || assignable(right)) { + return occurringVariables; + } + // Neither left- nor right-assigning, hence no variable is binding. + return occurringVariables; + } + + @Override + public List getSatisfyingSubstitutions(Substitution partialSubstitution) { + // Treat case where this is just comparison with all variables bound by partialSubstitution. + final CoreTerm left = getAtom().getTerms().get(0).substitute(partialSubstitution); + final CoreTerm right = getAtom().getTerms().get(1).substitute(partialSubstitution); + final boolean leftAssigning = assignable(left); + final boolean rightAssigning = assignable(right); + if (!leftAssigning && !rightAssigning) { + // No assignment (variables are bound by partialSubstitution), thus evaluate comparison only. + CoreTerm leftEvaluatedSubstitute = evaluateTerm(left); + if (leftEvaluatedSubstitute == null) { + return Collections.emptyList(); + } + CoreTerm rightEvaluatedSubstitute = evaluateTerm(right); + if (rightEvaluatedSubstitute == null) { + return Collections.emptyList(); + } + if (compare(leftEvaluatedSubstitute, rightEvaluatedSubstitute)) { + return Collections.singletonList(partialSubstitution); + } else { + return Collections.emptyList(); + } + } + // Treat case that this is X = t or t = X. + VariableTerm variable = null; + CoreTerm expression = null; + if (leftAssigning) { + variable = (VariableTerm) left; + expression = right; + } + if (rightAssigning) { + variable = (VariableTerm) right; + expression = left; + } + CoreTerm groundTerm = expression.substitute(partialSubstitution); + CoreTerm resultTerm = null; + // Check if the groundTerm is an arithmetic expression and evaluate it if so. + if (groundTerm instanceof ArithmeticTerm) { + Integer result = evaluateGroundTerm(groundTerm); + if (result == null) { + return Collections.emptyList(); + } + resultTerm = CoreConstantTerm.getInstance(result); + } else { + // Ground term is another term (constant, or function term). + resultTerm = groundTerm; + } + Substitution extendedSubstitution = new Substitution(partialSubstitution); + extendedSubstitution.put(variable, resultTerm); + return Collections.singletonList(extendedSubstitution); + } + + public boolean isLeftOrRightAssigning() { + final CoreTerm left = getTerms().get(0); + final CoreTerm right = getTerms().get(1); + return isNormalizedEquality && (assignable(left) && right.isGround() || assignable(right) && left.isGround()); + } + + private CoreTerm evaluateTerm(CoreTerm term) { + // Evaluate arithmetics. + if (term instanceof ArithmeticTerm) { + Integer result = ArithmeticTerm.evaluateGroundTerm(term); + if (result == null) { + return null; + } + return CoreConstantTerm.getInstance(result); + } + return term; + } + + private boolean compare(CoreTerm x, CoreTerm y) { + final int comparisonResult = x.compareTo(y); + ComparisonOperator operator = isNegated() ? getAtom().operator.getNegation() : getAtom().operator; + switch (operator) { + case EQ: + return comparisonResult == 0; + case LT: + return comparisonResult < 0; + case GT: + return comparisonResult > 0; + case LE: + return comparisonResult <= 0; + case GE: + return comparisonResult >= 0; + case NE: + return comparisonResult != 0; + default: + throw new UnsupportedOperationException("Unknown comparison operator requested!"); + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java new file mode 100644 index 000000000..d8fe2ee7e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2016-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.common.atoms; + +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.grounder.Unifier; + +/** + * An Atom is the common superclass of all representations of ASP atoms used by Alpha. + */ +public abstract class CoreAtom implements Comparable{ + + /** + * Creates a new Atom that represents this Atom, but has the given term list instead. + * + * @param terms the terms to set. + * @return a new Atom with the given terms set. + */ + public abstract CoreAtom withTerms(List terms); + + /** + * Returns the set of all variables occurring in the Atom. + */ + public Set getOccurringVariables() { + return toLiteral().getOccurringVariables(); + } + + /** + * This method applies a substitution to the atom. Note that, depending on the atom and the substitution, the + * resulting atom may still contain variables. + * + * @param substitution the variable substitution to apply. + * @return the atom resulting from the application of the substitution. + */ + public abstract CoreAtom substitute(Substitution substitution); + + public abstract List getTerms(); + + public abstract CorePredicate getPredicate(); + + /** + * Returns whether this atom is ground, i.e., variable-free. + * + * @return true iff the terms of this atom contain no {@link VariableTerm}. + */ + public abstract boolean isGround(); + + /** + * Creates a non-negated literal containing this atom. + */ + public CoreLiteral toLiteral() { + return toLiteral(true); + } + + public abstract CoreLiteral toLiteral(boolean positive); + + public CoreAtom renameVariables(String newVariablePrefix) { + Unifier renamingSubstitution = new Unifier(); + int counter = 0; + for (VariableTerm variable : getOccurringVariables()) { + renamingSubstitution.put(variable, VariableTerm.getInstance(newVariablePrefix + counter++)); + } + return this.substitute(renamingSubstitution); + } + + @Override + public int compareTo(CoreAtom o) { + if (o == null) { + return 1; + } + + final List aTerms = this.getTerms(); + final List bTerms = o.getTerms(); + + if (aTerms.size() != bTerms.size()) { + return Integer.compare(aTerms.size(), bTerms.size()); + } + + int result = this.getPredicate().compareTo(o.getPredicate()); + + if (result != 0) { + return result; + } + + for (int i = 0; i < aTerms.size(); i++) { + result = aTerms.get(i).compareTo(o.getTerms().get(i)); + if (result != 0) { + return result; + } + } + + return 0; + } + + @Override + public abstract boolean equals(Object o); + + @Override + public abstract int hashCode(); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java new file mode 100644 index 000000000..b87bafc64 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java @@ -0,0 +1,122 @@ +/** + * 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.common.atoms; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import org.apache.commons.collections4.SetUtils; + +import java.util.List; +import java.util.Set; + +/** + * A potentially negated {@link CoreAtom} + * + * Copyright (c) 2017-2018, the Alpha Team. + */ +public abstract class CoreLiteral { + + protected final CoreAtom atom; + protected final boolean positive; + + public CoreLiteral(CoreAtom atom, boolean positive) { + this.atom = atom; + this.positive = positive; + } + + public CoreAtom getAtom() { + return atom; + } + + public boolean isNegated() { + return !positive; + } + + public abstract CoreLiteral negate(); + + public abstract CoreLiteral substitute(Substitution substitution); + + public abstract Set getBindingVariables(); + + public abstract Set getNonBindingVariables(); + + /** + * Union of {@link #getBindingVariables()} and {@link #getNonBindingVariables()} + */ + public Set getOccurringVariables() { + return SetUtils.union(getBindingVariables(), getNonBindingVariables()); + } + + /** + * @see CoreAtom#getPredicate() + */ + public CorePredicate getPredicate() { + return atom.getPredicate(); + } + + /** + * @see CoreAtom#getTerms() + */ + public List getTerms() { + return atom.getTerms(); + } + + /** + * @see CoreAtom#isGround() + */ + public boolean isGround() { + return atom.isGround(); + } + + @Override + public String toString() { + return (positive ? "" : "not ") + atom.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + CoreLiteral that = (CoreLiteral) o; + + return atom.equals(that.atom) && positive == that.positive; + } + + @Override + public int hashCode() { + return 12 * atom.hashCode() + (positive ? 1 : 0); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java new file mode 100644 index 000000000..50a62cf63 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java @@ -0,0 +1,180 @@ +/** + * 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. + *

      + * 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.common.atoms; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static at.ac.tuwien.kr.alpha.Util.join; + +public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { + + private final List input; + private final List output; + + protected final CorePredicate predicate; + protected final PredicateInterpretation interpretation; + + public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { + if (predicate == null) { + throw new IllegalArgumentException("predicate must not be null!"); + } + if (interpretation == null) { + throw new IllegalArgumentException("interpretation must not be null!"); + } + if (input == null) { + throw new IllegalArgumentException("input must not be null!"); + } + if (output == null) { + throw new IllegalArgumentException("output must not be null!"); + } + this.predicate = predicate; + this.interpretation = interpretation; + this.input = input; + this.output = output; + } + + public boolean hasOutput() { + return !output.isEmpty(); + } + + @Override + public CorePredicate getPredicate() { + return predicate; + } + + public PredicateInterpretation getInterpretation() { + return interpretation; + } + + public List getInput() { + return Collections.unmodifiableList(input); + } + + public List getOutput() { + return Collections.unmodifiableList(output); + } + + @Override + public List getTerms() { + return input; + } + + @Override + public boolean isGround() { + for (CoreTerm t : input) { + if (!t.isGround()) { + return false; + } + } + for (CoreTerm t : output) { + if (!t.isGround()) { + return false; + } + } + return true; + } + + @Override + public ExternalAtom 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 ExternalAtom(predicate, interpretation, substitutedInput, substitutedOutput); + } + + @Override + public ExternalLiteral toLiteral(boolean positive) { + return new ExternalLiteral(this, positive); + } + + @Override + public String toString() { + String result = "&" + predicate.getName(); + if (!input.isEmpty()) { + result += join("[", input, "]"); + } + if (!output.isEmpty()) { + result += join("(", output, ")"); + } + return result; + } + + @Override + public CoreAtom withTerms(List terms) { + throw new UnsupportedOperationException("Editing term list is not supported for external atoms!"); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + this.input.hashCode(); + result = prime * result + this.output.hashCode(); + result = prime * result + this.predicate.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof ExternalAtom)) { + return false; + } + ExternalAtom other = (ExternalAtom) obj; + if (!this.input.equals(other.input)) { + return false; + } + if (!this.output.equals(other.output)) { + return false; + } + if (!this.predicate.equals(other.predicate)) { + return false; + } + return true; + } + + @Override + public ExternalAtom normalizeVariables(String prefix, int counterStartingValue) { + List renamedInput = CoreTerm.renameTerms(this.input, prefix + "_IN_", counterStartingValue); + List renamedOutput = CoreTerm.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); + return new ExternalAtom(this.predicate, this.interpretation, renamedInput, renamedOutput); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java new file mode 100644 index 000000000..29dfffed6 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java @@ -0,0 +1,209 @@ +/** + * 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.common.atoms; + +import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.*; + +/** + * Contains a potentially negated {@link ExternalAtom}. + */ +public class ExternalLiteral extends FixedInterpretationLiteral { + + public ExternalLiteral(ExternalAtom atom, boolean positive) { + super(atom, positive); + } + + @Override + public ExternalAtom getAtom() { + return (ExternalAtom) atom; + } + + /** + * Returns a new copy of this literal whose {@link Literal#isNegated()} status + * is inverted + */ + @Override + public ExternalLiteral negate() { + return new ExternalLiteral(getAtom(), !positive); + } + + /** + * @see CoreAtom#substitute(Substitution) + */ + @Override + public ExternalLiteral substitute(Substitution substitution) { + return new ExternalLiteral(getAtom().substitute(substitution), positive); + } + + @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 (!positive) { + return Collections.emptySet(); + } + + List output = getAtom().getOutput(); + + Set binding = new HashSet<>(output.size()); + + for (CoreTerm 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 (CoreTerm term : input) { + nonbindingVariables.addAll(term.getOccurringVariables()); + } + + // If the external atom is negative, then all variables of input and output are + // non-binding. + if (!positive) { + for (CoreTerm out : output) { + if (out instanceof VariableTerm) { + nonbindingVariables.add((VariableTerm) out); + } + } + } + + return nonbindingVariables; + } + + @Override + public List getSatisfyingSubstitutions(Substitution partialSubstitution) { + List input = getAtom().getInput(); + List substitutes = new ArrayList<>(input.size()); + + // In preparation for evaluating the external atom, set the input values according + // to the partial substitution supplied by the grounder. + for (CoreTerm t : input) { + substitutes.add(t.substitute(partialSubstitution)); + } + Set>> results = getAtom().getInterpretation().evaluate(substitutes); + if (results == null) { + throw new NullPointerException("Predicate " + getPredicate().getName() + " returned null. It must return a Set."); + } + + if (this.isNegated()) { + return this.isNegatedLiteralSatisfied(results) ? Collections.singletonList(partialSubstitution) : Collections.emptyList(); + } else { + return this.buildSubstitutionsForOutputs(partialSubstitution, results); + } + } + + /** + * Checks whether this negated external literal is satisfied. + * + * Note that this method must only be called on negated external literals. + * In that case, the literal itself does not bind any output variables, + * i.e. the underlying atom is satisfied iff the output terms obtained by + * evaluating the underlying external atom match the values to which + * the respective output variables are bound. The result of this method assumes + * that the literal is negated, i.e. for the underlying atom AT, it represents + * the truth value !AT. + * Furthermore, this method assumes that the output terms of the underlying atom + * are {@link ConstantTerm}s, i.e. that the grounder's current partial + * substitution has already been applied to them. That assumption is safe since + * in case of a negated external literal, the output variables are always + * non-binding. + * + * @param externalMethodResult The term lists obtained from evaluating the external atom + * (i.e. calling the java method) encapsulated by this literal + * @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) { + List externalAtomOutTerms = this.getAtom().getOutput(); + boolean outputMatches; + for (List> resultTerms : externalMethodResult) { + outputMatches = true; + for (int i = 0; i < externalAtomOutTerms.size(); i++) { + if (!resultTerms.get(i).equals(externalAtomOutTerms.get(i))) { + outputMatches = false; + break; + } + } + if (outputMatches) { + // We found one term list where all terms match the ground output terms of the + // external atom, therefore the atom is true and the (negative) literal false. + return false; + } + } + // We checked all term list and none matches the ground output terms, therefore + // the external atom is false, making the literal true. + return true; + } + + private List buildSubstitutionsForOutputs(Substitution partialSubstitution, Set>> outputs) { + List retVal = new ArrayList<>(); + List externalAtomOutputTerms = this.getAtom().getOutput(); + for (List> bindings : outputs) { + if (bindings.size() < externalAtomOutputTerms.size()) { + throw new RuntimeException( + "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() + + " were expected."); + } + Substitution ith = new Substitution(partialSubstitution); + boolean skip = false; + for (int i = 0; i < externalAtomOutputTerms.size(); i++) { + CoreTerm out = externalAtomOutputTerms.get(i); + + if (out instanceof VariableTerm) { + ith.put((VariableTerm) out, bindings.get(i)); + } else { + if (!bindings.get(i).equals(out)) { + skip = true; + break; + } + } + } + if (!skip) { + retVal.add(ith); + } + } + return retVal; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java new file mode 100644 index 000000000..fc318944e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2017-2018, 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.common.atoms; + +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.List; + +/** + * Represents a literal whose ground truth value(s) are independent of the + * current assignment. + * Examples of atoms underlying such literals are builtin atoms and external + * atoms. + * Copyright (c) 2017-2018, the Alpha Team. + */ +public abstract class FixedInterpretationLiteral extends CoreLiteral { + + public FixedInterpretationLiteral(CoreAtom atom, boolean positive) { + super(atom, positive); + } + + /** + * Creates a list of {@link Substitution}s based on the given partial + * substitution, such that + * this {@link FixedInterpretationLiteral} is true in every returned + * substitution. + * In cases where this is not possible (because of conflicting variable + * assignments in the partial substitution), getSatisfyingSubstitutions is + * required to return an empty list + * + * @param partialSubstitution a partial substitution that is required to bind + * all variables that are non-binding in this literal + * @return a list of substitutions, in each of which this literal is true, or an + * empty list if no such substitution exists + */ + public abstract List getSatisfyingSubstitutions(Substitution partialSubstitution); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java new file mode 100644 index 000000000..7c63cf0b9 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java @@ -0,0 +1,20 @@ +package at.ac.tuwien.kr.alpha.common.atoms; + +/** + * Interface for atom whose variables can be normalized, i.e., enumerated from + * left to right. + * Copyright (c) 2018 the Alpha Team. + */ +public interface VariableNormalizableAtom { + + /** + * Returns an Atom whose variables are enumerated as Vi, .. Vn. + * + * @param prefix the variable prefix V in front of the counter. + * @param counterStartingValue the initial value i of the counter. + * @return the Atom where all variables are renamed and enumerated + * left-to-right. + */ + CoreAtom normalizeVariables(String prefix, int counterStartingValue); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java new file mode 100644 index 000000000..34096e4f6 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2019, the Alpha Team. + * 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.common.depgraph; + +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import org.apache.commons.lang3.StringUtils; + +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; + +/** + * Representation of an {@link InternalProgram}'s component graph, i.e. the directed acyclic graph resulting from condensing the program's + * {@link DependencyGraph} into its strongly connected components. Needed in order to calculate stratifications from which an evaluation order for the + * {@link at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation} transformation can be derived. + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public final class ComponentGraph { + + private final ArrayList components; + private final List entryPoints; + + private ComponentGraph(ArrayList components, List entryPoints) { + this.components = components; + this.entryPoints = entryPoints; + } + + /** + * Creates a new {@link ComponentGraph} based on a dependency graph and an {@link StronglyConnectedComponentsAlgorithm.SccResult} representing the + * result of calculating the dependency graph's strongly connected components (SCCs). + * + * @param dg the dependency graph backing this component graph. + * @param sccResult the SCC calculation result for the dependency graph in question. + * @return a new {@link ComponentGraph} representing the strongly connected components of the given dependency graph. + */ + public static ComponentGraph buildComponentGraph(DependencyGraph dg, StronglyConnectedComponentsAlgorithm.SccResult sccResult) { + return new ComponentGraph.Builder(dg, sccResult).build(); + } + + public List getComponents() { + return Collections.unmodifiableList(components); + } + + public List getEntryPoints() { + return Collections.unmodifiableList(entryPoints); + } + + public static class SCComponent { + + private final int id; + private final List nodes; + private final Map dependencyIds; + private final Set dependentIds; + private final boolean hasNegativeCycle; + + private SCComponent(int id, List nodes, Map dependencyIds, Set dependentIds, boolean hasNegativeCycle) { + this.id = id; + this.nodes = nodes; + this.dependencyIds = dependencyIds; + this.dependentIds = dependentIds; + this.hasNegativeCycle = hasNegativeCycle; + } + + public Map getDependencyIds() { + return Collections.unmodifiableMap(dependencyIds); + } + + public Set getDependentIds() { + return Collections.unmodifiableSet(dependentIds); + } + + @Override + public String toString() { + return "SCComponent{" + StringUtils.join(nodes, ",") + "}"; + } + + public boolean hasNegativeCycle() { + return hasNegativeCycle; + } + + public List getNodes() { + return nodes; + } + + public int getId() { + return id; + } + + private static class Builder { + + private int id; + private List nodes; + private Map dependencyIds = new HashMap<>(); + private Set dependentIds = new HashSet<>(); + private boolean hasNegativeCycle; + + private Builder(int id, List nodes) { + this.nodes = nodes; + this.id = id; + } + + private SCComponent build() { + return new SCComponent(id, nodes, dependencyIds, dependentIds, hasNegativeCycle); + } + + } + + } + + private static class Builder { + + private DependencyGraph depGraph; + private List> componentMap; + private Map nodesByComponentId; + private ArrayList componentBuilders = new ArrayList<>(); + private ArrayList components = new ArrayList<>(); + + private Builder(DependencyGraph dg, StronglyConnectedComponentsAlgorithm.SccResult sccResult) { + this.depGraph = dg; + this.componentMap = sccResult.stronglyConnectedComponents; + this.nodesByComponentId = sccResult.nodesByComponentId; + } + + private ComponentGraph build() { + // Create a ComponentBuilder for each component. + for (int i = 0; i < componentMap.size(); i++) { + componentBuilders.add(new SCComponent.Builder(i, componentMap.get(i))); + } + // Iterate and register each edge of every component. + for (int i = 0; i < componentBuilders.size(); i++) { + SCComponent.Builder builder = componentBuilders.get(i); + for (Node node : builder.nodes) { + for (Edge edge : depGraph.getAdjancencyMap().get(node)) { + registerEdge(i, edge); + } + } + } + // Build each component and identify starting components. + List startingPoints = new ArrayList<>(); + for (SCComponent.Builder builder : componentBuilders) { + SCComponent tmpComponent = builder.build(); + components.add(tmpComponent); + // Component is starting if it has no dependencies. + if (tmpComponent.getDependencyIds().isEmpty()) { + startingPoints.add(tmpComponent); + } + } + return new ComponentGraph(components, startingPoints); + } + + private void registerEdge(int srcComponentId, Edge edge) { + int destComponentId = nodesByComponentId.get(edge.getTarget()); + if (srcComponentId == destComponentId) { + // Record negative self-loop. + if (!edge.getSign()) { + componentBuilders.get(srcComponentId).hasNegativeCycle = true; + } + } else { + SCComponent.Builder srcComponentBld = componentBuilders.get(srcComponentId); + srcComponentBld.dependentIds.add(destComponentId); + SCComponent.Builder destComponentBld = componentBuilders.get(destComponentId); + boolean isPositiveDep = true; + if (destComponentBld.dependencyIds.containsKey(srcComponentId)) { + isPositiveDep = destComponentBld.dependencyIds.get(srcComponentId); + } + // If the dependency to srcComponent already is negative, it stays that way, otherwise it is determined by the edge's sign. + destComponentBld.dependencyIds.put(srcComponentId, isPositiveDep & edge.getSign()); + } + } + + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java new file mode 100644 index 000000000..395daeb4a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2019, the Alpha Team. + * 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.common.depgraph; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Internal representation of an {@link at.ac.tuwien.kr.alpha.common.program.InternalProgram}'s dependency graph. The dependency graph tracks dependencies + * between rules of a program. Each {@link Node} of the graph represents a {@link CorePredicate} occurring in the program. A node has an incoming {@link Edge} for + * every {@link Literal} in some rule body that depends on it, i.e. the predicate of the literal in question is the same as that of the node. The "sign" flag of + * an {@link Edge} indicates whether the dependency is a positive or negative one, i.e. if the atom in question is preceded by a "not". + * + * Note that constraints are represented by one dummy predicate (named "constr_{num}"). Each constraint node has a negative edge to itself to express the + * notation of a constraint ":- a, b." as "x :- a, b, not x.". + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public final class DependencyGraph { + + private static final Logger LOGGER = LoggerFactory.getLogger(DependencyGraph.class); + + /* + * Maps nodes to outgoing edges of that node. + * Note: using List rather than Map as one node may have positive and negative edges to + * another. + */ + private final Map> adjacencyMap; + + private final Map nodesByPredicate; + + private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { + this.adjacencyMap = adjacencyMap; + this.nodesByPredicate = nodesByPredicate; + } + + public static DependencyGraph buildDependencyGraph(Map nonGroundRules) { + return new DependencyGraph.Builder(nonGroundRules.values()).build(); + } + + public Node getNodeForPredicate(CorePredicate p) { + return nodesByPredicate.get(p); + } + + public Map> getAdjancencyMap() { + return Collections.unmodifiableMap(adjacencyMap); + } + + private static class Builder { + + private static final String CONSTRAINT_PREDICATE_FORMAT = "[constr_%d]"; + + private int constraintNumber; + private Collection rules; + + private Map> adjacentNodesMap = new HashMap<>(); + private Map nodesByPredicate = new HashMap<>(); + + private Builder(Collection rules) { + this.rules = rules; + this.constraintNumber = 0; + } + + private DependencyGraph build() { + for (InternalRule rule : rules) { + LOGGER.debug("Processing rule: {}", rule); + Node headNode = handleRuleHead(rule); + for (CoreLiteral literal : rule.getBody()) { + LOGGER.trace("Processing rule body literal: {}", literal); + if (literal instanceof FixedInterpretationLiteral) { + LOGGER.trace("Ignoring FixedInterpretationLiteral {}", literal); + continue; + } + handleRuleBodyLiteral(headNode, literal); + } + } + return new DependencyGraph(adjacentNodesMap, nodesByPredicate); + } + + private Node handleRuleHead(InternalRule rule) { + LOGGER.trace("Processing head of rule: {}", rule); + Node headNode; + if (rule.isConstraint()) { + CorePredicate pred = generateConstraintDummyPredicate(); + headNode = new Node(pred); + List dependencies = new ArrayList<>(); + dependencies.add(new Edge(headNode, false)); + if (adjacentNodesMap.containsKey(headNode)) { + throw new IllegalStateException("Dependency graph already contains node for constraint " + pred.toString() + "!"); + } + adjacentNodesMap.put(headNode, dependencies); + nodesByPredicate.put(pred, headNode); + } else { + CoreAtom head = rule.getHeadAtom(); + CorePredicate pred = head.getPredicate(); + if (!nodesByPredicate.containsKey(pred)) { + headNode = new Node(pred); + adjacentNodesMap.put(headNode, new ArrayList<>()); + nodesByPredicate.put(pred, headNode); + } else { + headNode = nodesByPredicate.get(pred); + } + } + return headNode; + } + + private void handleRuleBodyLiteral(Node headNode, CoreLiteral lit) { + List dependants; + Node bodyNode; + CorePredicate bodyPred = lit.getPredicate(); + if (!nodesByPredicate.containsKey(bodyPred)) { + LOGGER.trace("Creating new node for bodyPred {}", bodyPred); + dependants = new ArrayList<>(); + bodyNode = new Node(bodyPred); + nodesByPredicate.put(bodyPred, bodyNode); + adjacentNodesMap.put(bodyNode, dependants); + } else { + LOGGER.trace("Node for bodyPred {} already exists", bodyPred); + bodyNode = nodesByPredicate.get(bodyPred); + dependants = adjacentNodesMap.get(bodyNode); + } + Edge tmpEdge = new Edge(headNode, !lit.isNegated()); + if (!dependants.contains(tmpEdge)) { + LOGGER.trace("Adding dependency: {} -> {} ({})", bodyNode.getPredicate(), headNode.getPredicate(), tmpEdge.getSign() ? "+" : "-"); + dependants.add(tmpEdge); + } + nodesByPredicate.put(bodyPred, bodyNode); + } + + private CorePredicate generateConstraintDummyPredicate() { + return CorePredicate.getInstance(String.format(DependencyGraph.Builder.CONSTRAINT_PREDICATE_FORMAT, ++constraintNumber), 0); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java new file mode 100644 index 000000000..02b0347e1 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2019, the Alpha Team. + * 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.common.depgraph; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Performs a depth-first search on a given graph. + * The algorithm follows the approach outlined in "Introduction to Algorithms, 3rd Edition" by Cormen et al. + */ +class DepthFirstSearchAlgorithm { + + private Set discoveredNodes; // The "gray" nodes that have been seen but not fully processed yet. + private Deque finishedNodes; // The "black" nodes that have been processed. + private Map> depthFirstReachable; // Per root node, all others that are reachable from it. + + private DepthFirstSearchAlgorithm() { + discoveredNodes = new HashSet<>(); + finishedNodes = new LinkedList<>(); + depthFirstReachable = new HashMap<>(); + depthFirstReachable.put(null, new ArrayList<>()); + } + + public static DfsResult performDfs(Map> graph) { + return performDfs(graph.keySet().iterator(), graph); + } + + /** + * Performs a depth-first search on the given graph. The algorithm follows the approach outlined in + * "Introduction to Algortihms, 3rd Edition" by Cormen et al. + * Discovered nodes are "gray" and finished nodes "black", respectively, in the terminology used in the book. + * + * @param nodeVisitIt an Iterator over all nodes of the graph, defining in which sequence nodes should be + * visited (i.e., nodeVisitIt yields all initially "white" nodes of the graph). + * @param graph an adjacency map defining the dependency graph of an ASP program. + * @return a {@link DfsResult} holding all nodes in the sequence they were finished and per root node all its + * depth-first reachable nodes. + */ + public static DfsResult performDfs(Iterator nodeVisitIt, Map> graph) { + DepthFirstSearchAlgorithm algorithm = new DepthFirstSearchAlgorithm(); + return algorithm.performDepthFirstSearchAlgorithm(nodeVisitIt, graph); + } + + private DfsResult performDepthFirstSearchAlgorithm(Iterator nodeVisitIt, Map> graph) { + while (nodeVisitIt.hasNext()) { + Node currentNode = nodeVisitIt.next(); + if (!discoveredNodes.contains(currentNode)) { + depthFirstReachable.get(null).add(currentNode); + dfsVisit(currentNode, currentNode, graph); + } + } + DfsResult dfsResult = new DfsResult(); + dfsResult.finishedNodes = finishedNodes; + dfsResult.depthFirstReachable = depthFirstReachable; + return dfsResult; + } + + private void dfsVisit(Node currNode, Node rootNode, Map> graph) { + discoveredNodes.add(currNode); + + // Record root-reachability of current node. + if (!depthFirstReachable.containsKey(rootNode)) { + depthFirstReachable.put(rootNode, new ArrayList<>()); + } + depthFirstReachable.get(rootNode).add(currNode); + + for (Edge edge : graph.get(currNode)) { + // Proceed with adjacent (i.e., deeper) nodes first. + Node tmpNeighbor = edge.getTarget(); + if (!discoveredNodes.contains(tmpNeighbor)) { + dfsVisit(tmpNeighbor, rootNode, graph); + } + } + finishedNodes.add(currNode); + } + + /** + * The result of a depth first search: + * - a deque containing all nodes in their finishing order and + * - per root node all reachable other nodes (including the root itself). + */ + static class DfsResult { + Deque finishedNodes; + Map> depthFirstReachable; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java new file mode 100644 index 000000000..f286020b7 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2019, the Alpha Team. + * 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.common.depgraph; + +/** + * An edge in a dependency graph to be used in adjacency lists (i.e., only the target of the edge is recorded). Edges + * are labelled with a boolean sign indicating the polarity of the edge. + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public class Edge { + + private final Node target; + private final boolean sign; + + /** + * Creates a new edge for a dependency graph. Read as "target depends on source". The sign indicates whether the + * dependency is positive or negative (target node depends on default negated atom). + * Note: working assumption is that strong negation is treated like a positive dependency. + * + * @param target the target node. + * @param sign the polarity of the edge. + */ + public Edge(Node target, boolean sign) { + this.target = target; + this.sign = sign; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Edge)) { + return false; + } + Edge other = (Edge) o; + return this.target.equals(other.target) && this.sign == other.sign; + } + + @Override + public int hashCode() { + return ("" + target.getPredicate().toString() + sign).hashCode(); + } + + @Override + public String toString() { + return "(" + (sign ? "+" : "-") + ") ---> " + target.toString(); + } + + public Node getTarget() { + return target; + } + + public boolean getSign() { + return sign; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java new file mode 100644 index 000000000..f7f041aba --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2019, the Alpha Team. + * 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.common.depgraph; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; + +/** + * A node in a dependency graph. One node references exactly one predicate. This means that all rule heads deriving the + * same predicate will be condensed into the same graph node. In some cases this results in more "conservative" results + * in stratification analysis, where some rules will not be evaluated up-front, although that would be possible. + * + * Copyright (c) 2017-2020, the Alpha Team. + */ +public class Node { + + private final CorePredicate predicate; + + public Node(CorePredicate predicate) { + this.predicate = predicate; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Node)) { + return false; + } + return predicate.equals(((Node) o).predicate); + } + + @Override + public int hashCode() { + return predicate.hashCode(); + } + + @Override + public String toString() { + return "Node{" + predicate.toString() + "}"; + } + + public String getLabel() { + return predicate.toString(); + } + + public CorePredicate getPredicate() { + return predicate; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java new file mode 100644 index 000000000..cab16a8a9 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2019, the Alpha Team. + * 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.common.depgraph; + +import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Algorithm for finding a stratification of a given {@link ComponentGraph}. + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public class StratificationAlgorithm { + + private static final Logger LOGGER = LoggerFactory.getLogger(StratificationAlgorithm.class); + + private ComponentGraph componentGraph; + + private final boolean[] visitedComponents; // Marks visited components. + private final boolean[] isUnstratifiableComponent; // Marks those known to be not stratifiable (may be due to parent not being stratifiable). + private final SCComponent[] componentEvaluationSequence; // Store the topological order of all components. + + private int doneComponents; + private int numComponents; + + private StratificationAlgorithm(ComponentGraph cg) { + componentGraph = cg; + doneComponents = 0; + numComponents = cg.getComponents().size(); + visitedComponents = new boolean[numComponents]; + isUnstratifiableComponent = new boolean[numComponents]; + componentEvaluationSequence = new SCComponent[numComponents]; + } + + /** + * Calculates a stratification covering as much as possible (the maximal stratifiable part) of the given + * component graph. It assigns each strongly-connected component its own stratum and returns a sequence of + * all stratifiable components in topological order, i.e., if component A depends on component B then B occurs + * earlier in the returned sequence. + * + * @param cg the graph of strongly-connected-components (that must be acyclic). + * @return a list of all stratifiable components in the order that they can be evaluated. + */ + public static List calculateStratification(ComponentGraph cg) { + return new StratificationAlgorithm(cg).runStratification(); + } + + + private List runStratification() { + LOGGER.debug("Initial call to stratify with entry points!"); + + // Compute topological order and mark unstratifiable components. + for (SCComponent component : componentGraph.getEntryPoints()) { + topoSort(component, false); + } + + // Extract list of stratifiable components. + List stratifiableComponentsSequence = new ArrayList<>(); + for (SCComponent component : componentEvaluationSequence) { + if (!isUnstratifiableComponent[component.getId()]) { + stratifiableComponentsSequence.add(component); + } + } + + return stratifiableComponentsSequence; + } + + private void topoSort(SCComponent component, boolean hasUnstratifiableParent) { + // We compute a topological ordering using a depth-first search where for any node its position in the + // topological ordering is the reverse of its finishing time (i.e., last-finishing node comes first). + + int componentId = component.getId(); + + // If this component is marked unstratifiable, it was processed already, immediately return. + if (isUnstratifiableComponent[componentId]) { + return; + } + + boolean isUnstratifiable = hasUnstratifiableParent || component.hasNegativeCycle(); + isUnstratifiableComponent[componentId] = isUnstratifiable; + + // Note: the input graph is a component graph, hence it is a DAG and has no cycles, thus we do not have + // to mark nodes as visited before descending to deeper nodes. + + for (Integer dependentComponentId : component.getDependentIds()) { + // Descend if the lower node has not been visited yet or we need to propagate unstratifiable. + if (isUnstratifiable || !visitedComponents[dependentComponentId]) { + topoSort(componentGraph.getComponents().get(dependentComponentId), isUnstratifiable); + } + } + + // Add current component in front of all others (if we are visiting for the first time). + if (!visitedComponents[componentId]) { + visitedComponents[componentId] = true; + doneComponents++; + componentEvaluationSequence[numComponents - doneComponents] = component; + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java new file mode 100644 index 000000000..0854e7f3d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2019, the Alpha Team. + * 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.common.depgraph; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Algorithm to find strongly connected components of a given {@link DependencyGraph}. + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public class StronglyConnectedComponentsAlgorithm { + + private Map nodesByComponentId = new HashMap<>(); + + /** + * Calculates the strongly connected components of the given {@link DependencyGraph} according to the algorithm + * given in "Introduction to algorithms" by Cormen, Leiserson, Rivest, and Stein + * (aka Kosajaru-algorithm). + * + * @param dg the {@link DependencyGraph} for which to compute the strongly-connected components. + * @return an {@link SccResult} containing a list of all strongly-connected components and a mapping of each + * node to the component it belongs to. + */ + public static SccResult findStronglyConnectedComponents(DependencyGraph dg) { + return new StronglyConnectedComponentsAlgorithm().runStronglyConnectedComponentsAlgorithm(dg); + } + + private SccResult runStronglyConnectedComponentsAlgorithm(DependencyGraph dg) { + // Find al SCCs with Kosajaru's algorithm. + DepthFirstSearchAlgorithm.DfsResult intermediateResult = DepthFirstSearchAlgorithm.performDfs(dg.getAdjancencyMap()); + Map> transposedNodes = transposeGraph(dg.getAdjancencyMap()); + Deque finishedNodes = intermediateResult.finishedNodes; + DepthFirstSearchAlgorithm.DfsResult finalResult = DepthFirstSearchAlgorithm.performDfs(finishedNodes.descendingIterator(), transposedNodes); + // Extract components. + List> componentMap = extractComponents(finalResult); + return new SccResult(componentMap, nodesByComponentId); + } + + private List> extractComponents(DepthFirstSearchAlgorithm.DfsResult dfsResult) { + // Each node reachable from "null" in the DfsResult points to a different strongly-connected component. + List> componentMap = new ArrayList<>(); + for (Node componentRoot : dfsResult.depthFirstReachable.get(null)) { + int componentId = componentMap.size(); + // Note: every node inside a component is reachable from its root, even the root itself. + List nodesInComponent = dfsResult.depthFirstReachable.get(componentRoot); + for (Node node : nodesInComponent) { + nodesByComponentId.put(node, componentId); + } + List componentMembers = new ArrayList<>(nodesInComponent); + componentMap.add(componentMembers); + } + return componentMap; + } + + /** + * Transposes the given dependency graph, i.e. reverses the direction of each edge. + */ + private static Map> transposeGraph(Map> graph) { + Map> transposed = new HashMap<>(); + for (Map.Entry> entry : graph.entrySet()) { + Node srcNode = entry.getKey(); + if (!transposed.containsKey(srcNode)) { + transposed.put(srcNode, new ArrayList<>()); + } + for (Edge e : entry.getValue()) { + Node targetNode = e.getTarget(); + if (!transposed.containsKey(e.getTarget())) { + transposed.put(targetNode, new ArrayList<>()); + } + transposed.get(targetNode).add(new Edge(srcNode, e.getSign())); + } + } + return transposed; + } + + /** + * Represents the result of a search for strongly connected components on a {@link DependencyGraph}. + */ + public static class SccResult { + + final List> stronglyConnectedComponents; // List of strongly-connected-components (each component being a list of nodes). + final Map nodesByComponentId; // Reverse association of stronglyConnectedComponents. + + SccResult(List> components, Map nodesByComponentId) { + this.stronglyConnectedComponents = components; + this.nodesByComponentId = nodesByComponentId; + } + + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java new file mode 100644 index 000000000..aabd4f55b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; + +import java.util.List; + +public class BinaryPredicateInterpretation extends NonBindingPredicateInterpretation { + private final java.util.function.BiPredicate predicate; + + public BinaryPredicateInterpretation(java.util.function.BiPredicate predicate) { + super(2); + this.predicate = predicate; + } + + @Override + @SuppressWarnings("unchecked") + public boolean test(List> terms) { + return predicate.test( + (T) terms.get(0).getObject(), + (U) terms.get(1).getObject() + ); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java new file mode 100644 index 000000000..081de663b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import org.apache.commons.lang3.ClassUtils; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +public class BindingMethodPredicateInterpretation implements BindingPredicateInterpretation { + private final Method method; + + public BindingMethodPredicateInterpretation(Method method) { + if (!method.getReturnType().equals(Set.class)) { + throw new IllegalArgumentException("method must return Set"); + } + + this.method = method; + } + + @Override + @SuppressWarnings("unchecked") + public Set>> evaluate(List terms) { + if (terms.size() != method.getParameterCount()) { + throw new IllegalArgumentException( + "Parameter count mismatch when calling " + method.getName() + ". " + + "Expected " + method.getParameterCount() + " parameters but got " + terms.size() + "."); + } + + final Class[] parameterTypes = method.getParameterTypes(); + + final Object[] arguments = new Object[terms.size()]; + + for (int i = 0; i < arguments.length; i++) { + if (!(terms.get(i) instanceof ConstantTerm)) { + throw new IllegalArgumentException( + "Expected only constants as input for " + method.getName() + ", but got " + + "something else at position " + i + "."); + } + + arguments[i] = ((ConstantTerm) terms.get(i)).getObject(); + + final Class expected = parameterTypes[i]; + final Class actual = arguments[i].getClass(); + + if (expected.isAssignableFrom(actual)) { + continue; + } + + if (expected.isPrimitive() && ClassUtils.primitiveToWrapper(expected).isAssignableFrom(actual)) { + continue; + } + + throw new IllegalArgumentException( + "Parameter type mismatch when calling " + method.getName() + + " at position " + i + ". Expected " + expected + " but got " + + actual + "."); + } + + try { + 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-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java new file mode 100644 index 000000000..908f34a35 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; + +import java.util.List; + +public class IntPredicateInterpretation extends NonBindingPredicateInterpretation { + private final java.util.function.IntPredicate predicate; + + public IntPredicateInterpretation(java.util.function.IntPredicate predicate) { + this.predicate = predicate; + } + + @Override + protected boolean test(List> terms) { + if (!(terms.get(0).getObject() instanceof Integer)) { + throw new IllegalArgumentException("Integer expected"); + } + return predicate.test((Integer) terms.get(0).getObject()); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java new file mode 100644 index 000000000..e572b78db --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; + +import java.util.List; + +public class LongPredicateInterpretation extends NonBindingPredicateInterpretation { + private final java.util.function.LongPredicate predicate; + + public LongPredicateInterpretation(java.util.function.LongPredicate predicate) { + this.predicate = predicate; + } + + @Override + protected boolean test(List> terms) { + if (!(terms.get(0).getObject() instanceof Long)) { + throw new IllegalArgumentException("Long expected"); + } + return predicate.test((Long) terms.get(0).getObject()); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java new file mode 100644 index 000000000..622efdaa4 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import org.apache.commons.lang3.ClassUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +public class MethodPredicateInterpretation extends NonBindingPredicateInterpretation { + private final Method method; + + public MethodPredicateInterpretation(Method method) { + super(method.getParameterCount()); + + if (!method.getReturnType().equals(boolean.class)) { + throw new IllegalArgumentException("method must return boolean"); + } + + this.method = method; + } + + @Override + protected boolean test(List> terms) { + final Class[] parameterTypes = method.getParameterTypes(); + final Object[] arguments = new Object[terms.size()]; + + for (int i = 0; i < arguments.length; i++) { + arguments[i] = terms.get(i).getObject(); + + final Class expected = parameterTypes[i]; + final Class actual = arguments[i].getClass(); + + if (expected.isAssignableFrom(actual)) { + continue; + } + + if (expected.isPrimitive() && ClassUtils.primitiveToWrapper(expected).isAssignableFrom(actual)) { + continue; + } + + throw new IllegalArgumentException( + "Parameter type mismatch at position " + i + ". Expected " + expected + " but got " + + actual + "." + ); + } + + try { + return (boolean) method.invoke(null, arguments); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java new file mode 100644 index 000000000..9ff2080a6 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Template for predicate interpretations that do not generate new bindings but only return + * a truth value. + */ +public abstract class NonBindingPredicateInterpretation implements PredicateInterpretation { + private final int arity; + + public NonBindingPredicateInterpretation(int arity) { + this.arity = arity; + } + + public NonBindingPredicateInterpretation() { + this(1); + } + + @Override + public Set>> evaluate(List terms) { + if (terms.size() != arity) { + throw new IllegalArgumentException("Exactly " + arity + " term(s) required."); + } + + final List> constants = new ArrayList<>(terms.size()); + for (int i = 0; i < terms.size(); i++) { + if (!(terms.get(i) instanceof ConstantTerm)) { + throw new IllegalArgumentException( + "Expected only constants as input, but got " + + "something else at position " + i + "." + ); + } + + constants.add((ConstantTerm) terms.get(i)); + } + + try { + return test(constants) ? TRUE : FALSE; + } catch (ClassCastException e) { + throw new IllegalArgumentException("Argument types do not match.", e); + } + } + + protected abstract boolean test(List> terms); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java new file mode 100644 index 000000000..1e2011898 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java @@ -0,0 +1,12 @@ +package at.ac.tuwien.kr.alpha.common.fixedinterpretations; + +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +public interface PredicateInterpretationImpl extends PredicateInterpretation { + @Override + Set>> evaluate(List terms); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java new file mode 100644 index 000000000..d440837b8 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + +public class SuppliedPredicateInterpretation implements BindingPredicateInterpretation { + private final Supplier>>> supplier; + + public SuppliedPredicateInterpretation(Supplier>>> supplier) { + this.supplier = supplier; + } + + @Override + public Set>> evaluate(List terms) { + if (!terms.isEmpty()) { + throw new IllegalArgumentException("Can only be used without any arguments."); + } + return supplier.get(); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java new file mode 100644 index 000000000..fca1f5484 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2017-2018, 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.common.fixedinterpretations; + +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; + +import java.util.List; + +public class UnaryPredicateInterpretation extends NonBindingPredicateInterpretation { + private final java.util.function.Predicate predicate; + + public UnaryPredicateInterpretation(java.util.function.Predicate predicate) { + this.predicate = predicate; + } + + @Override + @SuppressWarnings("unchecked") + protected boolean test(List> terms) { + return predicate.test((T) terms.get(0).getObject()); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java new file mode 100644 index 000000000..de315f778 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2019-2020, the Alpha Team. + * 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.common.graphio; + +import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; +import at.ac.tuwien.kr.alpha.common.depgraph.Node; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.List; +import java.util.Map.Entry; + +public class ComponentGraphWriter { + + private static final String GRAPH_HEADING = "digraph componentGraph"; + + private static final String NODE_FMT = "n%d [label = C%d]%n"; + private static final String EDGE_FMT = "n%d -> n%d [xlabel=\"%s\" labeldistance=0.1]%n"; + + public void writeAsDot(ComponentGraph graph, OutputStream out) { + PrintStream ps = new PrintStream(out); + startGraph(ps); + writeComponentsTable(ps, graph); + ps.println(); + writeGraph(ps, graph); + finishGraph(ps); + ps.close(); + } + + private void startGraph(PrintStream ps) { + ps.println(ComponentGraphWriter.GRAPH_HEADING); + ps.println("{"); + ps.println("splines=false;"); + ps.println("ranksep=4.0;"); + } + + private void writeComponentsTable(PrintStream ps, ComponentGraph cg) { + ps.println("label = <"); + ps.println("\t"); + StringBuilder headerBuilder = new StringBuilder(""); + headerBuilder.append(""); + for (int i = 0; i < cg.getComponents().size(); i++) { + headerBuilder.append(""); + } + headerBuilder.append(""); + ps.println("\t\t" + headerBuilder.toString()); + StringBuilder contentBuilder = new StringBuilder(""); + contentBuilder.append(""); + for (int i = 0; i < cg.getComponents().size(); i++) { + contentBuilder.append(""); + } + contentBuilder.append(""); + ps.println("\t\t" + contentBuilder.toString()); + ps.println("\t
      Component Id").append(i).append("
      Predicates"); + for (Node n : cg.getComponents().get(i).getNodes()) { + contentBuilder.append(n.getLabel()).append("
      "); + } + contentBuilder.append("
      "); + ps.println(">"); + } + + private void writeGraph(PrintStream ps, ComponentGraph cg) { + List components = cg.getComponents(); + // Write the node descriptors for the components. + for (int componentId = 0; componentId < components.size(); componentId++) { + ps.printf(NODE_FMT, componentId, componentId); + for (Entry dependency : components.get(componentId).getDependencyIds().entrySet()) { + ps.printf(EDGE_FMT, dependency.getKey(), componentId, dependency.getValue().equals(true) ? "+" : "-"); + } + } + } + + private void finishGraph(PrintStream ps) { + ps.println("}"); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java new file mode 100644 index 000000000..7d838f8ca --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2019-2020, the Alpha Team. + * 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.common.graphio; + +import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.common.depgraph.Edge; +import at.ac.tuwien.kr.alpha.common.depgraph.Node; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; + +public class DependencyGraphWriter { + + private static final String DEFAULT_GRAPH_HEADING = "digraph dependencyGraph"; + + private static final String DEFAULT_NODE_FORMAT = "n%d [label = \"%s\"]%n"; + private static final String DEFAULT_EDGE_FORMAT = "n%d -> n%d [xlabel=\"%s\" labeldistance=0.1]%n"; + + public void writeAsDot(DependencyGraph graph, OutputStream out) { + writeAsDot(graph.getAdjancencyMap(), out); + } + + private void writeAsDot(Map> graph, OutputStream out) { + BiFunction nodeFormatter = this::buildNodeString; + writeAsDot(graph, out, nodeFormatter); + } + + private void writeAsDot(Map> graph, OutputStream out, BiFunction nodeFormatter) { + PrintStream ps = new PrintStream(out); + startGraph(ps); + + Set>> graphDataEntries = graph.entrySet(); + // First, write all nodes. + int nodeCnt = 0; + Map nodesToNumbers = new HashMap<>(); + for (Map.Entry> entry : graphDataEntries) { + ps.print(nodeFormatter.apply(entry.getKey(), nodeCnt)); + nodesToNumbers.put(entry.getKey(), nodeCnt); + nodeCnt++; + } + + // Second, write all edges. + for (Map.Entry> entry : graphDataEntries) { + int fromNodeNum = nodesToNumbers.get(entry.getKey()); + for (Edge edge : entry.getValue()) { + int toNodeNum = nodesToNumbers.get(edge.getTarget()); + ps.printf(DependencyGraphWriter.DEFAULT_EDGE_FORMAT, fromNodeNum, toNodeNum, edge.getSign() ? "+" : "-"); + } + } + + finishGraph(ps); + ps.close(); + } + + private void startGraph(PrintStream ps) { + ps.println(DependencyGraphWriter.DEFAULT_GRAPH_HEADING); + ps.println("{"); + ps.println("splines=false;"); + ps.println("ranksep=4.0;"); + } + + private void finishGraph(PrintStream ps) { + ps.println("}"); + } + + private String buildNodeString(Node n, int nodeNum) { + return String.format(DependencyGraphWriter.DEFAULT_NODE_FORMAT, nodeNum, n.getLabel()); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java new file mode 100644 index 000000000..0043b5e7b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java @@ -0,0 +1,52 @@ +package at.ac.tuwien.kr.alpha.common.program; + +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.rule.AbstractRule; +import at.ac.tuwien.kr.alpha.common.rule.head.Head; +import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; + +import java.util.Collections; +import java.util.List; + +/** + * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives) + * + * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an implementation permits + * Copyright (c) 2019, the Alpha Team. + */ +public abstract class AbstractProgram> { + + private final List rules; + private final List facts; + private final InlineDirectives inlineDirectives; + + public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { + this.rules = rules; + this.facts = facts; + this.inlineDirectives = inlineDirectives; + } + + public List getRules() { + return Collections.unmodifiableList(rules); + } + + public List getFacts() { + return Collections.unmodifiableList(facts); + } + + public InlineDirectives getInlineDirectives() { + return inlineDirectives; + } + + @Override + public String toString() { + final String ls = System.lineSeparator(); + final String result = facts.isEmpty() ? "" : Util.join("", facts, "." + ls, "." + ls); + if (rules.isEmpty()) { + return result; + } + return Util.join(result, rules, ls, ls); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java new file mode 100644 index 000000000..6a7437c36 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java @@ -0,0 +1,48 @@ +package at.ac.tuwien.kr.alpha.common.program; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.common.depgraph.StronglyConnectedComponentsAlgorithm; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.List; + + +/** + * An {@link InternalProgram} with dependency information. + * + * Copyright (c) 2019-2020, the Alpha Team + */ +public class AnalyzedProgram extends InternalProgram { + + private final DependencyGraph dependencyGraph; + private final ComponentGraph componentGraph; + + public AnalyzedProgram(List rules, List facts) { + super(rules, facts); + dependencyGraph = DependencyGraph.buildDependencyGraph(getRulesById()); + componentGraph = buildComponentGraph(dependencyGraph); + } + + public static AnalyzedProgram analyzeNormalProgram(NormalProgram prog) { + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); + return new AnalyzedProgram(rulesAndFacts.left, rulesAndFacts.right); + } + + private ComponentGraph buildComponentGraph(DependencyGraph depGraph) { + StronglyConnectedComponentsAlgorithm.SccResult sccResult = StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(depGraph); + return ComponentGraph.buildComponentGraph(depGraph, sccResult); + } + + public ComponentGraph getComponentGraph() { + return componentGraph; + } + + public DependencyGraph getDependencyGraph() { + return dependencyGraph; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java new file mode 100644 index 000000000..3bb1d8190 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 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.common.program; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. + *

      + * Copyright (c) 2017-2019, the Alpha Team. + */ +public class InputProgram extends AbstractProgram implements Program { + + public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectives()); + + public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { + super(rules, facts, inlineDirectives); + } + + public InputProgram() { + super(new ArrayList<>(), new ArrayList<>(), new InlineDirectives()); + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(InputProgram prog) { + return new Builder(prog); + } + + /** + * Builder for more complex program construction scenarios, ensuring that an {@link InputProgram} is immutable + */ + public static class Builder { + + private List rules = new ArrayList<>(); + private List facts = new ArrayList<>(); + private InlineDirectives inlineDirectives = new InlineDirectives(); + + public Builder(InputProgram prog) { + this.addRules(prog.getRules()); + this.addFacts(prog.getFacts()); + this.addInlineDirectives(prog.getInlineDirectives()); + } + + public Builder() { + + } + + public Builder addRules(List rules) { + this.rules.addAll(rules); + return this; + } + + public Builder addRule(BasicRule r) { + this.rules.add(r); + return this; + } + + public Builder addFacts(List facts) { + this.facts.addAll(facts); + return this; + } + + public Builder addFact(CoreAtom fact) { + this.facts.add(fact); + return this; + } + + public Builder addInlineDirectives(InlineDirectives inlineDirectives) { + this.inlineDirectives.accumulate(inlineDirectives); + return this; + } + + 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); + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java new file mode 100644 index 000000000..dd8f88f53 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java @@ -0,0 +1,89 @@ +package at.ac.tuwien.kr.alpha.common.program; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.rule.NormalRule; +import at.ac.tuwien.kr.alpha.grounder.FactIntervalEvaluator; +import at.ac.tuwien.kr.alpha.grounder.Instance; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; + +/** + * A program in the internal representation needed for grounder and solver, i.e.: rules must have normal heads, all + * aggregates must be rewritten, all intervals must be preprocessed (into interval atoms), and equality predicates must + * be rewritten. + *

      + * Copyright (c) 2017-2020, the Alpha Team. + */ +public class InternalProgram extends AbstractProgram { + + private final Map> predicateDefiningRules = new LinkedHashMap<>(); + private final Map> factsByPredicate = new LinkedHashMap<>(); + private final Map rulesById = new LinkedHashMap<>(); + + public InternalProgram(List rules, List facts) { + super(rules, facts, null); + recordFacts(facts); + recordRules(rules); + } + + static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { + List internalRules = new ArrayList<>(); + List facts = new ArrayList<>(normalProgram.getFacts()); + for (NormalRule r : normalProgram.getRules()) { + if (r.getBody().isEmpty()) { + if (!r.getHead().isGround()) { + throw new IllegalArgumentException("InternalProgram does not support non-ground rules with empty bodies! (Head = " + r.getHead().toString() + ")"); + } + facts.add(r.getHeadAtom()); + } else { + internalRules.add(InternalRule.fromNormalRule(r)); + } + } + return new ImmutablePair<>(internalRules, facts); + } + + public static InternalProgram fromNormalProgram(NormalProgram normalProgram) { + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); + return new InternalProgram(rulesAndFacts.left, rulesAndFacts.right); + } + + private void recordFacts(List facts) { + for (CoreAtom fact : facts) { + List tmpInstances = FactIntervalEvaluator.constructFactInstances(fact); + CorePredicate tmpPredicate = fact.getPredicate(); + factsByPredicate.putIfAbsent(tmpPredicate, new LinkedHashSet<>()); + factsByPredicate.get(tmpPredicate).addAll(tmpInstances); + } + } + + private void recordRules(List rules) { + for (InternalRule rule : rules) { + rulesById.put(rule.getRuleId(), rule); + if (!rule.isConstraint()) { + recordDefiningRule(rule.getHeadAtom().getPredicate(), rule); + } + } + } + + private void recordDefiningRule(CorePredicate headPredicate, InternalRule rule) { + predicateDefiningRules.putIfAbsent(headPredicate, new LinkedHashSet<>()); + predicateDefiningRules.get(headPredicate).add(rule); + } + + public Map> getPredicateDefiningRules() { + return Collections.unmodifiableMap(predicateDefiningRules); + } + + public Map> getFactsByPredicate() { + return Collections.unmodifiableMap(factsByPredicate); + } + + public Map getRulesById() { + return Collections.unmodifiableMap(rulesById); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java new file mode 100644 index 000000000..d6d1b18e9 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java @@ -0,0 +1,31 @@ +package at.ac.tuwien.kr.alpha.common.program; + +import java.util.ArrayList; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.NormalRule; +import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; + +/** + * A program that only contains NormalRules. + * + * Copyright (c) 2019, the Alpha Team. + */ +public class NormalProgram extends AbstractProgram { + + public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { + super(rules, facts, inlineDirectives); + } + + public static NormalProgram fromInputProgram(InputProgram inputProgram) { + List normalRules = new ArrayList<>(); + for (BasicRule r : inputProgram.getRules()) { + normalRules.add(NormalRule.fromBasicRule(r)); + } + return new NormalProgram(normalRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java new file mode 100644 index 000000000..1353864ef --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java @@ -0,0 +1,23 @@ +package at.ac.tuwien.kr.alpha.common.program; + +import org.antlr.v4.runtime.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; + +public class Programs { + + private Programs() { + throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); + } + + public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { + ProgramParser parser = new ProgramParser(externals); + return parser.parse(CharStreams.fromStream(is)); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java new file mode 100644 index 000000000..a4c41973e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java @@ -0,0 +1,128 @@ +package at.ac.tuwien.kr.alpha.common.rule; + +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.Util; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.head.Head; + +/** + * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) + * + * @param the type of head for this rule + * + * Copyright (c) 2017-2019, the Alpha Team. + */ +public abstract class AbstractRule { + + private final H head; + private final Set bodyLiteralsPositive; + private final Set bodyLiteralsNegative; + + public AbstractRule(H head, List body) { + this.head = head; + Set positiveBody = new LinkedHashSet<>(); + Set negativeBody = new LinkedHashSet<>(); + for (CoreLiteral bodyLiteral : body) { + if (bodyLiteral.isNegated()) { + negativeBody.add(bodyLiteral); + } else { + positiveBody.add(bodyLiteral); + } + } + this.bodyLiteralsPositive = Collections.unmodifiableSet(positiveBody); + this.bodyLiteralsNegative = Collections.unmodifiableSet(negativeBody); + + if (!this.isSafe()) { + // TODO: safety check needs to be adapted to solver what the solver actually understands. Will change in the future, + // adapt exception message accordingly. + throw new RuntimeException("Encountered unsafe rule: " + toString() + System.lineSeparator() + + "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."); + } + } + + /** + * Checks whether a rule is safe. The actual safety condition may vary over the next improvements. Currently, a rule is + * safe iff all negated variables and + * all variables occurring in the head also occur in the positive body). + * + * @return true if this rule is safe. + */ + private boolean isSafe() { + // TODO: do the real check. + // Note that - once a proper safety check is implemented - that check should probably be specific for each rule + // implementation, therefore this method should be "protected abstract" here and implemented in each subclass. + return true; + /* + * Set positiveVariables = new HashSet<>(); Set builtinVariables = new HashSet<>(); + * + * // Check that all negative variables occur in the positive body. for (Literal literal : body) { // FIXME: The + * following five lines depend on concrete + * // implementations of the Atom interface. Not nice. if (literal instanceof BasicAtom) { + * positiveVariables.addAll(literal.getOccurringVariables()); } + * else if (literal instanceof BuiltinAtom) { builtinVariables.addAll(literal.getOccurringVariables()); } } + * + * for (Atom negAtom : bodyAtomsNegative) { for (VariableTerm term : negAtom.getOccurringVariables()) { if + * (!positiveVariables.contains(term)) { return + * false; } } } for (VariableTerm builtinVariable : builtinVariables) { if + * (!positiveVariables.contains(builtinVariable)) { return false; } } + * + * // Constraint are safe at this point if (isConstraint()) { return true; } + * + * // Check that all variables of the head occur in the positive body. List headVariables = + * head.getOccurringVariables(); + * headVariables.removeAll(positiveVariables); return headVariables.isEmpty(); + */ + } + + public boolean isConstraint() { + return head == null; + } + + @Override + public String toString() { + return Util.join((isConstraint() ? "" : head.toString() + " ") + ":- ", getBody(), "."); + } + + public H getHead() { + return head; + } + + public Set getBody() { + return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); + } + + public Set getPositiveBody() { + return this.bodyLiteralsPositive; + } + + public Set getNegativeBody() { + return this.bodyLiteralsNegative; + } + + @Override + public int hashCode() { + return Objects.hash(bodyLiteralsNegative, bodyLiteralsPositive, head); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof AbstractRule)) { + 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); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java new file mode 100644 index 000000000..db05e1164 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 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.common.rule; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.head.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 NormalRule}. + */ +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/common/rule/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java new file mode 100644 index 000000000..ace3930f3 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2016-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.common.rule; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.annotations.VisibleForTesting; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrders; +import at.ac.tuwien.kr.alpha.grounder.Unifier; + +/** + * 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 NormalRule { + + private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); + + private final int ruleId; + + private final List occurringPredicates; + + private final RuleGroundingOrders groundingOrders; + + public InternalRule(NormalHead head, List body) { + super(head, 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.occurringPredicates = new ArrayList<>(); + if (!isConstraint()) { + this.occurringPredicates.add(this.getHeadAtom().getPredicate()); + } + + for (CoreLiteral literal : body) { + if (literal instanceof AggregateLiteral) { + throw new IllegalArgumentException("AggregateLiterals aren't supported in InternalRules! (lit: " + literal.toString() + ")"); + } + 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 RuleGroundingOrders(this); + this.groundingOrders.computeGroundingOrders(); + } + + @VisibleForTesting + public static void resetIdGenerator() { + InternalRule.ID_GENERATOR.resetGenerator(); + } + + public static InternalRule fromNormalRule(NormalRule rule) { + return new InternalRule(rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()), 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 + */ + public InternalRule renameVariables(String newVariablePostfix) { + List occurringVariables = new ArrayList<>(); + CoreAtom headAtom = this.getHeadAtom(); + occurringVariables.addAll(headAtom.getOccurringVariables()); + for (CoreLiteral literal : this.getBody()) { + occurringVariables.addAll(literal.getOccurringVariables()); + } + Unifier variableReplacement = new Unifier(); + for (VariableTerm occurringVariable : occurringVariables) { + final String newVariableName = occurringVariable.toString() + newVariablePostfix; + variableReplacement.put(occurringVariable, VariableTerm.getInstance(newVariableName)); + } + CoreAtom renamedHeadAtom = headAtom.substitute(variableReplacement); + ArrayList renamedBody = new ArrayList<>(this.getBody().size()); + for (CoreLiteral literal : this.getBody()) { + renamedBody.add(literal.substitute(variableReplacement)); + } + return new InternalRule(new NormalHead(renamedHeadAtom), renamedBody); + } + + /** + * Returns the predicates occurring in this rule. + * @return a list of all predicates occurring in the rule (may contain duplicates and builtin atoms). + */ + public List getOccurringPredicates() { + return this.occurringPredicates; + } + + public RuleGroundingOrders getGroundingOrders() { + return this.groundingOrders; + } + + public int getRuleId() { + return this.ruleId; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java new file mode 100644 index 000000000..db9f8ac7e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java @@ -0,0 +1,50 @@ +package at.ac.tuwien.kr.alpha.common.rule; + +import java.util.ArrayList; +import java.util.List; + +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; + +/** + * 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. + * + * Copyright (c) 2019, the Alpha Team. + */ +public class NormalRule extends AbstractRule { + + public NormalRule(NormalHead head, List body) { + super(head, body); + } + + public static NormalRule fromBasicRule(BasicRule rule) { + CoreAtom 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(); + } + return new NormalRule(headAtom != null ? new NormalHead(headAtom) : null, new ArrayList<>(rule.getBody())); + } + + public boolean isGround() { + if (!isConstraint() && !this.getHead().isGround()) { + return false; + } + for (CoreLiteral bodyElement : this.getBody()) { + if (!bodyElement.isGround()) { + return false; + } + } + return true; + } + + public CoreAtom getHeadAtom() { + return this.isConstraint() ? null : this.getHead().getAtom(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java new file mode 100644 index 000000000..6a43cb24d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java @@ -0,0 +1,147 @@ +package at.ac.tuwien.kr.alpha.common.rule.head; + +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.terms.Term; + +import java.util.List; + +import static at.ac.tuwien.kr.alpha.Util.join; + +/** + * Represents the head of a choice rule. + * + * Copyright (c) 2017-2019, the Alpha Team. + */ +public class ChoiceHead extends Head { + private final List choiceElements; + + private final Term lowerBound; + private final ComparisonOperator lowerOp; + + private final Term upperBound; + private final ComparisonOperator upperOp; + + public static class ChoiceElement { + public final CoreAtom choiceAtom; + public final List conditionLiterals; + + public ChoiceElement(CoreAtom choiceAtom, List conditionLiterals) { + this.choiceAtom = choiceAtom; + this.conditionLiterals = conditionLiterals; + } + + @Override + public String toString() { + String result = choiceAtom.toString(); + + if (conditionLiterals == null || conditionLiterals.size() == 0) { + return result; + } + + return join(result + " : ", conditionLiterals, ""); + } + } + + public ComparisonOperator getLowerOperator() { + return lowerOp; + } + + public ComparisonOperator getUpperOperator() { + return upperOp; + } + + public List getChoiceElements() { + return choiceElements; + } + + public Term getLowerBound() { + return lowerBound; + } + + public Term getUpperBound() { + return upperBound; + } + + public ChoiceHead(List choiceElements, Term lowerBound, ComparisonOperator lowerOp, Term upperBound, ComparisonOperator upperOp) { + this.choiceElements = choiceElements; + this.lowerBound = lowerBound; + this.lowerOp = lowerOp; + this.upperBound = upperBound; + this.upperOp = upperOp; + } + + @Override + public String toString() { + String result = ""; + + if (lowerBound != null) { + result += lowerBound.toString() + lowerOp; + } + + result += join("{ ", choiceElements, "; ", " }"); + + if (upperBound != null) { + result += upperOp.toString() + upperBound; + } + + return result; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.choiceElements == null) ? 0 : this.choiceElements.hashCode()); + result = prime * result + ((this.lowerBound == null) ? 0 : this.lowerBound.hashCode()); + result = prime * result + ((this.lowerOp == null) ? 0 : this.lowerOp.hashCode()); + result = prime * result + ((this.upperBound == null) ? 0 : this.upperBound.hashCode()); + result = prime * result + ((this.upperOp == null) ? 0 : this.upperOp.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof ChoiceHead)) { + return false; + } + ChoiceHead other = (ChoiceHead) obj; + if (this.choiceElements == null) { + if (other.choiceElements != null) { + return false; + } + } else if (!this.choiceElements.equals(other.choiceElements)) { + return false; + } + if (this.lowerBound == null) { + if (other.lowerBound != null) { + return false; + } + } else if (!this.lowerBound.equals(other.lowerBound)) { + return false; + } + if (this.lowerOp != other.lowerOp) { + return false; + } + if (this.upperBound == null) { + if (other.upperBound != null) { + return false; + } + } else if (!this.upperBound.equals(other.upperBound)) { + return false; + } + if (this.upperOp != other.upperOp) { + return false; + } + return true; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java new file mode 100644 index 000000000..11f0e365d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java @@ -0,0 +1,66 @@ +package at.ac.tuwien.kr.alpha.common.rule.head; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; + +import java.util.List; + +import static at.ac.tuwien.kr.alpha.Util.join; + +/** + * Copyright (c) 2017, the Alpha Team. + */ +public class DisjunctiveHead extends Head { + public final List disjunctiveAtoms; + + public DisjunctiveHead(List disjunctiveAtoms) { + this.disjunctiveAtoms = disjunctiveAtoms; + if (disjunctiveAtoms != null && disjunctiveAtoms.size() > 1) { + throw new UnsupportedOperationException("Disjunction in rule heads is not yet supported"); + } + } + + @Override + public String toString() { + return join("", disjunctiveAtoms, " | ", ""); + } + + public boolean isGround() { + for (Atom atom : disjunctiveAtoms) { + if (!atom.isGround()) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.disjunctiveAtoms == null) ? 0 : this.disjunctiveAtoms.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof DisjunctiveHead)) { + return false; + } + DisjunctiveHead other = (DisjunctiveHead) obj; + if (this.disjunctiveAtoms == null) { + if (other.disjunctiveAtoms != null) { + return false; + } + } else if (!this.disjunctiveAtoms.equals(other.disjunctiveAtoms)) { + return false; + } + return true; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java new file mode 100644 index 000000000..535466cb6 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java @@ -0,0 +1,19 @@ +package at.ac.tuwien.kr.alpha.common.rule.head; + +/** + * Represents the head of a rule, i.e., either a choice or a disjunction of atoms, but not both. For normal rules the disjunction contains only one atom. + * + * Copyright (c) 2017-2019, the Alpha Team. + */ +public abstract class Head { + + @Override + public abstract String toString(); + + @Override + public abstract boolean equals(Object o); + + @Override + public abstract int hashCode(); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java new file mode 100644 index 000000000..650eadbc2 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java @@ -0,0 +1,61 @@ +package at.ac.tuwien.kr.alpha.common.rule.head; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; + +/** + * Represents a normal head, i.e., a head that is an Atom. + * Copyright (c) 2019, the Alpha Team. + */ +public class NormalHead extends Head { + + private final CoreAtom atom; + + public NormalHead(CoreAtom atom) { + this.atom = atom; + } + + // Note that at some point in the future it might make sense to have this method directly in Head + public boolean isGround() { + return atom.isGround(); + } + + public CoreAtom getAtom() { + return atom; + } + + @Override + public String toString() { + return atom.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((atom == null) ? 0 : atom.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof NormalHead)) { + return false; + } + NormalHead other = (NormalHead) obj; + if (this.atom == null) { + if (other.atom != null) { + return false; + } + } else if (!this.atom.equals(other.atom)) { + return false; + } + return true; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java new file mode 100644 index 000000000..3c6d525c0 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java @@ -0,0 +1,268 @@ +/** + * 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. + * + * 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.common.terms; + +import at.ac.tuwien.kr.alpha.common.Interner; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import com.google.common.math.IntMath; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; + +/** + * This class represents an arithmetic expression occurring as a term. + * Copyright (c) 2017-2019, the Alpha Team. + */ +public class ArithmeticTerm extends CoreTerm { + private static final Interner INTERNER = new Interner<>(); + protected final CoreTerm left; + private final ArithmeticOperator arithmeticOperator; + private final CoreTerm right; + + private ArithmeticTerm(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { + this.left = left; + this.arithmeticOperator = arithmeticOperator; + this.right = right; + } + + public static CoreTerm getInstance(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { + // Evaluate ground arithmetic terms immediately and return result. + if (left.isGround() && right.isGround()) { + Integer result = new ArithmeticTerm(left, arithmeticOperator, right).evaluateExpression(); + return CoreConstantTerm.getInstance(result); + } + return INTERNER.intern(new ArithmeticTerm(left, arithmeticOperator, right)); + } + + + @Override + public boolean isGround() { + return left.isGround() && right.isGround(); + } + + @Override + public List getOccurringVariables() { + LinkedHashSet occurringVariables = new LinkedHashSet<>(left.getOccurringVariables()); + occurringVariables.addAll(right.getOccurringVariables()); + return new ArrayList<>(occurringVariables); + } + + @Override + public CoreTerm substitute(Substitution substitution) { + return getInstance(left.substitute(substitution), arithmeticOperator, right.substitute(substitution)); + } + + @Override + public CoreTerm renameVariables(String renamePrefix) { + return getInstance(left.renameVariables(renamePrefix), arithmeticOperator, right.renameVariables(renamePrefix)); + } + + @Override + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); + CoreTerm normalizedRight = right.normalizeVariables(renamePrefix, counter); + return ArithmeticTerm.getInstance(normalizedLeft, arithmeticOperator, normalizedRight); + + } + + public static Integer evaluateGroundTerm(CoreTerm term) { + if (!term.isGround()) { + throw new RuntimeException("Cannot evaluate arithmetic term since it is not ground: " + term); + } + return evaluateGroundTermHelper(term); + } + + private static Integer evaluateGroundTermHelper(CoreTerm term) { + if (term instanceof CoreConstantTerm + && ((CoreConstantTerm) term).getObject() instanceof Integer) { + // Extract integer from the constant. + return (Integer) ((CoreConstantTerm) term).getObject(); + } else if (term instanceof ArithmeticTerm) { + return ((ArithmeticTerm) term).evaluateExpression(); + } else { + // ASP Core 2 standard allows non-integer terms in arithmetic expressions, result is to simply ignore the ground instance. + return null; + } + } + + Integer evaluateExpression() { + Integer leftInt = evaluateGroundTermHelper(left); + Integer rightInt = evaluateGroundTermHelper(right); + if (leftInt == null || rightInt == null) { + return null; + } + return arithmeticOperator.eval(leftInt, rightInt); + } + + @Override + public String toString() { + return left + " " + arithmeticOperator + " " + right; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ArithmeticTerm that = (ArithmeticTerm) o; + + if (left != that.left) { + return false; + } + if (arithmeticOperator != that.arithmeticOperator) { + return false; + } + return right == that.right; + } + + @Override + public int hashCode() { + return 31 * (31 * left.hashCode() + arithmeticOperator.hashCode()) + right.hashCode(); + } + + public enum ArithmeticOperator { + PLUS("+"), + MINUS("-"), + TIMES("*"), + DIV("/"), + POWER("**"), + MODULO("\\"), + BITXOR("^"); + + + private String asString; + + ArithmeticOperator(String asString) { + this.asString = asString; + } + + @Override + public String toString() { + return asString; + } + + public Integer eval(Integer left, Integer right) { + switch (this) { + case PLUS: + return left + right; + case MINUS: + return left - right; + case TIMES: + return left * right; + case DIV: + return left / right; + case POWER: + return IntMath.checkedPow(left, right); + case MODULO: + return left % right; + case BITXOR: + return left ^ right; + default: + throw new RuntimeException("Unknown arithmetic operator encountered."); + + } + } + } + + public static class MinusTerm extends ArithmeticTerm { + + private MinusTerm(CoreTerm term) { + super(term, null, null); + } + + + public static CoreTerm getInstance(CoreTerm term) { + // Evaluate ground arithmetic terms immediately and return result. + if (term.isGround()) { + Integer result = evaluateGroundTermHelper(term) * -1; + return CoreConstantTerm.getInstance(result); + } + return INTERNER.intern(new MinusTerm(term)); + } + + @Override + Integer evaluateExpression() { + return evaluateGroundTermHelper(left) * -1; + } + + @Override + public boolean isGround() { + return left.isGround(); + } + + @Override + public List getOccurringVariables() { + return left.getOccurringVariables(); + } + + @Override + public CoreTerm substitute(Substitution substitution) { + return getInstance(left.substitute(substitution)); + } + + @Override + public CoreTerm renameVariables(String renamePrefix) { + return getInstance(left.renameVariables(renamePrefix)); + } + + @Override + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); + return MinusTerm.getInstance(normalizedLeft); + } + + @Override + public String toString() { + return "-" + left; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + MinusTerm that = (MinusTerm) o; + + return left == that.left; + } + + @Override + public int hashCode() { + return 31 * left.hashCode(); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java new file mode 100644 index 000000000..dd64324dc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java @@ -0,0 +1,154 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +import at.ac.tuwien.kr.alpha.common.Interner; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.Collections; +import java.util.List; + +/** + * Copyright (c) 2016-2020, the Alpha Team. + */ +public class CoreConstantTerm> extends CoreTerm { + private static final Interner> INTERNER = new Interner<>(); + + private final T object; + private final boolean symbolic; + + private CoreConstantTerm(T object, boolean symbolic) { + this.object = object; + this.symbolic = symbolic; + } + + @SuppressWarnings("unchecked") + public static > CoreConstantTerm getInstance(T symbol) { + return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, false)); + } + + @SuppressWarnings("unchecked") + public static > CoreConstantTerm getSymbolicInstance(String symbol) { + return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, true)); + } + + @Override + public boolean isGround() { + return true; + } + + @Override + public List getOccurringVariables() { + return Collections.emptyList(); + } + + @Override + public CoreTerm substitute(Substitution substitution) { + return this; + } + + @Override + public String toString() { + if (object instanceof String) { + if (symbolic) { + return (String) object; + } else { + return "\"" + object + "\""; + } + } + return object.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + CoreConstantTerm that = (CoreConstantTerm) o; + if (this.symbolic != that.symbolic) { + return false; + } + + return object.equals(that.object); + } + + @Override + public int hashCode() { + int result = object.hashCode(); + result = 31 * result + (symbolic ? 1 : 0); + return result; + } + + /** + * Establishes "priority" for ordering of constant terms depending on the type + * of the corresponding object according to ASP-Core-2.03c. + */ + private static final int priority(final Class clazz, CoreConstantTerm term) { + if (clazz.equals(Integer.class)) { + return 1; + } else if (clazz.equals(String.class)) { + return term.symbolic ? 2 : 3; + } + return 0; + } + + @Override + @SuppressWarnings("unchecked") + public int compareTo(CoreTerm o) { + if (this == o) { + return 0; + } + + if (!(o instanceof CoreConstantTerm)) { + return super.compareTo(o); + } + + CoreConstantTerm other = (CoreConstantTerm) o; + + // We will perform an unchecked cast. + // Because of type erasure, we cannot know the exact type + // of other.object. + // However, may assume that other.object actually is of + // type T. + // We know that this.object if of type T and implements + // Comparable. We ensure that the class of other.object + // equals the class of this.object, which in turn is T. + // That assumption should be quite safe. It can only be + // wrong if we have some bug that generates strange + // ConstantTerms at runtime, bypassing the check for T + // at compile-time. + if (other.object.getClass() == this.object.getClass() && other.symbolic == this.symbolic) { + return this.object.compareTo((T) other.object); + } + + Class thisType = this.object.getClass(); + Class otherType = other.object.getClass(); + + int thisPrio = priority(thisType, this); + int otherPrio = priority(otherType, other); + + if (thisPrio == 0 || otherPrio == 0) { + return thisType.getName().compareTo(otherType.getName()); + } + + return Integer.compare(thisPrio, otherPrio); + } + + @Override + public CoreTerm renameVariables(String renamePrefix) { + // Constant contains no variables, hence stays the same. + return this; + } + + @Override + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + return this; + } + + public T getObject() { + return object; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java new file mode 100644 index 000000000..7f740aa37 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java @@ -0,0 +1,100 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +//@formatter:off +/** + * Common representation of Terms. Terms are constructed such that each term is represented by a unique object, hence + * term equality can be checked by object reference comparison. Each concrete subclass of a Term must implement a + * factory-like method to obtain instances. + * + * We use {@link Comparable} to establish the following ordering among terms: + *

        + *
      1. Constant terms according to their corresponding object and its type + *
          + *
        1. {@link ConstantTerm} ordered by value of the integers
        2. + *
        3. {@link ConstantTerm} and symbolic, lexicographically ordered on the symbol
        4. + *
        5. {@link ConstantTerm} lexicographically + *
        6. {@link ConstantTerm} for all other types, where {@link Comparable#compareTo(Object)} is used as ordering whenever + * possible (i.e. two terms' objects have the same type). For two terms with objects of different type, + * the result is the lexicographic ordering of the type names.
        7. + *
        + *
      2. + *
      3. Function terms (ordered by arity, functor name, and then on their argument terms).
      4. + *
      5. Variable terms (lexicographically ordered on their variable names)
      6. + *
      + * + * Copyright (c) 2016-2020, the Alpha Team. + */ +//@formatter:on +public abstract class CoreTerm implements Comparable { + + public abstract List getOccurringVariables(); + + /** + * Applies a substitution, result may be nonground. + * + * @param substitution the variable substitution to apply. + * @return the non-substitute term where all variable substitutions have been applied. + */ + public abstract CoreTerm substitute(Substitution substitution); + + private static int priority(CoreTerm term) { + final Class clazz = term.getClass(); + if (clazz.equals(ConstantTerm.class)) { + return 1; + } else if (clazz.equals(FunctionTerm.class)) { + return 2; + } else if (clazz.equals(VariableTerm.class)) { + return 3; + } + throw new UnsupportedOperationException("Can only compare constant term, function terms and variable terms among each other."); + } + + @Override + public int compareTo(CoreTerm o) { + return o == null ? 1 : Integer.compare(priority(this), priority(o)); + } + + public abstract boolean isGround(); + + /** + * Rename all variables occurring in this Term by prefixing their name. + * + * @param renamePrefix the name to prefix all occurring variables. + * @return the term with all variables renamed. + */ + public abstract CoreTerm renameVariables(String renamePrefix); + + public abstract CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter); + + public static class RenameCounter { + int counter; + final HashMap renamedVariables; + + public RenameCounter(int startingValue) { + counter = startingValue; + renamedVariables = new HashMap<>(); + } + } + + public static List renameTerms(List terms, String prefix, int counterStartingValue) { + List renamedTerms = new ArrayList<>(terms.size()); + CoreTerm.RenameCounter renameCounter = new CoreTerm.RenameCounter(counterStartingValue); + for (CoreTerm term : terms) { + renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); + } + return renamedTerms; + } + + @Override + public abstract boolean equals(Object o); + + @Override + public abstract int hashCode(); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java new file mode 100644 index 000000000..e2529258a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java @@ -0,0 +1,157 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +import at.ac.tuwien.kr.alpha.common.Interner; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.Util.join; + +/** + * Copyright (c) 2016-2017, the Alpha Team. + */ +public class FunctionTerm extends CoreTerm { + private static final Interner INTERNER = new Interner<>(); + + private final String symbol; + private final List terms; + private final boolean ground; + + private FunctionTerm(String symbol, List terms) { + if (symbol == null) { + throw new IllegalArgumentException(); + } + + this.symbol = symbol; + this.terms = Collections.unmodifiableList(terms); + + boolean ground = true; + for (CoreTerm term : terms) { + if (!term.isGround()) { + ground = false; + break; + } + } + this.ground = ground; + } + + public static FunctionTerm getInstance(String functionSymbol, List termList) { + return INTERNER.intern(new FunctionTerm(functionSymbol, termList)); + } + + public static FunctionTerm getInstance(String functionSymbol, CoreTerm... terms) { + return getInstance(functionSymbol, Arrays.asList(terms)); + } + + public List getTerms() { + return terms; + } + + public String getSymbol() { + return symbol; + } + + @Override + public boolean isGround() { + return ground; + } + + @Override + public List getOccurringVariables() { + LinkedList vars = new LinkedList<>(); + for (CoreTerm term : terms) { + vars.addAll(term.getOccurringVariables()); + } + return vars; + } + + @Override + public FunctionTerm substitute(Substitution substitution) { + List groundTermList = new ArrayList<>(terms.size()); + for (CoreTerm term : terms) { + groundTermList.add(term.substitute(substitution)); + } + return FunctionTerm.getInstance(symbol, groundTermList); + } + + @Override + public String toString() { + if (terms.isEmpty()) { + return symbol; + } + + return join(symbol + "(", terms, ")"); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + FunctionTerm that = (FunctionTerm) o; + + if (!symbol.equals(that.symbol)) { + return false; + } + return terms.equals(that.terms); + } + + @Override + public int hashCode() { + return 31 * symbol.hashCode() + terms.hashCode(); + } + + @Override + public int compareTo(CoreTerm o) { + if (this == o) { + return 0; + } + + if (!(o instanceof FunctionTerm)) { + return super.compareTo(o); + } + + FunctionTerm other = (FunctionTerm)o; + + if (terms.size() != other.terms.size()) { + return terms.size() - other.terms.size(); + } + + int result = symbol.compareTo(other.symbol); + + if (result != 0) { + return result; + } + + for (int i = 0; i < terms.size(); i++) { + result = terms.get(i).compareTo(other.terms.get(i)); + if (result != 0) { + return result; + } + } + + return 0; + } + + @Override + public CoreTerm renameVariables(String renamePrefix) { + List renamedTerms = new ArrayList<>(terms.size()); + for (CoreTerm term : terms) { + renamedTerms.add(term.renameVariables(renamePrefix)); + } + return FunctionTerm.getInstance(symbol, renamedTerms); + } + + @Override + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + List normalizedTerms = new ArrayList<>(terms.size()); + for (CoreTerm term : terms) { + normalizedTerms.add(term.normalizeVariables(renamePrefix, counter)); + } + return FunctionTerm.getInstance(symbol, normalizedTerms); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java new file mode 100644 index 000000000..3a801e7a8 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java @@ -0,0 +1,160 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +import at.ac.tuwien.kr.alpha.common.Interner; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.LinkedList; +import java.util.List; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +/** + * An IntervalTerm represents the shorthand notation for a set of rules where all elements in this interval occur once, e.g., fact(2..5). + * An IntervalTerm is a meta-term and the grounder must replace it with its corresponding set of facts or rules. + * Copyright (c) 2017, the Alpha Team. + */ +public class IntervalTerm extends CoreTerm { + private static final Interner INTERNER = new Interner<>(); + private final CoreTerm lowerBoundTerm; + private final CoreTerm upperBoundTerm; + + private final int lowerBound; + private final int upperBound; + + private final boolean ground; + + private IntervalTerm(CoreTerm lowerBound, CoreTerm upperBound) { + if (lowerBound == null || upperBound == null) { + throw new IllegalArgumentException(); + } + + this.ground = !((lowerBound instanceof VariableTerm) || (upperBound instanceof VariableTerm)); + + this.lowerBoundTerm = lowerBound; + this.upperBoundTerm = upperBound; + + if (this.ground) { + this.upperBound = Integer.parseInt(upperBoundTerm.toString()); + this.lowerBound = Integer.parseInt(lowerBoundTerm.toString()); + } else { + this.upperBound = -1; + this.lowerBound = -1; + } + } + + public static IntervalTerm getInstance(CoreTerm lowerBound, CoreTerm upperBound) { + return INTERNER.intern(new IntervalTerm(lowerBound, upperBound)); + } + + @Override + public boolean isGround() { + return this.ground; + } + + public int getLowerBound() { + if (!isGround()) { + throw oops("Cannot get the lower bound of non-ground interval"); + } + return this.lowerBound; + } + + public int getUpperBound() { + if (!isGround()) { + throw oops("Cannot get the upper bound of non-ground interval"); + } + return this.upperBound; + } + + @Override + public List getOccurringVariables() { + LinkedList variables = new LinkedList<>(); + if (lowerBoundTerm instanceof VariableTerm) { + variables.add((VariableTerm) lowerBoundTerm); + } + if (upperBoundTerm instanceof VariableTerm) { + variables.add((VariableTerm) upperBoundTerm); + } + return variables; + } + + @Override + public IntervalTerm substitute(Substitution substitution) { + if (isGround()) { + return this; + } + return new IntervalTerm(lowerBoundTerm.substitute(substitution), upperBoundTerm.substitute(substitution)); + } + + @Override + public String toString() { + return lowerBoundTerm + ".." + upperBoundTerm; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + IntervalTerm that = (IntervalTerm) o; + + if (!lowerBoundTerm.equals(that.lowerBoundTerm)) { + return false; + } + return upperBoundTerm.equals(that.upperBoundTerm); + + } + + @Override + public int hashCode() { + return 31 * lowerBoundTerm.hashCode() + upperBoundTerm.hashCode(); + } + + @Override + public int compareTo(CoreTerm o) { + throw new UnsupportedOperationException("Intervals cannot be compared."); + } + + @Override + public CoreTerm renameVariables(String renamePrefix) { + return new IntervalTerm(lowerBoundTerm.renameVariables(renamePrefix), upperBoundTerm.renameVariables(renamePrefix)); + } + + @Override + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + return IntervalTerm.getInstance( + lowerBoundTerm.normalizeVariables(renamePrefix, counter), + upperBoundTerm.normalizeVariables(renamePrefix, counter)); + } + + /** + * Returns true if the term contains (or is) some IntervalTerm. + * @param term the term to test + * @return true iff an IntervalTerm occurs in term. + */ + public static boolean termContainsIntervalTerm(CoreTerm term) { + if (term instanceof IntervalTerm) { + return true; + } else if (term instanceof FunctionTerm) { + return functionTermContainsIntervals((FunctionTerm) term); + } else { + return false; + } + } + + public static boolean functionTermContainsIntervals(FunctionTerm functionTerm) { + // Test whether a function term contains an interval term (recursively). + for (CoreTerm term : functionTerm.getTerms()) { + if (term instanceof IntervalTerm) { + return true; + } + if (term instanceof FunctionTerm && functionTermContainsIntervals((FunctionTerm) term)) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java new file mode 100644 index 000000000..7ba67d17a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java @@ -0,0 +1,33 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +import java.util.ArrayList; +import java.util.List; + +/** + * Convenience methods for {@link CoreTerm}s. The methods provided here are an + * attempt to avoid repeating commonly used code snippets, like wrapping sets of + * values in {@link CoreTerm}s and creating lists of those terms, etc. + * + * Copyright (c) 2020, the Alpha Team. + */ +public final class Terms { + + /** + * Since this is purely a utility class, it may not be instantiated. + * + * @throws AssertionError if called + */ + private Terms() { + throw new AssertionError(Terms.class.getSimpleName() + " is a non-instantiable utility class!"); + } + + @SafeVarargs + public static > List> asTermList(T... values) { + List> retVal = new ArrayList<>(); + for (T value : values) { + retVal.add(CoreConstantTerm.getInstance(value)); + } + return retVal; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java new file mode 100644 index 000000000..0fd29c5e8 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java @@ -0,0 +1,108 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +import at.ac.tuwien.kr.alpha.common.Interner; +import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.Collections; +import java.util.List; + +/** + * Copyright (c) 2016-2017, the Alpha Team. + */ +public class VariableTerm extends CoreTerm { + private static final Interner INTERNER = new Interner<>(); + + private static final String ANONYMOUS_VARIABLE_PREFIX = "_"; + private static final IntIdGenerator ANONYMOUS_VARIABLE_COUNTER = new IntIdGenerator(); + + private final String variableName; + + private VariableTerm(String variableName) { + this.variableName = variableName; + } + + public static VariableTerm getInstance(String variableName) { + return INTERNER.intern(new VariableTerm(variableName)); + } + + public static VariableTerm getAnonymousInstance() { + return getInstance(ANONYMOUS_VARIABLE_PREFIX + ANONYMOUS_VARIABLE_COUNTER.getNextId()); + } + + @Override + public boolean isGround() { + return false; + } + + @Override + public List getOccurringVariables() { + return Collections.singletonList(this); + } + + @Override + public CoreTerm substitute(Substitution substitution) { + CoreTerm groundTerm = substitution.eval(this); + if (groundTerm == null) { + // If variable is not substituted, keep term as is. + return this; + } + return groundTerm; + } + + @Override + public String toString() { + return variableName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + VariableTerm that = (VariableTerm) o; + + return variableName.equals(that.variableName); + } + + @Override + public int hashCode() { + return variableName.hashCode(); + } + + @Override + public int compareTo(CoreTerm o) { + if (this == o) { + return 0; + } + + if (!(o instanceof VariableTerm)) { + return super.compareTo(o); + } + + VariableTerm other = (VariableTerm)o; + return variableName.compareTo(other.variableName); + } + + @Override + public CoreTerm renameVariables(String renamePrefix) { + return VariableTerm.getInstance(renamePrefix + variableName); + } + + @Override + public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + VariableTerm renamedThis = counter.renamedVariables.get(this); + if (renamedThis != null) { + return renamedThis; + } else { + VariableTerm renamedVariable = VariableTerm.getInstance(renamePrefix + counter.counter++); + counter.renamedVariables.put(this, renamedVariable); + return renamedVariable; + } + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java new file mode 100644 index 000000000..f37739534 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java @@ -0,0 +1,18 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public abstract class AbstractGrounder implements Grounder { + protected final java.util.function.Predicate filter; + + protected AbstractGrounder(java.util.function.Predicate filter) { + this.filter = filter; + } + + protected AbstractGrounder() { + this(p -> true); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java new file mode 100644 index 000000000..98b18eb5b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import java.util.HashSet; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; + +public abstract class BridgedGrounder extends AbstractGrounder { + protected final Bridge[] bridges; + + protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { + super(filter); + this.bridges = bridges; + } + + protected BridgedGrounder(Bridge... bridges) { + super(); + this.bridges = bridges; + } + + protected Set collectExternalRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator) { + Set collectedRules = new HashSet<>(); + + for (Bridge bridge : bridges) { + collectedRules.addAll(bridge.getRules(assignment, atomStore, intIdGenerator)); + } + + return collectedRules; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java new file mode 100644 index 000000000..c807e0bae --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java @@ -0,0 +1,128 @@ +/** + * 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. + * + * 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.grounder; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom.off; +import static at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom.on; +import static java.util.Collections.emptyList; + +public class ChoiceRecorder { + private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); + + private final AtomStore atomStore; + private Pair, Map> newChoiceAtoms = new ImmutablePair<>(new LinkedHashMap<>(), new LinkedHashMap<>()); + private Map> newHeadsToBodies = new LinkedHashMap<>(); + + public ChoiceRecorder(AtomStore atomStore) { + this.atomStore = atomStore; + } + + /** + * @return new choice points and their enablers and disablers. + */ + public Pair, Map> getAndResetChoices() { + Pair, Map> currentChoiceAtoms = newChoiceAtoms; + newChoiceAtoms = new ImmutablePair<>(new LinkedHashMap<>(), new LinkedHashMap<>()); + return currentChoiceAtoms; + } + + /** + * @return a set of new mappings from head atoms to {@link RuleAtom}s deriving it. + */ + public Map> getAndResetHeadsToBodies() { + Map> currentHeadsToBodies = newHeadsToBodies; + newHeadsToBodies = new LinkedHashMap<>(); + return currentHeadsToBodies; + } + + + public List generateChoiceNoGoods(final List posLiterals, final List negLiterals, final int bodyRepresentingLiteral) { + // Obtain an ID for this new choice. + final int choiceId = ID_GENERATOR.getNextId(); + final int bodyRepresentingAtom = atomOf(bodyRepresentingLiteral); + // Create ChoiceOn and ChoiceOff atoms. + final int choiceOnAtom = atomStore.putIfAbsent(on(choiceId)); + newChoiceAtoms.getLeft().put(bodyRepresentingAtom, choiceOnAtom); + final int choiceOffAtom = atomStore.putIfAbsent(off(choiceId)); + newChoiceAtoms.getRight().put(bodyRepresentingAtom, choiceOffAtom); + + final List noGoods = generateNeg(choiceOffAtom, negLiterals); + noGoods.add(generatePos(choiceOnAtom, posLiterals)); + + return noGoods; + } + + private NoGood generatePos(final int atomOn, List posLiterals) { + final int literalOn = atomToLiteral(atomOn); + + return NoGood.fromBodyInternal(posLiterals, emptyList(), literalOn); + } + + private List generateNeg(final int atomOff, List negLiterals) { + final int negLiteralOff = negateLiteral(atomToLiteral(atomOff)); + + final List noGoods = new ArrayList<>(negLiterals.size() + 1); + for (Integer negLiteral : negLiterals) { + // Choice is off if any of the negative atoms is assigned true, + // hence we add one nogood for each such atom. + noGoods.add(NoGood.headFirstInternal(negLiteralOff, negLiteral)); + } + return noGoods; + } + + public void addHeadToBody(int headId, int bodyId) { + Set existingBodies = newHeadsToBodies.get(headId); + if (existingBodies == null) { + existingBodies = new HashSet<>(); + newHeadsToBodies.put(headId, existingBodies); + } + existingBodies.add(bodyId); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("[enablers: "); + for (Map.Entry enablers : newChoiceAtoms.getLeft().entrySet()) { + sb.append(enablers.getKey()).append("/").append(enablers.getValue()).append(", "); + } + sb.append(" disablers: "); + for (Map.Entry disablers : newChoiceAtoms.getRight().entrySet()) { + sb.append(disablers.getKey()).append("/").append(disablers.getValue()); + } + return sb.append("]").toString(); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java new file mode 100644 index 000000000..7f762c773 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java @@ -0,0 +1,67 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.terms.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Helper functions to evaluate facts potentially containing intervals. + * Copyright (c) 2017, the Alpha Team. + */ +public class FactIntervalEvaluator { + + /** + * Helper to construct Instances from a fact that may contain intervals. + * + * @param fact the fact potentially containing intervals. + * @return all instances stemming from unfolding the intervals. + */ + public static List constructFactInstances(CoreAtom fact) { + // Construct instance(s) from the fact. + int arity = fact.getPredicate().getArity(); + CoreTerm[] currentTerms = new CoreTerm[arity]; + boolean containsIntervals = false; + // Check if instance contains intervals at all. + for (int i = 0; i < arity; i++) { + CoreTerm term = fact.getTerms().get(i); + currentTerms[i] = term; + if (term instanceof IntervalTerm) { + containsIntervals = true; + } else if (term instanceof FunctionTerm && IntervalTerm.functionTermContainsIntervals((FunctionTerm) term)) { + containsIntervals = true; + throw new UnsupportedOperationException("Intervals inside function terms in facts are not supported yet. Try turning the fact into a rule."); + } + } + // If fact contains no intervals, simply return the single instance. + if (!containsIntervals) { + return Collections.singletonList(new Instance(currentTerms)); + } + // Fact contains intervals, unroll them all. + return unrollInstances(currentTerms, 0); + } + + private static List unrollInstances(CoreTerm[] currentTerms, int currentPosition) { + if (currentPosition == currentTerms.length) { + return Collections.singletonList(new Instance(currentTerms)); + } + CoreTerm currentTerm = currentTerms[currentPosition]; + if (!(currentTerm instanceof IntervalTerm)) { + return unrollInstances(currentTerms, currentPosition + 1); + } + + List instances = new ArrayList<>(); + + int lower = ((IntervalTerm) currentTerm).getLowerBound(); + int upper = ((IntervalTerm) currentTerm).getUpperBound(); + + for (int i = lower; i <= upper; i++) { + CoreTerm[] clonedTerms = currentTerms.clone(); + clonedTerms[currentPosition] = CoreConstantTerm.getInstance(i); + instances.addAll(unrollInstances(clonedTerms, currentPosition + 1)); + } + return instances; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java new file mode 100644 index 000000000..03aac3274 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java @@ -0,0 +1,18 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public abstract class FilteringGrounder implements Grounder { + protected final java.util.function.Predicate filter; + + protected FilteringGrounder(java.util.function.Predicate filter) { + this.filter = filter; + } + + protected FilteringGrounder() { + this(p -> true); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java new file mode 100644 index 000000000..41849fa53 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java @@ -0,0 +1,82 @@ +/** + * 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 + * 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.grounder; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.IntIterator; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.Map; +import java.util.Set; + +public interface Grounder { + /** + * Translates an answer-set represented by true atom IDs into its logical representation. + * @param trueAtoms + * @return + */ + AnswerSet assignmentToAnswerSet(Iterable trueAtoms); + + /** + * Applies lazy grounding and returns all newly derived (fully ground) NoGoods. + * @return a mapping of nogood IDs to NoGoods. + */ + Map getNoGoods(Assignment assignment); + + /** + * Return choice points and their enablers and disablers. + * Must be preceeded by a call to getNoGoods(). + * @return a pair (choiceOn, choiceOff) of two maps from atomIds to atomIds, + * choiceOn maps atoms (choice points) to their enabling atoms + * and choiceOff maps atoms (choice points) to their disabling atoms. + */ + Pair, Map> getChoiceAtoms(); + + /** + * Updates the grounder with atoms assigned a positive truth value. + * @param it an iterator over all newly assigned positive atoms. + */ + void updateAssignment(IntIterator it); + + /** + * Returns a set of new mappings from head atoms to {@link RuleAtom}s deriving it. + */ + Map> getHeadsToBodies(); + + void forgetAssignment(int[] atomIds); + + /** + * Registers the given NoGood and returns the identifier of it. + * @param noGood + * @return + */ + int register(NoGood noGood); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java new file mode 100644 index 000000000..a24c9c8a8 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2016-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.grounder; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.config.InputConfig; +import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; +import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; + +public final class GrounderFactory { + public static Grounder getInstance(String name, InternalProgram 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."); + } + + public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { + return getInstance(name, program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); + } + + public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, boolean debugInternalChecks) { + return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, new GrounderHeuristicsConfiguration(), debugInternalChecks); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java new file mode 100644 index 000000000..578596886 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2016-2018, 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.grounder; + +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 at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; + +/** + * A storage for instances with a certain arity, where each position of the instance can be indexed. + * This aids in matching and joining instances. An index can be added or removed at any time for a desired position of + * all instances. + * Copyright (c) 2016-2020, the Alpha Team. + */ +public class IndexedInstanceStorage { + private final CorePredicate predicate; + private final boolean positive; + + /** + * A collection of all instances currently stored in this storage. + */ + private final LinkedHashSet instances = new LinkedHashSet<>(); + + /** + * For each position, a mapping of termIds to list of instances with this termId at the corresponding position + */ + private final ArrayList>> indices = new ArrayList<>(); + + private final ArrayList recentlyAddedInstances = new ArrayList<>(); + + public IndexedInstanceStorage(CorePredicate predicate, boolean positive) { + this.predicate = predicate; + this.positive = positive; + + // Create list of mappings, initialize to null. + while (indices.size() < predicate.getArity()) { + indices.add(null); + } + } + + public CorePredicate getPredicate() { + return predicate; + } + + public void markRecentlyAddedInstancesDone() { + recentlyAddedInstances.clear(); + } + + public void addIndexPosition(int position) { + if (position < 0 || position > predicate.getArity() - 1) { + throw new RuntimeException("Requested to create indices for attribute out of range." + + "IndexedInstanceStorage: " + this + " requested indices position: " + position); + } + // Add index + indices.set(position, new LinkedHashMap<>()); + + // Initialize index with all instances currently used. + for (Instance instance : instances) { + indices.get(position).putIfAbsent(instance.terms.get(position), new ArrayList<>()); + ArrayList instancesAtPosition = indices.get(position).get(instance.terms.get(position)); + instancesAtPosition.add(instance); + } + } + + public void removeIndexPosition(int position) { + if (position < 0 || position > predicate.getArity() - 1) { + throw new RuntimeException("Requested to create indices for attribute out of range." + + "IndexedInstanceStorage: " + this + " requested indices position: " + position); + } + indices.set(position, null); + } + + /** + * Returns whether an instance is already contained in the storage. + * + * @param instance the instance to check for containment. + * @return true if the instance is already contained in the storage. + */ + public boolean containsInstance(Instance instance) { + return instances.contains(instance); + } + + public void addInstance(Instance instance) { + if (instance.terms.size() != predicate.getArity()) { + throw new RuntimeException("Instance length does not match arity of IndexedInstanceStorage: " + + "instance size: " + instance.terms.size() + + "IndexedInstanceStorage: " + this); + } + instances.add(instance); + recentlyAddedInstances.add(instance); + // Add instance to all indices. + for (int i = 0; i < indices.size(); i++) { + HashMap> posIndex = indices.get(i); + if (posIndex == null) { + continue; + } + posIndex.putIfAbsent(instance.terms.get(i), new ArrayList<>()); + ArrayList matchingInstancesAtPos = posIndex.get(instance.terms.get(i)); + matchingInstancesAtPos.add(instance); // Add instance + } + } + + public void removeInstance(Instance instance) { + if (recentlyAddedInstances.size() != 0) { + // Hint: exception may be replaced by removing the instance also from the list of recentlyAddedInstances. + throw new RuntimeException("Instance is removed while there are unprocessed new instances; Result dubious."); + } + // Remove from all indices + for (int i = 0; i < indices.size(); i++) { + HashMap> posIndex = indices.get(i); + if (posIndex == null) { + continue; + } + ArrayList matchingInstancesAtPos = posIndex.get(instance.terms.get(i)); + matchingInstancesAtPos.remove(instance); // Remove instance + + // If there are no more instances having the term at the current position, + // remove the entry from the hash. + if (matchingInstancesAtPos.size() == 0) { + posIndex.remove(instance.terms.get(i)); + } + } + instances.remove(instance); + } + + public List getRecentlyAddedInstances() { + return recentlyAddedInstances; + } + + /** + * Returns a list of all instances having the given term at the given position. Returns null if no such + * instances exist. + * + * @param term + * @param position + * @return + */ + public List getInstancesMatchingAtPosition(CoreTerm term, int position) { + Map> indexForPosition = indices.get(position); + if (indexForPosition == null) { + throw new RuntimeException("IndexedInstanceStorage queried for position " + position + " which is not indexed."); + } + ArrayList matchingInstances = indexForPosition.get(term); + return matchingInstances == null ? Collections.emptyList() : matchingInstances; + } + + private int getMostSelectiveGroundTermPosition(CoreAtom atom) { + int smallestNumberOfInstances = Integer.MAX_VALUE; + int mostSelectiveTermPosition = -1; + for (int i = 0; i < atom.getTerms().size(); i++) { + CoreTerm testTerm = atom.getTerms().get(i); + if (testTerm.isGround()) { + ArrayList instancesMatchingTest = indices.get(i).get(testTerm); + if (instancesMatchingTest == null) { + // Ground term at i matches zero instances, it is most selective. + return i; + } + int numInstancesTestTerm = instancesMatchingTest.size(); + if (numInstancesTestTerm < smallestNumberOfInstances) { + smallestNumberOfInstances = numInstancesTestTerm; + mostSelectiveTermPosition = i; + } + } + } + return mostSelectiveTermPosition; + } + + public List getInstancesFromPartiallyGroundAtom(CoreAtom substitute) { + // For selection of the instances, find ground term on which to select. + int firstGroundTermPosition = getMostSelectiveGroundTermPosition(substitute); + // Select matching instances, select all if no ground term was found. + if (firstGroundTermPosition != -1) { + CoreTerm firstGroundTerm = substitute.getTerms().get(firstGroundTermPosition); + return getInstancesMatchingAtPosition(firstGroundTerm, firstGroundTermPosition); + } else { + return new ArrayList<>(getAllInstances()); + } + } + + public Set getAllInstances() { + return instances; + } + + @Override + public String toString() { + return (positive ? "+" : "-") + predicate; + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java new file mode 100644 index 000000000..9897b5a03 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java @@ -0,0 +1,57 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import static at.ac.tuwien.kr.alpha.Util.join; + +import java.util.Arrays; +import java.util.List; + +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; + +/** + * An instance is a positional association of terms, e.g., representing a variable substitution, or a ground instance of + * a predicate. + * Copyright (c) 2016, the Alpha Team. + */ +public class Instance { + public final List terms; + + public Instance(CoreTerm... terms) { + this(Arrays.asList(terms)); + } + + public Instance(List terms) { + this.terms = terms; + } + + public static Instance fromAtom(CoreAtom atom) { + if (!atom.isGround()) { + throw Util.oops("Cannot create instance from non-ground atom " + atom.toString()); + } + return new Instance(atom.getTerms()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + return terms.equals(((Instance) o).terms); + } + + @Override + public int hashCode() { + return terms.hashCode(); + } + + @Override + public String toString() { + return join("(", terms, ")"); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java new file mode 100644 index 000000000..7e5aade1d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java @@ -0,0 +1,33 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +/** + * Generates unique, sequential integers starting at 0, i.e., it maintains a counter that is incremented for each getNextId(). + * Copyright (c) 2016, the Alpha Team. + */ +public class IntIdGenerator { + private int highestId; + + public IntIdGenerator() { + this(0); + } + + public IntIdGenerator(int initial) { + this.highestId = initial; + } + + public int getNextId() { + if (highestId == Integer.MAX_VALUE) { + throw oops("Ran out of IDs (integer overflow)"); + } + return highestId++; + } + + /** + * Resets the internal counter. Useful for resetting before each test. + */ + public void resetGenerator() { + highestId = 0; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java new file mode 100644 index 000000000..cb19e5cb3 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java @@ -0,0 +1,639 @@ +/** + * 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 + * 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.grounder; + +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +import java.util.ArrayList; +import java.util.Collection; +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.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.IntIterator; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom; +import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; +import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; +import at.ac.tuwien.kr.alpha.grounder.instantiation.BindingResult; +import at.ac.tuwien.kr.alpha.grounder.instantiation.DefaultLazyGroundingInstantiationStrategy; +import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; +import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; +import at.ac.tuwien.kr.alpha.grounder.structure.AnalyzeUnjustified; + +/** + * A semi-naive grounder. + * + * Copyright (c) 2016-2020, the Alpha Team. + */ +public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGrounder { + private static final Logger LOGGER = LoggerFactory.getLogger(NaiveGrounder.class); + + private final WorkingMemory workingMemory = new WorkingMemory(); + private final AtomStore atomStore; + private final NogoodRegistry registry = new NogoodRegistry(); + final NoGoodGenerator noGoodGenerator; + private final ChoiceRecorder choiceRecorder; + private final InternalProgram program; + private final AnalyzeUnjustified analyzeUnjustified; + + private final Map> factsFromProgram; + private final Map> rulesUsingPredicateWorkingMemory = new HashMap<>(); + private final Map knownNonGroundRules; + + private ArrayList fixedRules = new ArrayList<>(); + private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); + private final boolean debugInternalChecks; + + private final GrounderHeuristicsConfiguration heuristicsConfiguration; + + // Handles instantiation of literals, i.e. supplies ground substitutions for literals of non-ground rules + // according to the rules set by the LiteralInstantiationStrategy used by this grounder. + private final LiteralInstantiator ruleInstantiator; + private final DefaultLazyGroundingInstantiationStrategy instantiationStrategy; + + public NaiveGrounder(InternalProgram program, AtomStore atomStore, boolean debugInternalChecks, Bridge... bridges) { + this(program, atomStore, new GrounderHeuristicsConfiguration(), debugInternalChecks, bridges); + } + + private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, bridges); + } + + NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + super(filter, bridges); + this.atomStore = atomStore; + this.heuristicsConfiguration = heuristicsConfiguration; + LOGGER.debug("Grounder configuration: {}", heuristicsConfiguration); + + this.program = program; + + this.factsFromProgram = program.getFactsByPredicate(); + this.knownNonGroundRules = program.getRulesById(); + + this.analyzeUnjustified = new AnalyzeUnjustified(this.program, this.atomStore, this.factsFromProgram); + + this.initializeFactsAndRules(); + + final Set uniqueGroundRulePerGroundHead = getRulesWithUniqueHead(); + choiceRecorder = new ChoiceRecorder(atomStore); + noGoodGenerator = new NoGoodGenerator(atomStore, choiceRecorder, factsFromProgram, this.program, uniqueGroundRulePerGroundHead); + + this.debugInternalChecks = debugInternalChecks; + + // Initialize RuleInstantiator and instantiation strategy. Note that the instantiation strategy also + // needs the current assignment, which is set with every call of getGroundInstantiations. + this.instantiationStrategy = new DefaultLazyGroundingInstantiationStrategy(this.workingMemory, this.atomStore, this.factsFromProgram); + this.instantiationStrategy.setStaleWorkingMemoryEntries(this.removeAfterObtainingNewNoGoods); + this.ruleInstantiator = new LiteralInstantiator(this.instantiationStrategy); + } + + private void initializeFactsAndRules() { + // Initialize all facts. + for (CoreAtom fact : program.getFacts()) { + final CorePredicate predicate = fact.getPredicate(); + + // Record predicate + workingMemory.initialize(predicate); + } + + // Register internal atoms. + workingMemory.initialize(RuleAtom.PREDICATE); + workingMemory.initialize(ChoiceAtom.OFF); + workingMemory.initialize(ChoiceAtom.ON); + + // Initialize rules and constraints in working memory. + for (InternalRule nonGroundRule : program.getRulesById().values()) { + // Create working memories for all predicates occurring in the rule. + for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { + // FIXME: this also contains interval/builtin predicates that are not needed. + workingMemory.initialize(predicate); + } + + // If the rule has fixed ground instantiations, it is not registered but grounded once like facts. + if (nonGroundRule.getGroundingOrders().fixedInstantiation()) { + fixedRules.add(nonGroundRule); + continue; + } + + // Register each starting literal at the corresponding working memory. + for (CoreLiteral literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { + registerLiteralAtWorkingMemory(literal, nonGroundRule); + } + } + } + + private Set getRulesWithUniqueHead() { + // FIXME: below optimisation (adding support nogoods if there is only one rule instantiation per unique atom over the interpretation) could be done as a transformation (adding a non-ground constraint corresponding to the nogood that is generated by the grounder). + // Record all unique rule heads. + final Set uniqueGroundRulePerGroundHead = new HashSet<>(); + + for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { + if (headDefiningRules.getValue().size() != 1) { + continue; + } + + InternalRule nonGroundRule = headDefiningRules.getValue().iterator().next(); + // Check that all variables of the body also occur in the head (otherwise grounding is not unique). + CoreAtom headAtom = nonGroundRule.getHeadAtom(); + + // Rule is not guaranteed unique if there are facts for it. + HashSet potentialFacts = factsFromProgram.get(headAtom.getPredicate()); + if (potentialFacts != null && !potentialFacts.isEmpty()) { + continue; + } + + // Collect head and body variables. + HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); + HashSet occurringVariablesBody = new HashSet<>(); + for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { + occurringVariablesBody.addAll(lit.getBindingVariables()); + } + occurringVariablesBody.removeAll(occurringVariablesHead); + + // Check if ever body variables occurs in the head. + if (occurringVariablesBody.isEmpty()) { + uniqueGroundRulePerGroundHead.add(nonGroundRule); + } + } + return uniqueGroundRulePerGroundHead; + } + + /** + * Registers a starting literal of a NonGroundRule at its corresponding working memory. + * @param nonGroundRule the rule in which the literal occurs. + */ + private void registerLiteralAtWorkingMemory(CoreLiteral literal, InternalRule nonGroundRule) { + if (literal.isNegated()) { + throw new RuntimeException("Literal to register is negated. Should not happen."); + } + IndexedInstanceStorage workingMemory = this.workingMemory.get(literal.getPredicate(), true); + rulesUsingPredicateWorkingMemory.putIfAbsent(workingMemory, new ArrayList<>()); + rulesUsingPredicateWorkingMemory.get(workingMemory).add(new FirstBindingAtom(nonGroundRule, literal)); + } + + @Override + public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { + Map> predicateInstances = new LinkedHashMap<>(); + SortedSet knownPredicates = new TreeSet<>(); + + // Iterate over all true atomIds, computeNextAnswerSet instances from atomStore and add them if not filtered. + for (int trueAtom : trueAtoms) { + final CoreAtom atom = atomStore.get(trueAtom); + CorePredicate predicate = atom.getPredicate(); + + // Skip atoms over internal predicates. + if (predicate.isInternal()) { + continue; + } + + // Skip filtered predicates. + if (!filter.test(predicate)) { + continue; + } + + knownPredicates.add(predicate); + predicateInstances.putIfAbsent(predicate, new TreeSet<>()); + Set instances = predicateInstances.get(predicate); + instances.add(atom); + } + + // Add true atoms from facts. + for (Map.Entry> facts : factsFromProgram.entrySet()) { + CorePredicate factPredicate = facts.getKey(); + // Skip atoms over internal predicates. + if (factPredicate.isInternal()) { + continue; + } + // Skip filtered predicates. + if (!filter.test(factPredicate)) { + continue; + } + // Skip predicates without any instances. + if (facts.getValue().isEmpty()) { + continue; + } + knownPredicates.add(factPredicate); + predicateInstances.putIfAbsent(factPredicate, new TreeSet<>()); + for (Instance factInstance : facts.getValue()) { + SortedSet instances = predicateInstances.get(factPredicate); + instances.add(new BasicAtom(factPredicate, factInstance.terms)); + } + } + + if (knownPredicates.isEmpty()) { + return BasicAnswerSet.EMPTY; + } + + return new BasicAnswerSet(knownPredicates, predicateInstances); + } + + /** + * Prepares facts of the input program for joining and derives all NoGoods representing ground rules. May only be called once. + * @return + */ + protected HashMap bootstrap() { + final HashMap groundNogoods = new LinkedHashMap<>(); + + for (CorePredicate predicate : factsFromProgram.keySet()) { + // Instead of generating NoGoods, add instance to working memories directly. + workingMemory.addInstances(predicate, true, factsFromProgram.get(predicate)); + } + + for (InternalRule nonGroundRule : fixedRules) { + // Generate NoGoods for all rules that have a fixed grounding. + RuleGroundingOrder groundingOrder = nonGroundRule.getGroundingOrders().getFixedGroundingOrder(); + BindingResult bindingResult = getGroundInstantiations(nonGroundRule, groundingOrder, new Substitution(), null); + groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), groundNogoods); + } + + fixedRules = null; + + return groundNogoods; + } + + @Override + public Map getNoGoods(Assignment currentAssignment) { + // In first call, prepare facts and ground rules. + final Map newNoGoods = fixedRules != null ? bootstrap() : new LinkedHashMap<>(); + + // Compute new ground rule (evaluate joins with newly changed atoms) + for (IndexedInstanceStorage modifiedWorkingMemory : workingMemory.modified()) { + // Skip predicates solely used in the solver which do not occur in rules. + CorePredicate workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); + if (workingMemoryPredicate.isSolverInternal()) { + continue; + } + + // Iterate over all rules whose body contains the interpretation corresponding to the current workingMemory. + final ArrayList firstBindingAtoms = rulesUsingPredicateWorkingMemory.get(modifiedWorkingMemory); + + // Skip working memories that are not used by any rule. + if (firstBindingAtoms == null) { + continue; + } + + for (FirstBindingAtom firstBindingAtom : firstBindingAtoms) { + // Use the recently added instances from the modified working memory to construct an initial substitution + InternalRule nonGroundRule = firstBindingAtom.rule; + + // Generate substitutions from each recent instance. + for (Instance instance : modifiedWorkingMemory.getRecentlyAddedInstances()) { + // Check instance if it matches with the atom. + + final Substitution unifier = Substitution.specializeSubstitution(firstBindingAtom.startingLiteral, instance, Substitution.EMPTY_SUBSTITUTION); + + if (unifier == null) { + continue; + } + + final BindingResult bindingResult = getGroundInstantiations( + nonGroundRule, + nonGroundRule.getGroundingOrders().orderStartingFrom(firstBindingAtom.startingLiteral), + unifier, + currentAssignment + ); + + groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), newNoGoods); + } + } + + // Mark instances added by updateAssignment as done + modifiedWorkingMemory.markRecentlyAddedInstancesDone(); + } + + workingMemory.reset(); + for (CoreAtom removeAtom : removeAfterObtainingNewNoGoods) { + final IndexedInstanceStorage storage = workingMemory.get(removeAtom, true); + Instance instance = new Instance(removeAtom.getTerms()); + if (storage.containsInstance(instance)) { + // permissive grounder heuristics may attempt to remove instances that are not yet in the working memory + storage.removeInstance(instance); + } + } + + // Re-Initialize the stale working memory entries set and pass to instantiation strategy. + removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); + instantiationStrategy.setStaleWorkingMemoryEntries(removeAfterObtainingNewNoGoods); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Grounded NoGoods are:"); + for (Map.Entry noGoodEntry : newNoGoods.entrySet()) { + LOGGER.debug("{} == {}", noGoodEntry.getValue(), atomStore.noGoodToString(noGoodEntry.getValue())); + } + LOGGER.debug("{}", choiceRecorder); + } + + if (debugInternalChecks) { + checkTypesOfNoGoods(newNoGoods.values()); + } + + return newNoGoods; + } + + /** + * Grounds the given {@code nonGroundRule} by applying the given {@code substitutions} and registers the nogoods generated during that process. + * + * @param nonGroundRule the rule to be grounded. + * @param substitutions the substitutions to be applied. + * @param newNoGoods a set of nogoods to which newly generated nogoods will be added. + */ + private void groundAndRegister(final InternalRule nonGroundRule, final List substitutions, final Map newNoGoods) { + for (Substitution substitution : substitutions) { + List generatedNoGoods = noGoodGenerator.generateNoGoodsFromGroundSubstitution(nonGroundRule, substitution); + registry.register(generatedNoGoods, newNoGoods); + } + } + + @Override + public int register(NoGood noGood) { + return registry.register(noGood); + } + + // Ideally, this method should be private. It's only visible because NaiveGrounderTest needs to access it. + BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder groundingOrder, Substitution partialSubstitution, + Assignment currentAssignment) { + int tolerance = heuristicsConfiguration.getTolerance(rule.isConstraint()); + if (tolerance < 0) { + tolerance = Integer.MAX_VALUE; + } + + // Update instantiationStrategy with current assignment. + // Note: Actually the assignment could be an instance variable of the grounder (shared with solver), + // but this would have a larger impact on grounder/solver communication design as a whole. + instantiationStrategy.setCurrentAssignment(currentAssignment); + BindingResult bindingResult = bindNextAtomInRule(groundingOrder, 0, tolerance, tolerance, partialSubstitution); + if (LOGGER.isDebugEnabled()) { + for (int i = 0; i < bindingResult.size(); i++) { + Integer numberOfUnassignedPositiveBodyAtoms = bindingResult.getNumbersOfUnassignedPositiveBodyAtoms().get(i); + if (numberOfUnassignedPositiveBodyAtoms > 0) { + LOGGER.debug("Grounded rule in which {} positive atoms are still unassigned: {} (substitution: {})", numberOfUnassignedPositiveBodyAtoms, rule, bindingResult.getGeneratedSubstitutions().get(i)); + } + } + } + return bindingResult; + } + + /** + * Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrder, int, int, int, Substitution)}. + * + * Takes an ImmutablePair of a {@link Substitution} and an accompanying {@link AssignmentStatus} and calls + * bindNextAtomInRule for the next literal in the grounding order. + * If the assignment status for the last bound literal was {@link AssignmentStatus#UNASSIGNED}, the remainingTolerance + * parameter is decreased by 1. If the remaining tolerance drops below zero, this method returns an empty {@link BindingResult}. + * + * @param groundingOrder + * @param orderPosition + * @param originalTolerance + * @param remainingTolerance + * @param lastLiteralBindingResult + * @return the result of calling bindNextAtomInRule on the next literal in the grounding order, or an empty binding result if remaining + * tolerance is less than zero. + */ + private BindingResult continueBinding(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, + ImmutablePair lastLiteralBindingResult) { + Substitution substitution = lastLiteralBindingResult.left; + AssignmentStatus lastBoundLiteralAssignmentStatus = lastLiteralBindingResult.right; + switch (lastBoundLiteralAssignmentStatus) { + case TRUE: + return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, substitution); + case UNASSIGNED: + // The last literal bound to obtain the current substitution has not been assigned a truth value by the solver yet. + // If we still have enough tolerance, we can continue grounding nevertheless. + int toleranceForNextRun = remainingTolerance - 1; + if (toleranceForNextRun >= 0) { + return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, toleranceForNextRun, substitution); + } else { + return BindingResult.empty(); + } + case FALSE: + throw Util.oops("Got an assignmentStatus FALSE for literal " + groundingOrder.getLiteralAtOrderPosition(orderPosition) + " and substitution " + + substitution + " - should not happen!"); + default: + throw Util.oops("Got unsupported assignmentStatus " + lastBoundLiteralAssignmentStatus); + } + } + + private BindingResult advanceAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, + Substitution partialSubstitution) { + groundingOrder.considerUntilCurrentEnd(); + return bindNextAtomInRule(groundingOrder, orderPosition + 1, originalTolerance, remainingTolerance, partialSubstitution); + } + + private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, + Substitution partialSubstitution) { + RuleGroundingOrder modifiedGroundingOrder = groundingOrder.pushBack(orderPosition); + if (modifiedGroundingOrder == null) { + return BindingResult.empty(); + } + return bindNextAtomInRule(modifiedGroundingOrder, orderPosition + 1, originalTolerance, remainingTolerance, partialSubstitution); + } + + //@formatter:off + + /** + * Computes ground substitutions for a literal based on a {@link RuleGroundingOrder} and a {@link Substitution}. + * + * Computes ground substitutions for the literal at position orderPosition of groundingOrder + * Actual substitutions are computed by this grounder's {@link LiteralInstantiator}. + * + * @param groundingOrder a {@link RuleGroundingOrder} representing the body literals of a rule in the + * sequence in which the should be bound during grounding. + * @param orderPosition the current position within groundingOrder, indicates which literal should be bound + * @param originalTolerance the original tolerance of the used grounding heuristic + * @param remainingTolerance the remaining tolerance, determining if binding continues in the presence of substitutions based on unassigned atoms + * @param partialSubstitution a substitution + * @return a {@link BindingResult} representing applicable ground substitutions for all literals after orderPosition in groundingOrder + */ + //@formatter:on + private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, + Substitution partialSubstitution) { + CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); + if (currentLiteral == null) { + LOGGER.trace("No more literals found in grounding order, therefore stopping binding!"); + return BindingResult.singleton(partialSubstitution, originalTolerance - remainingTolerance); + } + LOGGER.trace("Binding current literal {} with remaining tolerance {} and partial substitution {}.", currentLiteral, + remainingTolerance, partialSubstitution); + LiteralInstantiationResult instantiationResult = ruleInstantiator.instantiateLiteral(currentLiteral, partialSubstitution); + switch (instantiationResult.getType()) { + case CONTINUE: + /* + * Recursively call bindNextAtomInRule for each generated substitution + * and the next literal in the grounding order (i.e. advance), thereby reducing remaining + * tolerance by 1 iff a substitution uses an unassigned ground atom. + * If remainingTolerance falls below zero, an empty {@link BindingResult} is returned. + */ + List> substitutionInfos = instantiationResult.getSubstitutions(); + LOGGER.trace("Literal instantiator yielded {} substitutions for literal {}.", substitutionInfos.size(), currentLiteral); + BindingResult retVal = new BindingResult(); + for (ImmutablePair substitutionInfo : substitutionInfos) { + retVal.add(this.continueBinding(groundingOrder, orderPosition, originalTolerance, remainingTolerance, + substitutionInfo)); + } + return retVal; + case PUSH_BACK: + /* + * Delegate to pushBackAndBindNextAtomInRule(RuleGroundingOrder, int, int, int, Substitution, Assignment). + * Pushes the current literal to the end of the grounding order and calls bindNextAtomInRule with the modified grounding oder. + */ + LOGGER.trace("Pushing back literal {} in grounding order.", currentLiteral); + return pushBackAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, partialSubstitution); + case MAYBE_PUSH_BACK: + /* + * Indicates that the rule instantiator could not find any substitutions for the current literal. If a permissive grounder heuristic is in + * use, push the current literal to the end of the grounding order and proceed with the next one, otherwise return an empty BindingResult. + */ + if (originalTolerance > 0) { + LOGGER.trace("No substitutions yielded by literal instantiator for literal {}, but using permissive heuristic, therefore pushing the literal back.", currentLiteral); + // This occurs when the grounder heuristic in use is a "permissive" one, + // i.e. it is deemed acceptable to have ground rules where a number of body atoms are not yet assigned a truth value by the solver. + return pushBackAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, partialSubstitution); + } else { + LOGGER.trace("No substitutions found for literal {}", currentLiteral); + return BindingResult.empty(); + } + case STOP_BINDING: + LOGGER.trace("No substitutions found for literal {}", currentLiteral); + return BindingResult.empty(); + default: + throw Util.oops("Unhandled literal instantiation result type: " + instantiationResult.getType()); + } + } + + @Override + public Pair, Map> getChoiceAtoms() { + return choiceRecorder.getAndResetChoices(); + } + + @Override + public Map> getHeadsToBodies() { + return choiceRecorder.getAndResetHeadsToBodies(); + } + + @Override + public void updateAssignment(IntIterator it) { + while (it.hasNext()) { + workingMemory.addInstance(atomStore.get(it.next()), true); + } + } + + @Override + public void forgetAssignment(int[] atomIds) { + throw new UnsupportedOperationException("Forgetting assignments is not implemented"); + } + + @Override + public InternalRule getNonGroundRule(Integer ruleId) { + return knownNonGroundRules.get(ruleId); + } + + @Override + public boolean isFact(CoreAtom atom) { + LinkedHashSet instances = factsFromProgram.get(atom.getPredicate()); + if (instances == null) { + return false; + } + return instances.contains(new Instance(atom.getTerms())); + } + + @Override + public Set justifyAtom(int atomToJustify, Assignment currentAssignment) { + Set literals = analyzeUnjustified.analyze(atomToJustify, currentAssignment); + // Remove facts from justification before handing it over to the solver. + for (Iterator iterator = literals.iterator(); iterator.hasNext(); ) { + CoreLiteral literal = iterator.next(); + if (literal.isNegated()) { + continue; + } + LinkedHashSet factsOverPredicate = factsFromProgram.get(literal.getPredicate()); + if (factsOverPredicate != null && factsOverPredicate.contains(new Instance(literal.getAtom().getTerms()))) { + iterator.remove(); + } + } + return literals; + } + + /** + * Checks that every nogood not marked as {@link NoGoodInterface.Type#INTERNAL} contains only + * atoms which are not {@link CorePredicate#isSolverInternal()} (except {@link RuleAtom}s, which are allowed). + * + * @param newNoGoods + */ + private void checkTypesOfNoGoods(Collection newNoGoods) { + for (NoGood noGood : newNoGoods) { + if (noGood.getType() != NoGoodInterface.Type.INTERNAL) { + for (int literal : noGood) { + CoreAtom atom = atomStore.get(atomOf(literal)); + if (atom.getPredicate().isSolverInternal() && !(atom instanceof RuleAtom)) { + throw oops("NoGood containing atom of internal predicate " + atom + " is " + noGood.getType() + " instead of INTERNAL"); + } + } + } + } + } + + private static class FirstBindingAtom { + final InternalRule rule; + final CoreLiteral startingLiteral; + + FirstBindingAtom(InternalRule rule, CoreLiteral startingLiteral) { + this.rule = rule; + this.startingLiteral = startingLiteral; + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java new file mode 100644 index 000000000..69996e2e6 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java @@ -0,0 +1,204 @@ +/** + * Copyright (c) 2017-2018, 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.grounder; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.common.Literals.negateLiteral; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; + +/** + * Class to generate ground NoGoods out of non-ground rules and grounding substitutions. + * Copyright (c) 2017-2018, the Alpha Team. + */ +public class NoGoodGenerator { + private final AtomStore atomStore; + private final ChoiceRecorder choiceRecorder; + private final Map> factsFromProgram; + private final InternalProgram programAnalysis; + private final Set uniqueGroundRulePerGroundHead; + + NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { + this.atomStore = atomStore; + this.choiceRecorder = recorder; + this.factsFromProgram = factsFromProgram; + this.programAnalysis = programAnalysis; + this.uniqueGroundRulePerGroundHead = uniqueGroundRulePerGroundHead; + } + + /** + * Generates all NoGoods resulting from a non-ground rule and a variable substitution. + * + * @param nonGroundRule + * the non-ground rule. + * @param substitution + * the grounding substitution, i.e., applying substitution to nonGroundRule results in a ground rule. + * Assumption: atoms with fixed interpretation evaluate to true under the substitution. + * @return a list of the NoGoods corresponding to the ground rule. + */ + List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundRule, final Substitution substitution) { + final List posLiterals = collectPosLiterals(nonGroundRule, substitution); + final List negLiterals = collectNegLiterals(nonGroundRule, substitution); + + if (posLiterals == null || negLiterals == null) { + return emptyList(); + } + + // A constraint is represented by exactly one nogood. + if (nonGroundRule.isConstraint()) { + return singletonList(NoGood.fromConstraint(posLiterals, negLiterals)); + } + + final List result = new ArrayList<>(); + + final CoreAtom groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); + final int headId = atomStore.putIfAbsent(groundHeadAtom); + + // Prepare atom representing the rule body. + final RuleAtom bodyAtom = new RuleAtom(nonGroundRule, substitution); + + // Check uniqueness of ground rule by testing whether the + // body representing atom already has an id. + if (atomStore.contains(bodyAtom)) { + // The current ground instance already exists, + // therefore all nogoods have already been created. + return emptyList(); + } + + final int bodyRepresentingLiteral = atomToLiteral(atomStore.putIfAbsent(bodyAtom)); + final int headLiteral = atomToLiteral(atomStore.putIfAbsent(nonGroundRule.getHeadAtom().substitute(substitution))); + + choiceRecorder.addHeadToBody(headId, atomOf(bodyRepresentingLiteral)); + + // Create a nogood for the head. + result.add(NoGood.headFirst(negateLiteral(headLiteral), bodyRepresentingLiteral)); + + final NoGood ruleBody = NoGood.fromBody(posLiterals, negLiterals, bodyRepresentingLiteral); + result.add(ruleBody); + + // Nogoods such that the atom representing the body is true iff the body is true. + for (int j = 1; j < ruleBody.size(); j++) { + result.add(new NoGood(bodyRepresentingLiteral, negateLiteral(ruleBody.getLiteral(j)))); + } + + // If the rule head is unique, add support. + if (uniqueGroundRulePerGroundHead.contains(nonGroundRule)) { + result.add(NoGood.support(headLiteral, bodyRepresentingLiteral)); + } + + // If the body of the rule contains negation, add choices. + if (!negLiterals.isEmpty()) { + result.addAll(choiceRecorder.generateChoiceNoGoods(posLiterals, negLiterals, bodyRepresentingLiteral)); + } + + return result; + } + + List collectNegLiterals(final InternalRule nonGroundRule, final Substitution substitution) { + final List bodyLiteralsNegative = new ArrayList<>(); + for (CoreLiteral lit : nonGroundRule.getNegativeBody()) { + CoreAtom groundAtom = lit.getAtom().substitute(substitution); + + final Set factInstances = factsFromProgram.get(groundAtom.getPredicate()); + + if (factInstances != null && factInstances.contains(new Instance(groundAtom.getTerms()))) { + // Negative atom that is always true encountered, skip whole rule as it will never fire. + return null; + } + + if (!existsRuleWithPredicateInHead(groundAtom.getPredicate())) { + // Negative atom is no fact and no rule defines it, it is always false, skip it. + continue; + } + + bodyLiteralsNegative.add(atomToLiteral(atomStore.putIfAbsent(groundAtom))); + } + return bodyLiteralsNegative; + } + + private List collectPosLiterals(final InternalRule nonGroundRule, final Substitution substitution) { + final List bodyLiteralsPositive = new ArrayList<>(); + for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { + if (lit instanceof FixedInterpretationLiteral) { + // TODO: conversion of atom to literal is ugly. NonGroundRule could manage atoms instead of literals, cf. FIXME there + // Atom has fixed interpretation, hence was checked earlier that it + // evaluates to true under the given substitution. + // FixedInterpretationAtoms need not be shown to the solver, skip it. + continue; + } + final CoreAtom atom = lit.getAtom(); + // Skip the special enumeration atom. + if (atom instanceof EnumerationAtom) { + continue; + } + + final CoreAtom groundAtom = atom.substitute(substitution); + + // Consider facts to eliminate ground atoms from the generated nogoods that are always true + // and eliminate nogoods that are always satisfied due to facts. + Set factInstances = factsFromProgram.get(groundAtom.getPredicate()); + if (factInstances != null && factInstances.contains(new Instance(groundAtom.getTerms()))) { + // Skip positive atoms that are always true. + continue; + } + + if (!existsRuleWithPredicateInHead(groundAtom.getPredicate())) { + // Atom is no fact and no rule defines it, it cannot be derived (i.e., is always false), skip whole rule as it will never fire. + return null; + } + + bodyLiteralsPositive.add(atomToLiteral(atomStore.putIfAbsent(groundAtom))); + } + return bodyLiteralsPositive; + } + + private boolean existsRuleWithPredicateInHead(final CorePredicate predicate) { + final HashSet definingRules = programAnalysis.getPredicateDefiningRules().get(predicate); + return definingRules != null && !definingRules.isEmpty(); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java new file mode 100644 index 000000000..43fdd9fce --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java @@ -0,0 +1,44 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import at.ac.tuwien.kr.alpha.common.NoGood; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class NogoodRegistry { + private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); + + private Map registeredIdentifiers = new LinkedHashMap<>(); + + /** + * Helper methods to analyze average nogood length. + * @return + */ + public float computeAverageNoGoodLength() { + int totalSizes = 0; + for (Map.Entry noGoodEntry : registeredIdentifiers.entrySet()) { + totalSizes += noGoodEntry.getKey().size(); + } + return ((float) totalSizes) / registeredIdentifiers.size(); + } + + void register(Iterable noGoods, Map difference) { + for (NoGood noGood : noGoods) { + // Check if noGood was already derived earlier, add if it is new + if (!registeredIdentifiers.containsKey(noGood)) { + int noGoodId = ID_GENERATOR.getNextId(); + registeredIdentifiers.put(noGood, noGoodId); + difference.put(noGoodId, noGood); + } + } + } + + int register(NoGood noGood) { + if (!registeredIdentifiers.containsKey(noGood)) { + int noGoodId = ID_GENERATOR.getNextId(); + registeredIdentifiers.put(noGood, noGoodId); + return noGoodId; + } + return registeredIdentifiers.get(noGood); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java new file mode 100644 index 000000000..ec99f727d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java @@ -0,0 +1,36 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; + +/** + * Copyright (c) 2017, the Alpha Team. + */ +public interface ProgramAnalyzingGrounder extends Grounder { + + /** + * Justifies the absence of an atom, i.e., returns reasons why the atom is not TRUE given the assignment. + * @param atomToJustify the atom to justify. + * @param currentAssignment the current assignment. + * @return a set of literals who jointly imply the atomToJustify not being TRUE. + */ + Set justifyAtom(int atomToJustify, Assignment currentAssignment); + + /** + * Returns true iff the given atom is known to the grounder as a fact (hence not occurring in any assignment). + * @param atom the atom. + * @return true iff atom is a fact. + */ + boolean isFact(CoreAtom atom); + + /** + * Returns the NonGroundRule identified by the given id. + * @param ruleId the id of the rule. + * @return the corresponding NonGroundRule. + */ + InternalRule getNonGroundRule(Integer ruleId); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java new file mode 100644 index 000000000..a3a7c16d7 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2019 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.grounder; + +import java.util.ArrayList; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; + +/** + * A grounding order computed by {@link RuleGroundingOrders} for a specific {@link InternalRule} and a specific starting literal. + */ +public class RuleGroundingOrder { + + private CoreLiteral startingLiteral; + private List otherLiterals; + private int positionLastVarBound; + private int stopBindingAtOrderPosition; + private final boolean ground; + + RuleGroundingOrder(CoreLiteral startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { + super(); + this.startingLiteral = startingLiteral; + this.otherLiterals = otherLiterals; + this.positionLastVarBound = positionLastVarBound; + this.stopBindingAtOrderPosition = otherLiterals.size(); + this.ground = isGround; + } + + private RuleGroundingOrder(RuleGroundingOrder otherRuleGroundingOrder) { + this(otherRuleGroundingOrder.startingLiteral, new ArrayList<>(otherRuleGroundingOrder.otherLiterals), otherRuleGroundingOrder.positionLastVarBound, otherRuleGroundingOrder.ground); + this.stopBindingAtOrderPosition = otherRuleGroundingOrder.stopBindingAtOrderPosition; + } + + /** + * Returns the literal at the given position in the grounding order, + * except it is already known that this literal is not able to yield new bindings. + * + * A literal cannot yield new bindings if it has been copied to the end of the grounding order + * when no bindings could be found, and no bindings for other literals could be found in the meantime. + * + * @param orderPosition zero-based index into list of literals except the starting literal + * @return the literal at the given position, or {@code null} if it is already known that this literal is not able to yield new bindings + */ + public CoreLiteral getLiteralAtOrderPosition(int orderPosition) { + if (orderPosition >= stopBindingAtOrderPosition) { + return null; + } + return otherLiterals.get(orderPosition); + } + + /** + * @return the zero-based position from which on all variables are bound in list of literals except the starting literal + */ + public int getPositionFromWhichAllVarsAreBound() { + return positionLastVarBound + 1; + } + + public boolean isGround() { + return ground; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(startingLiteral); + sb.append(" : "); + for (int i = 0; i < otherLiterals.size(); i++) { + if (i == positionLastVarBound + 1) { + sb.append("| "); + } + sb.append(otherLiterals.get(i)); + if (i < otherLiterals.size() - 1) { + sb.append(", "); + } + } + + return sb.toString(); + } + + /** + * "Pushes a literal back" in a grounding order because the literal cannot be used to generate substitutions now but + * maybe later. Pushing back means adding the literal again at the end of the grounding order. Since the literal will + * occur twice in the new grounding order returned by this method, we assume that the grounding order is processed + * from left to right and the literal at {@code orderPosition} will not be considered again. + * + * @param orderPosition the position in the grounding order of the literal to be pushed back. + * @return a new grounding order in which the atom is pushed back, + * or {@code null} if the position of the grounding order after which no new bindings can be found has been reached. + */ + public RuleGroundingOrder pushBack(int orderPosition) { + if (orderPosition >= stopBindingAtOrderPosition - 1) { + return null; + } + RuleGroundingOrder reorderedGroundingOrder = new RuleGroundingOrder(this); + reorderedGroundingOrder.otherLiterals.add(otherLiterals.get(orderPosition)); + return reorderedGroundingOrder; + } + + public void considerUntilCurrentEnd() { + this.stopBindingAtOrderPosition = this.otherLiterals.size(); + } + + public CoreLiteral getStartingLiteral() { + return this.startingLiteral; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java new file mode 100644 index 000000000..a3e022aa3 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java @@ -0,0 +1,229 @@ +/** + * 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 + * 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.grounder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; + +/** + * Provides the grounder with information on the order to ground the literals in the body of a rule. + * Grounding starts with some starting literal (i.e., one that does not require any variables to be bound already) and + * then may join this with any other literal that requires no other variables to be bound other than those already bound + * by the first literal. This class is prepared to take join-selectivities into account for finding a good grounding + * order. + * + * Since the grounder must yield all ground instantiations of rules whose positive body is true in the current assignment, + * a starting literals is a positive BasicAtom and the grounder can wait until after some instance in the working memory + * of the corresponding predicate arrives and only then start grounding. + * + * There is also the case that a rule has no ordinary positive literals (i.e., no positive BasicAtom) but is still safe. + * Such a rule has no starting literal but those rules have a fixed number of ground instantiations and they can be + * computed similar to facts at the beginning of the computation. + * + * Note that rules with self-joins (rules with p(X,Y), p(A,B) in their body) make it necessary that every positive + * literal (whose interpretation is not fixed) is a starting literal, at least for the current grounding procedure. + */ +public class RuleGroundingOrders { + private final InternalRule internalRule; + HashMap groundingOrders; + private HashMap literalSelectivity; + private List startingLiterals; + + private final boolean fixedGroundingInstantiation; + private RuleGroundingOrder fixedGroundingOrder; + + public RuleGroundingOrders(InternalRule internalRule) { + this.internalRule = internalRule; + this.literalSelectivity = new HashMap<>(); + resetLiteralSelectivity(); + this.groundingOrders = new HashMap<>(); + this.fixedGroundingInstantiation = computeStartingLiterals(); + } + + private void resetLiteralSelectivity() { + // Set selectivity of all literals to 1.0f. + for (CoreLiteral literal : internalRule.getBody()) { + literalSelectivity.put(literal, 1.0f); + } + } + + /** + * Computes starting literals and indicates whether there is a fixed ground instantiation for this rule. + * @return true iff the rule has a fixed ground instantiation. + */ + private boolean computeStartingLiterals() { + LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); + LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); + + // If the rule is ground, every body literal is a starting literal and the ground instantiation is fixed. + if (internalRule.isGround()) { + startingLiterals = new LinkedList<>(internalRule.getBody()); + return true; + } + + // Check each literal in the rule body whether it is eligible. + for (CoreLiteral literal : internalRule.getBody()) { + // Only literals that need no variables already bound can start grounding. + if (literal.getNonBindingVariables().size() != 0) { + continue; + } + + if (literal.getAtom() instanceof BasicAtom && !literal.isNegated()) { + // Positive BasicAtom is the main/ordinary case. + ordinaryStartingLiterals.add(literal); + } else { + // If literal is no positive BasicAtom but requires no bound variables, + // it can be the starting literal for some (fixed) instantiation. + fixedStartingLiterals.add(literal); + } + } + // If there are no positive BasicAtoms, the rule only contains fixed ground + // instantiation literals and those are starting for the one-time grounding. + if (!ordinaryStartingLiterals.isEmpty()) { + startingLiterals = new LinkedList<>(ordinaryStartingLiterals); + return false; + } else if (!fixedStartingLiterals.isEmpty()) { + startingLiterals = new LinkedList<>(fixedStartingLiterals); + return true; + } else { + throw new RuntimeException("Unsafe rule encountered: " + internalRule); + } + } + + public List getStartingLiterals() { + return Collections.unmodifiableList(startingLiterals); + } + + public void updateLiteralSelectivity(CoreLiteral literal, int numGivenTuples, int numObtainedTuples) { + // TODO: add old selectivity (with a decay factor) and new selectivity. + } + + public RuleGroundingOrder orderStartingFrom(CoreLiteral startingLiteral) { + return groundingOrders.get(startingLiteral); + } + + + public RuleGroundingOrder getFixedGroundingOrder() { + return fixedGroundingOrder; + } + + /** + * States whether the rule is without positive ordinary atoms, as for example in: p(Y) :- X = 1..3, not q(X), Y = X + 2, &ext[X,Y](). + * @return true if the rule has a (limited number of) fixed grounding instantiation(s). + */ + public boolean fixedInstantiation() { + return fixedGroundingInstantiation; + } + + public void computeGroundingOrders() { + if (fixedGroundingInstantiation) { + // Fixed grounding is only evaluated once and not depending on a starting variable, just use the first. + computeGroundingOrder(startingLiterals.get(0)); + return; + } + // Compute grounding orders for all positive BasicAtoms. + for (CoreLiteral literal : startingLiterals) { + computeGroundingOrder(literal); + } + } + + private void computeGroundingOrder(CoreLiteral startingLiteral) { + Set bodyLiterals = internalRule.getBody(); + HashSet boundVariables = new HashSet<>(); + boundVariables.addAll(startingLiteral.getBindingVariables()); + LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); + remainingLiterals.remove(startingLiteral); + ArrayList literalsOrder; + if (fixedGroundingInstantiation) { + literalsOrder = new ArrayList<>(bodyLiterals.size()); + literalsOrder.add(startingLiteral); + } else { + literalsOrder = new ArrayList<>(bodyLiterals.size() - 1); + } + + int position = 0; + int positionLastVarBound = -1; + while (!remainingLiterals.isEmpty()) { + CoreLiteral nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); + if (nextGroundingLiteral == null) { + throw new RuntimeException("Could not find a grounding order for rule " + internalRule + " with starting literal: " + startingLiteral + ". Rule is not safe."); + } + remainingLiterals.remove(nextGroundingLiteral); + boolean boundNewVars = boundVariables.addAll(nextGroundingLiteral.getBindingVariables()); + if (boundNewVars) { + positionLastVarBound = position; + } + literalsOrder.add(nextGroundingLiteral); + position++; + } + if (fixedGroundingInstantiation) { + fixedGroundingOrder = new RuleGroundingOrder(null, literalsOrder, positionLastVarBound, internalRule.isGround()); + } + groundingOrders.put(startingLiteral, new RuleGroundingOrder(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); + } + + private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { + Float bestSelectivity = Float.MAX_VALUE; + CoreLiteral bestLiteral = null; + boolean bestLiteralSharesVariables = false; + // Find the best literal whose nonbinding variables are already bound and whose selectivity is highest. + // To avoid cross products, select those first that have some of their variables already bound. + for (CoreLiteral literal : remainingLiterals) { + if (!boundVariables.containsAll(literal.getNonBindingVariables())) { + // Only consider literals whose nonbinding variables are already bound. + continue; + } + Float selectivity = literalSelectivity.get(literal); + boolean sharesVariables = sharesVariables(boundVariables, literal.getBindingVariables(), literal.getNonBindingVariables()); + if (bestLiteral == null + || sharesVariables && selectivity < bestSelectivity + || sharesVariables && !bestLiteralSharesVariables) { + bestLiteral = literal; + bestSelectivity = selectivity; + bestLiteralSharesVariables = sharesVariables; + } + } + return bestLiteral; + } + + private boolean sharesVariables(Collection set1, Collection set2part1, Collection set2part2) { + return !Collections.disjoint(set1, set2part1) || !Collections.disjoint(set1, set2part2); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java new file mode 100644 index 000000000..7cc35a992 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2016-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.grounder; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.TreeMap; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; + +public class Substitution { + + private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); + public static final Substitution EMPTY_SUBSTITUTION = new Substitution() { + @Override + public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { + throw oops("Should not be called on EMPTY_SUBSTITUTION"); + } + }; + + protected TreeMap substitution; + + private Substitution(TreeMap substitution) { + if (substitution == null) { + throw oops("Substitution is null."); + } + this.substitution = substitution; + } + + public Substitution() { + this(new TreeMap<>()); + } + + public Substitution(Substitution clone) { + this(new TreeMap<>(clone.substitution)); + } + + public static Substitution specializeSubstitution(CoreLiteral literal, Instance instance, Substitution substitution) { + return specializeSubstitution(literal.getAtom(), instance, substitution); + } + + /** + * Helper class to lazily clone the input substitution of Substitution.specializeSubstitution only when needed. + */ + private static class SpecializationHelper { + Substitution updatedSubstitution; // Is null for as long as the given partial substitution is not extended, afterwards holds the updated/extended/specialized substitution. + + Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { + for (int i = 0; i < termList.size(); i++) { + if (!unifyTerms(termList.get(i), instance.terms.get(i), partialSubstitution)) { + return null; + } + } + if (updatedSubstitution == null) { + // All terms unify but there was no need to assign a new variable, return the input substitution. + return partialSubstitution; + } + return updatedSubstitution; + } + + boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution partialSubstitution) { + if (termNonGround == termGround) { + // Both terms are either the same constant or the same variable term + return true; + } else if (termNonGround instanceof ConstantTerm) { + // Since right term is ground, both terms differ + return false; + } else if (termNonGround instanceof VariableTerm) { + VariableTerm variableTerm = (VariableTerm) termNonGround; + // Left term is variable, bind it to the right term. Use original substitution if it has + // not been cloned yet. + CoreTerm bound = (updatedSubstitution == null ? partialSubstitution : updatedSubstitution).eval(variableTerm); // Get variable binding, either from input substitution if it has not been updated yet, or from the cloned/updated substitution. + if (bound != null) { + // Variable is already bound, return true if binding is the same as the current ground term. + return termGround == bound; + } + // Record new variable binding. + if (updatedSubstitution == null) { + // Clone substitution if it was not yet updated. + updatedSubstitution = new Substitution(partialSubstitution); + } + updatedSubstitution.put(variableTerm, termGround); + return true; + } else if (termNonGround instanceof FunctionTerm && termGround instanceof FunctionTerm) { + // Both terms are function terms + FunctionTerm ftNonGround = (FunctionTerm) termNonGround; + FunctionTerm ftGround = (FunctionTerm) termGround; + + if (!(ftNonGround.getSymbol().equals(ftGround.getSymbol()))) { + return false; + } + if (ftNonGround.getTerms().size() != ftGround.getTerms().size()) { + return false; + } + + // Iterate over all subterms of both function terms + for (int i = 0; i < ftNonGround.getTerms().size(); i++) { + if (!unifyTerms(ftNonGround.getTerms().get(i), ftGround.getTerms().get(i), partialSubstitution)) { + return false; + } + } + + return true; + } + return false; + } + } + + /** + * Specializes a given substitution such that applying the specialized substitution on the given atom yields the + * given instance (if such a specialized substitution exists). Computes the unifier of the (nonground) atom and + * the given ground instance such that the unifier is an extension of the given partial substitution. If + * specialization succeeds the unifying substitution is returned, if no such unifier exists null is returned. In + * any case the partial substitution is left unchanged. + * + * @param atom the (potentially nonground) atom to unify. + * @param instance the ground instance to unify the atom with. + * @param substitution the (partial) substitution for the atom. This is left unchanged in all cases. + * @return null if the unification/specialization fails, otherwise it is a unifying substitution. If the + * parameter substitution already is a unifier, it is returned. If the unifying substitution is an + * extension of the input substitution, a new substitution will be returned. + */ + public static Substitution specializeSubstitution(CoreAtom atom, Instance instance, Substitution substitution) { + return new SpecializationHelper().unify(atom.getTerms(), instance, substitution); + } + + /** + * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTerm} under this substitution. + * + * @param variableTerm the variable term to substitute, if possible + * @return a constant term if the substitution contains the given variable, {@code null} otherwise. + */ + public CoreTerm eval(VariableTerm variableTerm) { + return this.substitution.get(variableTerm); + } + + public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { + if (!groundTerm.isGround()) { + throw oops("Right-hand term is not ground."); + } + CoreTerm alreadyAssigned = substitution.get(variableTerm); + if (alreadyAssigned != null && alreadyAssigned != groundTerm) { + throw oops("Variable is already assigned to another term."); + } + // Note: We're destroying type information here. + return substitution.put(variableTerm, groundTerm); + } + + public boolean isEmpty() { + return substitution.isEmpty(); + } + + public boolean isVariableSet(VariableTerm variable) { + return substitution.get(variable) != null; + } + + public Set getMappedVariables() { + return substitution.keySet(); + } + + /** + * Prints the variable substitution in a uniform way (sorted by variable names). + * + * @return + */ + @Override + public String toString() { + final StringBuilder ret = new StringBuilder("{"); + boolean isFirst = true; + for (Map.Entry e : substitution.entrySet()) { + if (isFirst) { + isFirst = false; + } else { + ret.append(","); + } + ret.append(e.getKey()).append("->").append(e.getValue()); + } + ret.append("}"); + return ret.toString(); + } + + public static Substitution fromString(String substitution) { + String bare = substitution.substring(1, substitution.length() - 1); + String[] assignments = bare.split(","); + Substitution ret = new Substitution(); + for (String assignment : assignments) { + String[] keyVal = assignment.split("->"); + VariableTerm variable = VariableTerm.getInstance(keyVal[0]); + CoreTerm assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); + ret.put(variable, assignedTerm); + } + return ret; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Substitution that = (Substitution) o; + + return Objects.equals(substitution, that.substitution); + } + + @Override + public int hashCode() { + return substitution != null ? substitution.hashCode() : 0; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java new file mode 100644 index 000000000..a188d7adf --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2017-2018, 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.grounder; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; + +import java.util.Set; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +/** + * Copyright (c) 2017, the Alpha Team. + */ +public class Unification { + + public static Unifier unifyAtoms(CoreAtom left, CoreAtom right) { + return unifyAtoms(left, right, false); + } + + /** + * Instantiates the general Atom to match the specific one and returns the corresponding substitution. + * @param general the general Atom to instantiate. + * @param specific the specific Atom. + * @return a Unifier sigma such that specific == general.substitute(sigma), returns null if no such sigma exists. + */ + public static Unifier instantiate(CoreAtom general, CoreAtom specific) { + return unifyAtoms(specific, general, true); + } + + private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLeftAsIs) { + Set leftOccurringVariables = left.getOccurringVariables(); + Set rightOccurringVaribles = right.getOccurringVariables(); + boolean leftSmaller = leftOccurringVariables.size() < rightOccurringVaribles.size(); + Set smallerSet = leftSmaller ? leftOccurringVariables : rightOccurringVaribles; + Set largerSet = leftSmaller ? rightOccurringVaribles : leftOccurringVariables; + for (VariableTerm variableTerm : smallerSet) { + if (largerSet.contains(variableTerm)) { + throw oops("Left and right atom share variables."); + } + } + Unifier mgu = new Unifier(); + if (!left.getPredicate().equals(right.getPredicate())) { + return null; + } + for (int i = 0; i < left.getPredicate().getArity(); i++) { + final CoreTerm leftTerm = left.getTerms().get(i); + final CoreTerm rightTerm = right.getTerms().get(i); + if (!unifyTerms(leftTerm, rightTerm, mgu, keepLeftAsIs)) { + return null; + } + } + return mgu; + } + + private static boolean unifyTerms(CoreTerm left, CoreTerm right, Unifier currentSubstitution, boolean keepLeftAsIs) { + final CoreTerm leftSubs = left.substitute(currentSubstitution); + final CoreTerm rightSubs = right.substitute(currentSubstitution); + if (leftSubs == rightSubs) { + return true; + } + if (!keepLeftAsIs && leftSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) leftSubs)) { + currentSubstitution.put((VariableTerm) leftSubs, rightSubs); + return true; + } + if (rightSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) rightSubs)) { + currentSubstitution.put((VariableTerm) rightSubs, leftSubs); + return true; + } + if (leftSubs instanceof FunctionTerm && rightSubs instanceof FunctionTerm) { + final FunctionTerm leftFunction = (FunctionTerm) leftSubs; + final FunctionTerm rightFunction = (FunctionTerm) rightSubs; + if (!leftFunction.getSymbol().equals(rightFunction.getSymbol()) + || leftFunction.getTerms().size() != rightFunction.getTerms().size()) { + return false; + } + for (int i = 0; i < leftFunction.getTerms().size(); i++) { + final CoreTerm leftTerm = leftFunction.getTerms().get(i); + final CoreTerm rightTerm = rightFunction.getTerms().get(i); + if (!unifyTerms(leftTerm, rightTerm, currentSubstitution, keepLeftAsIs)) { + return false; + } + } + return true; + } + return false; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java new file mode 100644 index 000000000..92a3df759 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java @@ -0,0 +1,134 @@ +package at.ac.tuwien.kr.alpha.grounder; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; + +/** + * A variable substitution allowing variables to occur on the right-hand side. Chains of variable substitutions are + * resolved automatically, i.e., adding the substitutions (X -> A) and (A -> d) results in (X -> d), (A -> d). + * Copyright (c) 2018-2020, the Alpha Team. + */ +public class Unifier extends Substitution { + + private final TreeMap> rightHandVariableOccurrences; + + private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { + if (substitution == null) { + throw oops("Substitution is null."); + } + this.substitution = substitution; + this.rightHandVariableOccurrences = rightHandVariableOccurrences; + } + + public Unifier() { + this(new TreeMap<>(), new TreeMap<>()); + } + + public Unifier(Unifier clone) { + this(new TreeMap<>(clone.substitution), new TreeMap<>(clone.rightHandVariableOccurrences)); + } + + public Unifier(Substitution clone) { + this(new TreeMap<>(clone.substitution), new TreeMap<>()); + } + + + public Unifier extendWith(Substitution extension) { + for (Map.Entry extensionVariable : extension.substitution.entrySet()) { + this.put(extensionVariable.getKey(), extensionVariable.getValue()); + } + return this; + } + + /** + * Returns a list of all variables occurring in that unifier, i.e., variables that are mapped and those that occur (nested) in the right-hand side of the unifier. + * @return the list of variables occurring somewhere in the unifier. + */ + @Override + public Set getMappedVariables() { + Set ret = new HashSet<>(); + for (Map.Entry substitution : substitution.entrySet()) { + ret.add(substitution.getKey()); + ret.addAll(substitution.getValue().getOccurringVariables()); + } + return ret; + } + + + @Override + public > CoreTerm put(VariableTerm variableTerm, CoreTerm term) { + // If term is not ground, store it for right-hand side reverse-lookup. + if (!term.isGround()) { + for (VariableTerm rightHandVariable : term.getOccurringVariables()) { + rightHandVariableOccurrences.putIfAbsent(rightHandVariable, new ArrayList<>()); + rightHandVariableOccurrences.get(rightHandVariable).add(variableTerm); + } + } + // Note: We're destroying type information here. + CoreTerm ret = substitution.put(variableTerm, term); + + // Check if the just-assigned variable occurs somewhere in the right-hand side already. + List rightHandOccurrences = rightHandVariableOccurrences.get(variableTerm); + if (rightHandOccurrences != null) { + // Replace all occurrences on the right-hand side with the just-assigned term. + for (VariableTerm rightHandOccurrence : rightHandOccurrences) { + // Substitute the right hand where this assigned variable occurs with the new value and store it. + CoreTerm previousRightHand = substitution.get(rightHandOccurrence); + if (previousRightHand == null) { + // Variable does not occur on the lef-hand side, skip. + continue; + } + substitution.put(rightHandOccurrence, previousRightHand.substitute(this)); + } + } + + return ret; + } + + /** + * Merge substitution right into left as used in the AnalyzeUnjustified. + * Left mappings are seen as equalities, i.e., + * if left has A -> B and right has A -> t then the result will have A -> t and B -> t. + * If both substitutions are inconsistent, i.e., A -> t1 in left and A -> t2 in right, then null is returned. + * @param left + * @param right + * @return + */ + public static Unifier mergeIntoLeft(Unifier left, Unifier right) { + // Note: we assume both substitutions are free of chains, i.e., no A->B, B->C but A->C, B->C. + Unifier ret = new Unifier(left); + for (Map.Entry mapping : right.substitution.entrySet()) { + VariableTerm variable = mapping.getKey(); + CoreTerm term = mapping.getValue(); + // If variable is unset, simply add. + if (!ret.isVariableSet(variable)) { + ret.put(variable, term); + continue; + } + // Variable is already set. + CoreTerm setTerm = ret.eval(variable); + if (setTerm instanceof VariableTerm) { + // Variable maps to another variable in left. + // Add a new mapping of the setTerm variable into our right-assigned term. + ret.put((VariableTerm) setTerm, term); + // Note: Unifier.put takes care of resolving the chain variable->setTerm->term. + continue; + } + // Check for inconsistency. + if (setTerm != term) { + return null; + } + // Now setTerm equals term, no action needed. + } + return ret; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java new file mode 100644 index 000000000..b5ba106f2 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2016-2018, 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.grounder; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.commons.lang3.tuple.ImmutablePair; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; + +public class WorkingMemory { + protected HashMap> workingMemory = new HashMap<>(); + private HashSet modifiedWorkingMemories = new LinkedHashSet<>(); + + public boolean contains(CorePredicate predicate) { + return workingMemory.containsKey(predicate); + } + + public void initialize(CorePredicate predicate) { + if (workingMemory.containsKey(predicate)) { + return; + } + + IndexedInstanceStorage pos = new IndexedInstanceStorage(predicate, true); + IndexedInstanceStorage neg = new IndexedInstanceStorage(predicate, false); + // Index all positions of the storage (may impair efficiency) + for (int i = 0; i < predicate.getArity(); i++) { + pos.addIndexPosition(i); + neg.addIndexPosition(i); + } + + workingMemory.put(predicate, new ImmutablePair<>(pos, neg)); + } + + public IndexedInstanceStorage get(CoreLiteral literal) { + return get(literal.getAtom(), !literal.isNegated()); + } + + public IndexedInstanceStorage get(CoreAtom atom, boolean value) { + return get(atom.getPredicate(), value); + } + + public IndexedInstanceStorage get(CorePredicate predicate, boolean value) { + ImmutablePair pair = workingMemory.get(predicate); + if (value) { + return pair.getLeft(); + } else { + return pair.getRight(); + } + } + + public void addInstance(CoreAtom atom, boolean value) { + addInstance(atom.getPredicate(), value, new Instance(atom.getTerms())); + } + + public void addInstance(CorePredicate predicate, boolean value, Instance instance) { + IndexedInstanceStorage storage = get(predicate, value); + + if (!storage.containsInstance(instance)) { + storage.addInstance(instance); + modifiedWorkingMemories.add(storage); + } + } + + public void addInstances(CorePredicate predicate, boolean value, Iterable instances) { + IndexedInstanceStorage storage = get(predicate, value); + + for (Instance instance : instances) { + if (!storage.containsInstance(instance)) { + storage.addInstance(instance); + modifiedWorkingMemories.add(storage); + } + } + } + + public void reset() { + modifiedWorkingMemories = new LinkedHashSet<>(); + } + + public Set modified() { + return modifiedWorkingMemories; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java new file mode 100644 index 000000000..3ce4e494e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2016-2018, 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.grounder.atoms; + +import static at.ac.tuwien.kr.alpha.Util.join; + +import java.util.Collections; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +public class ChoiceAtom extends CoreAtom { + + public static final CorePredicate ON = CorePredicate.getInstance("ChoiceOn", 1, true, true); + public static final CorePredicate OFF = CorePredicate.getInstance("ChoiceOff", 1, true, true); + + private final CorePredicate predicate; + private final List terms; + + private ChoiceAtom(CorePredicate predicate, CoreTerm term) { + this.predicate = predicate; + this.terms = Collections.singletonList(term); + } + + private ChoiceAtom(CorePredicate predicate, int id) { + this(predicate, CoreConstantTerm.getInstance(Integer.toString(id))); + } + + public static ChoiceAtom on(int id) { + return new ChoiceAtom(ON, id); + } + + public static ChoiceAtom off(int id) { + return new ChoiceAtom(OFF, id); + } + + @Override + public CorePredicate getPredicate() { + return predicate; + } + + @Override + public List getTerms() { + return terms; + } + + @Override + public boolean isGround() { + // NOTE: Term is a ConstantTerm, which is ground by definition. + return true; + } + + @Override + public CoreLiteral toLiteral(boolean negated) { + throw new UnsupportedOperationException("ChoiceAtom cannot be literalized"); + } + + @Override + public CoreAtom substitute(Substitution substitution) { + return this; + } + + @Override + public String toString() { + return join(predicate.getName() + "(", terms, ")"); + } + + @Override + public CoreAtom withTerms(List terms) { + throw new UnsupportedOperationException("Changing terms is not supported for ChoiceAtoms!"); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.predicate == null) ? 0 : this.predicate.hashCode()); + result = prime * result + ((this.terms == null) ? 0 : this.terms.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof ChoiceAtom)) { + return false; + } + ChoiceAtom other = (ChoiceAtom) obj; + if (this.predicate == null) { + if (other.predicate != null) { + return false; + } + } else if (!this.predicate.equals(other.predicate)) { + return false; + } + if (this.terms == null) { + if (other.terms != null) { + return false; + } + } else if (!this.terms.equals(other.terms)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java new file mode 100644 index 000000000..80d310fad --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java @@ -0,0 +1,95 @@ +package at.ac.tuwien.kr.alpha.grounder.atoms; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.HashMap; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Represents a ground-instance enumeration atom of form: + * enum(enumId, groundTerm, sequenceNo). + * + * The semantics of this is: + * if enum(A,T1, N1) and enum(A,T2,N2) are both true and T1 != T2, then N1 != N2. + * Furthermore, If enum(A,T1,N1) is true with N1 > 0 then enum(A,T2,N1 - 1) is true for some T1 != T2 and + * both, T1 and T2, are ground instances the grounder encountered during the search so far. + * + * Copyright (c) 2017, the Alpha Team. + */ +public class EnumerationAtom extends BasicAtom { + public static final CorePredicate ENUMERATION_PREDICATE = CorePredicate.getInstance("_Enumeration", 3); + private static final HashMap> ENUMERATIONS = new HashMap<>(); + + public EnumerationAtom(List terms) { + super(ENUMERATION_PREDICATE, terms); + if (terms.size() != 3) { + throw new RuntimeException("EnumerationAtom must have arity three. Given terms are of wrong size: " + terms); + } + if (!(getTerms().get(2) instanceof VariableTerm)) { + throw new RuntimeException("Third parameter of EnumerationAtom must be a variable: " + terms); + } + } + + public static void resetEnumerations() { + ENUMERATIONS.clear(); + } + + private Integer getEnumerationIndex(CoreTerm identifier, CoreTerm enumerationTerm) { + ENUMERATIONS.putIfAbsent(identifier, new HashMap<>()); + HashMap enumeratedTerms = ENUMERATIONS.get(identifier); + Integer assignedInteger = enumeratedTerms.get(enumerationTerm); + if (assignedInteger == null) { + int enumerationIndex = enumeratedTerms.size() + 1; + enumeratedTerms.put(enumerationTerm, enumerationIndex); + return enumerationIndex; + } else { + return assignedInteger; + } + + } + + /** + * Based on a given substitution, substitutes the first two terms of this {@link EnumerationAtom} with the values from the substitution, + * and returns a new substitution with all mappings from the input substitution plus a binding for the third term of the enum atom to the + * integer index that is mapped to the first two terms in the internal ENUMERATIONS map. + * + * @param substitution an input substitution which must provide ground terms for the first two terms of the enumeration atom. + * @return a new substitution where the third term of the enumeration atom is bound to an integer. + */ + public Substitution addEnumerationIndexToSubstitution(Substitution substitution) { + CoreTerm idTerm = this.getTerms().get(0).substitute(substitution); + CoreTerm enumerationTerm = this.getTerms().get(1).substitute(substitution); + if (!enumerationTerm.isGround()) { + throw new RuntimeException("Enumeration term is not ground after substitution. Should not happen."); + } + Integer enumerationIndex = getEnumerationIndex(idTerm, enumerationTerm); + Substitution retVal = new Substitution(substitution); + retVal.put((VariableTerm) getTerms().get(2), CoreConstantTerm.getInstance(enumerationIndex)); + return retVal; + } + + @Override + public EnumerationAtom substitute(Substitution substitution) { + return new EnumerationAtom(super.substitute(substitution).getTerms()); + } + + @Override + public EnumerationLiteral toLiteral(boolean positive) { + if (!positive) { + throw oops("IntervalLiteral cannot be negated"); + } + return new EnumerationLiteral(this); + } + + @Override + public EnumerationLiteral toLiteral() { + return toLiteral(true); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java new file mode 100644 index 000000000..99c1735fd --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java @@ -0,0 +1,59 @@ +package at.ac.tuwien.kr.alpha.grounder.atoms; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Copyright (c) 2018, the Alpha Team. + */ +public class EnumerationLiteral extends BasicLiteral { + + public EnumerationLiteral(EnumerationAtom atom) { + super(atom, true); + } + + @Override + public EnumerationAtom getAtom() { + return (EnumerationAtom) super.getAtom(); + } + + @Override + public EnumerationLiteral negate() { + throw new UnsupportedOperationException("EnumerationLiteral cannot be negated"); + } + + @Override + public EnumerationLiteral substitute(Substitution substitution) { + return new EnumerationLiteral(getAtom().substitute(substitution)); + } + + @Override + public Set getBindingVariables() { + return Collections.singleton((VariableTerm)getTerms().get(2)); + } + + @Override + public Set getNonBindingVariables() { + Set ret = new HashSet<>(2); + CoreTerm idTerm = getTerms().get(0); + CoreTerm enumTerm = getTerms().get(1); + if (idTerm instanceof VariableTerm) { + ret.add((VariableTerm) idTerm); + } + if (enumTerm instanceof VariableTerm) { + ret.add((VariableTerm) enumTerm); + } + return ret; + + } + + public Substitution addEnumerationIndexToSubstitution(Substitution partialSubstitution) { + return this.getAtom().addEnumerationIndexToSubstitution(partialSubstitution); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java new file mode 100644 index 000000000..5d1b96580 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2017-2018, 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.grounder.atoms; + +import static at.ac.tuwien.kr.alpha.Util.join; +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.Arrays; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Helper for treating IntervalTerms in rules. + * + * Each IntervalTerm is replaced by a variable and this special IntervalAtom is added to the rule body for generating + * all bindings of the variable. + * + * The first term of this atom is an IntervalTerm while the second term is any Term (if it is a VariableTerm, this will + * bind to all elements of the interval, otherwise it is a simple check whether the Term is a ConstantTerm with + * the Integer being inside the interval. + * + * Copyright (c) 2017, the Alpha Team. + */ +public class IntervalAtom extends CoreAtom implements VariableNormalizableAtom { + private static final CorePredicate PREDICATE = CorePredicate.getInstance("_interval", 2, true); + + private final List terms; + + public IntervalAtom(IntervalTerm intervalTerm, CoreTerm intervalRepresentingVariable) { + this.terms = Arrays.asList(intervalTerm, intervalRepresentingVariable); + } + + @Override + public CorePredicate getPredicate() { + return PREDICATE; + } + + @Override + public List getTerms() { + return terms; + } + + @Override + public boolean isGround() { + for (CoreTerm t : this.terms) { + if (!t.isGround()) { + return false; + } + } + return true; + } + + @Override + public IntervalLiteral toLiteral(boolean positive) { + if (!positive) { + throw oops("IntervalLiteral cannot be negated"); + } + return new IntervalLiteral(this); + } + + @Override + public IntervalLiteral toLiteral() { + return toLiteral(true); + } + + @Override + public String toString() { + return join(PREDICATE.getName() + "(", terms, ")"); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + IntervalAtom that = (IntervalAtom) o; + + return terms.equals(that.terms); + } + + @Override + public int hashCode() { + return terms.hashCode(); + } + + @Override + public IntervalAtom substitute(Substitution substitution) { + return new IntervalAtom((IntervalTerm) terms.get(0).substitute(substitution), terms.get(1).substitute(substitution)); + } + + @Override + public IntervalAtom normalizeVariables(String prefix, int counterStartingValue) { + List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); + return new IntervalAtom((IntervalTerm) renamedTerms.get(0), renamedTerms.get(1)); + } + + @Override + public CoreAtom withTerms(List terms) { + throw new UnsupportedOperationException("IntervalAtoms do not support setting of terms!"); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java new file mode 100644 index 000000000..5b6505c5f --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2017-2018, 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.grounder.atoms; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import com.google.common.collect.Sets; + +import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * @see IntervalAtom + */ +public class IntervalLiteral extends FixedInterpretationLiteral { + + public IntervalLiteral(IntervalAtom atom) { + super(atom, true); + } + + @Override + public IntervalAtom getAtom() { + return (IntervalAtom) atom; + } + + @Override + public IntervalLiteral negate() { + throw new UnsupportedOperationException("IntervalLiteral cannot be negated"); + } + + private List getIntervalSubstitutions(Substitution partialSubstitution) { + List substitutions = new ArrayList<>(); + List terms = getTerms(); + CoreTerm intervalRepresentingVariable = terms.get(1); + IntervalTerm intervalTerm = (IntervalTerm) terms.get(0); + // Check whether intervalRepresentingVariable is bound already. + if (intervalRepresentingVariable instanceof VariableTerm) { + // Still a variable, generate all elements in the interval. + for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) { + Substitution ith = new Substitution(partialSubstitution); + ith.put((VariableTerm) intervalRepresentingVariable, CoreConstantTerm.getInstance(i)); + substitutions.add(ith); + } + return substitutions; + } else { + // The intervalRepresentingVariable is bound already, check if it is in the interval. + if (!(intervalRepresentingVariable instanceof ConstantTerm) + || !(((CoreConstantTerm) intervalRepresentingVariable).getObject() instanceof Integer)) { + // Term is not bound to an integer constant, not in the interval. + return Collections.emptyList(); + } + Integer integer = (Integer) ((CoreConstantTerm) intervalRepresentingVariable).getObject(); + if (intervalTerm.getLowerBound() <= integer && integer <= intervalTerm.getUpperBound()) { + return Collections.singletonList(partialSubstitution); + } + return Collections.emptyList(); + } + } + + @Override + public Set getBindingVariables() { + CoreTerm term = getTerms().get(1); + if (term instanceof VariableTerm) { + return Collections.singleton((VariableTerm) term); + } + return Collections.emptySet(); + } + + @Override + public Set getNonBindingVariables() { + return Sets.newHashSet(getTerms().get(0).getOccurringVariables()); + } + + @Override + public List getSatisfyingSubstitutions(Substitution partialSubstitution) { + // Substitute variables occurring in the interval itself. + IntervalLiteral groundInterval = substitute(partialSubstitution); + // Generate all substitutions for the interval representing variable. + return groundInterval.getIntervalSubstitutions(partialSubstitution); + } + + @Override + public IntervalLiteral substitute(Substitution substitution) { + return new IntervalLiteral(getAtom().substitute(substitution)); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java new file mode 100644 index 000000000..cbe2f5a66 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2016-2018, 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.grounder.atoms; + +import static at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm.getInstance; + +import java.util.Arrays; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Atoms corresponding to rule bodies use this predicate, first term is rule number, + * second is a term containing variable substitutions. + */ +public class RuleAtom extends CoreAtom { + public static final CorePredicate PREDICATE = CorePredicate.getInstance("_R_", 2, true, true); + + private final List> terms; + + private RuleAtom(List> terms) { + if (terms.size() != 2) { + throw new IllegalArgumentException(); + } + + this.terms = terms; + } + + public RuleAtom(InternalRule nonGroundRule, Substitution substitution) { + this(Arrays.asList( + getInstance(Integer.toString(nonGroundRule.getRuleId())), + getInstance(substitution.toString()) + ) + ); + } + + @Override + public CorePredicate getPredicate() { + return PREDICATE; + } + + @Override + public List getTerms() { + return Arrays.asList(terms.get(0), terms.get(1)); + } + + @Override + public boolean isGround() { + // NOTE: Both terms are ConstantTerms, which are ground by definition. + return true; + } + + @Override + public CoreLiteral toLiteral(boolean positive) { + throw new UnsupportedOperationException("RuleAtom cannot be literalized"); + } + + @Override + public CoreAtom substitute(Substitution substitution) { + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + RuleAtom that = (RuleAtom) o; + + return terms.equals(that.terms); + } + + @Override + public int hashCode() { + return 31 * PREDICATE.hashCode() + terms.hashCode(); + } + + @Override + public String toString() { + return PREDICATE.getName() + "(" + terms.get(0) + "," + terms.get(1) + ')'; + } + + @Override + public CoreAtom withTerms(List terms) { + throw new UnsupportedOperationException("RuleAtoms do not support setting of terms!"); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java new file mode 100644 index 000000000..15e30600b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java @@ -0,0 +1,12 @@ +package at.ac.tuwien.kr.alpha.grounder.bridges; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; + +import java.util.Collection; + +public interface Bridge { + Collection getRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java new file mode 100644 index 000000000..79026fdcc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.grounder.Instance; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.ArrayList; +import java.util.List; + +/** + * Abstract base implementation of {@link LiteralInstantiationStrategy} that outlines a basic workflow for + * {@link LiteralInstantiationStrategy#getTruthForGroundLiteral(Literal)} and + * {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)} while leaving details of when an atom is true and + * which {@link AssignmentStatus}es to consider valid for getAcceptedSubstitutions to implementations. + * + * Copyright (c) 2020, the Alpha Team. + */ +public abstract class AbstractLiteralInstantiationStrategy implements LiteralInstantiationStrategy { + + /** + * See {@link LiteralInstantiationStrategy#getTruthForGroundLiteral(Literal). + * + * In general - since this code is used in a grounding context where negative literals in rule bodies can be handled in different ways - the + * logic for determining the {@link AssignmentStatus} of a negated literal is delegated to the abstract method + * {@link AbstractLiteralInstantiationStrategy#getAssignmentStatusForNegatedGroundLiteral(Literal)}. The assignment status for positive + * literals is determined using the abstract method {@link AbstractLiteralInstantiationStrategy#getAssignmentStatusForAtom(Atom)}. + */ + @Override + public final AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral) { + if (groundLiteral.isNegated()) { + return this.getAssignmentStatusForNegatedGroundLiteral(groundLiteral); + } + return this.getAssignmentStatusForAtom(groundLiteral.getAtom()); + } + + /** + * See {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)}. + * + * A very general implementation of the basic steps needed to obtain ground substitutions for a positive literal. + * Potentially valid ground instances are obtained using {@link AbstractLiteralInstantiationStrategy#computeCandidateInstances(Atom)}, then + * checked, such that each candidate instance unifies with the given partial substitution and has a "valid" {@link AssignmentStatus}, + * where "validity" of an {@link AssignmentStatus} is determined using the abstract method + * {@link AbstractLiteralInstantiationStrategy#assignmentStatusAccepted(AssignmentStatus)}. + */ + @Override + public final List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution) { + CoreAtom atom = lit.getAtom(); + Iterable groundInstances = this.computeCandidateInstances(atom); + return this.buildSubstitutionsFromInstances(atom, groundInstances, partialSubstitution); + } + + /** + * Computes instances that are potentially valid ground instances of the given partially-ground atom. + * + * A candidate instance is a ground instance of the same predicate where all terms that are ground in partiallyGroundAtom have + * the same values in the candidate. + * + * @param partiallyGroundAtom a partially ground atom for which to find fitting ground instances + * @return a list of candidate instances + */ + protected abstract Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom); + + /** + * Based on a list of candidate instances (see {@link AbstractLiteralInstantiationStrategy#computeCandidateInstances(Atom)}), create a list + * of substitutions and assignment statuses such that each substitution represents a valid (according to the implementation-specific + * definition of this instantiation strategy) ground instance of atomToSubstitute. + * + * @param atomToSubstitute + * @param candidateInstances + * @param partialSubstitution + * @return + */ + protected final List> buildSubstitutionsFromInstances(CoreAtom atomToSubstitute, + Iterable candidateInstances, Substitution partialSubstitution) { + List> retVal = new ArrayList<>(); + // Filter for only instances unifying with partialSubsitution, i.e. "where all joins work out". + Substitution currentInstanceSubstitution; + CoreAtom atomForCurrentInstance; + for (Instance instance : candidateInstances) { + currentInstanceSubstitution = Substitution.specializeSubstitution(atomToSubstitute, instance, partialSubstitution); + if (currentInstanceSubstitution == null) { + // Instance does not unify with partialSubstitution, move on to the next instance. + continue; + } + // At this point, we know that the substitution works out. + // Now check whether the resulting Atom has an acceptable AssignmentStatus. + atomForCurrentInstance = new BasicAtom(atomToSubstitute.getPredicate(), atomToSubstitute.getTerms()) + .substitute(currentInstanceSubstitution); + AssignmentStatus assignmentStatus = this.getAssignmentStatusForAtom(atomForCurrentInstance); + if (!this.assignmentStatusAccepted(assignmentStatus)) { + // Atom has an assignment status deemed unacceptable by this instantiation strategy. + continue; + } + retVal.add(new ImmutablePair<>(currentInstanceSubstitution, assignmentStatus)); + } + return retVal; + } + + protected abstract AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom); + + protected abstract AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral); + + protected abstract boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java new file mode 100644 index 000000000..8555e91c6 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; + +/** + * Helper type to represent truth values as understood by a {@link Grounder} and {@link LiteralInstantiator}. + * + * Note that this enum is not related in any way to {@link ThriceTruth} and mainly serves to have a clear mechanism to indicate that the + * truth value of an atom is not known at a given point in time (UNASSIGNED) + * + * Copyright (c) 2020, the Alpha Team. + */ +public enum AssignmentStatus { + + /** + * True + */ + TRUE, + + /** + * False + */ + FALSE, + + /** + * Unassigned - indicates that at a given point in time, a {@link LiteralInstantiationStrategy} can not determine whether a literal is true + * or false. This is needed because some grounding strategies consider UNASSIGNED atoms to be valid ground instances in order to be able to + * ground larger parts of a program earlier on in the ground/solve cycle + */ + UNASSIGNED; +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java new file mode 100644 index 000000000..34ff021bf --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import java.util.ArrayList; +import java.util.List; + +/** + * Contains substitutions produced for generating ground substitutions of a rule, + * and for every substitution the number of positive body atoms still unassigned in the respective ground rule. + */ +public class BindingResult { + + private final List generatedSubstitutions = new ArrayList<>(); + private final List numbersOfUnassignedPositiveBodyAtoms = new ArrayList<>(); + + public void add(Substitution generatedSubstitution, int numberOfUnassignedPositiveBodyAtoms) { + generatedSubstitutions.add(generatedSubstitution); + numbersOfUnassignedPositiveBodyAtoms.add(numberOfUnassignedPositiveBodyAtoms); + } + + public void add(BindingResult otherBindingResult) { + generatedSubstitutions.addAll(otherBindingResult.generatedSubstitutions); + numbersOfUnassignedPositiveBodyAtoms.addAll(otherBindingResult.numbersOfUnassignedPositiveBodyAtoms); + } + + public int size() { + return generatedSubstitutions.size(); + } + + public static BindingResult empty() { + return new BindingResult(); + } + + public static BindingResult singleton(Substitution generatedSubstitution, int numberOfUnassignedPositiveBodyAtoms) { + BindingResult bindingResult = new BindingResult(); + bindingResult.add(generatedSubstitution, numberOfUnassignedPositiveBodyAtoms); + return bindingResult; + } + + public List getGeneratedSubstitutions() { + return generatedSubstitutions; + } + + public List getNumbersOfUnassignedPositiveBodyAtoms() { + return numbersOfUnassignedPositiveBodyAtoms; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java new file mode 100644 index 000000000..21f30e40b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java @@ -0,0 +1,177 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import java.util.LinkedHashSet; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; +import at.ac.tuwien.kr.alpha.grounder.Instance; +import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; +import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.solver.Solver; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; + +/** + * Implementation of {@link AbstractLiteralInstantiationStrategy} designed for use in {@link NaiveGrounder}. + * + * The instantiation strategy shares a {@link WorkingMemory}, an {@link AtomStore}, an {@link Assignment}, a {@link Map} of atoms that were + * facts of the currently grounded program, as well as a list of {@link CoreAtom}s that should be lazily deleted from the working memory, + * with + * the grounder. + * + * The working memory and the facts map are maintained by the grounder and are being read by + * {@link DefaultLazyGroundingInstantiationStrategy} in order to determine {@link AssignmentStatus}es for atoms. The {@link AtomStore} is + * maintained by {@link DefaultLazyGroundingInstantiationStrategy} in the sense that atoms created from newly encountered ground instances + * are added by the instantiation strategy. The {@link Assignment} reflects the {@link Solver}s "current view of the world". It is used by + * {@link DefaultLazyGroundingInstantiationStrategy} to determine {@link AssignmentStatus}es for atoms. + * + * A specialty of this implementation is that - since deletion of obsolete {@link CoreAtom}s from {@link NaiveGrounder}s + * {@link WorkingMemory} + * happens lazily (i.e. at the end of each run of {@link NaiveGrounder#getNoGoods(Assignment)}) - it maintains a set of "stale" atoms that + * is shared with the grounder. Specifically, whenever {@link DefaultLazyGroundingInstantiationStrategy#getAssignmentStatusForAtom(Atom)} + * determines that an {@link CoreAtom} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link CoreAtom} is + * added to + * the stale atom set, which in turn is processed by the grounder, which then deletes the respective atoms from the working memory. + * + * Copyright (c) 2020, the Alpha Team. + */ +public class DefaultLazyGroundingInstantiationStrategy extends AbstractLiteralInstantiationStrategy { + + private WorkingMemory workingMemory; + private AtomStore atomStore; + private Assignment currentAssignment; + private LinkedHashSet staleWorkingMemoryEntries; + private Map> facts; + + public DefaultLazyGroundingInstantiationStrategy(WorkingMemory workingMemory, AtomStore atomStore, + Map> facts) { + this.workingMemory = workingMemory; + this.atomStore = atomStore; + this.facts = facts; + } + + @Override + protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { + IndexedInstanceStorage instanceStorage = this.workingMemory.get(partiallyGroundAtom, true); + return instanceStorage.getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); + } + + //@formatter:off + /** + * Computes the {@link AssignmentStatus} for a given {@link CoreAtom} a. + * + * The atom a is {@link AssignmentStatus#TRUE} iff + *

        + *
      • The instantiation strategy's
        currentAssignment
        is null (i.e. the call originated from {@link NaiveGrounder#bootstrap}).
      • + *
      • a is a fact.
      • + *
      • a is assigned {@link ThriceTruth#TRUE} or {@link ThriceTruth#MBT} in the current assignment by the {@link Solver}. + *
      + * + * An atom is {@link AssignmentStatus#UNASSIGNED} iff it has no {@link ThriceTruth} assigned to it in the current assignment. + * An atom is {@link AssignmentStatus#FALSE} iff it is assigned {@link ThriceTruth#FALSE} in the current assignment by the {@link Solver}. + * + * Whenever an {@link CoreAtom} is found to be UNASSIGNED or FALSE, + * that {@link CoreAtom} is added to the stale atom set for later deletion from working memory by the grounder. + */ + //@formatter:on + @Override + protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { + if (this.currentAssignment == null || this.isFact(atom)) { + // currentAssignment == null is a legitimate case, grounder may be in bootstrap + // and will call bindNextAtom with null assignment in that case. + // Assumption: since the atom came from working memory and we must be in + // bootstrap here, we can assume for the atom to be true (or atom is a fact + // anyway, in which case it's also true). + return AssignmentStatus.TRUE; + } + AssignmentStatus retVal; + // First, make sure that the Atom in question exists in the AtomStore. + if (atomStore.contains(atom)) { + int atomId = this.atomStore.get(atom); + this.currentAssignment.growForMaxAtomId(); + if (currentAssignment.isAssigned(atomId)) { + retVal = currentAssignment.getTruth(atomId).toBoolean() ? AssignmentStatus.TRUE : AssignmentStatus.FALSE; + } else { + retVal = AssignmentStatus.UNASSIGNED; + } + } else { + retVal = AssignmentStatus.UNASSIGNED; + } + if (retVal == AssignmentStatus.FALSE || retVal == AssignmentStatus.UNASSIGNED) { + this.staleWorkingMemoryEntries.add(atom); + } + return retVal; + } + + private boolean isFact(CoreAtom atom) { + if (this.facts.get(atom.getPredicate()) == null) { + return false; + } else { + return this.facts.get(atom.getPredicate()).contains(Instance.fromAtom(atom)); + } + } + + @Override + protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { + return AssignmentStatus.TRUE; + } + + /** + * Checks whether a given {@link AssignmentStatus} is "acceptable" in the sense + * that an atom with that assignment status represents a valid ground + * substitution for a non-ground atom. This instantiation strategy accepts + * {@link AssignmentStatus#TRUE} and {@link AssignmentStatus#UNASSIGNED}. + */ + @Override + protected boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus) { + switch (assignmentStatus) { + case TRUE: + case UNASSIGNED: + return true; + case FALSE: + return false; + default: + throw Util.oops("Unsupported AssignmentStatus: " + assignmentStatus); + } + } + + public void setCurrentAssignment(Assignment currentAssignment) { + this.currentAssignment = currentAssignment; + } + + public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { + this.staleWorkingMemoryEntries = staleWorkingMemoryEntries; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java new file mode 100644 index 000000000..42d7be9f1 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * Representation of the result of instantiating, i.e. finding ground instances for a literal, as performed by + * {@link LiteralInstantiator#instantiateLiteral(Literal, Substitution)}. + * + * 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}. + * + * Copyright (c) 2020, the Alpha Team. + */ +public class LiteralInstantiationResult { + + /** + * Indicates how a {@link Grounder} should treat this result. + */ + private final Type type; + + /** + * Ground substitutions together with the {@link AssignmentStatus} of the last literal bound to obtain the substitution. Empty for result + * types STOP_BINDING, PUSH_BACK and MAYBE_PUSH_BACK. + */ + private final List> substitutions; + + private LiteralInstantiationResult(Type type, List> substitutions) { + if (type == Type.CONTINUE && substitutions == null) { + throw new UnsupportedOperationException("A LiteralInstantiationResult of type CONTINUE must have substitutions!"); + } + this.type = type; + this.substitutions = substitutions; + } + + public static LiteralInstantiationResult continueBinding(List> substitutions) { + return new LiteralInstantiationResult(Type.CONTINUE, substitutions); + } + + //@formatter:off + public static LiteralInstantiationResult continueBindingWithTrueSubstitutions(List substitutions) { + List> substitutionsWithAssignment = substitutions.stream() + .map((substitution) -> new ImmutablePair<>(substitution, AssignmentStatus.TRUE)) + .collect(Collectors.toList()); + return new LiteralInstantiationResult(Type.CONTINUE, substitutionsWithAssignment); + } + //@formatter:on + + public static LiteralInstantiationResult continueBinding(Substitution substitution, AssignmentStatus assignmentStatus) { + return new LiteralInstantiationResult(Type.CONTINUE, Collections.singletonList(new ImmutablePair<>(substitution, assignmentStatus))); + } + + public static LiteralInstantiationResult stopBinding() { + return new LiteralInstantiationResult(Type.STOP_BINDING, null); + } + + public static LiteralInstantiationResult pushBack() { + return new LiteralInstantiationResult(Type.PUSH_BACK, null); + } + + public static LiteralInstantiationResult maybePushBack() { + return new LiteralInstantiationResult(Type.MAYBE_PUSH_BACK, null); + } + + public Type getType() { + return this.type; + } + + public List> getSubstitutions() { + if (this.type != Type.CONTINUE) { + throw new UnsupportedOperationException("A LiteralInstantiationResult of type " + this.type + " does not have substitutions!"); + } + return this.substitutions; + } + + /** + * Result type. Used by {@link Grounder}s to determine how to proceed grounding a rule after instantiating the literal that yielded the + * respective instantiation result. + * + * Copyright (c) 2020, the Alpha Team. + */ + public static enum Type { + + /** + * Grounder should stop working on the rule, no valid substitutions exist. + */ + STOP_BINDING, + + /** + * Grounder should continue with the next literal. + */ + CONTINUE, + + /** + * Literal instantiation yielded no ground instances, but depending on the specific workflow of the grounder, proceeding with another + * literal might yet make sense. Grounder should decide whether to stop binding or push the literal back in the overall grounding order. + */ + MAYBE_PUSH_BACK, + + /** + * Currently no ground instances, but proceeding with another literal might make sense, push the literal back in the overall grounding + * order. This is used for {@link at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral}s that do not produce bindings, like a + * comparision "X < Y" when one variable is not yet bound. + */ + PUSH_BACK; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java new file mode 100644 index 000000000..5a8489f77 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.grounder.Substitution; + +/** + * A {@link LiteralInstantiationStrategy} finds and validates {@link Substitution}s for {@link Literal}s based on a specific definition of + * when a {@link Substitution} is valid, i.e. what makes a literal "true", "false" or "unassigned". + * + * Copyright (c) 2020, the Alpha Team. + */ +public interface LiteralInstantiationStrategy { + + /** + * Computes the {@link AssignmentStatus} for the given {@link Literal} according to the rules of this {@link LiteralInstantiationStrategy}. + * + * @param groundLiteral a ground {@link Literal} for which to compute an {@link AssignmentStatus} + * @return the current {@link AssignmentStatus} for the given literal according to the rules of this {@link LiteralInstantiationStrategy} + */ + AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral); + + /** + * Computes {@link Substitution}s that yield ground instances for a given literal and starting substitution along with the + * {@link AssignmentStatus} of respective ground instances. Note that in all implementations it must hold that an {@link AssignmentStatus} + * AS for a {@link Substitution} S as yielded by this method for a {@link Literal} lit is the same as the result of calling + * getTruthForGroundLiteral(lit.substitute(S)), i.e. both methods must yield the same assignment status for the same ground + * literal. + * + * @param lit a non-ground {@link Literal} for which to compute substitutions. + * @param partialSubstitution a (possibly empty) substitution to use as a starting point + * @return a list of substitutions along with the assignment status of the respective ground atoms + */ + List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java new file mode 100644 index 000000000..607f3ac63 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java @@ -0,0 +1,187 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationLiteral; +import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalLiteral; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Provides ground instantiations for literals. + * + * This class is intended to be used for grounding and other use cases where ground instantiations of literals need to be computed and + * serves as an abstraction layer to decouple the knowledge of how to ground literals from the overall (rule-)grounding workflow. The task of + * actually finding fitting ground substitutions is mostly delegated to a {@link LiteralInstantiationStrategy}. + * + * Copyright (c) 2020, the Alpha Team. + */ +public class LiteralInstantiator { + + private static final Logger LOGGER = LoggerFactory.getLogger(LiteralInstantiator.class); + + private final LiteralInstantiationStrategy instantiationStrategy; + + /** + * Creates a new {@link LiteralInstantiator} with the given {@link LiteralInstantiationStrategy}. + * + * @param instantiationStrategy the instantiation strategy to use for this instantiator + */ + public LiteralInstantiator(LiteralInstantiationStrategy instantiationStrategy) { + this.instantiationStrategy = instantiationStrategy; + } + + /** + * Instantiates a literal using an existing {@link Substitution} as starting point. + * + * This method is intended to be called as part of a larger rule instantiation (i.e. grounding) workflow in order to find ground + * instantiations of literals, i.e. extensions of the given partial substitution that yield useable ground instances for the given literal. + * These substitutions (if any exist) are wrapped together with some additional status information in a {@link LiteralInstantiationResult}. + * + * @param lit the literal for which to find substitutions that yield ground instances + * @param partialSubstitution a substitution that serves as a starting point. May be empty. + * @return a {@link LiteralInstantiationResult} containing ground substitutions - if any exist - along with some metadata for the grounder + */ + public LiteralInstantiationResult instantiateLiteral(CoreLiteral lit, Substitution partialSubstitution) { + LOGGER.trace("Instantiating literal: {}", lit); + if (lit instanceof FixedInterpretationLiteral) { + return this.instantiateFixedInterpretationLiteral((FixedInterpretationLiteral) lit, partialSubstitution); + } else if (lit instanceof EnumerationLiteral) { + return this.instantiateEnumerationLiteral((EnumerationLiteral) lit, partialSubstitution); + } else { + // Note: At this point we just assume lit to be a basic literal, actual type + // check is not performed since the assumption is that any literal that is no + // FixedInterpretationLiteral or EnumerationLiteral follows the semantics of a + // BasicLiteral even if it has another (currently not existing) type. + return this.instantiateBasicLiteral(lit, partialSubstitution); + } + } + + /** + * Calculates satisfying substitutions for a given {@link FixedInterpretationLiteral} based on a partial substitution. This method assumes + * that the partial substitution has not been applied to the passed literal. + * + * @param lit the (fixed interpretation) literal for which to calculate substitutions + * @param partialSubstitution + * @return a LiteralInstantiationResult representing the result of the search for substitutions + */ + private LiteralInstantiationResult instantiateFixedInterpretationLiteral(FixedInterpretationLiteral lit, Substitution partialSubstitution) { + LOGGER.trace("Instantiating FixedInterpretationLiteral: {}", lit); + List substitutions; + FixedInterpretationLiteral substitutedLiteral = (FixedInterpretationLiteral) lit.substitute(partialSubstitution); + if (this.shouldPushBackFixedInterpretationLiteral(substitutedLiteral)) { + return LiteralInstantiationResult.pushBack(); + } else { + substitutions = substitutedLiteral.getSatisfyingSubstitutions(partialSubstitution); + return substitutions.isEmpty() ? LiteralInstantiationResult.stopBinding() + : LiteralInstantiationResult.continueBindingWithTrueSubstitutions(substitutions); + } + } + + /** + * 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. + * + * @param lit an enumeration literal + * @param partialSubstitution + */ + private LiteralInstantiationResult instantiateEnumerationLiteral(EnumerationLiteral lit, Substitution partialSubstitution) { + LOGGER.trace("Instantiating EnumerationLiteral: {}", lit); + return LiteralInstantiationResult.continueBinding(lit.addEnumerationIndexToSubstitution(partialSubstitution), AssignmentStatus.TRUE); + } + + /** + * Calculates substitutions for a given literal that is not a {@link FixedInterpretationLiteral} or {@link EnumerationLiteral}. + * If applying the given partial substitution to the literal already grounds the literal, the resulting ground literal is verified based on + * this instantiators {@link LiteralInstantiationStrategy}. If the literal is only partially ground after applying the partial substitution, + * ground substitutions are looked up using the instantiators {@link LiteralInstantiationStrategy}. This method assumes that the partial + * substitution has not been applied to the passed literal. + * + * @param lit + * @param partialSubstitution + */ + private LiteralInstantiationResult instantiateBasicLiteral(CoreLiteral lit, Substitution partialSubstitution) { + LOGGER.trace("Instantiating basic literal: {}", lit); + List> substitutions; + CoreLiteral substitutedLiteral = lit.substitute(partialSubstitution); + LOGGER.trace("Substituted literal is {}", substitutedLiteral); + if (substitutedLiteral.isGround()) { + LOGGER.trace("Literal {} is already ground, checking truth", substitutedLiteral); + // Lit seems to be a basic literal, so its satisfiability w.r.t. + // partialSubstitution is decided based on knownInstances by the + // instantiationStrategy. + AssignmentStatus truthForLiteral = this.instantiationStrategy.getTruthForGroundLiteral(substitutedLiteral); + if (truthForLiteral == AssignmentStatus.FALSE) { + return LiteralInstantiationResult.stopBinding(); + } else { + return LiteralInstantiationResult.continueBinding(partialSubstitution, truthForLiteral); + } + } else { + LOGGER.trace("Handling non-ground literal {}", substitutedLiteral); + if (substitutedLiteral.isNegated()) { + return LiteralInstantiationResult.maybePushBack(); + } + // Query instantiationStrategy for acceptable substitutions. + // Note: getAcceptedSubstitutions will only give substitutions where the + // resulting ground atom is true or unassigned, false atoms are internally + // discarded. + substitutions = this.instantiationStrategy.getAcceptedSubstitutions(substitutedLiteral, partialSubstitution); + LOGGER.trace("Got {} substitutions from instantiation strategy for {}", substitutions.size(), substitutedLiteral); + return substitutions.isEmpty() ? LiteralInstantiationResult.maybePushBack() : LiteralInstantiationResult.continueBinding(substitutions); + } + } + + /** + * Helper method for instantiateLiteral to determine whether a {@link FixedInterpretationLiteral} may have substitutions later + * on and should therefore be pushed back in the grounding order. + * + * Any {@link FixedInterpretationLiteral} that does not fulfil any of the following conditions is "pushed back" in the + * grounding order because it cannot be used to generate substitutions now but maybe later: + *

        + *
      • the literal is ground
      • + *
      • the literal is a {@link ComparisonLiteral} that is left-assigning or right-assigning
      • + *
      • the literal is an {@link IntervalLiteral} representing a ground interval term
      • + *
      • the literal is an {@link ExternalLiteral}.
      • + *
      + * + * @param lit a {@link FixedInterpretationLiteral} that is substituted with the partial substitution passed into + * instantiateLiteral + */ + private boolean shouldPushBackFixedInterpretationLiteral(FixedInterpretationLiteral lit) { + return !(lit.isGround() || + (lit instanceof ComparisonLiteral && ((ComparisonLiteral) lit).isLeftOrRightAssigning()) || + (lit instanceof IntervalLiteral && lit.getTerms().get(0).isGround()) || + (lit instanceof ExternalLiteral)); + + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java new file mode 100644 index 000000000..3f98f3695 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2020, the Alpha Team. + * 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.grounder.instantiation; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.grounder.Instance; +import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; + +/** + * A very basic implementation of {@link AbstractLiteralInstantiationStrategy} that determines truth of an atom solely based on the atom's + * presence in a working memory. Atoms that have a corresponding positive instance in the working memory have {@link AssignmentStatus#TRUE}, + * all other atoms have {@link AssignmentStatus#FALSE}. A negated literal lit is true iff + * getAssignmentStatusForAtom(lit.getAtom()) == AssignmentStatus.FALSE, false otherwise. + * + * Copyright (c) 2020, the Alpha Team. + */ +public class WorkingMemoryBasedInstantiationStrategy extends AbstractLiteralInstantiationStrategy { + + private final WorkingMemory workingMemory; + + public WorkingMemoryBasedInstantiationStrategy(WorkingMemory workingMemory) { + this.workingMemory = workingMemory; + } + + @Override + protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { + return this.workingMemory.get(partiallyGroundAtom, true).getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); + } + + @Override + protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { + return this.workingMemory.get(atom, true).containsInstance(Instance.fromAtom(atom)) ? AssignmentStatus.TRUE : AssignmentStatus.FALSE; + } + + @Override + protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { + return this.getAssignmentStatusForAtom(negatedGroundLiteral.getAtom()) == AssignmentStatus.TRUE ? AssignmentStatus.FALSE : AssignmentStatus.TRUE; + } + + @Override + protected boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus) { + return assignmentStatus == AssignmentStatus.TRUE; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java new file mode 100644 index 000000000..f6fc42ffb --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.kr.alpha.grounder.parser; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Stores directives appearing in the ASP program. Each directive starts with # and ends with . + * Copyright (c) 2017, the Alpha Team. + */ +public class InlineDirectives { + + public enum DIRECTIVE { + enum_predicate_is + } + + private final LinkedHashMap directives = new LinkedHashMap<>(); + + public String getDirectiveValue(DIRECTIVE directive) { + return directives.get(directive); + } + + public void addDirective(DIRECTIVE directive, String value) { + if (directives.get(directive) != null) { + throw new RuntimeException("Inline directive multiply defined."); + } + directives.put(directive, value); + } + + public void accumulate(InlineDirectives other) { + for (Map.Entry directiveEntry : other.directives.entrySet()) { + addDirective(directiveEntry.getKey(), directiveEntry.getValue()); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java new file mode 100644 index 000000000..3571d961b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java @@ -0,0 +1,583 @@ +/** + * Copyright (c) 2016-2018, 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.grounder.parser; + +import at.ac.tuwien.kr.alpha.antlr.ASPCore2BaseVisitor; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; +import at.ac.tuwien.kr.alpha.common.rule.head.Head; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.*; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.tree.TerminalNode; + +import java.util.*; + +import static java.util.Collections.emptyList; + +/** + * Copyright (c) 2016-2018, the Alpha Team. + */ +public class ParseTreeVisitor extends ASPCore2BaseVisitor { + private final Map externals; + private final boolean acceptVariables; + + private InputProgram.Builder programBuilder; + private InlineDirectives inlineDirectives; + + public ParseTreeVisitor(Map externals) { + this(externals, true); + } + + public ParseTreeVisitor(Map externals, boolean acceptVariables) { + this.externals = externals; + this.acceptVariables = acceptVariables; + } + + private UnsupportedOperationException notSupported(RuleContext ctx) { + return new UnsupportedOperationException("Unsupported syntax encountered: " + ctx.getText()); + } + + /** + * Translates a program context (referring to a node in an ATN specific to ANTLR) to the internal representation of Alpha. + */ + public InputProgram translate(ASPCore2Parser.ProgramContext input) { + return visitProgram(input); + } + + /** + * Translates a context for answer sets (referring to a node in an ATN specific to ANTLR) to the representation that Alpha uses. + */ + public Set translate(ASPCore2Parser.Answer_setsContext input) { + return visitAnswer_sets(input); + } + + @Override + public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { + Set result = new TreeSet<>(); + + for (ASPCore2Parser.Answer_setContext answerSetContext : ctx.answer_set()) { + result.add(visitAnswer_set(answerSetContext)); + } + + return result; + } + + @Override + public AnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { + SortedSet predicates = new TreeSet<>(); + Map> predicateInstances = new TreeMap<>(); + + for (ASPCore2Parser.Classical_literalContext classicalLiteralContext : ctx.classical_literal()) { + CoreAtom atom = visitClassical_literal(classicalLiteralContext); + + predicates.add(atom.getPredicate()); + predicateInstances.compute(atom.getPredicate(), (k, v) -> { + if (v == null) { + v = new TreeSet<>(); + } + v.add(atom); + return v; + }); + + } + + return new BasicAnswerSet(predicates, predicateInstances); + } + + @Override + public String visitTerminal(TerminalNode node) { + return node.getText(); + } + + @Override + public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { + // program : statements? query?; + if (ctx.query() != null) { + throw notSupported(ctx.query()); + } + + if (ctx.statements() == null) { + return InputProgram.EMPTY; + } + inlineDirectives = new InlineDirectives(); + programBuilder = InputProgram.builder(); + visitStatements(ctx.statements()); + programBuilder.addInlineDirectives(inlineDirectives); + return programBuilder.build(); + } + + @Override + public Object visitStatements(ASPCore2Parser.StatementsContext ctx) { + // statements : statement+; + for (ASPCore2Parser.StatementContext statementContext : ctx.statement()) { + visit(statementContext); + } + return null; + } + + @Override + public Object visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { + // head DOT + Head head = visitHead(ctx.head()); + if (head instanceof NormalHead) { + programBuilder.addFact(((NormalHead) head).getAtom()); + } else { + // Treat facts with choice or disjunction in the head like a rule. + programBuilder.addRule(new BasicRule(head, emptyList())); + } + return null; + } + + @Override + public Object visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx) { + // CONS body DOT + programBuilder.addRule(new BasicRule(null, 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()))); + return null; + } + + @Override + public Object visitStatement_weightConstraint(ASPCore2Parser.Statement_weightConstraintContext ctx) { + // WCONS body? DOT SQUARE_OPEN weight_at_level SQUARE_CLOSE + throw notSupported(ctx); + } + + @Override + public Object visitStatement_directive(ASPCore2Parser.Statement_directiveContext ctx) { + // directive + visitDirective(ctx.directive()); + // Parsed directives are globally stored, nothing to return here. + return null; + } + + @Override + public Head visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { + // disjunction : classical_literal (OR disjunction)?; + if (ctx.disjunction() != null) { + throw notSupported(ctx); + } + return new NormalHead(visitClassical_literal(ctx.classical_literal())); + } + + @Override + public Head visitHead(ASPCore2Parser.HeadContext ctx) { + // head : disjunction | choice; + if (ctx.choice() != null) { + return visitChoice(ctx.choice()); + } + return visitDisjunction(ctx.disjunction()); + } + + @Override + public Head visitChoice(ASPCore2Parser.ChoiceContext ctx) { + // choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; + Term lt = null; + ComparisonOperator lop = null; + Term ut = null; + ComparisonOperator uop = null; + if (ctx.lt != null) { + lt = (Term) visit(ctx.lt); + lop = visitBinop(ctx.lop); + } + if (ctx.ut != null) { + ut = (Term) visit(ctx.ut); + uop = visitBinop(ctx.uop); + } + return new ChoiceHead(visitChoice_elements(ctx.choice_elements()), lt, lop, ut, uop); + } + + @Override + public List visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { + // choice_elements : choice_element (SEMICOLON choice_elements)?; + List choiceElements; + if (ctx.choice_elements() != null) { + choiceElements = visitChoice_elements(ctx.choice_elements()); + } else { + choiceElements = new LinkedList<>(); + } + choiceElements.add(0, visitChoice_element(ctx.choice_element())); + return choiceElements; + } + + @Override + public ChoiceHead.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { + // choice_element : classical_literal (COLON naf_literals?)?; + BasicAtom atom = (BasicAtom) visitClassical_literal(ctx.classical_literal()); + if (ctx.naf_literals() != null) { + return new ChoiceHead.ChoiceElement(atom, visitNaf_literals(ctx.naf_literals())); + } else { + return new ChoiceHead.ChoiceElement(atom, Collections.emptyList()); + } + } + + @Override + public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { + // naf_literals : naf_literal (COMMA naf_literals)?; + List literals; + if (ctx.naf_literals() != null) { + literals = visitNaf_literals(ctx.naf_literals()); + } else { + literals = new LinkedList<>(); + } + literals.add(0, visitNaf_literal(ctx.naf_literal())); + return literals; + } + + @Override + public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx) { + // directive_enumeration : SHARP 'enum_predicate_is' ID DOT; + inlineDirectives.addDirective(InlineDirectives.DIRECTIVE.enum_predicate_is, ctx.ID().getText()); + return null; + } + + @Override + public List visitBody(ASPCore2Parser.BodyContext ctx) { + // body : ( naf_literal | aggregate ) (COMMA body)?; + if (ctx == null) { + return emptyList(); + } + + final List literals = new ArrayList<>(); + do { + if (ctx.naf_literal() != null) { + literals.add(visitNaf_literal(ctx.naf_literal())); + } else { + literals.add(visitAggregate(ctx.aggregate())); + } + } while ((ctx = ctx.body()) != null); + + return literals; + } + + @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)?; + boolean isPositive = ctx.NAF() == null; + CoreTerm lt = null; + ComparisonOperator lop = null; + Term ut = null; + ComparisonOperator uop = null; + if (ctx.lt != null) { + lt = (CoreTerm) visit(ctx.lt); + lop = visitBinop(ctx.lop); + } + if (ctx.ut != null) { + ut = (Term) visit(ctx.ut); + uop = visitBinop(ctx.uop); + } + AggregateAtom.AGGREGATEFUNCTION aggregateFunction = visitAggregate_function(ctx.aggregate_function()); + List aggregateElements = visitAggregate_elements(ctx.aggregate_elements()); + return new AggregateAtom(lop, lt, uop, ut, aggregateFunction, aggregateElements).toLiteral(isPositive); + } + + @Override + public List visitAggregate_elements(ASPCore2Parser.Aggregate_elementsContext ctx) { + // aggregate_elements : aggregate_element (SEMICOLON aggregate_elements)?; + final List aggregateElements = new ArrayList<>(); + do { + aggregateElements.add(visitAggregate_element(ctx.aggregate_element())); + } while ((ctx = ctx.aggregate_elements()) != null); + + return aggregateElements; + } + + @Override + public AggregateAtom.AggregateElement visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx) { + // aggregate_element : basic_terms? (COLON naf_literals?)?; + List basicTerms = ctx.basic_terms() != null ? visitBasic_terms(ctx.basic_terms()) : null; + if (ctx.naf_literals() != null) { + return new AggregateAtom.AggregateElement(basicTerms, visitNaf_literals(ctx.naf_literals())); + } + return new AggregateAtom.AggregateElement(basicTerms, Collections.emptyList()); + } + + @Override + public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { + // basic_terms : basic_term (COMMA basic_terms)? ; + List termList = new ArrayList<>(); + do { + termList.add(visitBasic_term(ctx.basic_term())); + } while ((ctx = ctx.basic_terms()) != null); + return termList; + } + + @Override + public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { + // basic_term : ground_term | variable_term; + if (ctx.ground_term() != null) { + return visitGround_term(ctx.ground_term()); + } else { + return visitVariable_term(ctx.variable_term()); + } + } + + @Override + public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { + // ground_term : ID | QUOTED_STRING | MINUS? NUMBER; + if (ctx.ID() != null) { + return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); + } else if (ctx.QUOTED_STRING() != null) { + String quotedString = ctx.QUOTED_STRING().getText(); + return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); + } else { + int multiplier = 1; + if (ctx.MINUS() != null) { + multiplier = -1; + } + return CoreConstantTerm.getInstance(multiplier * Integer.parseInt(ctx.NUMBER().getText())); + } + } + + @Override + public Term visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { + // variable_term : VARIABLE | ANONYMOUS_VARIABLE; + if (ctx.VARIABLE() != null) { + return VariableTerm.getInstance(ctx.VARIABLE().getText()); + } else { + return VariableTerm.getAnonymousInstance(); + } + } + + @Override + public AggregateAtom.AGGREGATEFUNCTION visitAggregate_function(ASPCore2Parser.Aggregate_functionContext ctx) { + // aggregate_function : AGGREGATE_COUNT | AGGREGATE_MAX | AGGREGATE_MIN | AGGREGATE_SUM; + if (ctx.AGGREGATE_COUNT() != null) { + return AggregateAtom.AGGREGATEFUNCTION.COUNT; + } else if (ctx.AGGREGATE_MAX() != null) { + return AggregateAtom.AGGREGATEFUNCTION.MAX; + } else if (ctx.AGGREGATE_MIN() != null) { + return AggregateAtom.AGGREGATEFUNCTION.MIN; + } else if (ctx.AGGREGATE_SUM() != null) { + return AggregateAtom.AGGREGATEFUNCTION.SUM; + } else { + throw notSupported(ctx); + } + } + + @Override + public ComparisonOperator visitBinop(ASPCore2Parser.BinopContext ctx) { + // binop : EQUAL | UNEQUAL | LESS | GREATER | LESS_OR_EQ | GREATER_OR_EQ; + if (ctx.EQUAL() != null) { + return ComparisonOperator.EQ; + } else if (ctx.UNEQUAL() != null) { + return ComparisonOperator.NE; + } else if (ctx.LESS() != null) { + return ComparisonOperator.LT; + } else if (ctx.LESS_OR_EQ() != null) { + return ComparisonOperator.LE; + } else if (ctx.GREATER() != null) { + return ComparisonOperator.GT; + } else if (ctx.GREATER_OR_EQ() != null) { + return ComparisonOperator.GE; + } else { + throw notSupported(ctx); + } + } + + @Override + public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { + // builtin_atom : term binop term; + return new ComparisonAtom( + (CoreTerm) visit(ctx.term(0)), + (CoreTerm) visit(ctx.term(1)), + visitBinop(ctx.binop()) + ); + } + + @Override + public CoreLiteral visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { + // naf_literal : NAF? (external_atom | classical_literal | builtin_atom); + boolean isCurrentLiteralNegated = ctx.NAF() != null; + if (ctx.builtin_atom() != null) { + return new ComparisonLiteral(visitBuiltin_atom(ctx.builtin_atom()), !isCurrentLiteralNegated); + } else if (ctx.classical_literal() != null) { + return new BasicLiteral(visitClassical_literal(ctx.classical_literal()), !isCurrentLiteralNegated); + } else if (ctx.external_atom() != null) { + return new ExternalLiteral(visitExternal_atom(ctx.external_atom()), !isCurrentLiteralNegated); + } + throw notSupported(ctx); + } + + @Override + public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext ctx) { + // classical_literal : MINUS? ID (PAREN_OPEN terms PAREN_CLOSE)?; + if (ctx.MINUS() != null) { + throw notSupported(ctx); + } + + final List terms = visitTerms(ctx.terms()); + return new BasicAtom(CorePredicate.getInstance(ctx.ID().getText(), terms.size()), terms); + } + + @Override + public List visitTerms(ASPCore2Parser.TermsContext ctx) { + // terms : term (COMMA terms)?; + if (ctx == null) { + return emptyList(); + } + + final List terms = new ArrayList<>(); + do { + ASPCore2Parser.TermContext term = ctx.term(); + terms.add((CoreTerm) visit(term)); + } while ((ctx = ctx.terms()) != null); + + return terms; + } + + @Override + public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { + return CoreConstantTerm.getInstance(Integer.parseInt(ctx.NUMBER().getText())); + } + + @Override + public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { + return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); + } + + @Override + public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { + String quotedString = ctx.QUOTED_STRING().getText().replace("\\\"", "\""); + return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); + } + + @Override + public FunctionTerm visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { + return FunctionTerm.getInstance(ctx.ID().getText(), visitTerms(ctx.terms())); + } + + @Override + public VariableTerm visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx) { + if (!acceptVariables) { + throw notSupported(ctx); + } + + return VariableTerm.getAnonymousInstance(); + } + + @Override + public VariableTerm visitTerm_variable(ASPCore2Parser.Term_variableContext ctx) { + if (!acceptVariables) { + throw notSupported(ctx); + } + + return VariableTerm.getInstance(ctx.VARIABLE().getText()); + } + + @Override + public Term visitTerm_parenthesisedTerm(ASPCore2Parser.Term_parenthesisedTermContext ctx) { + return (Term) visit(ctx.term()); + } + + @Override + public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) { + // external_atom : AMPERSAND ID (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; + + if (ctx.MINUS() != null) { + throw notSupported(ctx); + } + + final String predicateName = ctx.ID().getText(); + final PredicateInterpretation interpretation = externals.get(predicateName); + + if (interpretation == null) { + throw new IllegalArgumentException("Unknown interpretation name encountered: " + predicateName); + } + + List outputTerms = visitTerms(ctx.output); + + return new ExternalAtom( + CorePredicate.getInstance(predicateName, outputTerms.size()), + interpretation, + visitTerms(ctx.input), + outputTerms + ); + } + + @Override + public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) { + // interval : lower = (NUMBER | VARIABLE) DOT DOT upper = (NUMBER | VARIABLE); + ASPCore2Parser.IntervalContext ictx = ctx.interval(); + String lowerText = ictx.lower.getText(); + String upperText = ictx.upper.getText(); + CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) : VariableTerm.getInstance(lowerText); + CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) : VariableTerm.getInstance(upperText); + return IntervalTerm.getInstance(lower, upper); + } + + @Override + public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { + // | MINUS term + return ArithmeticTerm.MinusTerm.getInstance((CoreTerm) visit(ctx.term())); + } + + @Override + public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { + // | term (TIMES | DIV | MODULO) term + ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES + : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); + } + + @Override + public Object visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { + // | term (PLUS | MINUS) term + ArithmeticTerm.ArithmeticOperator op = ctx.PLUS() != null ? ArithmeticTerm.ArithmeticOperator.PLUS : ArithmeticTerm.ArithmeticOperator.MINUS; + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); + } + + @Override + public Object visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { + // | term POWER term + ArithmeticTerm.ArithmeticOperator op = ArithmeticTerm.ArithmeticOperator.POWER; + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); + } + + @Override + public Object visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { + // | term BITXOR term + return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (CoreTerm) visit(ctx.term(1))); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java new file mode 100644 index 000000000..7bea8f5a2 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java @@ -0,0 +1,111 @@ +package at.ac.tuwien.kr.alpha.grounder.parser; + +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.DefaultErrorStrategy; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.atn.PredictionMode; +import org.antlr.v4.runtime.misc.ParseCancellationException; + +import java.io.IOException; +import java.util.Collections; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.CustomErrorListener; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; + +public class ProgramParser { + private final Map externals; + + public ProgramParser(Map externals) { + this.externals = externals; + } + + public ProgramParser() { + this(Collections.emptyMap()); + } + + public InputProgram parse(String s) { + try { + return parse(CharStreams.fromString(s)); + } catch (IOException e) { + // In this case we assume that something went fundamentally + // wrong when using a String as input. The caller probably + // assumes that I/O on a String should always be fine. + throw new RuntimeException("Encountered I/O-related exception while parsing a String.", e); + } 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 input program.", e); + } + } + + public InputProgram parse(CharStream stream) throws IOException { + //@formatter:off + /* + * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. + * ASPCore2Lexer lexer = new ASPCore2Lexer(new UnbufferedCharStream(is)); + * lexer.setTokenFactory(new CommonTokenFactory(true)); + * final ASPCore2Parser parser = new ASPCore2Parser(new UnbufferedTokenStream<>(lexer)); + * parser.setBuildParseTree(false); + */ + //@formatter:on + CommonTokenStream tokens = new CommonTokenStream(new ASPCore2Lexer(stream)); + final ASPCore2Parser parser = new ASPCore2Parser(tokens); + + // Try SLL parsing mode (faster but may terminate incorrectly). + parser.getInterpreter().setPredictionMode(PredictionMode.SLL); + parser.removeErrorListeners(); + parser.setErrorHandler(new BailErrorStrategy()); + + final CustomErrorListener errorListener = new CustomErrorListener(stream.getSourceName()); + + ASPCore2Parser.ProgramContext programContext; + try { + // Parse program + programContext = parser.program(); + } catch (ParseCancellationException e) { + // Recognition exception may be caused simply by SLL parsing failing, + // retry with LL parser and DefaultErrorStrategy printing errors to console. + if (e.getCause() instanceof RecognitionException) { + tokens.seek(0); + parser.addErrorListener(errorListener); + parser.setErrorHandler(new DefaultErrorStrategy()); + parser.getInterpreter().setPredictionMode(PredictionMode.LL); + // Re-run parse. + programContext = parser.program(); + } else { + throw e; + } + } + + // If the our SwallowingErrorListener has handled some exception during parsing + // just re-throw that exception. + // At this time, error messages will be already printed out to standard error + // because ANTLR by default adds an org.antlr.v4.runtime.ConsoleErrorListener + // to every parser. + // That ConsoleErrorListener will print useful messages, but not report back to + // our code. + // org.antlr.v4.runtime.BailErrorStrategy cannot be used here, because it would + // abruptly stop parsing as soon as the first error is reached (i.e. no recovery + // is attempted) and the user will only see the first error encountered. + if (errorListener.getRecognitionException() != null) { + throw errorListener.getRecognitionException(); + } + + // Abort parsing if there were some (recoverable) syntax errors. + if (parser.getNumberOfSyntaxErrors() != 0) { + throw new ParseCancellationException(); + } + + // Construct internal program representation. + ParseTreeVisitor visitor = new ParseTreeVisitor(externals); + return visitor.translate(programContext); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java new file mode 100644 index 000000000..a7cc0f152 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java @@ -0,0 +1,80 @@ +/* + * 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.grounder.parser; + +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.misc.ParseCancellationException; + +import java.util.Collections; + +/** + * A parser that, in contrast to {@link ProgramParser}, 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); + + public CoreTerm parseTerm(String s) { + final ASPCore2Parser parser = getASPCore2Parser(s); + return (CoreTerm)parse(parser.term()); + } + + public BasicAtom parseBasicAtom(String s) { + final ASPCore2Parser parser = getASPCore2Parser(s); + return (BasicAtom)parse(parser.classical_literal()); + } + + public Literal parseLiteral(String s) { + final ASPCore2Parser parser = getASPCore2Parser(s); + return (Literal)parse(parser.naf_literal()); + } + + private ASPCore2Parser getASPCore2Parser(String s) { + return new ASPCore2Parser(new CommonTokenStream(new ASPCore2Lexer(CharStreams.fromString(s)))); + } + + private Object parse(ParserRuleContext context) { + try { + return visitor.visit(context); + } 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 term.", e); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java new file mode 100644 index 000000000..983f771ed --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java @@ -0,0 +1,7 @@ +package at.ac.tuwien.kr.alpha.grounder.rete; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public class TupleIndex { +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java new file mode 100644 index 000000000..798ad4db0 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java @@ -0,0 +1,10 @@ +package at.ac.tuwien.kr.alpha.grounder.rete; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public class TupleStore { + + int arity; + TupleIndex[] tupleIndex; +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java new file mode 100644 index 000000000..52be979bb --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java @@ -0,0 +1,409 @@ +package at.ac.tuwien.kr.alpha.grounder.structure; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Instance; +import at.ac.tuwien.kr.alpha.grounder.Unification; +import at.ac.tuwien.kr.alpha.grounder.Unifier; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +/** + * Copyright (c) 2018-2020, the Alpha Team. + */ +public class AnalyzeUnjustified { + private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeUnjustified.class); + private final InternalProgram programAnalysis; + private final AtomStore atomStore; + private final Map> factsFromProgram; + private int renamingCounter; + private int padDepth; + + public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { + this.programAnalysis = programAnalysis; + this.atomStore = atomStore; + this.factsFromProgram = factsFromProgram; + padDepth = 0; + } + + private Map> assignedAtoms; + + public Set analyze(int atomToJustify, Assignment currentAssignment) { + padDepth = 0; + CoreAtom atom = atomStore.get(atomToJustify); + if (!(atom instanceof BasicAtom)) { + throw oops("Starting atom must be a BasicAtom, but received: " + atom + " of type: " + atom.getClass()); + } + //@formatter:off + // Calling code must make sure it is a BasicAtom and take precautions. + // Potential solutions: + // If atom instanceof RuleAtom and atom is MBT, then the corresponding rule body has a BasicAtom that is MBT. + // If atom instanceof ChoiceAtom and atom is MBT, then the corresponding rule body has a BasicAtom that is MBT. + // If atom instanceof RuleAtom and atom is FALSE, then this comes from a violated constraint in the end and the corresponding rule body can be taken as the single rule deriving the RuleAtom. + //@formatter:on + assignedAtoms = new LinkedHashMap<>(); + for (int i = 1; i <= atomStore.getMaxAtomId(); i++) { + ThriceTruth truth = currentAssignment.getTruth(i); + if (truth == null) { + continue; + } + CoreAtom assignedAtom = atomStore.get(i); + assignedAtoms.putIfAbsent(assignedAtom.getPredicate(), new ArrayList<>()); + assignedAtoms.get(assignedAtom.getPredicate()).add(assignedAtom); + } + return analyze((BasicAtom) atom, currentAssignment); + } + + private Set analyze(BasicAtom atom, Assignment currentAssignment) { + log(pad("Starting analyze, current assignment is: {}"), currentAssignment); + LinkedHashSet vL = new LinkedHashSet<>(); + LinkedHashSet vToDo = new LinkedHashSet<>(Collections.singleton(new LitSet(atom, new LinkedHashSet<>()))); + LinkedHashSet vDone = new LinkedHashSet<>(); + while (!vToDo.isEmpty()) { + Iterator it = vToDo.iterator(); + LitSet x = it.next(); + it.remove(); + log(""); + log("Treating now: {}", x); + vDone.add(x); + ReturnExplainUnjust unjustRet = explainUnjust(x, currentAssignment); + log("Additional ToDo: {}", unjustRet.vToDo); + // Check each new LitSet if it does not already occur as done. + for (LitSet todoLitSet : unjustRet.vToDo) { + if (!vDone.contains(todoLitSet)) { + vToDo.add(todoLitSet); + } + } + vL.addAll(unjustRet.vL); + } + return vL; + } + + private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment) { + padDepth += 2; + log("Begin explainUnjust(): {}", x); + CoreAtom p = x.getAtom(); + + ReturnExplainUnjust ret = new ReturnExplainUnjust(); + + // Construct set of all 'rules' such that head unifies with p. + List rulesUnifyingWithP = rulesHeadUnifyingWith(p); + log("Rules unifying with {} are {}", p, rulesUnifyingWithP); + rulesLoop: + for (RuleAndUnifier ruleUnifier : rulesUnifyingWithP) { + Unifier sigma = ruleUnifier.unifier; + Set bodyR = ruleUnifier.ruleBody; + CoreAtom sigmaHr = ruleUnifier.originalHead.substitute(sigma); + log("Considering now: {}", ruleUnifier); + Set vN = new LinkedHashSet<>(x.getComplementSubstitutions()); + for (Unifier sigmaN : vN) { + if (Unification.instantiate(p.substitute(sigmaN), sigmaHr) != null) { + log("Unifier is excluded by: {}", sigmaN); + continue rulesLoop; + } + } + Set vNp = new LinkedHashSet<>(); + for (Unifier substitution : vN) { + Unifier merged = Unifier.mergeIntoLeft(substitution, sigma); + // Ignore inconsistent merges. + if (merged == null) { + continue; + } + vNp.add(merged); + } + log("Adapting N to N'. Original N is {}", vN); + log("Adapted N' is {}", vNp); + log("Searching for falsified negated literals in the body: {}", bodyR); + for (CoreLiteral lit : bodyR) { + if (!lit.isNegated()) { + continue; + } + CoreAtom lb = lit.getAtom().substitute(sigma); + log("Found: {}, searching falsifying ground instances of {} (with unifier from the head) now.", lit, lb); + AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(lb.getPredicate()); + while (assignedAtomsOverPredicate.hasNext()) { + CoreAtom lg = assignedAtomsOverPredicate.next(); + log("Considering: {}", lg); + if (atomStore.contains(lg)) { + int atomId = atomStore.get(lg); + if (!currentAssignment.getTruth(atomId).toBoolean()) { + log("{} is not assigned TRUE or MBT. Skipping.", lg); + continue; + } + } // Note: in case the atom is not in the atomStore, it came from a fact and hence is true. + log("{} is TRUE or MBT.", lg); + Unifier sigmagb = Unification.unifyAtoms(lg, lb); + if (sigmagb == null) { + log("{} does not unify with {}", lg, lb); + continue; + } + log("Checking if {} is already covered.", lb); + boolean isCovered = false; + for (Unifier sigmaN : vN) { + if (Unification.instantiate(p.substitute(sigmaN), sigmaHr.substitute(sigmagb)) != null) { + log("{} is already covered by {}", lb, sigmaN); + isCovered = true; + break; + } + } + if (!isCovered) { + Unifier sigmacirc = new Unifier(sigma).extendWith(sigmagb); + vNp.add(sigmacirc); + log("Literal {} is not excluded and falsifies body literal {}", lg, lit); + ret.vL.add(lg.toLiteral()); + log("Reasons extended by: {}", lg); + } + } + + } + List bodyPos = new ArrayList<>(); + for (CoreLiteral literal : bodyR) { + if (!literal.isNegated()) { + bodyPos.add(literal); + } + } + log("Calling UnjustCover() for positive body."); + ret.vToDo.addAll(unjustCover(bodyPos, Collections.singleton(sigma), vNp, currentAssignment)); + } + log("End explainUnjust()."); + padDepth -= 2; + return ret; + } + + private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { + padDepth += 2; + log("Begin UnjustCoverFixed()"); + log("Finding unjustified body literals in: {} / {} excluded {}", vB, vY, vN); + Set ret = new LinkedHashSet<>(); + if (vB.isEmpty() || vY.isEmpty()) { + log("End unjustCover()."); + padDepth -= 2; + return Collections.emptySet(); + } + int chosenLiteralPos = 0; + // Find a body literal that is not a ComparisonLiteral, because these do not generate/have atoms assigned. + for (int i = 0; i < vB.size(); i++) { + if (!(vB.get(i) instanceof ComparisonLiteral)) { + chosenLiteralPos = i; + break; + } + } + CoreAtom b = vB.get(chosenLiteralPos).getAtom(); + log("Picked literal from body is: {}", b); + for (Unifier sigmaY : vY) { + CoreAtom bSigmaY = b.substitute(sigmaY); + log("Treating substitution for: {}", bSigmaY); + Set vYp = new LinkedHashSet<>(); + + log("Checking atoms over predicate: {}", b.getPredicate()); + AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(b.getPredicate()); + atomLoop: + while (assignedAtomsOverPredicate.hasNext()) { + CoreAtom atom = assignedAtomsOverPredicate.next(); + // Check that atom is justified/true. + log("Checking atom: {}", atom); + if (atomStore.contains(atom)) { + int atomId = atomStore.get(atom); + if (currentAssignment.getTruth(atomId) != ThriceTruth.TRUE) { + log("Atom is not TRUE. Skipping."); + continue; + } + } // Note: in case the atom is not in the atomStore, it came from a fact and hence is true. + Unifier sigma = Unification.instantiate(b, atom); + if (sigma == null) { + log("Atom does not unify with picked body literal."); + continue; + } + + CoreAtom bSigma = b.substitute(sigma); + if (!bSigma.isGround()) { + throw oops("Resulting atom is not ground."); + } + Set variablesOccurringInSigma = sigma.getMappedVariables(); + if (Unification.instantiate(bSigmaY, bSigma) != null) { + for (Unifier sigmaN : vN) { + ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); + occurringVariables.addAll(sigmaN.getMappedVariables()); + BasicAtom genericAtom = new BasicAtom(CorePredicate.getInstance("_", occurringVariables.size(), true), occurringVariables); + CoreAtom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); + if (Unification.instantiate(genericSubstituted, genericAtom.substitute(sigma)) != null) { + log("Atom {} is excluded by: {} via {}", genericSubstituted, sigmaN, sigma); + continue atomLoop; + } + } + log("Adding corresponding substitution to Y': {}", sigma); + vYp.add(sigma); + } + } + + log("Unjustified body literals: {}", vYp); + + Set vYpUN = new LinkedHashSet<>(); + vYpUN.addAll(vYp); + vYpUN.addAll(vN); + LitSet toJustify = new LitSet(bSigmaY, vYpUN); + if (!toJustify.coversNothing()) { + log("New litset to do: {}", toJustify); + ret.add(toJustify); + } else { + log("Generated LitSet covers nothing. Ignoring: {}", toJustify); + } + ArrayList newB = new ArrayList<>(vB); + newB.remove(chosenLiteralPos); + ret.addAll(unjustCover(newB, vYp, vN, currentAssignment)); + log("Literal set(s) to treat: {}", ret); + } + log("End unjustCover()."); + padDepth -= 2; + return ret; + } + + private String pad(String string) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < padDepth; i++) { + sb.append(" "); + } + sb.append(string); + return sb.toString(); + } + + private AssignedAtomsIterator getAssignedAtomsOverPredicate(CorePredicate predicate) { + // Find more substitutions, consider currentAssignment. + List assignedAtoms = this.assignedAtoms.get(predicate); + // Consider instances from facts. + LinkedHashSet factsOverPredicate = factsFromProgram.get(predicate); + return new AssignedAtomsIterator(predicate, assignedAtoms, factsOverPredicate); + } + + private static class AssignedAtomsIterator implements Iterator { + private final CorePredicate predicate; + private final Iterator assignedAtomsIterator; + private final Iterator factsIterator; + + public AssignedAtomsIterator(CorePredicate predicate, List assignedAtoms, Set facts) { + this.predicate = predicate; + this.assignedAtomsIterator = assignedAtoms == null ? Collections.emptyIterator() : assignedAtoms.iterator(); + this.factsIterator = facts == null ? Collections.emptyIterator() : facts.iterator(); + } + + @Override + public boolean hasNext() { + return assignedAtomsIterator.hasNext() || factsIterator.hasNext(); + } + + @Override + public CoreAtom next() { + if (assignedAtomsIterator.hasNext()) { + return assignedAtomsIterator.next(); + } + if (factsIterator.hasNext()) { + return new BasicAtom(predicate, factsIterator.next().terms); + } + throw new NoSuchElementException(); + } + } + + private List rulesHeadUnifyingWith(CoreAtom p) { + + List rulesWithUnifier = new ArrayList<>(); + CorePredicate predicate = p.getPredicate(); + + ArrayList definingRulesAndFacts = new ArrayList<>(); + // Get facts over the same predicate. + LinkedHashSet factInstances = factsFromProgram.get(predicate); + if (factInstances != null) { + for (Instance factInstance : factInstances) { + definingRulesAndFacts.add(new FactOrNonGroundRule(factInstance)); + } + } + + HashSet rulesDefiningPredicate = programAnalysis.getPredicateDefiningRules().get(predicate); + if (rulesDefiningPredicate != null) { + for (InternalRule nonGroundRule : rulesDefiningPredicate) { + definingRulesAndFacts.add(new FactOrNonGroundRule(nonGroundRule)); + } + } + for (FactOrNonGroundRule factOrNonGroundRule : definingRulesAndFacts) { + boolean isNonGroundRule = factOrNonGroundRule.nonGroundRule != null; + Set renamedBody; + CoreAtom headAtom; + if (isNonGroundRule) { + // First rename all variables in the rule. + InternalRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++); + renamedBody = rule.getBody(); + headAtom = rule.getHeadAtom(); + } else { + // Create atom and empty rule body out of instance. + headAtom = new BasicAtom(p.getPredicate(), factOrNonGroundRule.factInstance.terms); + renamedBody = Collections.emptySet(); + } + // Unify rule head with literal to justify. + Unifier unifier = Unification.unifyAtoms(p, headAtom); + // Note: maybe it is faster to first check unification and only rename the whole rule afterwards? + // Skip if unification failed. + if (unifier == null) { + continue; + } + rulesWithUnifier.add(new RuleAndUnifier(renamedBody, unifier, headAtom)); + } + return rulesWithUnifier; + } + + private void log(String msg, Object... refs) { + LOGGER.trace(pad(msg), refs); + } + + private static class ReturnExplainUnjust { + Set vL; + Set vToDo; + + ReturnExplainUnjust() { + vL = new LinkedHashSet<>(); + vToDo = new LinkedHashSet<>(); + } + } + + private static class RuleAndUnifier { + final Set ruleBody; + final Unifier unifier; + final CoreAtom originalHead; + + private RuleAndUnifier(Set ruleBody, Unifier unifier, CoreAtom originalHead) { + this.ruleBody = ruleBody; + this.unifier = unifier; + this.originalHead = originalHead; + } + + @Override + public String toString() { + return unifier + "@" + originalHead + " :- " + ruleBody; + } + } + + private static class FactOrNonGroundRule { + final Instance factInstance; + final InternalRule nonGroundRule; + + private FactOrNonGroundRule(Instance factInstance) { + this.factInstance = factInstance; + this.nonGroundRule = null; + } + + private FactOrNonGroundRule(InternalRule nonGroundRule) { + this.nonGroundRule = nonGroundRule; + this.factInstance = null; + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java new file mode 100644 index 000000000..e599f42b8 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java @@ -0,0 +1,143 @@ +package at.ac.tuwien.kr.alpha.grounder.structure; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; +import at.ac.tuwien.kr.alpha.grounder.Unification; +import at.ac.tuwien.kr.alpha.grounder.Unifier; + +/** + * Copyright (c) 2018, the Alpha Team. + */ +public class LitSet { + private final CoreAtom atom; + private final Set complementSubstitutions; + private final int hashCode; + private final CoreAtom normalizedLiteral; + private final Set normalizedSubstitutions; + private static int litSetCounter = 1; + + LitSet(CoreAtom atom, Set complementSubstitutions) { + this.atom = atom.renameVariables("_AS" + litSetCounter++); + this.complementSubstitutions = new HashSet<>(); + for (Unifier complementSubstitution : complementSubstitutions) { + if (complementSubstitution == null) { + throw oops("Unifier is null."); + } + Unifier unifyRightAtom = normalizeSubstitution(atom, complementSubstitution, this.atom); + if (unifyRightAtom == null) { + throw oops("Unification result is null."); + } + this.complementSubstitutions.add(unifyRightAtom); + } + this.normalizedLiteral = computeNormalized(this.atom, "_N"); + this.normalizedSubstitutions = computeNormalizedSubstitutions(); + this.hashCode = computeHashCode(); + } + + /** + * Normalizes a substitution over the originalAtom into a substitution over the normalizedAtom. + * @param originalAtom + * @param substitution + * @param normalizedAtom + * @return + */ + private Unifier normalizeSubstitution(CoreAtom originalAtom, Unifier substitution, CoreAtom normalizedAtom) { + CoreAtom substitutedLiteral = originalAtom.substitute(substitution); + return Unification.instantiate(normalizedAtom, substitutedLiteral); + } + + /** + * Checks if the complementSubstitutions exclude everything. + * @return true if this LitSet represents the empty set (i.e., everything excluded). + */ + public boolean coversNothing() { + for (Unifier substitution : complementSubstitutions) { + if (Unification.instantiate(atom.substitute(substitution), atom) != null) { + return true; + } + } + return false; + } + + public CoreAtom getAtom() { + return atom; + } + + Set getComplementSubstitutions() { + return Collections.unmodifiableSet(complementSubstitutions); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("(" + atom + ",{"); + for (Unifier complementSubstitution : complementSubstitutions) { + sb.append(atom.substitute(complementSubstitution)); + sb.append(", "); + } + sb.append("})"); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + LitSet litSet = (LitSet) o; + + if (hashCode() != o.hashCode()) { + return false; + } + + if (!normalizedLiteral.equals(litSet.normalizedLiteral)) { + return false; + } + + return normalizedSubstitutions.equals(litSet.normalizedSubstitutions); + } + + @Override + public int hashCode() { + return hashCode; + } + + private int computeHashCode() { + int result = normalizedLiteral.hashCode(); + result = 31 * result + normalizedSubstitutions.hashCode(); + return result; + } + + private CoreAtom computeNormalized(CoreAtom atom, String prefix) { + if (atom instanceof VariableNormalizableAtom) { + return ((VariableNormalizableAtom) atom).normalizeVariables(prefix, 0); + } else { + throw oops("Atom to normalize is of unknown type: " + atom); + } + } + + private Set computeNormalizedSubstitutions() { + Set ret = new LinkedHashSet<>(); + for (Unifier substitution : complementSubstitutions) { + Unifier preNormalizedSubstitution = normalizeSubstitution(atom, substitution, normalizedLiteral); + // Unifier may still contain variables in the right-hand side, those have to be normalized, too. + CoreAtom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); + // Apply substitution and normalize all remaining variables, i.e., those appearing at the right-hand side of the substitution. + CoreAtom normalized = computeNormalized(appliedSub, "_X"); + // Compute final substitution from normalized atom to the one where also variables are normalized. + Unifier normalizedSubstitution = new Unifier(Unification.instantiate(normalizedLiteral, normalized)); + ret.add(normalizedSubstitution); + } + return ret; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java new file mode 100644 index 000000000..5ff468496 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java @@ -0,0 +1,259 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.grounder.Unifier; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; + +/** + * Copyright (c) 2017-2020, the Alpha Team. + */ +public class CardinalityNormalization extends ProgramTransformation { + + private int aggregateCount; + private ProgramParser parser = new ProgramParser(); + private final boolean useSortingCircuitEncoding; + + public CardinalityNormalization() { + this(true); + } + + public CardinalityNormalization(boolean useSortingCircuitEncoding) { + this.useSortingCircuitEncoding = useSortingCircuitEncoding; + } + + private InputProgram parse(String program) { + return parser.parse(program); + } + + @Override + public InputProgram apply(InputProgram inputProgram) { + if (!this.rewritingNecessary(inputProgram)) { + return inputProgram; + } + InputProgram.Builder programBuilder = InputProgram.builder(); + programBuilder.addFacts(inputProgram.getFacts()); + programBuilder.addInlineDirectives(inputProgram.getInlineDirectives()); + //@formatter:off + String cardinalityCountingGrid = + "span(R,1..I1) :- I1 = I-1, sorting_network_input_number(R,I).\n" + + "sum(R,0,0) :- sorting_network_input_number(R,_).\n" + + "sum(R,I,S) :- sum(R,I1,S), I1 = I-1, span(R,I).\n" + + "sum(R,I,S1) :- sum(R,I1,S),S1 = S+1, I1 = I-1, sorting_network_input_number(R,I),\n" + + " sorting_network_bound(R,K), S < K.\n" + + "sorting_network_output(R,K) :- sorting_network_bound(R,K), K <= S, sum(R,_,S).\n"; + + // Transforms all cardinality-aggregates into normal logic rules employing a lazy-grounded sorting circuit. + String phi = "N = (I - 1) / S - ((I - 1) / S / B) * B, S = 2 ** (P - L), B = 2 ** L"; + String cardinalitySortingCircuit = + "sorting_network_span(R,I) :- sorting_network_input_number(R,I).\n" + + "sorting_network_span(R,Im1) :- sorting_network_span(R,I), 1 rewrittenRules = rewriteAggregates(inputProgram.getRules()); + + String usedCardinalityEncoding = useSortingCircuitEncoding ? cardinalitySortingCircuit : cardinalityCountingGrid; + InputProgram cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParser().parse(usedCardinalityEncoding)); + programBuilder.addRules(rewrittenRules); + + // Add enumeration rule that uses the special EnumerationAtom. + // The enumeration rule is: "sorting_network_input_number(A, I) :- sorting_network_input(A, X), + // sorting_network_index(A, X, I)." + BasicRule tmpEnumRule = PredicateInternalizer.makePredicatesInternal(parse( + "sorting_network_input_number(A, I) :- sorting_network_input(A, X).")).getRules().get(0); + EnumerationAtom enumerationAtom = new EnumerationAtom(parse("sorting_network_index(A, X, I).").getFacts().get(0).getTerms()); + List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); + enumerationRuleBody.add(enumerationAtom.toLiteral()); + BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); + programBuilder.addRule(enumerationRule); + + // Add cardinality encoding to program. + programBuilder.accumulate(cardinalityEncoding); + return programBuilder.build(); + } + + /** + * Checks if rewriting of count aggregates is necessary for the given program, i.e. if such aggregates exist. + * + * @param program the program. + * @return true if count aggregates occur, false otherwise. + */ + private boolean rewritingNecessary(InputProgram program) { + for (BasicRule rule : program.getRules()) { + for (CoreLiteral lit : rule.getBody()) { + if (lit instanceof AggregateLiteral) { + AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); + if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.COUNT) { + return true; + } + } + } + } + return false; + } + + private List rewriteAggregates(List srcRules) { + List retVal = new ArrayList<>(); + for (BasicRule rule : srcRules) { + retVal.addAll(rewriteAggregatesInRule(rule)); + } + return retVal; + } + + private List rewriteAggregatesInRule(BasicRule rule) { + // Example rewriting/connection: + // num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K). + // is rewritten into: + // num(K) :- sorting_network_output(aggregate_arguments(-731776545), K), dom(K). + // sorting_network_input(aggregate_arguments(-731776545), element_tuple(X, Y, Z)) :- p(X, Y, Z). + // sorting_network_bound(aggregate_arguments(-731776545), K) :- dom(K). + + // Create interface atoms to the aggregate encoding. + final BasicAtom aggregateOutputAtom = (BasicAtom) PredicateInternalizer + .makePredicatesInternal(parse("sorting_network_output(aggregate_arguments(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); + final BasicAtom aggregateInputAtom = (BasicAtom) PredicateInternalizer + .makePredicatesInternal(parse("sorting_network_input(aggregate_arguments(AGGREGATE_ID), ELEMENT_TUPLE).")).getFacts().get(0); + final BasicAtom lowerBoundAtom = (BasicAtom) PredicateInternalizer + .makePredicatesInternal(parse("sorting_network_bound(aggregate_arguments(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); + + ArrayList aggregateOutputAtoms = new ArrayList<>(); + int aggregatesInRule = 0; // Only needed for limited rewriting. + ArrayList additionalRules = new ArrayList<>(); + + List rewrittenBody = new ArrayList<>(rule.getBody()); + + for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { + CoreLiteral bodyElement = iterator.next(); + // Skip non-aggregates. + if (!(bodyElement instanceof AggregateLiteral)) { + continue; + } + AggregateLiteral aggregateLiteral = (AggregateLiteral) bodyElement; + AggregateAtom aggregateAtom = aggregateLiteral.getAtom(); + + // Check that aggregate is limited to what we currently can deal with. + if (aggregateLiteral.isNegated() || aggregateAtom.getUpperBoundOperator() != null + || (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.COUNT + && aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.SUM) + || aggregatesInRule++ > 0) { + throw new UnsupportedOperationException( + "Only limited #count/#sum aggregates without upper bound are currently supported." + "No rule may have more than one aggregate."); + } + + // Only treat count aggregates. + if (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.COUNT) { + continue; + } + // Remove aggregate from rule body. + iterator.remove(); + + // Prepare aggregate parameters. + aggregateCount++; + Substitution aggregateSubstitution = new Unifier(); + Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); + if (globalVariables.isEmpty()) { + aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); + } else { + // In case some variables are not local to the aggregate, add them to the aggregate identifier + ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); + globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); + aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); + } + aggregateSubstitution.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); + + // Create new output atom for addition to rule body instead of the aggregate. + aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateSubstitution).toLiteral()); + + // Create input to sorting network from aggregate elements. + for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { + // Prepare element substitution. + List elementTerms = aggregateElement.getElementTerms(); + FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); + Substitution elementSubstitution = new Unifier(aggregateSubstitution); + elementSubstitution.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); + + // Create new rule for input. + BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementSubstitution); + List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); + + // If there are global variables used inside the aggregate, add original rule body + // (minus the aggregate itself) to input rule. + if (!globalVariables.isEmpty()) { + elementLiterals.addAll(rewrittenBody); + } + BasicRule inputRule = new BasicRule(new NormalHead(inputHeadAtom), elementLiterals); + additionalRules.add(inputRule); + } + + // Create lower bound for the aggregate. + BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateSubstitution); + List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. + additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); + + } + rewrittenBody.addAll(aggregateOutputAtoms); + BasicRule rewrittenSrcRule = new BasicRule(rule.getHead(), rewrittenBody); + additionalRules.add(rewrittenSrcRule); + return additionalRules; + } + + static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { + // Hacky way to get all global variables: take all variables inside the aggregate that occur also in the + // rest of the rule. + HashSet occurringVariables = new LinkedHashSet<>(); + for (CoreLiteral element : ruleBody) { + if (element instanceof AggregateLiteral) { + continue; + } + occurringVariables.addAll(element.getBindingVariables()); + occurringVariables.addAll(element.getNonBindingVariables()); + } + LinkedHashSet globalVariables = new LinkedHashSet<>(); + for (CoreTerm aggVariable : aggregateAtom.getAggregateVariables()) { + if (occurringVariables.contains(aggVariable)) { + globalVariables.add(aggVariable); + } + } + return globalVariables; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java new file mode 100644 index 000000000..8dfe872e0 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2017-2018, 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.grounder.transformation; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; +import at.ac.tuwien.kr.alpha.common.rule.head.Head; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.*; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Copyright (c) 2017-2020, the Alpha Team. + */ +public class ChoiceHeadToNormal extends ProgramTransformation { + private final static String PREDICATE_NEGATION_PREFIX = "_n"; + + @Override + public InputProgram apply(InputProgram inputProgram) { + InputProgram.Builder programBuilder = InputProgram.builder(); + List additionalRules = new ArrayList<>(); + + List srcRules = new ArrayList<>(inputProgram.getRules()); + Iterator ruleIterator = srcRules.iterator(); + while (ruleIterator.hasNext()) { + BasicRule rule = ruleIterator.next(); + + Head ruleHead = rule.getHead(); + if (!(ruleHead instanceof ChoiceHead)) { + // Rule is constraint or without choice in the head. Leave as is. + continue; + } + + // Remove this rule, as it will be transformed. + ruleIterator.remove(); + + ChoiceHead choiceHead = (ChoiceHead) ruleHead; + // Choice rules with boundaries are not yet supported. + if (choiceHead.getLowerBound() != null || choiceHead.getUpperBound() != null) { + throw new UnsupportedOperationException("Found choice rule with bounds, which are not yet supported. Rule is: " + rule); + } + + // Only rewrite rules with a choice in their head. + for (ChoiceHead.ChoiceElement choiceElement : choiceHead.getChoiceElements()) { + // Create two guessing rules for each choiceElement. + + // Construct common body to both rules. + CoreAtom head = choiceElement.choiceAtom; + List ruleBody = new ArrayList<>(rule.getBody()); + ruleBody.addAll(choiceElement.conditionLiterals); + + if (containsIntervalTerms(head)) { + throw new RuntimeException("Program contains a choice rule with interval terms in its head. This is not supported (yet)."); + } + + // Construct head atom for the choice. + CorePredicate headPredicate = head.getPredicate(); + + CorePredicate negPredicate = CorePredicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); + List headTerms = new ArrayList<>(head.getTerms()); + headTerms.add(0, CoreConstantTerm.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for + // classical negative atoms. + CoreAtom negHead = new BasicAtom(negPredicate, headTerms); + + // Construct two guessing rules. + List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); + guessingRuleBodyWithNegHead.add(new BasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); + additionalRules.add(new BasicRule(new NormalHead(negHead), guessingRuleBodyWithNegHead)); + + List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); + guessingRuleBodyWithHead.add(new BasicAtom(negPredicate, headTerms).toLiteral(false)); + additionalRules.add(new BasicRule(new NormalHead(head), guessingRuleBodyWithHead)); + + // TODO: when cardinality constraints are possible, process the boundaries by adding a constraint with a cardinality check. + } + } + return programBuilder.addRules(srcRules).addRules(additionalRules).addFacts(inputProgram.getFacts()) + .addInlineDirectives(inputProgram.getInlineDirectives()).build(); + } + + private static boolean containsIntervalTerms(CoreAtom atom) { + for (CoreTerm term : atom.getTerms()) { + if (IntervalTerm.termContainsIntervalTerm(term)) { + return true; + } + } + return false; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java new file mode 100644 index 000000000..54b78535c --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java @@ -0,0 +1,86 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; + +/** + * Rewrites the ordinary atom whose name is given in the input program by the enumeration directive #enum_atom_is into + * the special EnumerationAtom. + * + * Copyright (c) 2017-2020, the Alpha Team. + */ +public class EnumerationRewriting extends ProgramTransformation { + + @Override + public InputProgram apply(InputProgram inputProgram) { + // Read enumeration predicate from directive. + String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectives.DIRECTIVE.enum_predicate_is); + if (enumDirective == null) { + // Directive not set, nothing to rewrite. + return inputProgram; + } + CorePredicate enumPredicate = CorePredicate.getInstance(enumDirective, 3); + + InputProgram.Builder programBuilder = InputProgram.builder().addInlineDirectives(inputProgram.getInlineDirectives()); + + checkFactsAreEnumerationFree(inputProgram.getFacts(), enumPredicate); + programBuilder.addFacts(inputProgram.getFacts()); + + List srcRules = new ArrayList<>(inputProgram.getRules()); + programBuilder.addRules(rewriteRules(srcRules, enumPredicate)); + return programBuilder.build(); + } + + private void checkFactsAreEnumerationFree(List srcFacts, CorePredicate enumPredicate) { + for (CoreAtom fact : srcFacts) { + if (fact.getPredicate().equals(enumPredicate)) { + throw oops("Atom declared as enumeration atom by directive occurs in a fact: " + fact); + } + } + } + + private List rewriteRules(List srcRules, CorePredicate enumPredicate) { + List rewrittenRules = new ArrayList<>(); + for (BasicRule rule : srcRules) { + if (rule.getHead() != null && !(rule.getHead() instanceof NormalHead)) { + throw oops("Encountered rule whose head is not normal: " + rule); + } + 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()); + Iterator rit = modifiedBodyLiterals.iterator(); + LinkedList rewrittenLiterals = new LinkedList<>(); + while (rit.hasNext()) { + CoreLiteral literal = rit.next(); + if (!(literal instanceof BasicLiteral)) { + continue; + } + BasicLiteral basicLiteral = (BasicLiteral) literal; + if (!basicLiteral.getPredicate().equals(enumPredicate)) { + continue; + } + rit.remove(); + rewrittenLiterals.add(new EnumerationAtom(basicLiteral.getAtom().getTerms()).toLiteral()); + } + modifiedBodyLiterals.addAll(rewrittenLiterals); + rewrittenRules.add(new BasicRule(rule.getHead(), modifiedBodyLiterals)); + } + return rewrittenRules; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java new file mode 100644 index 000000000..0307133cf --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2017-2018, 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.grounder.transformation; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.common.rule.NormalRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalAtom; + +/** + * Rewrites all interval terms in a rule into a new variable and an IntervalAtom. + * + * Copyright (c) 2017-2019, the Alpha Team. + */ +public class IntervalTermToIntervalAtom extends ProgramTransformation { + private static final String INTERVAL_VARIABLE_PREFIX = "_Interval"; + + /** + * Rewrites intervals into a new variable and special IntervalAtom. + * + * @return true if some interval occurs in the rule. + */ + private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { + // Collect all intervals and replace them with variables. + Map intervalReplacements = new LinkedHashMap<>(); + + List rewrittenBody = new ArrayList<>(); + + for (CoreLiteral literal : rule.getBody()) { + rewrittenBody.add(rewriteLiteral(literal, intervalReplacements)); + } + NormalHead rewrittenHead = rule.isConstraint() ? null : + new NormalHead(rewriteLiteral(rule.getHeadAtom().toLiteral(), intervalReplacements).getAtom()); + + // If intervalReplacements is empty, no IntervalTerms have been found, keep rule as is. + if (intervalReplacements.isEmpty()) { + return rule; + } + + // Add new IntervalAtoms representing the interval specifications. + for (Map.Entry interval : intervalReplacements.entrySet()) { + rewrittenBody.add(new IntervalAtom(interval.getValue(), interval.getKey()).toLiteral()); + } + return new NormalRule(rewrittenHead, rewrittenBody); + } + + /** + * Replaces every IntervalTerm by a new variable and returns a mapping of the replaced VariableTerm -> IntervalTerm. + */ + private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { + CoreAtom atom = lit.getAtom(); + List termList = new ArrayList<>(atom.getTerms()); + boolean didChange = false; + for (int i = 0; i < termList.size(); i++) { + CoreTerm term = termList.get(i); + if (term instanceof IntervalTerm) { + VariableTerm replacementVariable = VariableTerm.getInstance(INTERVAL_VARIABLE_PREFIX + intervalReplacement.size()); + intervalReplacement.put(replacementVariable, (IntervalTerm) term); + termList.set(i, replacementVariable); + didChange = true; + } + if (term instanceof FunctionTerm) { + // Rewrite function terms recursively. + FunctionTerm rewrittenFunctionTerm = rewriteFunctionTerm((FunctionTerm) term, intervalReplacement); + termList.set(i, rewrittenFunctionTerm); + didChange = true; + } + } + if (didChange) { + CoreAtom rewrittenAtom = atom.withTerms(termList); + return lit.isNegated() ? rewrittenAtom.toLiteral().negate() : rewrittenAtom.toLiteral(); + } + return lit; + } + + private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map intervalReplacement) { + List termList = new ArrayList<>(functionTerm.getTerms()); + boolean didChange = false; + for (int i = 0; i < termList.size(); i++) { + CoreTerm term = termList.get(i); + if (term instanceof IntervalTerm) { + VariableTerm replacementVariable = VariableTerm.getInstance("_Interval" + intervalReplacement.size()); + intervalReplacement.put(replacementVariable, (IntervalTerm) term); + termList.set(i, replacementVariable); + didChange = true; + } + if (term instanceof FunctionTerm) { + // Recursively rewrite function terms. + FunctionTerm rewrittenFunctionTerm = rewriteFunctionTerm((FunctionTerm) term, intervalReplacement); + if (rewrittenFunctionTerm != term) { + termList.set(i, rewrittenFunctionTerm); + didChange = true; + } + } + } + if (didChange) { + return FunctionTerm.getInstance(functionTerm.getSymbol(), termList); + } + return functionTerm; + } + + @Override + public NormalProgram apply(NormalProgram inputProgram) { + boolean didChange = false; + List rewrittenRules = new ArrayList<>(); + for (NormalRule rule : inputProgram.getRules()) { + NormalRule rewrittenRule = rewriteIntervalSpecifications(rule); + rewrittenRules.add(rewrittenRule); + + // If no rewriting occurred, the output rule is the same as the input to the rewriting. + if (rewrittenRule != rule) { + didChange = true; + } + } + // Return original program if no rule was actually rewritten. + if (!didChange) { + return inputProgram; + } + return new NormalProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java new file mode 100644 index 000000000..3d68d7e06 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java @@ -0,0 +1,42 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; + +/** + * Encapsulates all transformations necessary to transform a given program into a @{link NormalProgram} that is understood by Alpha internally + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public class NormalizeProgramTransformation extends ProgramTransformation { + + private boolean useNormalizationGrid; + + public NormalizeProgramTransformation(boolean useNormalizationGrid) { + this.useNormalizationGrid = useNormalizationGrid; + } + + @Override + public NormalProgram apply(InputProgram inputProgram) { + InputProgram tmpPrg; + // Transform choice rules. + tmpPrg = new ChoiceHeadToNormal().apply(inputProgram); + // Transform cardinality aggregates. + tmpPrg = new CardinalityNormalization(!this.useNormalizationGrid).apply(tmpPrg); + // Transform sum aggregates. + tmpPrg = new SumNormalization().apply(tmpPrg); + // Transform enumeration atoms. + tmpPrg = new EnumerationRewriting().apply(tmpPrg); + EnumerationAtom.resetEnumerations(); + + // Construct the normal program. + NormalProgram retVal = NormalProgram.fromInputProgram(tmpPrg); + // Transform intervals - CAUTION - this MUST come before VariableEqualityRemoval! + retVal = new IntervalTermToIntervalAtom().apply(retVal); + // Remove variable equalities. + retVal = new VariableEqualityRemoval().apply(retVal); + return retVal; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java new file mode 100644 index 000000000..956296bdd --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java @@ -0,0 +1,61 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import java.util.ArrayList; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.head.Head; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; + +/** + * + * Rewrites all predicates of a given Program such that they are internal and hence hidden from answer sets. + * + * Copyright (c) 2018-2020, the Alpha Team. + */ +public class PredicateInternalizer { + + static InputProgram makePredicatesInternal(InputProgram program) { + InputProgram.Builder prgBuilder = InputProgram.builder(); + for (CoreAtom atom : program.getFacts()) { + prgBuilder.addFact(PredicateInternalizer.makePredicateInternal(atom)); + } + for (BasicRule rule : program.getRules()) { + prgBuilder.addRule(PredicateInternalizer.makePredicateInternal(rule)); + } + prgBuilder.addInlineDirectives(program.getInlineDirectives()); + return prgBuilder.build(); + } + + private static BasicRule makePredicateInternal(BasicRule rule) { + Head newHead = null; + if (rule.getHead() != null) { + if (!(rule.getHead() instanceof NormalHead)) { + throw new UnsupportedOperationException("Cannot make predicates in rules internal whose head is not normal."); + } + newHead = new NormalHead(makePredicateInternal(((NormalHead) rule.getHead()).getAtom())); + } + List newBody = new ArrayList<>(); + for (CoreLiteral bodyElement : rule.getBody()) { + // Only rewrite BasicAtoms. + if (bodyElement instanceof BasicLiteral) { + newBody.add(makePredicateInternal(bodyElement.getAtom()).toLiteral()); + } else { + // Keep other body element as is. + newBody.add(bodyElement); + } + } + return new BasicRule(newHead, newBody); + } + + private static CoreAtom makePredicateInternal(CoreAtom atom) { + CorePredicate newInternalPredicate = CorePredicate.getInstance(atom.getPredicate().getName(), atom.getPredicate().getArity(), true); + return new BasicAtom(newInternalPredicate, atom.getTerms()); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java new file mode 100644 index 000000000..6aa85027c --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java @@ -0,0 +1,12 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import at.ac.tuwien.kr.alpha.common.program.AbstractProgram; + +/** + * Copyright (c) 2017-2019, the Alpha Team. + */ +public abstract class ProgramTransformation, O extends AbstractProgram> { + + public abstract O apply(I inputProgram); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java new file mode 100644 index 000000000..4c7b470ef --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java @@ -0,0 +1,369 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import org.apache.commons.collections4.SetUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; +import at.ac.tuwien.kr.alpha.common.depgraph.Node; +import at.ac.tuwien.kr.alpha.common.depgraph.StratificationAlgorithm; +import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; +import at.ac.tuwien.kr.alpha.grounder.Instance; +import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrder; +import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrders; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; +import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; +import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; +import at.ac.tuwien.kr.alpha.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy; + +/** + * Evaluates the stratifiable part of a given (analyzed) ASP program. + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public class StratifiedEvaluation extends ProgramTransformation { + + private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluation.class); + + private WorkingMemory workingMemory = new WorkingMemory(); + private Map> predicateDefiningRules; + + private Map> modifiedInLastEvaluationRun = new HashMap<>(); + + private List additionalFacts = new ArrayList<>(); // 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; + + @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) { + // Calculate a stratification and initialize the working memory. + ComponentGraph componentGraph = inputProgram.getComponentGraph(); + List strata = StratificationAlgorithm.calculateStratification(componentGraph); + predicateDefiningRules = inputProgram.getPredicateDefiningRules(); + + // Set up list of atoms which are known to be true - these will be expand by the evaluation. + Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); + for (Map.Entry> entry : knownFacts.entrySet()) { + workingMemory.initialize(entry.getKey()); + workingMemory.addInstances(entry.getKey(), true, entry.getValue()); + } + + // Create working memories for all predicates occurring in each rule. + for (InternalRule nonGroundRule : inputProgram.getRulesById().values()) { + for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { + workingMemory.initialize(predicate); + } + } + + workingMemory.reset(); + + // Set up literal instantiator. + literalInstantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); + + // Evaluate the program part covered by the calculated stratification. + for (SCComponent currComponent : strata) { + evaluateComponent(currComponent); + } + + // 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); + } + + private void evaluateComponent(SCComponent comp) { + LOGGER.debug("Evaluating component {}", comp); + ComponentEvaluationInfo evaluationInfo = getRulesToEvaluate(comp); + if (evaluationInfo.isEmpty()) { + LOGGER.debug("No rules to evaluate for component {}", comp); + return; + } + + // Rules outside of dependency cycles only need to be evaluated once. + if (!evaluationInfo.nonRecursiveRules.isEmpty()) { + prepareInitialEvaluation(evaluationInfo.nonRecursiveRules); + 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(new BasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); + } + instanceStorage.markRecentlyAddedInstancesDone(); + } + } + boolean isInitialRun = true; + if (!evaluationInfo.recursiveRules.isEmpty()) { + do { + // Now do the rules that cyclically depend on each other, + // evaluate these until nothing new can be derived any more. + if (isInitialRun) { + prepareInitialEvaluation(evaluationInfo.recursiveRules); + } + evaluateRules(evaluationInfo.recursiveRules, isInitialRun); + isInitialRun = false; + modifiedInLastEvaluationRun = new HashMap<>(); + // 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(new BasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); + } + modifiedInLastEvaluationRun.putIfAbsent(instanceStorage.getPredicate(), new LinkedHashSet<>()); + modifiedInLastEvaluationRun.get(instanceStorage.getPredicate()).addAll(instanceStorage.getRecentlyAddedInstances()); + instanceStorage.markRecentlyAddedInstancesDone(); + } + // If the evaluation of rules did not modify the working memory we have a fixed-point. + } while (!workingMemory.modified().isEmpty()); + } + LOGGER.debug("Evaluation done - reached a fixed point on component {}", comp); + SetUtils.union(evaluationInfo.nonRecursiveRules, evaluationInfo.recursiveRules) + .forEach((rule) -> solvedRuleIds.add(rule.getRuleId())); + } + + private void evaluateRules(Set rules, boolean isInitialRun) { + workingMemory.reset(); + LOGGER.debug("Starting component evaluation run..."); + for (InternalRule r : rules) { + evaluateRule(r, !isInitialRun); + } + } + + /** + * To be called at the start of evaluateComponent. Adds all known instances of the predicates occurring in the given set + * of rules to the "modifiedInLastEvaluationRun" map in order to "bootstrap" incremental grounding, i.e. making sure + * that those instances are taken into account for ground substitutions by evaluateRule. + */ + private void prepareInitialEvaluation(Set rulesToEvaluate) { + modifiedInLastEvaluationRun = new HashMap<>(); + for (InternalRule rule : rulesToEvaluate) { + // Register rule head instances. + CorePredicate headPredicate = rule.getHeadAtom().getPredicate(); + IndexedInstanceStorage headInstances = workingMemory.get(headPredicate, true); + modifiedInLastEvaluationRun.putIfAbsent(headPredicate, new LinkedHashSet<>()); + if (headInstances != null) { + modifiedInLastEvaluationRun.get(headPredicate).addAll(headInstances.getAllInstances()); + } + // Register positive body literal instances. + for (CoreLiteral lit : rule.getPositiveBody()) { + CorePredicate bodyPredicate = lit.getPredicate(); + IndexedInstanceStorage bodyInstances = workingMemory.get(bodyPredicate, true); + modifiedInLastEvaluationRun.putIfAbsent(bodyPredicate, new LinkedHashSet<>()); + if (bodyInstances != null) { + modifiedInLastEvaluationRun.get(bodyPredicate).addAll(bodyInstances.getAllInstances()); + } + } + } + } + + private void evaluateRule(InternalRule rule, boolean checkAllStartingLiterals) { + LOGGER.debug("Evaluating rule {}", rule); + List satisfyingSubstitutions = calculateSatisfyingSubstitutionsForRule(rule, checkAllStartingLiterals); + for (Substitution subst : satisfyingSubstitutions) { + fireRule(rule, subst); + } + } + + private List calculateSatisfyingSubstitutionsForRule(InternalRule rule, boolean checkAllStartingLiterals) { + LOGGER.debug("Grounding rule {}", rule); + RuleGroundingOrders groundingOrders = rule.getGroundingOrders(); + + // Treat rules with fixed instantiation first. + LOGGER.debug("Is fixed rule? {}", rule.getGroundingOrders().fixedInstantiation()); + if (groundingOrders.fixedInstantiation()) { + RuleGroundingOrder fixedGroundingOrder = groundingOrders.getFixedGroundingOrder(); + return calcSubstitutionsWithGroundingOrder(fixedGroundingOrder, Collections.singletonList(new Substitution())); + } + + List startingLiterals = groundingOrders.getStartingLiterals(); + // Check only one starting literal if indicated by the parameter. + if (!checkAllStartingLiterals) { + // If this is the first evaluation run, it suffices to start from the first starting literal only. + CoreLiteral lit = startingLiterals.get(0); + return calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), substituteFromRecentlyAddedInstances(lit)); + } + + // Ground from all starting literals. + List groundSubstitutions = new ArrayList<>(); // Collection of full ground substitutions for the given rule. + for (CoreLiteral lit : startingLiterals) { + List substitutionsForStartingLiteral = calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), + substituteFromRecentlyAddedInstances(lit)); + groundSubstitutions.addAll(substitutionsForStartingLiteral); + } + return groundSubstitutions; + } + + /** + * 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). + */ + private List substituteFromRecentlyAddedInstances(CoreLiteral lit) { + List retVal = new ArrayList<>(); + Set instances = modifiedInLastEvaluationRun.get(lit.getPredicate()); + if (instances == null) { + return Collections.emptyList(); + } + for (Instance instance : instances) { + Substitution unifyingSubstitution = Substitution.specializeSubstitution(lit, instance, Substitution.EMPTY_SUBSTITUTION); + if (unifyingSubstitution != null) { + retVal.add(unifyingSubstitution); + } + } + return retVal; + } + + private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrder groundingOrder, List startingSubstitutions) { + // Iterate through the grounding order and whenever instantiation of a Literal with a given substitution + // causes a result with a type other than CONTINUE, discard that substitution. + + // Note that this function uses a stack of partial substitutions to simulate a recursive function. + Stack> substitutionStack = new Stack<>(); // For speed, we really want ArrayLists on the stack. + if (startingSubstitutions instanceof ArrayList) { + substitutionStack.push((ArrayList) startingSubstitutions); + } else { + substitutionStack.push(new ArrayList<>(startingSubstitutions)); // Copy startingSubstitutions into ArrayList. Note: mostly happens for empty or + // singleton lists. + } + int currentOrderPosition = 0; + List fullSubstitutions = new ArrayList<>(); + while (!substitutionStack.isEmpty()) { + List currentSubstitutions = substitutionStack.peek(); + // If no more substitutions remain at current position, all have been processed, continue on next lower level. + if (currentSubstitutions.isEmpty()) { + substitutionStack.pop(); + currentOrderPosition--; + continue; + } + // In case the full grounding order has been worked on, all current substitutions are full substitutions, add them to + // result. + CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(currentOrderPosition); + if (currentLiteral == null) { + fullSubstitutions.addAll(currentSubstitutions); + currentSubstitutions.clear(); + // Continue on next lower level. + substitutionStack.pop(); + currentOrderPosition--; + continue; + } + // 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). + 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. + ArrayList furtheredSubstitutions = new ArrayList<>(); + for (ImmutablePair resultSubstitution : currentLiteralResult.getSubstitutions()) { + furtheredSubstitutions.add(resultSubstitution.left); + } + substitutionStack.push(furtheredSubstitutions); + // Continue work on the higher level. + currentOrderPosition++; + } + } + return fullSubstitutions; + } + + private void fireRule(InternalRule rule, Substitution substitution) { + CoreAtom newAtom = rule.getHeadAtom().substitute(substitution); + if (!newAtom.isGround()) { + throw new IllegalStateException("Trying to fire rule " + rule.toString() + " with incompatible substitution " + substitution.toString()); + } + LOGGER.debug("Firing rule - got head atom: {}", newAtom); + workingMemory.addInstance(newAtom, true); + } + + private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { + Set nonRecursiveRules = new HashSet<>(); + Set recursiveRules = new HashSet<>(); + + // Collect all predicates occurring in heads of rules of the given component. + Set headPredicates = new HashSet<>(); + for (Node node : comp.getNodes()) { + headPredicates.add(node.getPredicate()); + } + // Check each predicate whether its defining rules depend on some of the head predicates, i.e., whether there is a + // cycle. + for (CorePredicate headPredicate : headPredicates) { + HashSet definingRules = predicateDefiningRules.get(headPredicate); + if (definingRules == null) { + // Predicate only occurs in facts, skip. + continue; + } + // Note: here we assume that all rules defining a predicate belong to the same SC component. + for (InternalRule rule : definingRules) { + boolean isRuleRecursive = false; + for (CoreLiteral lit : rule.getPositiveBody()) { + if (headPredicates.contains(lit.getPredicate())) { + // The rule body contains a predicate that is defined in the same + // component, the rule is therefore part of a cyclic dependency within + // this component. + isRuleRecursive = true; + } + } + if (isRuleRecursive) { + recursiveRules.add(rule); + } else { + nonRecursiveRules.add(rule); + } + } + } + return new ComponentEvaluationInfo(nonRecursiveRules, recursiveRules); + } + + /** + * Internal helper class to group rules within an {@SCComponent} into rules that are recursive, i.e. part of some cyclic + * 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 { + final Set nonRecursiveRules; + final Set recursiveRules; + + ComponentEvaluationInfo(Set nonRecursive, Set recursive) { + nonRecursiveRules = Collections.unmodifiableSet(nonRecursive); + recursiveRules = Collections.unmodifiableSet(recursive); + } + + boolean isEmpty() { + return nonRecursiveRules.isEmpty() && recursiveRules.isEmpty(); + } + + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java new file mode 100644 index 000000000..c12827fa7 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java @@ -0,0 +1,201 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import static at.ac.tuwien.kr.alpha.grounder.transformation.PredicateInternalizer.makePredicatesInternal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Unifier; +import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; + +/** + * Rewrites #sum aggregates into normal rules. + * Note: Currently only works for a restricted form. + * + * Copyright (c) 2018-2020, the Alpha Team. + */ +public class SumNormalization extends ProgramTransformation { + + private int aggregateCount; + private ProgramParser parser = new ProgramParser(); + + private InputProgram parse(String program) { + return parser.parse(program); + } + + @Override + public InputProgram apply(InputProgram inputProgram) { + if (!rewritingNecessary(inputProgram)) { + return inputProgram; + } + String summationSubprogram = "interesting_number(R, 1..I1) :- input_number_with_first(R, I, _), I1 = I - 1.\n" + + "prefix_subset_sum(R, 0, 0) :- input_number_with_first(R, _, _).\n" + + "prefix_subset_sum(R, I, S) :- prefix_subset_sum(R, I1, S), I1 = I - 1, interesting_number(R, I).\n" + + "prefix_subset_sum(R, I, SF) :- prefix_subset_sum(R, I1, S), I1 = I - 1, SF = S + F, input_number_with_first(R, I, F), bound(R, K), SF < K.\n" + + "output(R, K) :- bound(R, K), K <= 0." + + "output(R, K) :- prefix_subset_sum(R, I1, S), I1 = I - 1, input_number_with_first(R, I, F), bound(R, K), K <= S + F."; + + // Connect/Rewrite every aggregate in each rule. + List rewrittenRules = rewriteAggregates(inputProgram.getRules()); + + InputProgram.Builder prgBuilder = InputProgram.builder(); + prgBuilder.addFacts(inputProgram.getFacts()); + InputProgram summationEncoding = makePredicatesInternal(new ProgramParser().parse(summationSubprogram)); + prgBuilder.accumulate(summationEncoding); + prgBuilder.addRules(rewrittenRules); + + // Add enumeration rule that uses the special EnumerationAtom. + // The enumeration rule is: "input_number_with_first(A, I, F) :- input_with_first(A, X, F), _index(A, X, I)." + BasicRule tmpEnumRule = makePredicatesInternal(parse("input_number_with_first(A, I, F) :- input_with_first(A, X, F).")).getRules().get(0); + EnumerationAtom enumerationAtom = new EnumerationAtom(parse("index(A, X, I).").getFacts().get(0).getTerms()); + List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); + enumerationRuleBody.add(enumerationAtom.toLiteral()); + BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); + prgBuilder.addRule(enumerationRule); + + return prgBuilder.build(); + } + + /** + * Checks if rewriting of sum aggregates is necessary for the given program, i.e. if such aggregates exist. + * + * @param program the program. + * @return true if sum aggregates occur, false otherwise. + */ + private boolean rewritingNecessary(InputProgram program) { + for (BasicRule rule : program.getRules()) { + for (CoreLiteral lit : rule.getBody()) { + if (lit instanceof AggregateLiteral) { + AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); + if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.SUM) { + return true; + } + } + } + } + return false; + } + + private List rewriteAggregates(List srcRules) { + List rewrittenRules = new ArrayList<>(); + for (BasicRule rule : srcRules) { + rewrittenRules.addAll(rewriteAggregatesInRule(rule)); + } + return rewrittenRules; + } + + private List rewriteAggregatesInRule(BasicRule rule) { + + // Example rewriting/connection: + // x :- 6 <= #sum {3,a:a; 4,b:b; 5,c:c}. + // is rewritten to: + // x :- output(aggregate(1), 6). + // input_with_first(aggregate(1), element_tuple(3, a), 3) :- a. + // input_with_first(aggregate(1), element_tuple(4, b), 4) :- b. + // input_with_first(aggregate(1), element_tuple(5, c), 5) :- c. + // bound(aggregate(1), 6). + + // Create interface atoms to the aggregate encoding. + final BasicAtom aggregateOutputAtom = (BasicAtom) makePredicatesInternal(parse( + "output(aggregate(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); + final BasicAtom aggregateInputAtom = (BasicAtom) makePredicatesInternal(parse( + "input_with_first(aggregate(AGGREGATE_ID), ELEMENT_TUPLE, FIRST_VARIABLE).")).getFacts().get(0); + final BasicAtom lowerBoundAtom = (BasicAtom) makePredicatesInternal(parse( + "bound(aggregate(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); + + ArrayList aggregateOutputAtoms = new ArrayList<>(); + int aggregatesInRule = 0; // Only needed for limited rewriting. + ArrayList additionalRules = new ArrayList<>(); + + List rewrittenBody = new ArrayList<>(rule.getBody()); + for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { + CoreLiteral bodyElement = iterator.next(); + // Skip non-aggregates. + if (!(bodyElement instanceof AggregateLiteral)) { + continue; + } + AggregateLiteral aggregateLiteral = (AggregateLiteral) bodyElement; + AggregateAtom aggregateAtom = aggregateLiteral.getAtom(); + + // Check that aggregate is limited to what we currently can deal with. + if (aggregateLiteral.isNegated() || aggregateAtom.getUpperBoundOperator() != null + || (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.COUNT + && aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.SUM) + || aggregatesInRule++ > 0) { + throw new UnsupportedOperationException("Only limited #count/#sum aggregates without upper bound are currently supported." + "No rule may have more than one aggregate."); + } + + // Only treat sum aggregates. + if (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.SUM) { + continue; + } + // Remove aggregate from rule body. + iterator.remove(); + + // Prepare aggregate parameters. + aggregateCount++; + Unifier aggregateUnifier = new Unifier(); + Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); + if (globalVariables.isEmpty()) { + aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); + } else { + // In case some variables are not local to the aggregate, add them to the aggregate identifier + ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); + globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); + aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); + } + aggregateUnifier.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); + + // Create new output atom for addition to rule body instead of the aggregate. + aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateUnifier).toLiteral()); + + // Create input to sorting network from aggregate elements. + for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { + // Prepare element substitution. + List elementTerms = aggregateElement.getElementTerms(); + FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); + Unifier elementUnifier = new Unifier(aggregateUnifier); + elementUnifier.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); + elementUnifier.put(VariableTerm.getInstance("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); + + // Create new rule for input. + BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementUnifier); + List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); + + // If there are global variables used inside the aggregate, add original rule body (minus the aggregate itself) to input rule. + if (!globalVariables.isEmpty()) { + elementLiterals.addAll(rewrittenBody); + } + BasicRule inputRule = new BasicRule(new NormalHead(inputHeadAtom), elementLiterals); + additionalRules.add(inputRule); + } + + // Create lower bound for the aggregate. + BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateUnifier); + List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. + additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); + } + if (aggregatesInRule > 0) { + rewrittenBody.addAll(aggregateOutputAtoms); + additionalRules.add(new BasicRule(rule.getHead(), rewrittenBody)); + } else { + // Return original rule if no aggregate occurs in it. + additionalRules.add(rule); + } + return additionalRules; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java new file mode 100644 index 000000000..7a86941fc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2017-2018, 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.grounder.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 at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.common.rule.NormalRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.grounder.Unifier; + +/** + * Removes variable equalities from rules by replacing one variable with the other. + * + * Copyright (c) 2017-2020, the Alpha Team. + */ +public class VariableEqualityRemoval extends ProgramTransformation { + + @Override + public NormalProgram apply(NormalProgram inputProgram) { + List rewrittenRules = new ArrayList<>(); + for (NormalRule rule : inputProgram.getRules()) { + rewrittenRules.add(findAndReplaceVariableEquality(rule)); + } + return new NormalProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + } + + private NormalRule findAndReplaceVariableEquality(NormalRule rule) { + // Collect all equal variables. + HashMap> variableToEqualVariables = new LinkedHashMap<>(); + HashSet equalitiesToRemove = new HashSet<>(); + for (CoreLiteral bodyElement : rule.getBody()) { + if (!(bodyElement instanceof ComparisonLiteral)) { + continue; + } + ComparisonLiteral comparisonLiteral = (ComparisonLiteral) bodyElement; + if (!comparisonLiteral.isNormalizedEquality()) { + continue; + } + if (comparisonLiteral.getTerms().get(0) instanceof VariableTerm && comparisonLiteral.getTerms().get(1) instanceof VariableTerm) { + VariableTerm leftVariable = (VariableTerm) comparisonLiteral.getTerms().get(0); + VariableTerm rightVariable = (VariableTerm) comparisonLiteral.getTerms().get(1); + HashSet leftEqualVariables = variableToEqualVariables.get(leftVariable); + HashSet rightEqualVariables = variableToEqualVariables.get(rightVariable); + if (leftEqualVariables == null && rightEqualVariables == null) { + HashSet equalVariables = new LinkedHashSet<>(Arrays.asList(leftVariable, rightVariable)); + variableToEqualVariables.put(leftVariable, equalVariables); + variableToEqualVariables.put(rightVariable, equalVariables); + } + if (leftEqualVariables == null && rightEqualVariables != null) { + rightEqualVariables.add(leftVariable); + variableToEqualVariables.put(leftVariable, rightEqualVariables); + } + if (leftEqualVariables != null && rightEqualVariables == null) { + leftEqualVariables.add(rightVariable); + variableToEqualVariables.put(rightVariable, leftEqualVariables); + } + if (leftEqualVariables != null && rightEqualVariables != null) { + leftEqualVariables.addAll(rightEqualVariables); + for (VariableTerm rightEqualVariable : rightEqualVariables) { + variableToEqualVariables.put(rightEqualVariable, leftEqualVariables); + } + } + equalitiesToRemove.add(comparisonLiteral); + } + } + if (variableToEqualVariables.isEmpty()) { + // Skip rule if there is no equality between variables. + return rule; + } + + List rewrittenBody = new ArrayList<>(rule.getBody()); + NormalHead rewrittenHead = rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()); + + // Use substitution for actual replacement. + Unifier replacementSubstitution = new Unifier(); + // For each set of equal variables, take the first variable and replace all others by it. + for (Map.Entry> variableEqualityEntry : variableToEqualVariables.entrySet()) { + VariableTerm variableToReplace = variableEqualityEntry.getKey(); + VariableTerm replacementVariable = variableEqualityEntry.getValue().iterator().next(); + if (variableToReplace == replacementVariable) { + continue; + } + replacementSubstitution.put(variableToReplace, replacementVariable); + } + // Replace/Substitute in each literal every term where one of the common variables occurs. + Iterator bodyIterator = rewrittenBody.iterator(); + while (bodyIterator.hasNext()) { + CoreLiteral literal = bodyIterator.next(); + if (equalitiesToRemove.contains(literal)) { + bodyIterator.remove(); + } + for (int i = 0; i < literal.getTerms().size(); i++) { + CoreTerm replaced = literal.getTerms().get(i).substitute(replacementSubstitution); + literal.getTerms().set(i, replaced); + } + } + // Replace variables in head. + if (rewrittenHead != null) { + CoreAtom headAtom = rewrittenHead.getAtom(); + for (int i = 0; i < headAtom.getTerms().size(); i++) { + CoreTerm replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); + headAtom.getTerms().set(i, replaced); + } + } + return new NormalRule(rewrittenHead, rewrittenBody); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java new file mode 100644 index 000000000..254d0ed05 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java @@ -0,0 +1,38 @@ +package at.ac.tuwien.kr.alpha.solver; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.grounder.Grounder; + +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +abstract class AbstractSolver implements Solver { + protected final Grounder grounder; + protected final AtomStore atomStore; + + protected AbstractSolver(AtomStore atomStore, Grounder grounder) { + this.atomStore = atomStore; + this.grounder = grounder; + } + + protected AnswerSet translate(Iterable assignment) { + return grounder.assignmentToAnswerSet(assignment); + } + + protected abstract boolean tryAdvance(Consumer action); + + @Override + public Spliterator spliterator() { + return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 0) { + @Override + public boolean tryAdvance(Consumer action) { + return AbstractSolver.this.tryAdvance(action); + } + }; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java new file mode 100644 index 000000000..c841ecc0e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java @@ -0,0 +1,17 @@ +package at.ac.tuwien.kr.alpha.solver; + +/** + * An interface to reasons of implications as used internally by the solver. This is a lightweight {@link at.ac.tuwien.kr.alpha.common.NoGood} that only + * provides an array of literals (in some order) and has an activity that may change. + * + * Copyright (c) 2019, the Alpha Team. + */ +public interface Antecedent { + + int[] getReasonLiterals(); + + void bumpActivity(); + + void decreaseActivity(); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java new file mode 100644 index 000000000..506dddbcd --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2019 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.solver; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Counts the number of ground atoms stored for each type (i.e., subclass of {@link CoreAtom}. + * For every atom, only the counter for one class (the most specific one) is incremented, + * not the counters for more general classes of which the atom is also an instance. + */ +public class AtomCounter { + + private final Map, Integer> countByType = new HashMap<>(); + + public void add(CoreAtom atom) { + countByType.compute(atom.getClass(), (k, v) -> (v == null) ? 1 : v + 1); + } + + /** + * @param type the class of atoms to count + * @return the number of atoms of the given type + */ + public int getNumberOfAtoms(Class type) { + return countByType.getOrDefault(type, 0); + } + + /** + * @return a string giving statistics on numbers of atoms by type + */ + public String getStatsByType() { + List statsList = new ArrayList<>(); + for (Map.Entry, Integer> entry : countByType.entrySet()) { + statsList.add(entry.getKey().getSimpleName() + ": " + entry.getValue()); + } + Collections.sort(statsList); + return String.join(" ", statsList); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java new file mode 100644 index 000000000..de6f02a6a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java @@ -0,0 +1,9 @@ +package at.ac.tuwien.kr.alpha.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/solver/BinaryNoGoodPropagationEstimation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java new file mode 100644 index 000000000..edf3423fc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2018-2019 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.solver; + +/** + * Offers methods to estimate the effect of propagating binary nogoods. + */ +public interface BinaryNoGoodPropagationEstimation { + + /** + * Uses {@code strategy} to estimate the number of direct consequences of propagating binary nogoods after assigning + * {@code truth} to {@code atom}. + * + * If {@code strategy} is {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation}, {@code truth} is assigned to {@code atom}, + * only binary nogoods are propagated, a backtrack is executed, and the number of atoms that have been assigned + * additionally during this process is returned. + * + * If {@code strategy} is {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches}, on the other hand, the number of binary watches on + * the literal given by {@code atom} and {@code truth} is returned. + * + * @param atom the atom to estimate effects for + * @param truth gives, together with {@code atom}, a literal to estimate effects for + * @param strategy the strategy to use for estimation. If {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation} is given but + * no binary nogoods exist, {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches} will be used instead. + * @return an estimate on the effects of propagating binary nogoods after assigning {@code truth} to {@code atom}. + */ + int estimate(int atom, boolean truth, BinaryNoGoodPropagationEstimationStrategy strategy); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java new file mode 100644 index 000000000..369389d50 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java @@ -0,0 +1,12 @@ +package at.ac.tuwien.kr.alpha.solver; + +/** + * Marks classes that implement some "checking" logic that can perform + * exhaustive validation of the internal state of an object. This is + * mainly used in debugging and should not be done for production + * purposes. + */ +@FunctionalInterface +public interface Checkable { + void setChecksEnabled(boolean checksEnabled); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java new file mode 100644 index 000000000..eb70acd5d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2017-2018, 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.solver; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; + +class Choice { + private final int atom; + private final boolean value; + private final boolean backtracked; + + Choice(int atom, boolean value, boolean backtracked) { + this.atom = atom; + this.value = value; + this.backtracked = backtracked; + } + + Choice(int literal, boolean backtracked) { + this(atomOf(literal), isPositive(literal), backtracked); + } + + public int getAtom() { + return atom; + } + + public boolean getValue() { + return value; + } + + public boolean isBacktracked() { + return backtracked; + } + + @Override + public String toString() { + return atom + "=" + (value ? "TRUE" : "FALSE"); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java new file mode 100644 index 000000000..62624eecd --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java @@ -0,0 +1,235 @@ +/** + * 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. + * + * 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.solver; + +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; + +/** + * Manages influence of atoms on the activity of certain other atoms. Can be used for either choice points or heuristic atoms. + * + * Copyright (c) 2020, the Alpha Team. + */ +public class ChoiceInfluenceManager implements Checkable { + + private static final Logger LOGGER = LoggerFactory.getLogger(ChoiceInfluenceManager.class); + + // Active choice points and all atoms that influence a choice point (enabler, disabler, choice atom itself). + private final Set activeChoicePoints = new LinkedHashSet<>(); + private final Set activeChoicePointsAtoms = new LinkedHashSet<>(); + private ChoicePoint[] influencers = new ChoicePoint[0]; + private ActivityListener activityListener; + + private final WritableAssignment assignment; + + private boolean checksEnabled; + + /** + * @param assignment + * + */ + public ChoiceInfluenceManager(WritableAssignment assignment) { + this.assignment = assignment; + } + + void addInformation(Pair, Map> choiceAtoms) { + // Assumption: we get all enabler/disabler pairs in one call. + Map enablers = choiceAtoms.getLeft(); + Map disablers = choiceAtoms.getRight(); + for (Map.Entry atomToEnabler : enablers.entrySet()) { + addInformation(atomToEnabler, disablers); + } + } + + private void addInformation(Map.Entry atomToEnabler, Map disablers) { + // Construct and record ChoicePoint. + Integer atom = atomToEnabler.getKey(); + if (atom == null) { + throw oops("Incomplete choice point description found (no atom)"); + } + if (influencers[atom] != null) { + throw oops("Received choice information repeatedly"); + } + Integer enabler = atomToEnabler.getValue(); + Integer disabler = disablers.get(atom); + if (enabler == null || disabler == null) { + throw oops("Incomplete choice point description found (no enabler or disabler)"); + } + assignment.registerCallbackOnChange(atom); + assignment.registerCallbackOnChange(enabler); + assignment.registerCallbackOnChange(disabler); + ChoicePoint choicePoint = new ChoicePoint(atom, enabler, disabler); + influencers[atom] = choicePoint; + influencers[enabler] = choicePoint; + influencers[disabler] = choicePoint; + choicePoint.recomputeActive(); + } + + void checkActiveChoicePoints() { + HashSet actualActiveChoicePoints = new HashSet<>(); + for (int i = 0; i < influencers.length; i++) { + ChoicePoint choicePoint = influencers[i]; + if (choicePoint == null) { + continue; + } + if (checkActiveChoicePoint(choicePoint)) { + actualActiveChoicePoints.add(choicePoint); + } + } + if (!actualActiveChoicePoints.equals(activeChoicePoints)) { + throw oops("ChoiceInfluenceManager internal checker detected wrong activeChoicePoints"); + } + LOGGER.trace("Checking internal choice manger: all ok."); + } + + private boolean checkActiveChoicePoint(ChoicePoint choicePoint) { + ThriceTruth enablerTruth = assignment.getTruth(choicePoint.enabler); + ThriceTruth disablerTruth = assignment.getTruth(choicePoint.disabler); + boolean isActive = enablerTruth == TRUE + && (disablerTruth == null || !disablerTruth.toBoolean()); + ThriceTruth atomTruth = assignment.getTruth(choicePoint.atom); + boolean isNotChosen = atomTruth == null || atomTruth == MBT; + return isActive && isNotChosen; + } + + boolean isActive(int atom) { + if (checksEnabled) { + checkActiveChoicePoints(); + } + ChoicePoint choicePoint = influencers[atom]; + return choicePoint != null && choicePoint.isActive && choicePoint.atom == atom; + } + + int getNextActiveAtomOrDefault(int defaultAtom) { + if (checksEnabled) { + checkActiveChoicePoints(); + } + return activeChoicePointsAtoms.size() > 0 ? activeChoicePointsAtoms.iterator().next() : defaultAtom; + } + + boolean isAtomInfluenced(int atom) { + ChoicePoint choicePoint = influencers[atom]; + return choicePoint != null && choicePoint.atom == atom; + } + + @Override + public void setChecksEnabled(boolean checksEnabled) { + this.checksEnabled = checksEnabled; + } + + void callbackOnChanged(int atom) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Callback received on influencer atom: {}", atom); + } + ChoicePoint choicePoint = influencers[atom]; + if (choicePoint != null) { + choicePoint.recomputeActive(); + } + } + + public void growForMaxAtomId(int maxAtomId) { + // Grow arrays only if needed. + if (influencers.length > maxAtomId) { + return; + } + // Grow to default size, except if bigger array is required due to maxAtomId. + int newCapacity = arrayGrowthSize(influencers.length); + if (newCapacity < maxAtomId + 1) { + newCapacity = maxAtomId + 1; + } + influencers = Arrays.copyOf(influencers, newCapacity); + } + + void setActivityListener(ActivityListener listener) { + this.activityListener = listener; + } + + private class ChoicePoint { + final Integer atom; + final int enabler; + final int disabler; + boolean isActive; + + private ChoicePoint(Integer atom, Integer enabler, int disabler) { + this.atom = atom; + this.enabler = enabler; + this.disabler = disabler; + } + + private boolean isActiveChoicePoint() { + ThriceTruth enablerTruth = assignment.getTruth(enabler); + ThriceTruth disablerTruth = assignment.getTruth(disabler); + return enablerTruth == TRUE + && (disablerTruth == null || !disablerTruth.toBoolean()); + } + + private boolean isNotChosen() { + ThriceTruth atomTruth = assignment.getTruth(atom); + return atomTruth == null || atomTruth == MBT; + } + + void recomputeActive() { + LOGGER.trace("Recomputing activity of atom {}.", atom); + final boolean wasActive = isActive; + isActive = isNotChosen() && isActiveChoicePoint(); + boolean changed = false; + if (isActive && !wasActive) { + activeChoicePoints.add(this); + activeChoicePointsAtoms.add(atom); + changed = true; + LOGGER.debug("Activating choice point for atom {}", this.atom); + } else if (wasActive && !isActive) { + activeChoicePoints.remove(this); + activeChoicePointsAtoms.remove(atom); + changed = true; + LOGGER.debug("Deactivating choice point for atom {}", this.atom); + } + if (changed && activityListener != null) { + activityListener.callbackOnChanged(atom, isActive); + } + } + + @Override + public String toString() { + return String.valueOf(atom); + } + } + + public static interface ActivityListener { + void callbackOnChanged(int atom, boolean active); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java new file mode 100644 index 000000000..5feb085a3 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java @@ -0,0 +1,325 @@ +/** + * 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. + * + * 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.solver; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.NoGood; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; + +/** + * This class provides functionality for choice point management, detection of active choice points, etc. + * Copyright (c) 2017-2019, the Alpha Team. + */ +public class ChoiceManager implements Checkable { + + public static final int DEFAULT_CHOICE_ATOM = 0; + + private static final Logger LOGGER = LoggerFactory.getLogger(ChoiceManager.class); + private final WritableAssignment assignment; + private final Stack choiceStack; + private final Map> headsToBodies = new HashMap<>(); + private final Map bodiesToHeads = new HashMap<>(); + + // An "influence manager" managing active choice points and heuristics. + private final ChoiceInfluenceManager choicePointInfluenceManager; + + private final NoGoodStore store; + private final BinaryNoGoodPropagationEstimation bnpEstimation; + + private boolean checksEnabled; + private DebugWatcher debugWatcher; + + private int choices; + private int backtracks; + private int backtracksWithinBackjumps; + private int backjumps; + + public ChoiceManager(WritableAssignment assignment, NoGoodStore store) { + this.store = store; + this.assignment = assignment; + this.choicePointInfluenceManager = new ChoiceInfluenceManager(assignment); + this.choiceStack = new Stack<>(); + assignment.setCallback(this); + this.bnpEstimation = store instanceof BinaryNoGoodPropagationEstimation + ? (BinaryNoGoodPropagationEstimation)store + : null; + } + + public WritableAssignment getAssignment() { + return assignment; + } + + NoGood computeEnumeration() { + int[] enumerationLiterals = new int[choiceStack.size()]; + int enumerationPos = 0; + for (Choice e : choiceStack) { + enumerationLiterals[enumerationPos++] = atomToLiteral(e.getAtom(), e.getValue()); + } + return new NoGood(enumerationLiterals); + } + + @Override + public void setChecksEnabled(boolean checksEnabled) { + this.checksEnabled = checksEnabled; + this.choicePointInfluenceManager.setChecksEnabled(checksEnabled); + + if (checksEnabled) { + debugWatcher = new DebugWatcher(); + } else { + debugWatcher = null; + } + } + + public boolean isChecksEnabled() { + return checksEnabled; + } + + public void callbackOnChanged(int atom) { + choicePointInfluenceManager.callbackOnChanged(atom); + } + + public int getBackjumps() { + return backjumps; + } + + /** + * Returns the total number of backtracks. + * + * The number of backtracks excluding those within backjumps is {@link #getBacktracks()} minus {@link #getBacktracksWithinBackjumps()}. + * + * @return the total number of backtracks + */ + public int getBacktracks() { + return backtracks; + } + + /** + * Returns the number of backtracks made within backjumps. + * + * @return the number of backtracks made within backjumps. + */ + public int getBacktracksWithinBackjumps() { + return backtracksWithinBackjumps; + } + + public int getChoices() { + return choices; + } + + public void updateAssignments() { + LOGGER.trace("Updating assignments of ChoiceManager."); + if (checksEnabled) { + choicePointInfluenceManager.checkActiveChoicePoints(); + } + } + + public void choose(Choice choice) { + if (!choice.isBacktracked()) { + choices++; + } + + if (assignment.choose(choice.getAtom(), choice.getValue()) != null) { + throw oops("Picked choice is incompatible with current assignment"); + } + LOGGER.debug("Choice {} is {}@{}", choices, choice, assignment.getDecisionLevel()); + + if (debugWatcher != null) { + debugWatcher.runWatcher(); + } + + choiceStack.push(choice); + } + + public void backjump(int target) { + if (target < 0) { + throw oops("Backjumping to decision level less than 0"); + } + + backjumps++; + LOGGER.debug("Backjumping to decision level {}.", target); + + // Remove everything above the target level, but keep the target level unchanged. + int currentDecisionLevel = assignment.getDecisionLevel(); + assignment.backjump(target); + while (currentDecisionLevel-- > target) { + final Choice choice = choiceStack.pop(); + backtracksWithinBackjumps++; + backtracks++; + LOGGER.debug("Backjumping removed choice {}", choice); + } + } + + /** + * Fast backtracking will backtrack but not give any information about which choice was backtracked. This is + * handy in cases where higher level backtracking mechanisms already know what caused the backtracking and what + * to do next. + * + * In order to analyze the choice that was backtracked, use the more expensive {@link #backtrackSlow()}. + */ + public void backtrackFast() { + backtrack(); + + final Choice choice = choiceStack.pop(); + + LOGGER.debug("Backtracked (fast) to level {} from choice {}", assignment.getDecisionLevel(), choice); + } + + /** + * Slow backtracking will take more time, but allow to analyze the {@link Assignment.Entry} corresponding to the + * choice that is being backtracked. Higher level backtracking mechanisms can use this information to change + * their plans. + * + * @return the assignment entry of the choice being backtracked, or {@code null} if the choice cannot be + * backtracked any futher (it already is a backtracking choice) + */ + public Assignment.Entry backtrackSlow() { + final Choice choice = choiceStack.pop(); + final Assignment.Entry lastChoiceEntry = assignment.get(choice.getAtom()); + + backtrack(); + LOGGER.debug("Backtracked (slow) to level {} from choice {}", assignment.getDecisionLevel(), choice); + + if (choice.isBacktracked()) { + return null; + } + + return lastChoiceEntry; + } + + /** + * This method implements the backtracking "core" that will be executed for both slow and fast backtracking. + * It backtracks the NoGoodStore and recomputes choice points. + */ + private void backtrack() { + store.backtrack(); + backtracks++; + } + + void addChoiceInformation(Pair, Map> choiceAtoms, Map> headsToBodies) { + choicePointInfluenceManager.addInformation(choiceAtoms); + addHeadsToBodies(headsToBodies); + } + + public void growForMaxAtomId(int maxAtomId) { + choicePointInfluenceManager.growForMaxAtomId(maxAtomId); + } + + private void addHeadsToBodies(Map> headsToBodies) { + for (Entry> entry : headsToBodies.entrySet()) { + Integer head = entry.getKey(); + Set newBodies = entry.getValue(); + addHeadsToBodies(head, newBodies); + addBodiesToHeads(head, newBodies); + } + } + + private void addHeadsToBodies(Integer head, Set bodies) { + Set existingBodies = this.headsToBodies.get(head); + if (existingBodies == null) { + existingBodies = new HashSet<>(); + this.headsToBodies.put(head, existingBodies); + } + existingBodies.addAll(bodies); + } + + private void addBodiesToHeads(Integer head, Set bodies) { + for (Integer body : bodies) { + bodiesToHeads.put(body, head); + } + } + + public boolean isActiveChoiceAtom(int atom) { + return choicePointInfluenceManager.isActive(atom); + } + + public int getNextActiveChoiceAtom() { + return choicePointInfluenceManager.getNextActiveAtomOrDefault(DEFAULT_CHOICE_ATOM); + } + + public boolean isAtomChoice(int atom) { + return choicePointInfluenceManager.isAtomInfluenced(atom); + } + + public void setChoicePointActivityListener(ChoiceInfluenceManager.ActivityListener activityListener) { + choicePointInfluenceManager.setActivityListener(activityListener); + } + + public Integer getHeadDerivedByChoiceAtom(int choiceAtomId) { + return bodiesToHeads.get(choiceAtomId); + } + + public BinaryNoGoodPropagationEstimation getBinaryNoGoodPropagationEstimation() { + return bnpEstimation; + } + + /** + * A helper class for halting the debugger when certain assignments occur on the choice stack. + * + * Example usage (called from DefaultSolver): + * choiceStack = new ChoiceStack(grounder, true); + * choiceStack.getDebugWatcher().watchAssignments("_R_(0,_C:red_V:7)=TRUE", "_R_(0,_C:green_V:8)=TRUE", "_R_(0,_C:red_V:9)=TRUE", "_R_(0,_C:red_V:4)=TRUE"); + */ + class DebugWatcher { + ArrayList toWatchFor = new ArrayList<>(); + + private void runWatcher() { + if (toWatchFor.size() == 0) { + return; + } + String current = choiceStack.stream().map(Choice::toString).collect(Collectors.joining(", ")); + boolean contained = true; + for (String s : toWatchFor) { + if (!current.contains(s)) { + contained = false; + break; + } + } + if (contained && toWatchFor.size() != 0) { + LOGGER.debug("Marker hit."); // Set debug breakpoint here to halt when desired assignment occurs. + } + } + + /** + * Registers atom assignments to watch for. + * @param toWatch one or more strings as they occur in ChoiceStack.toString() + */ + public void watchAssignments(String... toWatch) { + toWatchFor = new ArrayList<>(); + Collections.addAll(toWatchFor, toWatch); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java new file mode 100644 index 000000000..b9b72ca58 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java @@ -0,0 +1,26 @@ +package at.ac.tuwien.kr.alpha.solver; + +/** + * Indicates the presence of a conflict and contains its reason in terms of a violated Antecedent. + * Throughout the solver the absence of a conflict is indicated by {@code ConflictCause = null}. + */ +public class ConflictCause { + // Note: Storing the Antecedent is necessary in order to distinguish the cases of no conflict occurring + // {@code ConflictCause==null} from the case where a choice (with no Antecedent, i.e., + // {@code violatedNoGood==null}) is the cause of the conflict. + // Resolving ConflictCause by Antecedent would require an indicator flag to distinguish these cases. + private final Antecedent violatedNoGood; + + public ConflictCause(Antecedent violatedNoGood) { + this.violatedNoGood = violatedNoGood; + } + + public Antecedent getAntecedent() { + return violatedNoGood; + } + + @Override + public String toString() { + return String.valueOf(violatedNoGood); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java new file mode 100644 index 000000000..34560c693 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java @@ -0,0 +1,599 @@ +/** + * 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 + * 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.solver; + +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.common.Literals.atomToNegatedLiteral; +import static at.ac.tuwien.kr.alpha.solver.NoGoodStore.LBD_NO_VALUE; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; +import static at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; +import static at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.Set; +import java.util.function.Consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.config.SystemConfig; +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.grounder.ProgramAnalyzingGrounder; +import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic; +import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; +import at.ac.tuwien.kr.alpha.solver.heuristics.ChainedBranchingHeuristics; +import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.solver.heuristics.NaiveHeuristic; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner; + +/** + * The new default solver employed in Alpha. + * + * Copyright (c) 2016-2020, the Alpha Team. + */ +public class DefaultSolver extends AbstractSolver implements SolverMaintainingStatistics { + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSolver.class); + + private final NoGoodStore store; + private final ChoiceManager choiceManager; + private final WritableAssignment assignment; + + private final GroundConflictNoGoodLearner learner; + + private final BranchingHeuristic branchingHeuristic; + + private boolean initialize = true; + private int mbtAtFixpoint; + private int conflictsAfterClosing; + private final boolean disableJustifications; + private boolean disableJustificationAfterClosing = true; // Keep disabled for now, case not fully worked out yet. + private final boolean disableNoGoodDeletion; + + private final PerformanceLog performanceLog; + + public DefaultSolver(AtomStore atomStore, Grounder grounder, NoGoodStore store, WritableAssignment assignment, Random random, SystemConfig config, HeuristicsConfiguration heuristicsConfiguration) { + super(atomStore, grounder); + + this.assignment = assignment; + this.store = store; + this.choiceManager = new ChoiceManager(assignment, store); + this.learner = new GroundConflictNoGoodLearner(assignment, atomStore); + this.branchingHeuristic = chainFallbackHeuristic(grounder, assignment, random, heuristicsConfiguration); + this.disableJustifications = config.isDisableJustificationSearch(); + this.disableNoGoodDeletion = config.isDisableNoGoodDeletion(); + this.performanceLog = new PerformanceLog(choiceManager, (TrailAssignment) assignment, 1000); + } + + private BranchingHeuristic chainFallbackHeuristic(Grounder grounder, WritableAssignment assignment, Random random, HeuristicsConfiguration heuristicsConfiguration) { + BranchingHeuristic branchingHeuristic = BranchingHeuristicFactory.getInstance(heuristicsConfiguration, grounder, assignment, choiceManager, random); + if (branchingHeuristic instanceof NaiveHeuristic) { + return branchingHeuristic; + } + if (branchingHeuristic instanceof ChainedBranchingHeuristics && ((ChainedBranchingHeuristics)branchingHeuristic).getLastElement() instanceof NaiveHeuristic) { + return branchingHeuristic; + } + return ChainedBranchingHeuristics.chainOf(branchingHeuristic, new NaiveHeuristic(choiceManager)); + } + + @Override + protected boolean tryAdvance(Consumer action) { + boolean didChange = false; + + // Initially, get NoGoods from grounder. + if (initialize) { + performanceLog.initialize(); + Map obtained = grounder.getNoGoods(assignment); + didChange = !obtained.isEmpty(); + if (!ingest(obtained)) { + logStats(); + return false; + } + initialize = false; + } else if (assignment.getDecisionLevel() == 0) { + logStats(); + return false; + } else { + // We already found one Answer-Set and are requested to find another one. + // Create enumeration NoGood to avoid finding the same Answer-Set twice. + final NoGood enumerationNoGood = choiceManager.computeEnumeration(); + final int backjumpLevel = assignment.minimumConflictLevel(enumerationNoGood); + if (backjumpLevel == -1) { + throw oops("Enumeration nogood is not violated"); + } + if (backjumpLevel == 0) { + // Search space exhausted (only happens if first choice is for TRUE at decision level 1 for an atom that was MBT at decision level 0 already). + return false; + } + // Backjump instead of backtrackSlow, enumerationNoGood will invert last choice. + choiceManager.backjump(backjumpLevel - 1); + LOGGER.debug("Adding enumeration nogood: {}", enumerationNoGood); + if (!addAndBackjumpIfNecessary(grounder.register(enumerationNoGood), enumerationNoGood, Integer.MAX_VALUE)) { + return false; + } + } + + boolean afterAllAtomsAssigned = false; + + // Try all assignments until grounder reports no more NoGoods and all of them are satisfied + while (true) { + performanceLog.infoIfTimeForOutput(LOGGER); + ConflictCause conflictCause = store.propagate(); + didChange |= store.didPropagate(); + LOGGER.trace("Assignment after propagation is: {}", assignment); + if (!disableNoGoodDeletion && conflictCause == null) { + // Run learned NoGood deletion strategy. + store.cleanupLearnedNoGoods(); + } + if (conflictCause != null) { + // Learn from conflict. + LOGGER.debug("Violating assignment is: {}", assignment); + Antecedent conflictAntecedent = conflictCause.getAntecedent(); + NoGood violatedNoGood = new NoGood(conflictAntecedent.getReasonLiterals().clone()); + // TODO: The violatedNoGood should not be necessary here, but this requires major type changes in heuristics. + branchingHeuristic.violatedNoGood(violatedNoGood); + if (!afterAllAtomsAssigned) { + if (!learnBackjumpAddFromConflict(conflictCause)) { + logStats(); + return false; + } + } else { + LOGGER.debug("Assignment is violated after all unassigned atoms have been assigned false."); + conflictsAfterClosing++; + if (!treatConflictAfterClosing(conflictAntecedent)) { + return false; + } + afterAllAtomsAssigned = false; + } + } else if (didChange) { + // Ask the grounder for new NoGoods, then propagate (again). + LOGGER.trace("Doing propagation step."); + + grounder.updateAssignment(assignment.getNewPositiveAssignmentsIterator()); + + Map obtained = grounder.getNoGoods(assignment); + didChange = !obtained.isEmpty(); + if (!ingest(obtained)) { + logStats(); + return false; + } + } else if (choose()) { + LOGGER.debug("Did choice."); + didChange = true; + } else if (close()) { + LOGGER.debug("Closed unassigned known atoms (assigning FALSE)."); + afterAllAtomsAssigned = true; + } else if (assignment.getMBTCount() == 0) { + // NOTE: If we would do optimization, we would now have a guaranteed upper bound. + AnswerSet as = translate(assignment.getTrueAssignments()); + LOGGER.debug("Answer-Set found: {}", as); + action.accept(as); + logStats(); + return true; + } else { + LOGGER.debug("Backtracking from wrong choices ({} MBTs).", assignment.getMBTCount()); + if (!justifyMbtAndBacktrack()) { + return false; + } + afterAllAtomsAssigned = false; + } + } + } + + /** + * Adds a noGood to the store and in case of out-of-order literals causing another conflict, triggers further backjumping. + * @param noGoodId the unique identifier of the NoGood to add. + * @param noGood the NoGood to add. + * @param lbd the LBD (literal blocks distance) value of the NoGood. + */ + private boolean addAndBackjumpIfNecessary(int noGoodId, NoGood noGood, int lbd) { + while (store.add(noGoodId, noGood, lbd) != null) { + LOGGER.debug("Adding noGood (again) caused conflict, computing real backjumping level now."); + int backjumpLevel = learner.computeConflictFreeBackjumpingLevel(noGood); + if (backjumpLevel < 0) { + return false; + } + choiceManager.backjump(backjumpLevel); + if (store.propagate() != null) { + throw oops("Violated NoGood after backtracking."); + } + } + return true; + } + + /** + * Analyzes the conflict and either learns a new NoGood (causing backjumping and addition to the NoGood store), + * or backtracks the choice causing the conflict. + * @return false iff the analysis result shows that the set of NoGoods is unsatisfiable. + */ + private boolean learnBackjumpAddFromConflict(ConflictCause conflictCause) { + GroundConflictNoGoodLearner.ConflictAnalysisResult analysisResult = learner.analyzeConflictingNoGood(conflictCause.getAntecedent()); + + LOGGER.debug("Analysis result: {}", analysisResult); + + if (analysisResult == UNSAT) { + // Halt if unsatisfiable. + return false; + } + + branchingHeuristic.analyzedConflict(analysisResult); + + if (analysisResult.learnedNoGood != null) { + choiceManager.backjump(analysisResult.backjumpLevel); + + final NoGood learnedNoGood = analysisResult.learnedNoGood; + int noGoodId = grounder.register(learnedNoGood); + if (!addAndBackjumpIfNecessary(noGoodId, learnedNoGood, analysisResult.lbd)) { + return false; + } + return true; + } + + choiceManager.backjump(analysisResult.backjumpLevel); + + choiceManager.backtrackFast(); + if (store.propagate() != null) { + throw oops("Violated NoGood after backtracking."); + } + if (!store.didPropagate()) { + throw oops("Nothing to propagate after backtracking from conflict-causing choice"); + } + + return true; + } + + private boolean justifyMbtAndBacktrack() { + mbtAtFixpoint++; + // Run justification only if enabled and possible. + if (disableJustifications || !(grounder instanceof ProgramAnalyzingGrounder)) { + if (!backtrack()) { + logStats(); + return false; + } + return true; + } + ProgramAnalyzingGrounder analyzingGrounder = (ProgramAnalyzingGrounder) grounder; + // Justify one MBT assigned atom. + int atomToJustify = assignment.getBasicAtomAssignedMBT(); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Searching for justification of {} / {}", atomToJustify, atomStore.atomToString(atomToJustify)); + LOGGER.debug("Assignment is (TRUE part only): {}", translate(assignment.getTrueAssignments())); + } + Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomToJustify, assignment); + NoGood noGood = noGoodFromJustificationReasons(atomToJustify, reasonsForUnjustified); + + + int noGoodID = grounder.register(noGood); + Map obtained = new LinkedHashMap<>(); + obtained.put(noGoodID, noGood); + LOGGER.debug("Learned NoGood is: {}", atomStore.noGoodToString(noGood)); + // Add NoGood and trigger backjumping. + if (!ingest(obtained)) { + logStats(); + return false; + } + return true; + } + + private NoGood noGoodFromJustificationReasons(int atomToJustify, Set reasonsForUnjustified) { + // Turn the justification into a NoGood. + int[] reasons = new int[reasonsForUnjustified.size() + 1]; + reasons[0] = atomToLiteral(atomToJustify); + int arrpos = 1; + for (CoreLiteral literal : reasonsForUnjustified) { + reasons[arrpos++] = atomToLiteral(atomStore.get(literal.getAtom()), !literal.isNegated()); + } + return NoGood.learnt(reasons); + } + + private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { + if (disableJustificationAfterClosing || disableJustifications || !(grounder instanceof ProgramAnalyzingGrounder)) { + // Will not learn from violated NoGood, do simple backtrack. + LOGGER.debug("NoGood was violated after all unassigned atoms were assigned to false; will not learn from it; skipping."); + if (!backtrack()) { + logStats(); + return false; + } + return true; + } + ProgramAnalyzingGrounder analyzingGrounder = (ProgramAnalyzingGrounder) grounder; + LOGGER.debug("Justifying atoms in violated nogood."); + LinkedHashSet toJustify = new LinkedHashSet<>(); + // Find those literals in violatedNoGood that were just assigned false. + for (Integer literal : violatedNoGood.getReasonLiterals()) { + if (assignment.getImpliedBy(atomOf(literal)) == TrailAssignment.CLOSING_INDICATOR_ANTECEDENT) { + toJustify.add(literal); + } + } + // Since the violatedNoGood may contain atoms other than BasicAtom, these have to be treated. + Map obtained = new LinkedHashMap<>(); + Iterator toJustifyIterator = toJustify.iterator(); + ArrayList ruleAtomReplacements = new ArrayList<>(); + while (toJustifyIterator.hasNext()) { + Integer literal = toJustifyIterator.next(); + CoreAtom atom = atomStore.get(atomOf(literal)); + if (atom instanceof BasicAtom) { + continue; + } + if (!(atom instanceof RuleAtom)) { + // Ignore atoms other than RuleAtom. + toJustifyIterator.remove(); + continue; + } + // For RuleAtoms in toJustify the corresponding ground body contains BasicAtoms that have been assigned FALSE in the closing. + // First, translate RuleAtom back to NonGroundRule + Substitution. + String ruleId = (String) ((CoreConstantTerm)atom.getTerms().get(0)).getObject(); + InternalRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); + String substitution = (String) ((CoreConstantTerm)atom.getTerms().get(1)).getObject(); + Substitution groundingSubstitution = Substitution.fromString(substitution); + // Find ground literals in the body that have been assigned false and justify those. + for (CoreLiteral bodyLiteral : nonGroundRule.getBody()) { + CoreAtom groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); + if (groundAtom instanceof ComparisonAtom || analyzingGrounder.isFact(groundAtom)) { + // Facts and ComparisonAtoms are always true, no justification needed. + continue; + } + int groundAtomId = atomStore.get(groundAtom); + Antecedent impliedBy = assignment.getImpliedBy(groundAtomId); + // Check if atom was assigned to FALSE during the closing. + if (impliedBy == TrailAssignment.CLOSING_INDICATOR_ANTECEDENT) { + ruleAtomReplacements.add(atomToNegatedLiteral(groundAtomId)); + } + } + toJustifyIterator.remove(); + } + toJustify.addAll(ruleAtomReplacements); + for (Integer literalToJustify : toJustify) { + LOGGER.debug("Searching for justification(s) of {} / {}", toJustify, atomStore.atomToString(atomOf(literalToJustify))); + Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomOf(literalToJustify), assignment); + NoGood noGood = noGoodFromJustificationReasons(atomOf(literalToJustify), reasonsForUnjustified); + int noGoodID = grounder.register(noGood); + obtained.put(noGoodID, noGood); + LOGGER.debug("Learned NoGood is: {}", atomStore.noGoodToString(noGood)); + } + // Backtrack to remove the violation. + if (!backtrack()) { + logStats(); + return false; + } + // Add newly obtained noGoods. + if (!ingest(obtained)) { + logStats(); + return false; + } + return true; + } + + private boolean close() { + return assignment.closeUnassignedAtoms(); + } + + /** + * Iterative implementation of recursive backtracking. + * + * @return {@code true} iff it is possible to backtrack even further, {@code false} otherwise + */ + private boolean backtrack() { + while (assignment.getDecisionLevel() != 0) { + final Assignment.Entry choice = choiceManager.backtrackSlow(); + store.propagate(); + + if (choice == null) { + LOGGER.debug("Backtracking further, because last choice was already backtracked."); + continue; + } + + final int lastChoice = choice.getAtom(); + final boolean choiceValue = choice.getTruth().toBoolean(); + + // Chronological backtracking: choose inverse now. + // Choose FALSE if the previous choice was for TRUE and the atom was not already MBT at that time. + ThriceTruth lastChoiceTruth = assignment.getTruth(lastChoice); + if (choiceValue && MBT.equals(lastChoiceTruth)) { + LOGGER.debug("Backtracking further, because last choice was MBT before choosing TRUE."); + continue; + } + + // If choice was assigned at lower decision level (due to added NoGoods), no inverted choice should be done. + if (choice.getImpliedBy() != null) { + LOGGER.debug("Last choice is now implied by {}", choice.getImpliedBy()); + //if (choice.getDecisionLevel() == assignment.getDecisionLevel() + 1) { + // throw oops("Choice was assigned but not at a lower decision level"); + //} + LOGGER.debug("Backtracking further, because last choice was assigned at a lower decision level."); + continue; + } + + // Choose inverse if it is not yet already assigned TRUE or FALSE. + if (lastChoiceTruth == null || (lastChoiceTruth.isMBT() && !choiceValue)) { + LOGGER.debug("Choosing inverse."); + choiceManager.choose(new Choice(lastChoice, !choiceValue, true)); + break; + } + // Continue backtracking. + } + + return assignment.getDecisionLevel() != 0; + } + + private boolean ingest(Map obtained) { + assignment.growForMaxAtomId(); + int maxAtomId = atomStore.getMaxAtomId(); + store.growForMaxAtomId(maxAtomId); + choiceManager.growForMaxAtomId(maxAtomId); + branchingHeuristic.growForMaxAtomId(maxAtomId); + branchingHeuristic.newNoGoods(obtained.values()); + + LinkedList> noGoodsToAdd = new LinkedList<>(obtained.entrySet()); + Map.Entry entry; + while ((entry = noGoodsToAdd.poll()) != null) { + if (NoGood.UNSAT.equals(entry.getValue())) { + // Empty NoGood cannot be satisfied, program is unsatisfiable. + return false; + } + + final ConflictCause conflictCause = store.add(entry.getKey(), entry.getValue(), Integer.MAX_VALUE); + if (conflictCause == null) { + // There is no conflict, all is fine. Just skip conflict treatment and carry on. + continue; + } + + if (!fixContradiction(entry, conflictCause)) { + return false; + } + } + return true; + } + + /** + * Attempts to fix a given conflict that arose from adding a nogood. + * @param noGoodEntry the description of the NoGood that caused the conflict. + * @param conflictCause a description of the cause of the conflict. + * @return true if the contradiction could be resolved (by backjumping) and the NoGood was added. + * False otherwise, i.e., iff the program is UNSAT. + */ + private boolean fixContradiction(Map.Entry noGoodEntry, ConflictCause conflictCause) { + LOGGER.debug("Attempting to fix violation of {} caused by {}", noGoodEntry.getValue(), conflictCause); + + GroundConflictNoGoodLearner.ConflictAnalysisResult conflictAnalysisResult = learner.analyzeConflictFromAddingNoGood(conflictCause.getAntecedent()); + if (conflictAnalysisResult == UNSAT) { + return false; + } + branchingHeuristic.analyzedConflict(conflictAnalysisResult); + if (conflictAnalysisResult.learnedNoGood != null) { + throw oops("Unexpectedly learned NoGood after addition of new NoGood caused a conflict."); + } + + choiceManager.backjump(conflictAnalysisResult.backjumpLevel); + + // If NoGood was learned, add it to the store. + // Note that the learned NoGood may cause further conflicts, since propagation on lower decision levels is lazy, + // hence backtracking once might not be enough to remove the real conflict cause. + return addAndBackjumpIfNecessary(noGoodEntry.getKey(), noGoodEntry.getValue(), LBD_NO_VALUE); + + } + + private boolean choose() { + choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); + choiceManager.updateAssignments(); + + // Hint: for custom heuristics, evaluate them here and pick a value if the heuristics suggests one. + + int literal; + + if ((literal = branchingHeuristic.chooseLiteral()) == DEFAULT_CHOICE_LITERAL) { + LOGGER.debug("No choices!"); + return false; + } else if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Branching heuristic chose literal {}", atomStore.literalToString(literal)); + } + + choiceManager.choose(new Choice(literal, false)); + return true; + } + + @Override + public int getNumberOfChoices() { + return choiceManager.getChoices(); + } + + @Override + public int getNumberOfBacktracks() { + return choiceManager.getBacktracks(); + } + + @Override + public int getNumberOfBacktracksWithinBackjumps() { + return choiceManager.getBacktracksWithinBackjumps(); + } + + @Override + public int getNumberOfBackjumps() { + return choiceManager.getBackjumps(); + } + + @Override + public int getNumberOfBacktracksDueToRemnantMBTs() { + return mbtAtFixpoint; + } + + @Override + public int getNumberOfConflictsAfterClosing() { + return conflictsAfterClosing; + } + + @Override + public int getNumberOfDeletedNoGoods() { + if (!(store instanceof NoGoodStoreAlphaRoaming)) { + return 0; + } + return ((NoGoodStoreAlphaRoaming)store).getLearnedNoGoodDeletion().getNumberOfDeletedNoGoods(); + } + + @Override + public NoGoodCounter getNoGoodCounter() { + return store.getNoGoodCounter(); + } + + private void logStats() { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(getStatisticsString()); + if (branchingHeuristic instanceof ChainedBranchingHeuristics) { + LOGGER.debug("Decisions made by each heuristic:"); + for (Entry heuristicToDecisionCounter : ((ChainedBranchingHeuristics)branchingHeuristic).getNumberOfDecisions().entrySet()) { + LOGGER.debug("{}: {}", heuristicToDecisionCounter.getKey(), heuristicToDecisionCounter.getValue()); + } + } + NoGoodCounter noGoodCounter = store.getNoGoodCounter(); + LOGGER.debug("Number of NoGoods by type: {}", noGoodCounter.getStatsByType()); + LOGGER.debug("Number of NoGoods by cardinality: {}", noGoodCounter.getStatsByCardinality()); + AtomCounter atomCounter = atomStore.getAtomCounter(); + LOGGER.debug("Number of atoms by type: {}", atomCounter.getStatsByType()); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java new file mode 100644 index 000000000..a17264654 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java @@ -0,0 +1,116 @@ +package at.ac.tuwien.kr.alpha.solver; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +/** + * Realizes a learned NoGood deletion strategy based on LBD and activity of NoGoods. + * + * Copyright (c) 2019, the Alpha Team. + */ +class LearnedNoGoodDeletion { + private static final Logger LOGGER = LoggerFactory.getLogger(LearnedNoGoodDeletion.class); + public static final int RESET_SEQUENCE_AFTER = 20; + public static final int RUN_AFTER_AT_LEAST = 2000; + public static final int GROWTH_FACTOR = 100; + private final ArrayList learnedNoGoods = new ArrayList<>(); // List of learned NoGoods that can be removed again. Note: should only contain NoGoods of size > 2. + private final NoGoodStoreAlphaRoaming store; + private final Assignment assignment; + private int conflictCounter; + private int cleanupCounter; + private int numberOfDeletedNoGoods; + + LearnedNoGoodDeletion(NoGoodStoreAlphaRoaming store, Assignment assignment) { + this.store = store; + this.assignment = assignment; + } + + void reset() { + learnedNoGoods.clear(); + conflictCounter = 0; + cleanupCounter = 0; + numberOfDeletedNoGoods = 0; + } + + /** + * Returns WatchedNoGoods known to {@link LearnedNoGoodDeletion}. + * Note: this is likely just a subset of all learned nogoods. + * @return an unmodifiable list of {@link WatchedNoGood}s. + */ + public List inspectLearnedNoGoods() { + return Collections.unmodifiableList(learnedNoGoods); + } + + void recordLearnedNoGood(WatchedNoGood learnedWatchedNoGood) { + learnedNoGoods.add(learnedWatchedNoGood); + } + + void increaseConflictCounter() { + conflictCounter++; + } + + boolean needToRunNoGoodDeletion() { + return conflictCounter > RUN_AFTER_AT_LEAST + (GROWTH_FACTOR * cleanupCounter); + } + + void runNoGoodDeletion() { + conflictCounter = 0; + cleanupCounter++; + // Reset the sequence after enough growth cycles. + if (cleanupCounter > RESET_SEQUENCE_AFTER) { + cleanupCounter = 0; + } + int deletedNoGoods = 0; + int originalSize = learnedNoGoods.size(); + if (originalSize == 0) { + return; + } + int toDeleteMax = originalSize / 2; + long activitySum = 0; + for (WatchedNoGood learnedNoGood : learnedNoGoods) { + activitySum += learnedNoGood.getActivity(); + } + double avgActivity = (double) activitySum / originalSize; + double scoreThreshold = avgActivity * 1.5; + for (Iterator iterator = learnedNoGoods.iterator(); iterator.hasNext();) { + WatchedNoGood learnedNoGood = iterator.next(); + if (deletedNoGoods >= toDeleteMax) { + break; + } + boolean keepNoGood = isLocked(learnedNoGood, assignment) + || learnedNoGood.getActivity() > scoreThreshold + || learnedNoGood.isLbdLessOrEqual2(); + if (!keepNoGood) { + iterator.remove(); + store.removeFromWatches(learnedNoGood); + learnedNoGood.decreaseActivity(); + deletedNoGoods++; + LOGGER.trace("Removed from store the NoGood: {}", learnedNoGood); + } + } + LOGGER.debug("Removed {} NoGoods from store.", deletedNoGoods); + this.numberOfDeletedNoGoods += deletedNoGoods; + } + + private boolean isLocked(WatchedNoGood noGood, Assignment assignment) { + int watchedAtom1 = atomOf(noGood.getLiteral(0)); + int watchedAtom2 = atomOf(noGood.getLiteral(1)); + if (!assignment.isAssigned(watchedAtom1) || !assignment.isAssigned(watchedAtom2)) { + return false; + } + return noGood == assignment.getImpliedBy(watchedAtom1) + || noGood == assignment.getImpliedBy(watchedAtom2); + } + + public int getNumberOfDeletedNoGoods() { + return numberOfDeletedNoGoods; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java new file mode 100644 index 000000000..28af2719c --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java @@ -0,0 +1,231 @@ +/** + * 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. + * + * 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.solver; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; + +import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; + +public class NaiveNoGoodStore implements NoGoodStore { + private static final Logger LOGGER = LoggerFactory.getLogger(NaiveNoGoodStore.class); + + private HashMap delegate = new HashMap<>(); + private final WritableAssignment assignment; + private final NoGoodCounter counter = new NoGoodCounter(); + + private boolean hasInferredAssignments; + + public NaiveNoGoodStore(WritableAssignment assignment) { + this.assignment = assignment; + } + + void clear() { + assignment.clear(); + delegate.clear(); + } + + @Override + public ConflictCause add(int id, NoGood noGood, int lbd) { + counter.add(noGood); + if (assignment.violates(noGood)) { + return new ConflictCause(noGood.asAntecedent()); + } + + delegate.put(id, noGood); + return null; + } + + @Override + public ConflictCause add(int id, NoGood noGood) { + return add(id, noGood, Integer.MAX_VALUE); + } + + @Override + public ConflictCause propagate() { + hasInferredAssignments = false; + + boolean any = false; + boolean retry; + + do { + retry = false; + ConflictCause conflictCause; + for (NoGood noGood : delegate.values()) { + hasInferredAssignments = false; + conflictCause = propagateWeakly(noGood); + if (conflictCause != null) { + return conflictCause; + } + if (hasInferredAssignments) { + any = true; + hasInferredAssignments = false; + retry = true; + } + } + for (NoGood noGood : delegate.values()) { + hasInferredAssignments = false; + conflictCause = propagateStrongly(noGood); + if (conflictCause != null) { + return conflictCause; + } + if (hasInferredAssignments) { + any = true; + hasInferredAssignments = false; + retry = true; + } + } + } while (retry); + + for (NoGood noGood : delegate.values()) { + if (assignment.violates(noGood)) { + return new ConflictCause(noGood.asAntecedent()); + } + } + + if (any) { + hasInferredAssignments = true; + } + + return null; + } + + @Override + public boolean didPropagate() { + return hasInferredAssignments; + } + + @Override + public void backtrack() { + assignment.backtrack(); + } + + @Override + public void growForMaxAtomId(int maxAtomId) { + } + + @Override + public NoGoodCounter getNoGoodCounter() { + return counter; + } + + @Override + public void cleanupLearnedNoGoods() { + } + + /** + * Infer an assignment from a nogood if it is weakly unit. + * + * This method iterates over all literals in the given nogood + * in order to check whether it is weakly unit. If the nogood + * turns out to be unit, then an assignment is generated and + * {@code true} is returned. Otherwise, {@code false} is + * returned. + * + * @param noGood the nogood to analyze. + * @return {@code true} iff an assignment was inferred, + * {@code false} otherwise. + */ + private ConflictCause propagateWeakly(NoGood noGood) { + int index = -1; + for (int i = 0; i < noGood.size(); i++) { + final int literal = noGood.getLiteral(i); + + if (assignment.isAssigned(atomOf(literal))) { + if (!assignment.isViolated(literal)) { + // Literal is satisfied! + return null; + } + } else if (index != -1) { + // There is more than one unassigned literal! + return null; + } else { + index = i; + } + } + + if (index == -1) { + return null; + } + + hasInferredAssignments = true; + + final int literal = noGood.getLiteral(index); + return assignment.assign(atomOf(literal), isNegated(literal) ? MBT : FALSE, noGood.asAntecedent()); + } + + /** + * Infer an assignment from a nogood if it is strongly unit. + * + * This method iterates over all literals in the given nogood + * in order to check whether it is strongly unit. If the nogood + * turns out to be unit, then an assignment for the head is + * generated and {@code true} is returned. Otherwise, + * {@code false} is returned. + * + * @param noGood the nogood to analyze. + * @return {@code true} iff an assignment was inferred, + * {@code false} otherwise. + */ + private ConflictCause propagateStrongly(NoGood noGood) { + if (!noGood.hasHead()) { + return null; + } + + final int headAtom = atomOf(noGood.getHead()); + + if (assignment.getTruth(headAtom) != MBT) { + return null; + } + + // Check that NoGood is violated except for the head + // (i.e., without the head set it would be unit) and + // that none of the true values are assigned MBT, but + // instead are all TRUE. + for (int i = 1; i < noGood.size(); i++) { + final int literal = noGood.getLiteral(i); + + if (!assignment.isViolated(literal)) { + return null; + } + + // Skip if positive literal is assigned MBT. + if (isPositive(literal) && assignment.getTruth(atomOf(literal)) != TRUE) { + return null; + } + } + + hasInferredAssignments = true; + + return assignment.assign(headAtom, TRUE, noGood.asAntecedent()); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java new file mode 100644 index 000000000..bf8f08268 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java @@ -0,0 +1,432 @@ +/** + * Copyright (c) 2016, 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.solver; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.IntIterator; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.function.Consumer; + +import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static java.lang.Math.abs; + +/** + * Copyright (c) 2016-2020, the Alpha Team. + */ +public class NaiveSolver extends AbstractSolver { + private static final Logger LOGGER = LoggerFactory.getLogger(NaiveSolver.class); + private final Stack choiceStack; + private HashMap truthAssignments = new HashMap<>(); + private ArrayList newTruthAssignments = new ArrayList<>(); + private ArrayList> decisionLevels = new ArrayList<>(); + + private HashMap knownNoGoods = new HashMap<>(); + + private boolean doInit = true; + private boolean didChange; + private int decisionLevel; + + private Map choiceOn = new HashMap<>(); + private Map choiceOff = new HashMap<>(); + private Integer nextChoice; + private HashSet mbtAssigned = new HashSet<>(); + private ArrayList> mbtAssignedFromUnassigned = new ArrayList<>(); + private ArrayList> trueAssignedFromMbt = new ArrayList<>(); + private List unassignedAtoms; + + NaiveSolver(AtomStore atomStore, Grounder grounder) { + super(atomStore, grounder); + + this.choiceStack = new Stack<>(); + + decisionLevels.add(0, new ArrayList<>()); + mbtAssignedFromUnassigned.add(0, new ArrayList<>()); + trueAssignedFromMbt.add(0, new ArrayList<>()); + } + + @Override + protected boolean tryAdvance(Consumer action) { + // Get basic rules and facts from grounder + if (doInit) { + obtainNoGoodsFromGrounder(); + doInit = false; + } else { + // We already found one Answer-Set and are requested to find another one + doBacktrack(); + if (isSearchSpaceExhausted()) { + return false; + } + } + + // Try all assignments until grounder reports no more NoGoods and all of them are satisfied + while (true) { + if (!propagationFixpointReached()) { + LOGGER.trace("Propagating."); + updateGrounderAssignments(); // After a choice, it would be more efficient to propagate first and only then ask the grounder. + obtainNoGoodsFromGrounder(); + doUnitPropagation(); + doMBTPropagation(); + LOGGER.trace("Assignment after propagation is: {}", truthAssignments); + } else if (assignmentViolatesNoGoods()) { + LOGGER.trace("Backtracking from wrong choices:"); + LOGGER.trace("Choice stack: {}", choiceStack); + doBacktrack(); + if (isSearchSpaceExhausted()) { + return false; + } + } else if (choicesLeft()) { + doChoice(); + } else if (!allAtomsAssigned()) { + LOGGER.trace("Closing unassigned known atoms (assigning FALSE)."); + assignUnassignedToFalse(); + didChange = true; + } else if (noMBTValuesReamining()) { + AnswerSet as = getAnswerSetFromAssignment(); + LOGGER.debug("Answer-Set found: {}", as); + LOGGER.trace("Choice stack: {}", choiceStack); + action.accept(as); + return true; + } else { + LOGGER.debug("Backtracking from wrong choices (MBT remaining):"); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Currently MBT:"); + for (Integer integer : mbtAssigned) { + LOGGER.trace(atomStore.atomToString(atomOf(integer))); + } + LOGGER.trace("Choice stack: {}", choiceStack); + } + doBacktrack(); + if (isSearchSpaceExhausted()) { + return false; + } + } + } + } + + private void assignUnassignedToFalse() { + for (Integer atom : unassignedAtoms) { + truthAssignments.put(atom, false); + newTruthAssignments.add(atom); + decisionLevels.get(decisionLevel).add(atom); + } + } + + private boolean allAtomsAssigned() { + unassignedAtoms = new ArrayList<>(); + HashSet knownAtoms = new HashSet<>(); + for (Map.Entry entry : knownNoGoods.entrySet()) { + for (Integer integer : entry.getValue()) { + knownAtoms.add(abs(integer)); + } + } + for (Integer atom : knownAtoms) { + if (!truthAssignments.containsKey(atom)) { + unassignedAtoms.add(atom); + } + } + return unassignedAtoms.isEmpty(); + } + + private boolean noMBTValuesReamining() { + return mbtAssigned.size() == 0; + } + + private void doMBTPropagation() { + boolean didPropagate = true; + while (didPropagate) { + didPropagate = false; + for (Map.Entry noGoodEntry : knownNoGoods.entrySet()) { + if (propagateMBT(noGoodEntry.getValue())) { + didPropagate = true; + didChange = true; + } + } + } + } + + private String reportTruthAssignments() { + StringBuilder report = new StringBuilder("Current Truth assignments: "); + for (Integer atomId : truthAssignments.keySet()) { + report.append(truthAssignments.get(atomId) ? "+" : "-").append(atomId).append(" "); + } + return report.toString(); + } + + private boolean propagationFixpointReached() { + // Check if anything changed. + // didChange is updated in places of change. + boolean changeCopy = didChange; + didChange = false; + return !changeCopy; + } + + private AnswerSet getAnswerSetFromAssignment() { + ArrayList trueAtoms = new ArrayList<>(); + for (Map.Entry atomAssignment : truthAssignments.entrySet()) { + if (atomAssignment.getValue()) { + trueAtoms.add(atomAssignment.getKey()); + } + } + return translate(trueAtoms); + } + + private void doChoice() { + decisionLevel++; + ArrayList list = new ArrayList<>(); + list.add(nextChoice); + decisionLevels.add(decisionLevel, list); + trueAssignedFromMbt.add(decisionLevel, new ArrayList<>()); + mbtAssignedFromUnassigned.add(decisionLevel, new ArrayList<>()); + // We choose true for any unassigned choice atom (backtrackFast tries false) + truthAssignments.put(nextChoice, true); + newTruthAssignments.add(nextChoice); + choiceStack.push(new Choice(nextChoice, true, false)); + // Record change to compute propagation fixpoint again. + didChange = true; + } + + private boolean choicesLeft() { + // Check if there is an enabled choice that is not also disabled + for (Map.Entry e : choiceOn.entrySet()) { + final int atom = e.getKey(); + + // Only consider unassigned choices that are enabled. + if (truthAssignments.containsKey(atom) || !truthAssignments.getOrDefault(e.getValue(), false)) { + continue; + } + + // Check that candidate is not disabled already + if (!truthAssignments.getOrDefault(choiceOff.getOrDefault(atom, 0), false)) { + nextChoice = atom; + return true; + } + } + return false; + } + + private void doBacktrack() { + if (decisionLevel <= 0) { + return; + } + + Choice lastChoice = choiceStack.pop(); + + int lastChoiceAtom = lastChoice.getAtom(); + boolean lastChoiceValue = lastChoice.getValue(); + + // Remove truth assignments of current decision level + for (Integer atomId : decisionLevels.get(decisionLevel)) { + truthAssignments.remove(atomId); + } + + // Handle MBT assigned values: + // First, restore mbt when it got assigned true in this decision level + mbtAssigned.addAll(trueAssignedFromMbt.get(decisionLevel)); + + // Second, remove mbt indicator for values that were unassigned + for (Integer atomId : mbtAssignedFromUnassigned.get(decisionLevel)) { + mbtAssigned.remove(atomId); + } + + // Clear atomIds in current decision level + decisionLevels.set(decisionLevel, new ArrayList<>()); + mbtAssignedFromUnassigned.set(decisionLevel, new ArrayList<>()); + trueAssignedFromMbt.set(decisionLevel, new ArrayList<>()); + + if (lastChoiceValue) { + // Choose false now + truthAssignments.put(lastChoiceAtom, false); + choiceStack.push(new Choice(lastChoiceAtom, false, true)); + newTruthAssignments.add(lastChoiceAtom); + decisionLevels.get(decisionLevel).add(lastChoiceAtom); + didChange = true; + } else { + decisionLevel--; + doBacktrack(); + } + } + + private static IntIterator fromIterator(Iterator it) { + return new IntIterator() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public int next() { + return it.next(); + } + }; + } + + private void updateGrounderAssignments() { + grounder.updateAssignment(fromIterator(newTruthAssignments.stream().filter(atom -> truthAssignments.get(atom)).iterator())); + newTruthAssignments.clear(); + } + + + private void obtainNoGoodsFromGrounder() { + final int oldSize = knownNoGoods.size(); + knownNoGoods.putAll(grounder.getNoGoods(null)); + if (oldSize != knownNoGoods.size()) { + // Record to detect propagation fixpoint, checking if new NoGoods were reported would be better here. + didChange = true; + } + + // Record choice atoms + final Pair, Map> choiceAtoms = grounder.getChoiceAtoms(); + choiceOn.putAll(choiceAtoms.getKey()); + choiceOff.putAll(choiceAtoms.getValue()); + } + + private boolean isSearchSpaceExhausted() { + return decisionLevel == 0; + } + + private void doUnitPropagation() { + // Check each NoGood if it is unit (naive algorithm) + for (NoGood noGood : knownNoGoods.values()) { + int implied = unitPropagate(noGood); + if (implied == -1) { // NoGood is not unit, skip. + continue; + } + int impliedLiteral = noGood.getLiteral(implied); + int impliedAtomId = atomOf(impliedLiteral); + boolean impliedTruthValue = isNegated(impliedLiteral); + if (truthAssignments.get(impliedAtomId) != null) { // Skip if value already was assigned. + continue; + } + truthAssignments.put(impliedAtomId, impliedTruthValue); + newTruthAssignments.add(impliedAtomId); + didChange = true; // Record to detect propagation fixpoint + decisionLevels.get(decisionLevel).add(impliedAtomId); + if (impliedTruthValue) { // Record MBT value in case true is assigned + mbtAssigned.add(impliedAtomId); + mbtAssignedFromUnassigned.get(decisionLevel).add(impliedAtomId); + } + } + } + + private boolean isLiteralAssigned(int literal) { + return truthAssignments.get(atomOf(literal)) != null; + } + + private boolean isLiteralViolated(int literal) { + final int atom = atomOf(literal); + final Boolean assignment = truthAssignments.get(atom); + + // For unassigned atoms, any literal is not violated. + return assignment != null && isNegated(literal) != assignment; + } + + /** + * Returns position of implied literal if input NoGood is unit. + * @param noGood + * @return -1 if NoGood is not unit. + */ + private int unitPropagate(NoGood noGood) { + int lastUnassignedPosition = -1; + for (int i = 0; i < noGood.size(); i++) { + int literal = noGood.getLiteral(i); + if (isLiteralAssigned(literal)) { + if (!isLiteralViolated(literal)) { + // The NoGood is satisfied, hence it cannot be unit. + return -1; + } + } else if (lastUnassignedPosition != -1) { + // NoGood is not unit, if there is not exactly one unassigned literal + return -1; + } else { + lastUnassignedPosition = i; + } + } + return lastUnassignedPosition; + } + + private boolean propagateMBT(NoGood noGood) { + // The MBT propagation checks whether the head-indicated literal is MBT + // and the remaining literals are violated + // and none of them are MBT, + // then the head literal is set from MBT to true. + + if (!noGood.hasHead()) { + return false; + } + + int headAtom = atomOf(noGood.getHead()); + + // Check whether head is assigned MBT. + if (!mbtAssigned.contains(headAtom)) { + return false; + } + + // Check that NoGood is violated except for the head (i.e., without the head set it would be unit) + // and that none of the true values is MBT. + for (int i = 1; i < noGood.size(); i++) { + int literal = noGood.getLiteral(i); + if (!(isLiteralAssigned(literal) && isLiteralViolated(literal))) { + return false; + } + // Skip if positive literal is assigned MBT. + if (isPositive(literal) && mbtAssigned.contains(atomOf(literal))) { + return false; + } + } + + // Set truth value from MBT to true. + mbtAssigned.remove(headAtom); + trueAssignedFromMbt.get(decisionLevel).add(headAtom); + return true; + } + + private boolean assignmentViolatesNoGoods() { + // Check each NoGood, if it is violated + for (NoGood noGood : knownNoGoods.values()) { + boolean isSatisfied = false; + for (Integer noGoodLiteral : noGood) { + if (!isLiteralAssigned(noGoodLiteral) || !isLiteralViolated(noGoodLiteral)) { + isSatisfied = true; + break; + } + } + if (!isSatisfied) { + LOGGER.trace("Violated NoGood: {}", noGood); + return true; + } + } + return false; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java new file mode 100644 index 000000000..432419ab1 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2019 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.solver; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface; + +import java.util.ArrayList; +import java.util.List; + +/** + * Maintains statistics on numbers of various types of {@link NoGood}s. + */ +public class NoGoodCounter { + + private static final int CARD_NARY = 0; + private static final int CARD_UNARY = 1; + private static final int CARD_BINARY = 2; + + private int[] countByType = new int[Type.values().length]; + private int[] countByCardinality = new int[3]; + + /** + * Increases counters for the types of the given NoGood + * @param noGood + */ + void add(NoGoodInterface noGood) { + countByType[noGood.getType().ordinal()]++; + countByCardinality[getAbstractCardinality(noGood)]++; + } + + /** + * Decreases counters for the types of the given NoGood + * @param noGood + */ + void remove(NoGoodInterface noGood) { + countByType[noGood.getType().ordinal()]--; + countByCardinality[getAbstractCardinality(noGood)]--; + } + + private int getAbstractCardinality(NoGoodInterface noGood) { + if (noGood.isUnary()) { + return CARD_UNARY; + } + if (noGood.isBinary()) { + return CARD_BINARY; + } + return CARD_NARY; + } + + /** + * @param type + * @return the number of nogoods of the given type + */ + public int getNumberOfNoGoods(Type type) { + return countByType[type.ordinal()]; + } + + /** + * @return the number of unary nogoods + */ + public int getNumberOfUnaryNoGoods() { + return countByCardinality[CARD_UNARY]; + } + + /** + * @return the number of binary nogoods + */ + public int getNumberOfBinaryNoGoods() { + return countByCardinality[CARD_BINARY]; + } + + /** + * @return the number of nogoods that are neither unary nor binary + */ + public int getNumberOfNAryNoGoods() { + return countByCardinality[CARD_NARY]; + } + + /** + * @return {@code true} iff there is at least one binary nogood + */ + public boolean hasBinaryNoGoods() { + return countByCardinality[CARD_BINARY] > 0; + } + + /** + * @return a string giving statistics on numbers of nogoods by type + */ + public String getStatsByType() { + List statsList = new ArrayList<>(Type.values().length); + for (Type type : Type.values()) { + statsList.add(type.name() + ": " + countByType[type.ordinal()]); + } + return String.join(" ", statsList); + } + + /** + * @return a string giving statistics on numbers of nogoods by cardinality + */ + public String getStatsByCardinality() { + return "unary: " + getNumberOfUnaryNoGoods() + " binary: " + getNumberOfBinaryNoGoods() + " larger: " + getNumberOfNAryNoGoods(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java new file mode 100644 index 000000000..7cd516b40 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java @@ -0,0 +1,58 @@ +package at.ac.tuwien.kr.alpha.solver; + +import at.ac.tuwien.kr.alpha.common.NoGood; + +/** + * An interface defining the use of a NoGood store. + * + * Copyright (c) 2016-2019, the Alpha Team. + */ +public interface NoGoodStore { + int LBD_NO_VALUE = -1; + + /** + * Adds a nogood with the given id. + * @param id the unique identifier of the nogood. + * @param noGood the nogood to add. + * @param lbd the literals block distance. + * @return {@code null} if the noGood was added without conflict, a {@link ConflictCause} describing + * the conflict otherwise. + */ + ConflictCause add(int id, NoGood noGood, int lbd); + + /** + * Adds a NoGood with no LBD value set. + * @param id the unique identifier of the NoGood. + * @param noGood the NoGood to add. + * @return {@code null} if the noGood was added without conflict, a {@link ConflictCause} describing +* * the conflict otherwise. + */ + ConflictCause add(int id, NoGood noGood); + + /** + * Apply weak propagation and strong propagation. Propagation should stop as soon as some nogood is violated. + * @return some cause iff a conflict was reached or {@code null} otherwise + */ + ConflictCause propagate(); + + /** + * After a call to {@link #propagate()} this method provides + * whether propagation was successful, i.e. at least one new + * assignment was inferred. + * @return {@code true} iff the last call to {@link #propagate()} + * inferred at least one assignment, {@code false} otherwise. + */ + boolean didPropagate(); + + void backtrack(); + + void growForMaxAtomId(int maxAtomId); + + /** + * Tests whether a cleanup of the learned NoGoods database is appropriate and exectutes the cleaning if + * necessary. + */ + void cleanupLearnedNoGoods(); + + NoGoodCounter getNoGoodCounter(); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java new file mode 100644 index 000000000..125b70976 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java @@ -0,0 +1,1003 @@ +/* + * Copyright (c) 2016-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.solver; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; +import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; +import static at.ac.tuwien.kr.alpha.common.Literals.literalToString; +import static at.ac.tuwien.kr.alpha.common.NoGood.HEAD; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; + +/** + * NoGoodStore using for each NoGood three watches, two ordinary ones and an alpha watch. + * The alpha watch may point to positive or negative literals but not the head of the NoGood. + * + * Note the following invariant for watches: + * (Inv): For every NoGood it either holds that both watched literals are unassigned, or for one watch holds: it + * points to a literal that is assigned a satisfying truth value at decision level d and the other + * watched literal is assigned at decision level d' such that d <= d'. + * The second condition ensures that after backtracking the NoGood is still satisfied or both watches + * point to unassigned literals. Observe that for an assignment to TRUE the (potentially lower) decision level of MBT + * is taken. + * + * Copyright (c) 2017-2020, the Alpha Team. + */ +public class NoGoodStoreAlphaRoaming implements NoGoodStore, BinaryNoGoodPropagationEstimation, Checkable { + private static final Logger LOGGER = LoggerFactory.getLogger(NoGoodStoreAlphaRoaming.class); + private static final int UNASSIGNED = Integer.MAX_VALUE; + + private final WritableAssignment assignment; + private final LearnedNoGoodDeletion learnedNoGoodDeletion; + @SuppressWarnings("unchecked") + private ArrayList[] watches = new ArrayList[0]; + @SuppressWarnings("unchecked") + private ArrayList[] watchesAlpha = new ArrayList[0]; + private BinaryWatchList[] binaryWatches = new BinaryWatchList[0]; + private int maxAtomId; + + private boolean checksEnabled; + private boolean didPropagate; + private boolean hasBinaryNoGoods; + + private final NoGoodCounter counter = new NoGoodCounter(); + + public NoGoodStoreAlphaRoaming(WritableAssignment assignment, boolean checksEnabled) { + this.assignment = assignment; + this.checksEnabled = checksEnabled; + this.learnedNoGoodDeletion = new LearnedNoGoodDeletion(this, assignment); + } + + public NoGoodStoreAlphaRoaming(WritableAssignment assignment) { + this(assignment, false); + } + + @SuppressWarnings("unchecked") + void clear() { + assignment.clear(); + learnedNoGoodDeletion.reset(); + binaryWatches = new BinaryWatchList[0]; + watches = new ArrayList[0]; + watchesAlpha = new ArrayList[0]; + maxAtomId = 0; + } + + public LearnedNoGoodDeletion getLearnedNoGoodDeletion() { + return learnedNoGoodDeletion; + } + + @Override + public void backtrack() { + didPropagate = false; + assignment.backtrack(); + if (checksEnabled) { + if (assignment.getAssignmentsToProcess().isEmpty()) { + new WatchedNoGoodsChecker().doWatchesCheck(); + } else { + LOGGER.trace("Skipping watches check since there are assignments to process first."); + } + } + } + + @Override + public void growForMaxAtomId(int maxAtomId) { + int requiredMaxSize = 2 * (maxAtomId + 2); + if (requiredMaxSize < binaryWatches.length) { + return; + } + int newCapacity = arrayGrowthSize(binaryWatches.length); + if (newCapacity < requiredMaxSize) { + newCapacity = requiredMaxSize; + } + int oldlength = binaryWatches.length; + binaryWatches = Arrays.copyOf(binaryWatches, newCapacity); + for (int i = oldlength; i < binaryWatches.length; i++) { + binaryWatches[i] = new BinaryWatchList(i); + } + watches = Arrays.copyOf(watches, newCapacity); + for (int i = oldlength; i < watches.length; i++) { + watches[i] = new ArrayList<>(); + } + watchesAlpha = Arrays.copyOf(watchesAlpha, newCapacity); + for (int i = oldlength; i < watchesAlpha.length; i++) { + watchesAlpha[i] = new ArrayList<>(); + } + this.maxAtomId = maxAtomId; + } + + @Override + public NoGoodCounter getNoGoodCounter() { + return counter; + } + + @Override + public void cleanupLearnedNoGoods() { + if (learnedNoGoodDeletion.needToRunNoGoodDeletion()) { + learnedNoGoodDeletion.runNoGoodDeletion(); + } + } + + void removeFromWatches(WatchedNoGood toRemove) { + counter.remove(toRemove); + int watchedLiteral1 = toRemove.getLiteral(0); + int watchedLiteral2 = toRemove.getLiteral(1); + if (!watches(watchedLiteral2).remove(toRemove) + || !watches(watchedLiteral1).remove(toRemove)) { + throw oops("Could not remove learned NoGood from watch lists."); + } + if (toRemove.hasHead()) { + throw oops("NoGood has a head."); // If this occurs, we need to remove the alpha watch too. + } + } + + private ArrayList watches(int literal) { + return watches[literal]; + } + + private ArrayList watchesAlpha(int literal) { + return watchesAlpha[literal]; + } + + private void addOrdinaryWatch(WatchedNoGood wng, int pointer) { + final int literal = wng.getLiteral(pointer); + watches(literal).add(wng); + } + + private void addAlphaWatch(WatchedNoGood wng) { + final int literal = wng.getLiteralAtAlpha(); + watchesAlpha(literal).add(wng); + } + + @Override + public ConflictCause add(int id, NoGood noGood, int lbd) { + LOGGER.trace("Adding {}", noGood); + + final ConflictCause conflictCause; + if (noGood.isUnary()) { + conflictCause = addUnary(noGood); + } else if (noGood.isBinary()) { + conflictCause = addAndWatchBinary(noGood); + } else { + conflictCause = addAndWatch(noGood, lbd); + } + + if (conflictCause == null) { + counter.add(noGood); + } + return conflictCause; + } + + public ConflictCause add(int id, NoGood noGood) { + return add(id, noGood, -1); + } + + /** + * Takes a noGood containing only a single literal and translates it into an assignment (because it + * is trivially unit). Still, a check for conflict is performed. + */ + private ConflictCause addUnary(final NoGood noGood) { + if (noGood.hasHead()) { + return assignStrongComplement(noGood, 0); + } else { + return assignWeakComplement(0, noGood, 0); + } + } + + private static boolean isComplementaryAssigned(int literal, ThriceTruth literalTruth) { + return literalTruth != null && literalTruth.toBoolean() != isPositive(literal); + } + + private int strongDecisionLevel(int atom) { + int strongDecisionLevel = assignment.getStrongDecisionLevel(atom); + return strongDecisionLevel == -1 ? UNASSIGNED : strongDecisionLevel; + } + + private ConflictCause addAndWatch(final NoGood noGood, int lbd) { + // Collect potential watch candidates. + int posWeakUnassigned1 = -1; + int posWeakUnassigned2 = -1; + int posSatisfiedLiteral1 = -1; + int posSatisfiedLiteral2 = -1; + int posWeakHighestAssigned = -1; + int weakDecisionLevelHighestAssigned = -1; + int posStrongHighestAssigned = -1; + int strongDecisionLevelHighestAssigned = -1; + int posPotentialAlphaWatch = -1; + int satisfiedLiteralWeakDecisionLevel = -1; + + // Used to detect always-satisfied NoGoods of form { L, -L, ... }. + Map occurringAtomPolarity = new HashMap<>(); + + // Iterate noGood and record satisfying/unassigned/etc positions. + int headAtom = atomOf(noGood.getHead()); + final ThriceTruth headTruth = noGood.hasHead() ? assignment.getTruth(headAtom) : null; + final boolean isHeadTrue = headTruth == TRUE; + for (int i = 0; i < noGood.size(); i++) { + final int literal = noGood.getLiteral(i); + final int atom = atomOf(literal); + final ThriceTruth atomTruthValue = assignment.getTruth(atom); + final int atomWeakDecisionLevel = assignment.getWeakDecisionLevel(atom); + final int atomStrongDecisionLevel = assignment.getStrongDecisionLevel(atom); + + // Check if NoGood can never be violated (atom occurring positive and negative) + if (occurringAtomPolarity.containsKey(atomOf(literal))) { + if (occurringAtomPolarity.get(atomOf(literal)) != isNegated(literal)) { + // NoGood cannot be violated or propagate, ignore it. + LOGGER.debug("Added NoGood can never propagate or be violated, ignoring it. NoGood is: {}", noGood); + return null; + } + } else { + occurringAtomPolarity.put(atomOf(literal), isNegated(literal)); + } + + // Check weak unassigned. + if (atomTruthValue == null) { + if (posWeakUnassigned1 == -1) { + posWeakUnassigned1 = i; + } else { + posWeakUnassigned2 = i; + } + } + // Alpha watch: + if (posPotentialAlphaWatch == -1 && noGood.hasHead() && i != HEAD) { + // Current literal is potential alpha watch if: + // 1) the head of the nogood is true and the literal is assigned at a higher-or-equal decision level. + // 2) the literal is complementary assigned and thus satisfies the nogood, or + // 3) the literal is unassigned or assigned must-be-true. + if (isHeadTrue && strongDecisionLevel(atomOf(literal)) >= strongDecisionLevel(headAtom) + || isComplementaryAssigned(noGood.getLiteral(i), atomTruthValue) + || strongDecisionLevel(atomOf(literal)) == Integer.MAX_VALUE) { + posPotentialAlphaWatch = i; + } + } + // Check satisfaction + if (atomTruthValue != null && atomTruthValue.toBoolean() != isPositive(literal)) { + if (posSatisfiedLiteral1 == -1) { + posSatisfiedLiteral1 = i; + satisfiedLiteralWeakDecisionLevel = atomWeakDecisionLevel; + } else { + posSatisfiedLiteral2 = i; + } + } + // Check violation. + if (atomTruthValue != null && atomTruthValue.toBoolean() == isPositive(literal)) { + if (atomWeakDecisionLevel > weakDecisionLevelHighestAssigned) { + weakDecisionLevelHighestAssigned = atomWeakDecisionLevel; + posWeakHighestAssigned = i; + } + if (!atomTruthValue.isMBT() && noGood.hasHead() // Ensure strong violation. + && atomStrongDecisionLevel > strongDecisionLevelHighestAssigned) { + strongDecisionLevelHighestAssigned = atomStrongDecisionLevel; + posStrongHighestAssigned = i; + } + } + } + + // Set ordinary and alpha watches now. + // Compute ordinary watches: + final int watch1; + final int watch2; + + + if (posWeakUnassigned1 != -1 && posWeakUnassigned2 != -1) { + // NoGood has two unassigned literals. + watch1 = posWeakUnassigned1; + watch2 = posWeakUnassigned2; + } else if (posSatisfiedLiteral1 != -1) { + // NoGood is satisfied. + int bestSecondPointer = posSatisfiedLiteral2 != -1 ? posSatisfiedLiteral2 + : posWeakUnassigned1 != -1 ? posWeakUnassigned1 + : posWeakHighestAssigned; + if (posSatisfiedLiteral2 == -1 && posWeakUnassigned1 == -1) { + // The NoGood has only one satisfied literal and is unit without it. + // If it is unit on lower decision level than it is satisfied, it propagates the satisfying literal on lower decision level. + if (satisfiedLiteralWeakDecisionLevel > weakDecisionLevelHighestAssigned) { + ConflictCause conflictCause = assignWeakComplement(posSatisfiedLiteral1, noGood, weakDecisionLevelHighestAssigned); + if (conflictCause != null) { + return conflictCause; + } + } + } + watch1 = posSatisfiedLiteral1; + watch2 = bestSecondPointer; + } else if (posWeakUnassigned1 != -1) { + // NoGood is weakly unit; propagate. + ConflictCause conflictCause = assignWeakComplement(posWeakUnassigned1, noGood, weakDecisionLevelHighestAssigned); + if (conflictCause != null) { + return conflictCause; + } + watch1 = posWeakUnassigned1; + watch2 = posWeakHighestAssigned; + } else { + // NoGood is violated. + return new ConflictCause(noGood.asAntecedent()); + } + + // Compute alpha watch: + int watchAlpha = -1; + if (noGood.hasHead()) { + if (posPotentialAlphaWatch != -1) { + // Found potential alpha watch. + watchAlpha = posPotentialAlphaWatch; + } else { + // No potential alpha watch found: noGood must be strongly unit. + ConflictCause conflictCause = assignStrongComplement(noGood, strongDecisionLevelHighestAssigned); + if (conflictCause != null) { + return conflictCause; + } + watchAlpha = posStrongHighestAssigned; + } + } + WatchedNoGood wng = new WatchedNoGood(noGood, watch1, watch2, watchAlpha); + LOGGER.trace("WatchedNoGood is {}.", wng); + + // Record for eventual removal if this NoGood is learned. + if (noGood.getType() == Type.LEARNT) { + wng.setLBD(lbd); + learnedNoGoodDeletion.recordLearnedNoGood(wng); + } + + if (wng.getAlphaPointer() == -1 && noGood.hasHead()) { + throw oops("Did not set alpha watch for nogood with head."); + } + + // Register alpha watch if present. + if (wng.getAlphaPointer() != -1) { + addAlphaWatch(wng); + } + // Set ordinary watches. + addOrdinaryWatch(wng, 0); + addOrdinaryWatch(wng, 1); + return null; + } + + private ConflictCause addAndWatchBinary(final NoGood noGood) { + // Shorthands for viewing the nogood as { a, b }. + final int a = noGood.getLiteral(0); + final int b = noGood.getLiteral(1); + final int atomA = atomOf(a); + final int atomB = atomOf(b); + + // Ignore NoGoods of the form { -a, a }. + if (a != b && atomA == atomB) { + return null; + } + + // Note: it might be faster to not check explicitly for violation but wait for conflict from assign. + final ThriceTruth atomATruthValue = assignment.getTruth(atomA); + final ThriceTruth atomBTruthValue = assignment.getTruth(atomB); + + final boolean isViolatedA = atomATruthValue != null && isPositive(a) == atomATruthValue.toBoolean(); + final boolean isViolatedB = atomBTruthValue != null && isPositive(b) == atomBTruthValue.toBoolean(); + + // Check for violation. + if (isViolatedA && isViolatedB) { + return new ConflictCause(noGood.asAntecedent()); + } + + // The above violation check guarantees that adding (and propagation on other literal) results in no conflict. + binaryWatches[a].add(noGood); + binaryWatches[b].add(noGood); + hasBinaryNoGoods = true; + return null; + } + + private ConflictCause assignWeakComplement(final int literalIndex, final NoGoodInterface impliedBy, int decisionLevel) { + final int literal = impliedBy.getLiteral(literalIndex); + ThriceTruth truth = isNegated(literal) ? MBT : FALSE; + return assignTruth(atomOf(literal), truth, impliedBy.asAntecedent(), decisionLevel); + } + + private ConflictCause assignStrongComplement(final NoGoodInterface impliedBy, int decisionLevel) { + return assignTruth(atomOf(impliedBy.getHead()), TRUE, impliedBy.asAntecedent(), decisionLevel); + } + + private ConflictCause assignTruth(int atom, ThriceTruth truth, Antecedent impliedBy, int decisionLevel) { + ConflictCause cause = assignment.assign(atom, truth, impliedBy, decisionLevel); + if (cause == null) { + didPropagate = true; + } + return cause; + } + + /** + * Propagates from Unassigned to MBT/FALSE. + * @param literal the literal that triggers the propagation. + */ + private ConflictCause propagateWeakly(int literal, int currentDecisionLevel, boolean restrictToBinaryNoGoods) { + final ArrayList watchesOfAssignedAtom = watches(literal); + + // Propagate binary watches. + ConflictCause conflictCause = binaryWatches[literal].propagateWeakly(); + if (conflictCause != null || restrictToBinaryNoGoods) { + return conflictCause; + } + + // Check all watched multi-ary NoGoods. + Iterator watchIterator = watchesOfAssignedAtom.iterator(); + clearOrdinaryWatchList(literal); + while (watchIterator.hasNext()) { + WatchedNoGood nextNoGood = watchIterator.next(); + conflictCause = processWeaklyWatchedNoGood(literal, nextNoGood, currentDecisionLevel); + if (conflictCause != null) { + // Copy over all non-treated NoGoods, so that they can be treated after backtracking. + ArrayList watchlist = watches(literal); + watchlist.add(nextNoGood); + while (watchIterator.hasNext()) { + watchlist.add(watchIterator.next()); + } + return conflictCause; + } + } + return null; + } + + private ConflictCause processWeaklyWatchedNoGood(int assignedLiteral, WatchedNoGood watchedNoGood, int currentDecisionLevel) { + final int assignedWatch = watchedNoGood.getLiteral(0) == assignedLiteral ? 0 : 1; + final int otherWatch = 1 - assignedWatch; + + final int otherLiteral = watchedNoGood.getLiteral(otherWatch); + final ThriceTruth otherAtomTruth = assignment.getTruth(atomOf(otherLiteral)); + + // Find new literal to watch. + + // Check if the other watch already satisfies the noGood. + if (otherAtomTruth != null && otherAtomTruth.toBoolean() != isPositive(otherLiteral)) { + // Keep this watch and return early. + addOrdinaryWatch(watchedNoGood, assignedWatch); + return null; + } else { + for (int i = 2; i < watchedNoGood.size(); i++) { + final int currentLiteral = watchedNoGood.getLiteral(i); + final ThriceTruth currentTruth = assignment.getTruth(atomOf(currentLiteral)); + + // Break if: 1) current literal is unassigned, or 2) satisfies the nogood. + if (currentTruth == null || currentTruth.toBoolean() != isPositive(currentLiteral)) { + // Move pointer to new literal. + watchedNoGood.setWatch(assignedWatch, i); + addOrdinaryWatch(watchedNoGood, assignedWatch); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Moved watch pointers of nogood:"); + logNoGoodAndAssignment(watchedNoGood, assignment); + } + return null; + } + } + } + + // NoGood is unit, propagate the other watched literal. + // Note: Violation is detected by Assignment. + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Nogood is unit:"); + logNoGoodAndAssignment(watchedNoGood, assignment); + } + ConflictCause conflictCause = assignWeakComplement(otherWatch, watchedNoGood, currentDecisionLevel); + // Return conflict if noGood is violated. + if (conflictCause != null) { + return conflictCause; + } + // Watch same literal again. + addOrdinaryWatch(watchedNoGood, assignedWatch); + return null; + } + + private void logNoGoodAndAssignment(WatchedNoGood noGood, Assignment assignment) { + if (!LOGGER.isTraceEnabled()) { + return; + } + StringBuilder sb = new StringBuilder("Watched NoGood is: " + noGood + "\t\t Assigned: "); + for (Integer literal : noGood) { + Assignment.Entry assignmentEntry = assignment.get(atomOf(literal)); + sb.append(atomOf(literal)); + sb.append("="); + sb.append(assignmentEntry); + sb.append(", "); + } + LOGGER.trace(sb.toString()); + } + + private ConflictCause propagateStrongly(int literal, int currentDecisionLevel, boolean restrictToBinaryNoGoods) { + + // Propagate binary watches. + ConflictCause conflictCause = binaryWatches[literal].propagateStrongly(); + if (conflictCause != null || restrictToBinaryNoGoods) { + return conflictCause; + } + + // Check all watched multi-ary NoGoods. + Iterator watchIterator = watchesAlpha(literal).iterator(); + clearAlphaWatchList(literal); + while (watchIterator.hasNext()) { + WatchedNoGood nextNoGood = watchIterator.next(); + if (!nextNoGood.hasHead()) { + throw oops("Strong propagation encountered NoGood without head"); + } + conflictCause = processStronglyWatchedNoGood(nextNoGood, currentDecisionLevel); + if (conflictCause != null) { + // Copy over all non-treated NoGoods, so that they can be treated after backtracking. + ArrayList watchlist = watchesAlpha(literal); + watchlist.add(nextNoGood); + while (watchIterator.hasNext()) { + watchlist.add(watchIterator.next()); + } + return conflictCause; + } + } + return null; + } + + private ConflictCause processStronglyWatchedNoGood(WatchedNoGood watchedNoGood, int currentDecisionLevel) { + + final int headAtom = atomOf(watchedNoGood.getHead()); + final ThriceTruth headAtomTruth = assignment.getTruth(headAtom); + // Check if the other watch, i.e., the head, already satisfies the noGood. + if (headAtomTruth != null && TRUE == headAtomTruth) { + // Keep this watch and return early. + addAlphaWatch(watchedNoGood); + return null; + } + + final int assignedIndex = watchedNoGood.getAlphaPointer(); + + // Find new literal to watch. + for (int i = 0; i < watchedNoGood.size(); i++) { + if (i == assignedIndex || i == watchedNoGood.getHeadIndex()) { + continue; + } + int currentLiteral = watchedNoGood.getLiteral(i); + int currentAtom = atomOf(currentLiteral); + ThriceTruth currentAtomTruth = assignment.getTruth(currentAtom); + + // Break if: 1) current literal is unassigned (or MBT), or 2) satisfies the nogood. + if (currentAtomTruth == null || currentAtomTruth.isMBT() || currentAtomTruth.toBoolean() != isPositive(currentLiteral)) { + // Move pointer to new literal. + watchedNoGood.setAlphaPointer(i); + addAlphaWatch(watchedNoGood); + return null; + } + } + + // NoGood is unit, propagate. + ConflictCause conflictCause = assignStrongComplement(watchedNoGood, currentDecisionLevel); + if (conflictCause != null) { + return conflictCause; + } + // Watch same literal again. + addAlphaWatch(watchedNoGood); + return null; + } + + @Override + public ConflictCause propagate() { + ConflictCause conflictCause = propagate(false); + if (conflictCause != null) { + learnedNoGoodDeletion.increaseConflictCounter(); + } + return conflictCause; + } + + private ConflictCause propagateOnlyBinaryNoGoods() { + return propagate(true); + } + + private ConflictCause propagate(boolean restrictToBinaryNoGoods) { + didPropagate = false; + + Assignment.Pollable assignmentsToProcess = assignment.getAssignmentsToProcess(); + int currentDecisionLevel = assignment.getDecisionLevel(); + while (!assignmentsToProcess.isEmpty()) { + final int atom = assignmentsToProcess.peek(); + final ThriceTruth currentTruth = assignment.getTruth(atom); + final int literal = atomToLiteral(atom, currentTruth.toBoolean()); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Propagation processing atom: {}={}", atom, currentTruth); + } + + // Propagate weakly, except if there is an earlier MBT, where propagation already took place. + if (currentTruth != TRUE || assignment.getWeakDecisionLevel(atom) == currentDecisionLevel) { + ConflictCause conflictCause = propagateWeakly(literal, currentDecisionLevel, restrictToBinaryNoGoods); + if (conflictCause != null) { + LOGGER.trace("Halting propagation due to conflict. Current assignment: {}.", assignment); + return conflictCause; + } + } + + // Propagate strongly only for TRUE/FALSE assignments. + if (currentTruth != MBT) { + ConflictCause conflictCause = propagateStrongly(literal, currentDecisionLevel, restrictToBinaryNoGoods); + if (conflictCause != null) { + LOGGER.trace("Halting propagation due to conflict. Current assignment: {}.", assignment); + return conflictCause; + } + } + assignmentsToProcess.remove(); + } + if (checksEnabled && !restrictToBinaryNoGoods) { + runInternalChecks(); + } + return null; + } + + @Override + public boolean didPropagate() { + return didPropagate; + } + + @Override + public void setChecksEnabled(boolean checksEnabled) { + this.checksEnabled = checksEnabled; + } + + class BinaryWatchList implements ShallowAntecedent { + private int[] noGoodsWithoutHead = new int[10]; + private int noGoodsWithoutHeadSize; + private int[] noGoodsWithHead = new int[10]; + private int noGoodsWithHeadSize; + private final int forLiteral; + + private BinaryWatchList(int forLiteral) { + this.forLiteral = forLiteral; + } + + ConflictCause add(NoGood noGood) { + if (!noGood.isBinary()) { + throw oops("Received noGood is not binary."); + } + if (noGood.hasHead() && noGood.getHead() != forLiteral) { + return addHeadedNoGood(noGood); + } else { + return addOrdinaryNoGood(noGood); + } + } + + private ConflictCause addHeadedNoGood(NoGood noGood) { + if (noGoodsWithHeadSize + 1 > noGoodsWithHead.length) { + noGoodsWithHead = Arrays.copyOf(noGoodsWithHead, arrayGrowthSize(noGoodsWithHeadSize)); + } + int otherLiteral = noGood.getLiteral(0) == forLiteral ? noGood.getLiteral(1) : noGood.getLiteral(0); + if (isPositive(otherLiteral)) { + throw oops("NoGood has wrong head."); + } + noGoodsWithHead[noGoodsWithHeadSize++] = otherLiteral; + // Assign (weakly) otherLiteral if the newly added NoGood is unit. + ThriceTruth literalTruth = assignment.getTruth(atomOf(forLiteral)); + if (literalTruth != null && literalTruth.toBoolean() == isPositive(forLiteral)) { + int weakDecisionLevel = assignment.getWeakDecisionLevel(atomOf(forLiteral)); + ConflictCause conflictCause = assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this, weakDecisionLevel); + if (conflictCause != null) { + return conflictCause; + } + } + // Assign head (strongly) if the newly added NoGood is unit. + int strongDecisionLevel = assignment.getStrongDecisionLevel(atomOf(forLiteral)); + if (strongDecisionLevel != -1 && assignment.getTruth(atomOf(forLiteral)).toBoolean() == isPositive(forLiteral)) { + return assignment.assign(atomOf(otherLiteral), TRUE, this, strongDecisionLevel); + } + return null; + } + + private ConflictCause addOrdinaryNoGood(NoGood noGood) { + if (noGoodsWithoutHeadSize + 1 > noGoodsWithoutHead.length) { + noGoodsWithoutHead = Arrays.copyOf(noGoodsWithoutHead, arrayGrowthSize(noGoodsWithoutHeadSize)); + } + int otherLiteral = noGood.getLiteral(0) == forLiteral ? noGood.getLiteral(1) : noGood.getLiteral(0); + noGoodsWithoutHead[noGoodsWithoutHeadSize++] = otherLiteral; + // Assign otherLiteral if the newly added NoGood is unit. + ThriceTruth literalTruth = assignment.getTruth(atomOf(forLiteral)); + if (literalTruth != null && literalTruth.toBoolean() == isPositive(forLiteral)) { + int weakDecisionLevel = assignment.getWeakDecisionLevel(atomOf(forLiteral)); + return assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this, weakDecisionLevel); + } + return null; + } + + ConflictCause propagateWeakly() { + didPropagate |= noGoodsWithHeadSize > 0 || noGoodsWithoutHeadSize > 0; + for (int i = 0; i < noGoodsWithoutHeadSize; i++) { + final int otherLiteral = noGoodsWithoutHead[i]; + ConflictCause conflictCause = assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this); + if (conflictCause != null) { + return conflictCause; + } + } + for (int i = 0; i < noGoodsWithHeadSize; i++) { + final int otherLiteral = noGoodsWithHead[i]; + ConflictCause conflictCause = assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this); + if (conflictCause != null) { + return conflictCause; + } + } + return null; + } + + ConflictCause propagateStrongly() { + didPropagate |= noGoodsWithHeadSize > 0; + for (int i = 0; i < noGoodsWithHeadSize; i++) { + final int headLiteral = noGoodsWithHead[i]; + ConflictCause conflictCause = assignment.assign(atomOf(headLiteral), TRUE, this); + if (conflictCause != null) { + return conflictCause; + } + } + return null; + } + + public int size() { + return noGoodsWithHeadSize + noGoodsWithoutHeadSize; + } + + @Override + public String toString() { + return "BinaryWatchList(" + forLiteral + ")"; + } + + @Override + public Antecedent instantiateAntecedent(int impliedLiteral) { + return new BinaryAntecedent(impliedLiteral, forLiteral); + } + + private class BinaryAntecedent implements Antecedent { + private final int[] literals = new int[2]; + + BinaryAntecedent(int lit1, int lit2) { + literals[0] = lit1; + literals[1] = lit2; + } + + @Override + public int[] getReasonLiterals() { + return literals; + } + + @Override + public void bumpActivity() { + } + + @Override + public void decreaseActivity() { + } + + @Override + public String toString() { + return "{" + literalToString(literals[0]) + ", " + literalToString(literals[1]) + "}"; + } + } + } + + private void clearOrdinaryWatchList(int literal) { + watches[literal] = new ArrayList<>(); + } + + private void clearAlphaWatchList(int literal) { + watchesAlpha[literal] = new ArrayList<>(); + } + + @Override + public int estimate(int atom, boolean truth, BinaryNoGoodPropagationEstimationStrategy strategy) { + switch (strategy) { + case BinaryNoGoodPropagation: + if (hasBinaryNoGoods) { + return estimateEffectsOfBinaryNoGoodPropagation(atom, truth) - 1; + } + case CountBinaryWatches: + default: + return getNumberOfBinaryWatches(atom, truth); + } + } + + private int getNumberOfBinaryWatches(int atom, boolean truth) { + return binaryWatches[atomToLiteral(atom, truth)].size(); + } + + private int estimateEffectsOfBinaryNoGoodPropagation(int atom, boolean truth) { + assignment.choose(atom, truth); + propagateOnlyBinaryNoGoods(); + int assignedNewly = assignment.getNumberOfAtomsAssignedSinceLastDecision(); + assignment.backtrack(); + return assignedNewly; + } + + private void runInternalChecks() { + new WatchedNoGoodsChecker().doWatchesCheck(); + } + + /** + * This class provides helper methods to detect NoGoods that are not properly watched by this NoGoodStore. + * This should be used only during debugging since checking is costly. + */ + private class WatchedNoGoodsChecker { + + void doWatchesCheck() { + LOGGER.debug("Checking watch invariant."); + // Check all watched NoGoods, if their pointers adhere to the watch-pointer invariant. + for (int literal = 0; literal < watches.length; literal++) { + if (isNegated(literal)) { + // We treat positive and negative ones at the iteration of the positive literal. + continue; + } + final int atom = atomOf(literal); + if (atom > maxAtomId) { + break; + } + checkOrdinaryWatchesInvariant(atom, true); + checkOrdinaryWatchesInvariant(atom, false); + checkAlphaWatchesInvariant(atom, true); + checkAlphaWatchesInvariant(atom, false); + } + LOGGER.debug("Checking watch invariant: all good."); + } + + int weakDecisionLevel(Assignment.Entry entry) { + return entry == null ? UNASSIGNED : entry.hasPreviousMBT() ? entry.getMBTDecisionLevel() : entry.getDecisionLevel(); + } + + int weakReplayLevel(int atom) { + if (assignment instanceof TrailAssignment) { + return ((TrailAssignment) assignment).getOutOfOrderDecisionLevel(atom); + } + return UNASSIGNED; + } + + int trailAwareStrongDecisionLevel(int atom) { + int trailStrongDecisionLevel = UNASSIGNED; + if (assignment instanceof TrailAssignment) { + trailStrongDecisionLevel = ((TrailAssignment) assignment).getOutOfOrderStrongDecisionLevel(atom); + } + int atomStrongDecisionLevel = strongDecisionLevel(atom); + return Math.min(trailStrongDecisionLevel, atomStrongDecisionLevel); + } + + private void checkAlphaWatchesInvariant(int atom, boolean truth) { + Assignment.Entry atomEntry = assignment.get(atom); + int atomLiteral = atomToLiteral(atom, truth); + boolean atomSatisfies = atomEntry != null && isPositive(atomLiteral) != atomEntry.getTruth().toBoolean(); + int atomDecisionLevel = strongDecisionLevel(atom); + BinaryWatchList binaryWatchList = binaryWatches[atomLiteral]; + for (int i = 0; i < binaryWatchList.noGoodsWithHeadSize; i++) { + int headLiteral = binaryWatchList.noGoodsWithHead[i]; + if (headLiteral == atomLiteral) { + throw oops("Watch invariant violated: alpha watch points at head."); + } + Assignment.Entry headEntry = assignment.get(atomOf(headLiteral)); + boolean headViolates = headEntry != null && isPositive(headLiteral) == headEntry.getTruth().toBoolean(); + int headDecisionLevel = trailAwareStrongDecisionLevel(atomOf(headLiteral)); + if (watchInvariant(atomSatisfies, atomDecisionLevel, headLiteral, headDecisionLevel, headEntry) + || headViolates) { // Head "pointer" is never moved and violation is checked by weak propagation, hence a violated head is okay. + continue; + } + throw oops("Watch invariant (alpha) violated"); + } + for (WatchedNoGood watchedNoGood : watchesAlpha(atomLiteral)) { + int headLiteral = watchedNoGood.getHead(); + if (headLiteral == atomLiteral) { + throw oops("Watch invariant violated: alpha watch points at head."); + } + Assignment.Entry headEntry = assignment.get(atomOf(headLiteral)); + boolean headViolates = headEntry != null && isPositive(headLiteral) == headEntry.getTruth().toBoolean(); + int headDecisionLevel = trailAwareStrongDecisionLevel(atomOf(headLiteral)); + if (watchInvariant(atomSatisfies, atomDecisionLevel, headLiteral, headDecisionLevel, headEntry) + || headViolates) { // Head "pointer" is never moved and violation is checked by weak propagation, hence a violated head is okay. + continue; + } + throw oops("Watch invariant (alpha) violated"); + } + } + + private void checkOrdinaryWatchesInvariant(int atom, boolean truth) { + Assignment.Entry atomEntry = assignment.get(atom); + int atomLiteral = atomToLiteral(atom, truth); + boolean atomSatisfies = atomEntry != null && isPositive(atomLiteral) != atomEntry.getTruth().toBoolean(); + int atomDecisionLevel = weakDecisionLevel(atomEntry); + int atomReplayLevel = weakReplayLevel(atom); + BinaryWatchList binaryWatchList = binaryWatches[atomLiteral]; + for (int i = 0; i < binaryWatchList.noGoodsWithoutHeadSize; i++) { + int otherLiteral = binaryWatchList.noGoodsWithoutHead[i]; + checkBinaryWatch(atomSatisfies, atomDecisionLevel, atomReplayLevel, otherLiteral); + } + for (int i = 0; i < binaryWatchList.noGoodsWithHeadSize; i++) { + int otherLiteral = binaryWatchList.noGoodsWithHead[i]; + checkBinaryWatch(atomSatisfies, atomDecisionLevel, atomReplayLevel, otherLiteral); + } + for (WatchedNoGood watchedNoGood : watches(atomLiteral)) { + // Ensure both watches are either unassigned, or one satisfies NoGood, or both are on highest decision level. + int otherPointer = atom == atomOf(watchedNoGood.getLiteral(1)) ? 0 : 1; + int otherLiteral = watchedNoGood.getLiteral(otherPointer); + int otherAtom = atomOf(otherLiteral); + int thisAtom = atomOf(watchedNoGood.getLiteral(1 - otherPointer)); + if (thisAtom != atom) { + throw oops("Watched atom is not at first/second position in literals array."); + } + Assignment.Entry otherEntry = assignment.get(otherAtom); + int otherDecisionLevel = weakDecisionLevel(otherEntry); + int otherReplayLevel = weakReplayLevel(otherAtom); + boolean otherSatisfies = otherEntry != null && isPositive(otherLiteral) != otherEntry.getTruth().toBoolean(); + if (watchInvariant(atomSatisfies, otherSatisfies, atomDecisionLevel, atomReplayLevel, otherDecisionLevel, otherReplayLevel)) { + continue; + } + throw oops("Watch invariant violated"); + } + } + + private void checkBinaryWatch(boolean atomSatisfies, int atomDecisionLevel, int atomReplayLevel, int otherLiteral) { + int otherAtom = atomOf(otherLiteral); + Assignment.Entry otherEntry = assignment.get(otherAtom); + boolean otherSatisfies = otherEntry != null && isPositive(otherLiteral) != otherEntry.getTruth().toBoolean(); + int otherDecisionLevel = weakDecisionLevel(otherEntry); + int otherReplayLevel = weakReplayLevel(otherAtom); + if (watchInvariant(atomSatisfies, otherSatisfies, atomDecisionLevel, atomReplayLevel, otherDecisionLevel, otherReplayLevel)) { + return; + } + throw oops("Watch invariant violated"); + } + + private boolean watchInvariant(boolean atomSatisfies, boolean otherAtomSatisfies, int atomDecisionLevel, int atomReplayLevel, int otherAtomDecisionLevel, int otherAtomReplayLevel) { + if (atomDecisionLevel == UNASSIGNED && otherAtomDecisionLevel == UNASSIGNED) { + // Both watches are unassigned. + return true; + } + if ((atomSatisfies && (otherAtomDecisionLevel >= atomDecisionLevel || otherAtomDecisionLevel >= atomReplayLevel)) + || (otherAtomSatisfies && (atomDecisionLevel >= otherAtomDecisionLevel || atomDecisionLevel >= otherAtomReplayLevel))) { + // One watch satisfies the nogood and the other is assigned at higher decision level (or higher than the replay level of the satisfying one). + return true; + } + return false; + } + + private boolean watchInvariant(boolean atomSatisfies, int atomDecisionLevel, int otherLiteral, int otherDecisionLevel, Assignment.Entry otherEntry) { + boolean otherSatisfies = otherEntry != null && isPositive(otherLiteral) != otherEntry.getTruth().toBoolean(); + if (atomDecisionLevel == Integer.MAX_VALUE && otherDecisionLevel == Integer.MAX_VALUE) { + // Both watches are unassigned. + return true; + } + if ((atomSatisfies && otherDecisionLevel >= atomDecisionLevel) + || (otherSatisfies && atomDecisionLevel >= otherDecisionLevel)) { + // One watch satisfies the nogood and the other is assigned at higher decision level. + return true; + } + return false; + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java new file mode 100644 index 000000000..9c4d74601 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2019 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.solver; + +import org.slf4j.Logger; + +/** + * Collects performance data (mainly number of decisions per second) and outputs them on demand. + */ +public class PerformanceLog { + + private ChoiceManager choiceManager; + private TrailAssignment assignment; + private long msBetweenOutputs; + + private Long timeFirstEntry; + private Long timeLastPerformanceLog; + private int numberOfChoicesLastPerformanceLog; + + /** + * @param msBetweenOutputs + */ + public PerformanceLog(ChoiceManager choiceManager, TrailAssignment assignment, long msBetweenOutputs) { + super(); + this.choiceManager = choiceManager; + this.assignment = assignment; + this.msBetweenOutputs = msBetweenOutputs; + } + + public void initialize() { + timeFirstEntry = System.currentTimeMillis(); + timeLastPerformanceLog = timeFirstEntry; + } + + /** + * @param logger + */ + public void infoIfTimeForOutput(Logger logger) { + long currentTime = System.currentTimeMillis(); + int currentNumberOfChoices = choiceManager.getChoices(); + if (currentTime >= timeLastPerformanceLog + msBetweenOutputs) { + logger.info("Decisions in {}s: {}", (currentTime - timeLastPerformanceLog) / 1000.0f, currentNumberOfChoices - numberOfChoicesLastPerformanceLog); + timeLastPerformanceLog = currentTime; + numberOfChoicesLastPerformanceLog = currentNumberOfChoices; + float overallTime = (currentTime - timeFirstEntry) / 1000.0f; + float decisionsPerSec = currentNumberOfChoices / overallTime; + logger.info("Overall performance: {} decisions in {}s or {} decisions per sec. Overall replayed assignments: {}.", currentNumberOfChoices, overallTime, decisionsPerSec, assignment.replayCounter); + } + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java new file mode 100644 index 000000000..54be1ceca --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java @@ -0,0 +1,33 @@ +package at.ac.tuwien.kr.alpha.solver; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +/** + * Represents a shallow {@link Antecedent} that must be instantiated before use. + * + * Copyright (c) 2020, the Alpha Team. + */ +public interface ShallowAntecedent extends Antecedent { + + /** + * Instantiates the shallow antecedent. + * @param impliedLiteral the literal that is implied by this {@link ShallowAntecedent}. + * @return a (full) {@link Antecedent}. + */ + Antecedent instantiateAntecedent(int impliedLiteral); + + @Override + default int[] getReasonLiterals() { + throw oops("ShallowAntecedent must be instantiated first."); + } + + @Override + default void bumpActivity() { + throw oops("ShallowAntecedent must be instantiated first."); + } + + @Override + default void decreaseActivity() { + throw oops("ShallowAntecedent must be instantiated first."); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java new file mode 100644 index 000000000..d6900d382 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java @@ -0,0 +1,27 @@ +package at.ac.tuwien.kr.alpha.solver; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; + +import java.util.List; +import java.util.Set; +import java.util.Spliterator; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +@FunctionalInterface +public interface Solver { + Spliterator spliterator(); + + default Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + default Set collectSet() { + return stream().collect(Collectors.toSet()); + } + + default List collectList() { + return stream().collect(Collectors.toList()); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java new file mode 100644 index 000000000..36bbe668d --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2016-2017, 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.solver; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.config.SystemConfig; +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.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); + + NoGoodStore store; + + switch (nogoodStoreName.toLowerCase()) { + case "naive": + store = new NaiveNoGoodStore(assignment); + break; + case "alpharoaming": + store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); + break; + default: + throw new IllegalArgumentException("Unknown store requested."); + } + + switch (solverName.toLowerCase()) { + case "naive" : + return new NaiveSolver(atomStore, grounder); + case "default": + return new DefaultSolver(atomStore, grounder, store, assignment, random, config, heuristicsConfiguration); + } + 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/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java new file mode 100644 index 000000000..0c29abef7 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2017-2019 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.solver; + +import java.io.PrintStream; + +public interface SolverMaintainingStatistics { + + int getNumberOfChoices(); + + int getNumberOfBacktracks(); + + int getNumberOfBacktracksWithinBackjumps(); + + int getNumberOfBackjumps(); + + int getNumberOfBacktracksDueToRemnantMBTs(); + + int getNumberOfDeletedNoGoods(); + + /** + * @return the number of times the solver had to backtrack after closing unassigned atoms + */ + int getNumberOfConflictsAfterClosing(); + + NoGoodCounter getNoGoodCounter(); + + default String getStatisticsString() { + return "g=" + getNumberOfChoices() + ", bt=" + getNumberOfBacktracks() + ", bj=" + getNumberOfBackjumps() + ", bt_within_bj=" + + getNumberOfBacktracksWithinBackjumps() + ", mbt=" + getNumberOfBacktracksDueToRemnantMBTs() + ", cac=" + getNumberOfConflictsAfterClosing() + + ", del_ng=" + getNumberOfDeletedNoGoods(); + } + + default String getStatisticsCSV() { + return String.format("%d,%d,%d,%d,%d,%d,%d", getNumberOfChoices(), getNumberOfBacktracks(), getNumberOfBackjumps(), getNumberOfBacktracksWithinBackjumps(), getNumberOfBacktracksDueToRemnantMBTs(), getNumberOfConflictsAfterClosing(), getNumberOfDeletedNoGoods()); + } + + default void printStatistics(PrintStream out) { + out.println(getStatisticsString()); + } + + default void printStatistics() { + printStatistics(System.out); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java new file mode 100644 index 000000000..ade2ccb9c --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2016, 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.solver; + +import at.ac.tuwien.kr.alpha.common.Truth; + +public enum ThriceTruth implements Truth { + TRUE("T", true), + FALSE("F", false), + MBT("M", true); + + private final String asString; + private final boolean asBoolean; + + ThriceTruth(String asString, boolean asBoolean) { + this.asString = asString; + this.asBoolean = asBoolean; + } + + @Override + public boolean toBoolean() { + return asBoolean; + } + + @Override + public String toString() { + return asString; + } + + public static ThriceTruth valueOf(boolean value) { + return value ? TRUE : FALSE; + } + + /** + * @return true if this is MBT. + */ + public boolean isMBT() { + return this == ThriceTruth.MBT; + } + + /** + * Returns true if the two truth values are not compatible with each other. + * Each truth value is compatible with itself and both MBT and TRUE are compatible. All other combinations are + * conflicting. + * @param value1 the first truth value. + * @param value2 the second truth value. + * @return true iff first and second truth value are conflicting (i.e., not compatible). + */ + public static boolean isConflicting(ThriceTruth value1, ThriceTruth value2) { + return (FALSE == value1 || FALSE == value2) && value1 != value2; + } +} \ No newline at end of file diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java new file mode 100644 index 000000000..4e2974d51 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java @@ -0,0 +1,783 @@ +/** + * 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 + * 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.solver; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.IntIterator; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static at.ac.tuwien.kr.alpha.solver.Atoms.isAtom; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; + +/** + * An implementation of Assignment using a trail (of literals) and arrays as underlying structures for storing + * assignments. + * + * Copyright (c) 2018-2020, the Alpha Team. + */ +public class TrailAssignment implements WritableAssignment, Checkable { + private static final Logger LOGGER = LoggerFactory.getLogger(TrailAssignment.class); + static final Antecedent CLOSING_INDICATOR_ANTECEDENT = new Antecedent() { + int[] literals = new int[0]; + + @Override + public int[] getReasonLiterals() { + return literals; + } + + @Override + public void bumpActivity() { + } + + @Override + public void decreaseActivity() { + + } + }; + + private final AtomStore atomStore; + private ChoiceManager choiceManagerCallback; + + /** + * Contains for each known atom a value whose two least + * significant bits encode the atom's truth value + * (cf. {@link TrailAssignment#translateTruth(int)} + * and whose remaining bits encode the atom's weak decision level. + */ + private int[] values; + + private int[] strongDecisionLevels; + private Antecedent[] impliedBy; + private boolean[] callbackUponChange; + private ArrayList outOfOrderLiterals = new ArrayList<>(); + private int highestDecisionLevelContainingOutOfOrderLiterals; + private int[] trail = new int[0]; + private int trailSize; + private ArrayList trailIndicesOfDecisionLevels = new ArrayList<>(); + + private int nextPositionInTrail; + private int newAssignmentsPositionInTrail; + private int newAssignmentsIterator; + private int assignmentsForChoicePosition; + private int mbtCount; + private boolean checksEnabled; + long replayCounter; + + public TrailAssignment(AtomStore atomStore, boolean checksEnabled) { + this.checksEnabled = checksEnabled; + this.atomStore = atomStore; + this.values = new int[0]; + this.strongDecisionLevels = new int[0]; + this.impliedBy = new Antecedent[0]; + this.callbackUponChange = new boolean[0]; + this.trailIndicesOfDecisionLevels.add(0); + nextPositionInTrail = 0; + newAssignmentsIterator = 0; + newAssignmentsPositionInTrail = 0; + assignmentsForChoicePosition = 0; + } + + public TrailAssignment(AtomStore atomStore) { + this(atomStore, false); + } + + @Override + public void clear() { + mbtCount = 0; + Arrays.fill(values, 0); + Arrays.fill(strongDecisionLevels, -1); + Arrays.fill(impliedBy, null); + Arrays.fill(callbackUponChange, false); + outOfOrderLiterals = new ArrayList<>(); + highestDecisionLevelContainingOutOfOrderLiterals = 0; + Arrays.fill(trail, 0); + trailSize = 0; + trailIndicesOfDecisionLevels = new ArrayList<>(); + trailIndicesOfDecisionLevels.add(0); + nextPositionInTrail = 0; + newAssignmentsIterator = 0; + newAssignmentsPositionInTrail = 0; + assignmentsForChoicePosition = 0; + } + + @Override + public void registerCallbackOnChange(int atom) { + callbackUponChange[atom] = true; + } + + @Override + public void setCallback(ChoiceManager choiceManager) { + choiceManagerCallback = choiceManager; + } + + @Override + public boolean isAssigned(int atom) { + return values[atom] != 0; + } + + @Override + public int getBasicAtomAssignedMBT() { + for (int atom = 1; atom <= atomStore.getMaxAtomId(); atom++) { + if (getTruth(atom) == MBT && atomStore.get(atom) instanceof BasicAtom) { + return atom; + } + } + throw oops("No BasicAtom is assigned MBT."); + } + + @Override + public Pollable getAssignmentsToProcess() { + return new TrailPollable(); + } + + @Override + public int getRealWeakDecisionLevel(int atom) { + if (getTruth(atom) == null) { + return -1; + } + int lowestDecisionLevelForAtom = getWeakDecisionLevel(atom); + for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { + if (outOfOrderLiteral.atom == atom && outOfOrderLiteral.decisionLevel < lowestDecisionLevelForAtom) { + lowestDecisionLevelForAtom = outOfOrderLiteral.decisionLevel; + } + } + return lowestDecisionLevelForAtom; + } + + /** + * Searches out-of-order literals for the lowest decision level the atom is assigned in. + * @param atom the atom to check. + * @return Integer.MAX_VALUE if the atom is not assigned out-of-order, otherwise the lowest decision level it is assigned. + */ + public int getOutOfOrderDecisionLevel(int atom) { + int lowestDecisionLevel = Integer.MAX_VALUE; + for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { + if (outOfOrderLiteral.atom == atom && outOfOrderLiteral.decisionLevel < lowestDecisionLevel) { + lowestDecisionLevel = outOfOrderLiteral.decisionLevel; + } + } + return lowestDecisionLevel; + } + + int getOutOfOrderStrongDecisionLevel(int atom) { + int lowestDecisionLevel = Integer.MAX_VALUE; + for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { + if (outOfOrderLiteral.atom == atom && outOfOrderLiteral.value == TRUE && outOfOrderLiteral.decisionLevel < lowestDecisionLevel) { + lowestDecisionLevel = outOfOrderLiteral.decisionLevel; + } + } + return lowestDecisionLevel; + } + + private void informCallback(int atom) { + if (callbackUponChange[atom]) { + choiceManagerCallback.callbackOnChanged(atom); + } + } + + private void removeLastDecisionLevel() { + // Remove all atoms recorded in the highest decision level. + int start = trailIndicesOfDecisionLevels.get(getDecisionLevel()); + for (int i = start; i < trailSize; i++) { + int backtrackAtom = atomOf(trail[i]); //atomOf(backtrackIterator.next()); + // Skip already backtracked atoms. + if (getTruth(backtrackAtom) == null) { + continue; + } + if (getWeakDecisionLevel(backtrackAtom) < getDecisionLevel()) { + // Restore TRUE to MBT if this was assigned at a lower level. + if (getTruth(backtrackAtom) != TRUE) { + throw oops("Backtracking assignment with lower decision level whose value is not TRUE."); + } + values[backtrackAtom] = (getWeakDecisionLevel(backtrackAtom) << 2) | translateTruth(MBT); + mbtCount++; + } else { + if (getTruth(backtrackAtom) == MBT) { + mbtCount--; + } + values[backtrackAtom] = 0; + } + strongDecisionLevels[backtrackAtom] = -1; + informCallback(backtrackAtom); + } + // Remove atoms from trail. + trailSize = start; + trailIndicesOfDecisionLevels.remove(trailIndicesOfDecisionLevels.size() - 1); + } + + private void replayOutOfOrderLiterals() { + // Replay out-of-order assigned literals. + if (highestDecisionLevelContainingOutOfOrderLiterals >= getDecisionLevel()) { + // Replay all still-valid literals and remove invalid ones. + LOGGER.trace("Replaying out-of-order literals."); + int k = 0; // counter for out-of-order literals to keep further. + for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { + if (outOfOrderLiteral.decisionLevel <= getDecisionLevel()) { + // Replay assignment at current decision level. + assign(outOfOrderLiteral.atom, outOfOrderLiteral.value, outOfOrderLiteral.impliedBy); + // If literal is actually below current decision level, keep it. + if (outOfOrderLiteral.decisionLevel < getDecisionLevel()) { + outOfOrderLiterals.set(k++, outOfOrderLiteral); + } + } + } + replayCounter += outOfOrderLiterals.size(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Replay list contained {} literals, {} were again assigned. Overall replays: {}.", outOfOrderLiterals.size(), k, replayCounter); + } + // Remove remaining entries from k onwards. + while (outOfOrderLiterals.size() > k) { + outOfOrderLiterals.remove(outOfOrderLiterals.size() - 1); + } + highestDecisionLevelContainingOutOfOrderLiterals = outOfOrderLiterals.isEmpty() ? 0 : getDecisionLevel(); + } + } + + private void resetTrailPointersAndReplayOutOfOrderLiterals() { + nextPositionInTrail = Math.min(nextPositionInTrail, trailSize); + newAssignmentsPositionInTrail = Math.min(newAssignmentsPositionInTrail, trailSize); + newAssignmentsIterator = Math.min(newAssignmentsIterator, trailSize); + assignmentsForChoicePosition = Math.min(assignmentsForChoicePosition, trailSize); + replayOutOfOrderLiterals(); + if (checksEnabled) { + runInternalChecks(); + } + } + + @Override + public void backjump(int decisionLevel) { + // Remove everything above the target level, but keep the target level unchanged. + while (getDecisionLevel() > decisionLevel) { + removeLastDecisionLevel(); + } + resetTrailPointersAndReplayOutOfOrderLiterals(); + } + + @Override + public void backtrack() { + removeLastDecisionLevel(); + resetTrailPointersAndReplayOutOfOrderLiterals(); + } + + @Override + public int getMBTCount() { + return mbtCount; + } + + @Override + public ConflictCause choose(int atom, ThriceTruth value) { + if (checksEnabled) { + runInternalChecks(); + } + trailIndicesOfDecisionLevels.add(trailSize); + return assign(atom, value, null); + } + + @Override + public ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy) { + ConflictCause conflictCause = assignWithTrail(atom, value, impliedBy); + if (conflictCause != null && LOGGER.isDebugEnabled()) { + LOGGER.debug("Assign is conflicting: atom: {}, value: {}, impliedBy: {}.", atom, value, impliedBy); + } + return conflictCause; + } + + @Override + public ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy, int decisionLevel) { + ConflictCause conflictCause = assign(atom, value, impliedBy); + if (conflictCause == null && decisionLevel < getDecisionLevel()) { + outOfOrderLiterals.add(new OutOfOrderLiteral(atom, value, decisionLevel, impliedBy)); + if (highestDecisionLevelContainingOutOfOrderLiterals < getDecisionLevel()) { + highestDecisionLevelContainingOutOfOrderLiterals = getDecisionLevel(); + } + } + return conflictCause; + } + + private boolean assignmentsConsistent(ThriceTruth oldTruth, ThriceTruth value) { + return oldTruth == null || oldTruth.toBoolean() == value.toBoolean(); + } + + private ConflictCause assignWithTrail(int atom, ThriceTruth value, Antecedent impliedBy) { + if (!isAtom(atom)) { + throw new IllegalArgumentException("not an atom"); + } + if (value == null) { + throw new IllegalArgumentException("value must not be null"); + } + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Recording assignment {}={}@{} impliedBy: {}", atom, value, getDecisionLevel(), impliedBy); + if (impliedBy != null) { + for (Integer literal : impliedBy.getReasonLiterals()) { + LOGGER.trace("impliedBy literal assignment: {}={}.", atomOf(literal), get(atomOf(literal))); + } + } + } + + // If the atom currently is not assigned, simply record the assignment. + final ThriceTruth currentTruth = getTruth(atom); + if (currentTruth == null) { + trail[trailSize++] = atomToLiteral(atom, value.toBoolean()); + values[atom] = (getDecisionLevel() << 2) | translateTruth(value); + this.impliedBy[atom] = impliedBy; + // Adjust MBT counter. + if (value == MBT) { + mbtCount++; + } + if (value == TRUE) { + strongDecisionLevels[atom] = getDecisionLevel(); + } + informCallback(atom); + return null; + } + + // Nothing to do if the new value is the same as the current one (or current is TRUE and new is MBT). + if (value == currentTruth || value == MBT && currentTruth == TRUE) { + return null; + } + + // Check if the new assignments contradicts the current one. + if (!assignmentsConsistent(currentTruth, value)) { + // Assignments are inconsistent, prepare the reason. + // Due to the conflict, the impliedBy NoGood is not the recorded one but the one this method is invoked with.stems from this assignment. + if (impliedBy instanceof ShallowAntecedent) { + // Instantiate Antecedent in case it is a shallow one for binary nogoods. + return new ConflictCause(((ShallowAntecedent) impliedBy).instantiateAntecedent(atomToLiteral(atom, !value.toBoolean()))); + } + return new ConflictCause(impliedBy); + } + if (value == TRUE && currentTruth != MBT) { + throw oops("Assigning TRUE without assigning MBT before."); + } + + // Previous assignment exists, and the new one is consistent with it. + // There is nothing to do except if MBT becomes TRUE. + if (currentTruth == MBT && value == TRUE) { + // Record new truth value but keep weak decision level unchanged. + trail[trailSize++] = atomToLiteral(atom, true); + values[atom] = (getWeakDecisionLevel(atom) << 2) | translateTruth(TRUE); + // Record strong decision level. + strongDecisionLevels[atom] = getDecisionLevel(); + // Adjust MBT counter. + mbtCount--; + informCallback(atom); + return null; + } + throw oops("Assignment conditions are not covered."); + } + + private ThriceTruth translateTruth(int value) { + switch (value & 0x3) { + case 0: + return null; + case 1: + return FALSE; + case 2: + return MBT; + case 3: + return TRUE; + default: + throw oops("Unknown truth value."); + } + } + + private int translateTruth(ThriceTruth value) { + if (value == null) { + return 0; + } + switch (value) { + case FALSE: + return 1; + case MBT: + return 2; + case TRUE: + return 3; + } + throw oops("Unknown truth value."); + } + + @Override + public ThriceTruth getTruth(int atom) { + return translateTruth(values[atom]); + } + + @Override + public int getWeakDecisionLevel(int atom) { + return values[atom] >> 2; + } + + @Override + public int getStrongDecisionLevel(int atom) { + return getTruth(atom) == FALSE ? getWeakDecisionLevel(atom) : strongDecisionLevels[atom]; + } + + @Override + public Antecedent getImpliedBy(int atom) { + Antecedent antecedent = impliedBy[atom]; + // Check if the Antecedent is a shallow one from binary nogoods, in this case instantiate it to a full Antecedent. + if (antecedent instanceof ShallowAntecedent) { + return ((ShallowAntecedent) antecedent).instantiateAntecedent(atomToLiteral(atom, !getTruth(atom).toBoolean())); + } + return antecedent; + } + + @Override + public Set getTrueAssignments() { + Set result = new HashSet<>(); + for (int i = 0; i < values.length; i++) { + if (getTruth(i) == TRUE) { + result.add(i); + } + } + return result; + } + + @Override + public Entry get(int atom) { + if (values[atom] == 0) { + return null; + } + if (strongDecisionLevels[atom] == -1) { + return new Entry(getTruth(atom), atom, getWeakDecisionLevel(atom), getImpliedBy(atom)); + } else { + return new Entry(getTruth(atom), atom, strongDecisionLevels[atom], getImpliedBy(atom), getWeakDecisionLevel(atom)); + } + } + + private void runInternalChecks() { + // Ensure that incrementally updated values agree with actual values. + LOGGER.trace("Checking assignment."); + // Check that MBT counter is correct. + if (getMBTCount() != getMBTAssignedAtoms().size()) { + throw oops("MBT counter and amount of actually MBT-assigned atoms disagree"); + } else { + LOGGER.trace("MBT count agrees with amount of MBT-assigned atoms."); + } + // Check that out of order literals are actually assigned. + for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { + if (outOfOrderLiteral.decisionLevel <= getDecisionLevel()) { + ThriceTruth atomTruth = getTruth(outOfOrderLiteral.atom); + if (outOfOrderLiteral.value == atomTruth || outOfOrderLiteral.value == MBT && atomTruth == TRUE) { + continue; + } + throw oops("Out-of-order assigned literal is not in current assignment."); + } + } + LOGGER.trace("Checking assignment: all good."); + } + + /** + * Debug helper collecting all atoms that are assigned MBT. + * @return a list of all atomIds that are assigned MBT (and not TRUE). + */ + private List getMBTAssignedAtoms() { + List ret = new ArrayList<>(); + for (int i = 0; i < values.length; i++) { + if (getTruth(i) == MBT) { + ret.add(i); + } + } + return ret; + } + + @Override + public boolean closeUnassignedAtoms() { + boolean didAssign = false; + for (int i = 1; i <= atomStore.getMaxAtomId(); i++) { + if (!isAssigned(i)) { + assign(i, FALSE, CLOSING_INDICATOR_ANTECEDENT); + didAssign = true; + } + } + return didAssign; + } + + @Override + public void growForMaxAtomId() { + int maxAtomId = atomStore.getMaxAtomId(); + // Grow arrays only if needed. + if (values.length > maxAtomId) { + return; + } + // Grow by 1.5 current size, except if bigger array is required due to maxAtomId. + int newCapacity = arrayGrowthSize(values.length); + if (newCapacity < maxAtomId + 1) { + newCapacity = maxAtomId + 1; + } + values = Arrays.copyOf(values, newCapacity); + int oldLength = strongDecisionLevels.length; + strongDecisionLevels = Arrays.copyOf(strongDecisionLevels, newCapacity); + Arrays.fill(strongDecisionLevels, oldLength, strongDecisionLevels.length, -1); + impliedBy = Arrays.copyOf(impliedBy, newCapacity); + callbackUponChange = Arrays.copyOf(callbackUponChange, newCapacity); + trail = Arrays.copyOf(trail, newCapacity * 2); // Trail has at most 2 assignments (MBT+TRUE) for each atom. + } + + public int getNumberOfAssignedAtoms() { + int n = 0; + for (int value : values) { + if (translateTruth(value) != null) { + n++; + } + } + return n; + } + + @Override + public int getNumberOfAtomsAssignedSinceLastDecision() { + Set newlyAssignedAtoms = new HashSet<>(); + int trailIndex = trailIndicesOfDecisionLevels.get(getDecisionLevel()); + for (; trailIndex < trailSize; trailIndex++) { + newlyAssignedAtoms.add(atomOf(trail[trailIndex])); + } + return newlyAssignedAtoms.size(); + } + + @Override + public int getDecisionLevel() { + return trailIndicesOfDecisionLevels.size() - 1; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("["); + boolean isFirst = true; + for (int i = 0; i < values.length; i++) { + ThriceTruth atomTruth = getTruth(i); + if (atomTruth == null) { + continue; + } + if (!isFirst) { + sb.append(", "); + } + isFirst = false; + sb.append(atomTruth); + sb.append("_"); + if (atomStore != null) { + sb.append(atomStore.atomToString(i)); + } else { + sb.append(i); + } + sb.append("@"); + sb.append(getWeakDecisionLevel(i)); + } + sb.append("]"); + return sb.toString(); + } + + @Override + public AssignmentIterator getNewPositiveAssignmentsIterator() { + return new AssignmentIterator(); + } + + @Override + public void setChecksEnabled(boolean checksEnabled) { + this.checksEnabled = checksEnabled; + } + + private class AssignmentIterator implements IntIterator { + + private void advanceCursorToNextPositiveAssignment() { + while (newAssignmentsIterator < trailSize) { + ThriceTruth truth = getTruth(atomOf(trail[newAssignmentsIterator])); + if (truth != null && truth.toBoolean()) { + return; + } + newAssignmentsIterator++; + } + } + + @Override + public boolean hasNext() { + advanceCursorToNextPositiveAssignment(); + return newAssignmentsIterator < trailSize; + } + + @Override + public int next() { + return atomOf(trail[newAssignmentsIterator++]); + + } + } + + private static class OutOfOrderLiteral { + final int atom; + final ThriceTruth value; + final int decisionLevel; + final Antecedent impliedBy; + + private OutOfOrderLiteral(int atom, ThriceTruth value, int decisionLevel, Antecedent impliedBy) { + this.atom = atom; + this.decisionLevel = decisionLevel; + this.impliedBy = impliedBy; + this.value = value; + } + + @Override + public String toString() { + return atom + "=" + value + "@" + decisionLevel + " implied by " + impliedBy; + } + } + + private class TrailPollable implements Pollable { + + @Override + public int peek() { + return atomOf(trail[nextPositionInTrail]); + } + + @Override + public int remove() { + int current = peek(); + nextPositionInTrail++; + return current; + } + + @Override + public boolean isEmpty() { + return nextPositionInTrail >= trailSize; + } + } + + public TrailBackwardsWalker getTrailBackwardsWalker() { + return new TrailBackwardsWalker(); + } + + public class TrailBackwardsWalker { + + int trailPos; + + TrailBackwardsWalker() { + trailPos = trailSize; + } + + public int getNextLowerLiteral() { + return trail[--trailPos]; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("["); + for (int i = 0; i < trailSize; i++) { + int literalOnTrail = trail[i]; + sb.append(isPositive(literalOnTrail) ? "+" + atomOf(literalOnTrail) : "-" + atomOf(literalOnTrail)); + sb.append("@"); + sb.append(TrailAssignment.this.getWeakDecisionLevel(atomOf(literalOnTrail))); + sb.append(", "); + } + sb.append("]"); + return sb.toString(); + } + } + + private static final class Entry implements Assignment.Entry { + private final ThriceTruth value; + private final int decisionLevel; + private final int previousDecisionLevel; + private final Antecedent impliedBy; + private final int atom; + + Entry(ThriceTruth value, int atom, int decisionLevel, Antecedent noGood) { + this(value, atom, decisionLevel, noGood, -1); + } + + Entry(ThriceTruth value, int atom, int decisionLevel, Antecedent impliedBy, int previousDecisionLevel) { + this.value = value; + this.decisionLevel = decisionLevel; + this.impliedBy = impliedBy; + this.previousDecisionLevel = previousDecisionLevel; + this.atom = atom; + if (previousDecisionLevel != -1 && value != TRUE) { + throw oops("Assignment.Entry instantiated with previous entry set and truth values other than TRUE now and MBT previous"); + } + } + + @Override + public ThriceTruth getTruth() { + return value; + } + + @Override + public int getDecisionLevel() { + return decisionLevel; + } + + @Override + public boolean hasPreviousMBT() { + return previousDecisionLevel != -1; + } + + @Override + public int getMBTDecisionLevel() { + return previousDecisionLevel; + } + + @Override + public Antecedent getImpliedBy() { + return impliedBy; + } + + @Override + public int getAtom() { + return atom; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Entry entry = (Entry) o; + + return atom == entry.atom; + } + + @Override + public int hashCode() { + return atom; + } + + @Override + public String toString() { + return atom + "=" + value.toString() + "(DL" + decisionLevel + ")" + + (hasPreviousMBT() ? "MBT(DL" + getMBTDecisionLevel() + ")" : ""); + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java new file mode 100644 index 000000000..4395d9ed5 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2016-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.solver; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface; + +import java.util.Iterator; + +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.literalToString; + +public final class WatchedNoGood implements NoGoodInterface, Antecedent { + private int activity; + private final int[] literals; + private int alpha; + private int head; + private final Type type; + private boolean isLbdLessOrEqual2; + + WatchedNoGood(NoGood noGood, int a, int b, int alpha) { + if (noGood.size() < 3) { + throw oops("WatchedNoGood should not be used for small NoGoods."); + } + literals = new int[noGood.size()]; + checkPointers(a, b, alpha); + int i = 0; + for (Integer lit : noGood) { + literals[i++] = lit; + } + this.alpha = alpha; + head = noGood.hasHead() ? 0 : -1; + activity = 0; + if (b == 0) { + swap(1, a); + } else { + swap(0, a); + swap(1, b); + } + this.type = noGood.getType(); + } + + private void checkPointers(int a, int b, int alpha) { + if (a == b) { + throw new IllegalArgumentException("First two pointers must not point at the same literal."); + } + if (a < 0 || b < 0 || alpha < -1 || a >= literals.length || b >= literals.length || alpha >= literals.length) { + throw new IllegalArgumentException("Pointers must be within bounds."); + } + } + + private void swap(int a, int b) { + int tmp = literals[a]; + literals[a] = literals[b]; + literals[b] = tmp; + if (hasHead()) { + // If WatchedNoGood has a head, ensure the head pointer and alpha watch follow the swap. + if (head == a) { + head = b; + } else if (head == b) { + head = a; + } + if (alpha == a) { + alpha = b; + } else if (alpha == b) { + alpha = a; + } + } + } + + @Override + public boolean hasHead() { + return head != -1; + } + + @Override + public int getHead() { + return literals[head]; + } + + int getHeadIndex() { + return head; + } + + void setWatch(int index, int value) { + if (index != 0 && index != 1) { + throw new IndexOutOfBoundsException(); + } + swap(index, value); + } + + @Override + public int getLiteral(int index) { + return literals[index]; + } + + int getAlphaPointer() { + return alpha; + } + + void setAlphaPointer(int value) { + alpha = value; + } + + int getLiteralAtAlpha() { + return literals[alpha]; + } + + @Override + public int size() { + return literals.length; + } + + @Override + public Type getType() { + return type; + } + + @Override + public Antecedent asAntecedent() { + return this; + } + + @Override + public Iterator iterator() { + return new Iterator() { + private int i; + + public boolean hasNext() { + return literals.length > i; + } + + public Integer next() { + return literals[i++]; + } + }; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (hasHead()) { + sb.append("*"); + } + + sb.append("{ "); + + int hcount = 0; + for (int literal : literals) { + sb.append(literalToString(literal)); + sb.append(hasHead() && head == hcount ? "h" : ""); + sb.append(" "); + hcount++; + } + + sb.append("}{"); + sb.append(alpha); + sb.append("}"); + return sb.toString(); + } + + @Override + public int[] getReasonLiterals() { + return literals; + } + + public int getActivity() { + return activity; + } + + @Override + public void decreaseActivity() { + activity >>= 1; + } + + @Override + public void bumpActivity() { + activity++; + } + + void setLBD(int lbd) { + isLbdLessOrEqual2 = lbd <= 2; + } + + boolean isLbdLessOrEqual2() { + return isLbdLessOrEqual2; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java new file mode 100644 index 000000000..806a29957 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2016, 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.solver; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.NoGood; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; + +public interface WritableAssignment extends Assignment { + /** + * Delete all information stored in the assignment. + */ + void clear(); + + /** + * Backtracks the most recent decision level. + */ + void backtrack(); + + /** + * Backtracks to the indicated decision level. Every assignment on a higher decisionLevel is removed. + * All assignments below (or equal to) decisionLevel are kept. Note that for atoms being TRUE this may require + * setting the assigned value to MBT during backtracking. + * @param decisionLevel the decision level to backjump to (this decision level is the highest that is kept). + */ + void backjump(int decisionLevel); + + /** + * Assigns an atom some value on a lower decision level than the current one. + * @param atom + * @param value + * @param impliedBy + * @param decisionLevel + * @return + */ + ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy, int decisionLevel); + + default ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy) { + return assign(atom, value, impliedBy, getDecisionLevel()); + } + + default ConflictCause assign(int atom, ThriceTruth value) { + return assign(atom, value, null); + } + + ConflictCause choose(int atom, ThriceTruth value); + + void registerCallbackOnChange(int atom); + + void setCallback(ChoiceManager choiceManager); + + default ConflictCause choose(int atom, boolean value) { + return choose(atom, ThriceTruth.valueOf(value)); + } + + default int minimumConflictLevel(NoGood noGood) { + int minimumConflictLevel = -1; + for (Integer literal : noGood) { + ThriceTruth atomTruth = getTruth(atomOf(literal)); + if (atomTruth == null || isPositive(literal) != atomTruth.toBoolean()) { + return -1; + } + int literalDecisionLevel = getWeakDecisionLevel(atomOf(literal)); + if (literalDecisionLevel > minimumConflictLevel) { + minimumConflictLevel = literalDecisionLevel; + } + } + return minimumConflictLevel; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java new file mode 100644 index 000000000..dd17bb114 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java @@ -0,0 +1,42 @@ +/** + * 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.solver.heuristics; + +/** + * A heuristic that selects an atom to choose on by maintaining activity values for literals. + * + */ +public interface ActivityBasedBranchingHeuristic extends BranchingHeuristic { + + /** + * Gets the activity value associated with the given literal + * + * @param literal + * @return the activity value associated with the given literal + */ + double getActivity(int literal); + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java new file mode 100644 index 000000000..b2b76ba26 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2017 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import java.util.Random; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +/** + * A variant of {@link DependencyDrivenHeuristic} that counts the activity of non-body-representing atoms towards bodies of rules in which they occur. + */ +public class AlphaActiveRuleHeuristic extends DependencyDrivenHeuristic { + + public AlphaActiveRuleHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { + super(assignment, choiceManager, decayPeriod, decayFactor, random, BodyActivityType.DEFAULT); + } + + public AlphaActiveRuleHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { + super(assignment, choiceManager, random); + } + + @Override + protected void incrementActivityCounter(int literal) { + int atom = atomOf(literal); + if (choiceManager.isAtomChoice(atom)) { + activityCounters.compute(atom, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); + } else { + for (int body : atomsToBodiesAtoms.get(atom)) { + activityCounters.compute(body, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); + } + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java new file mode 100644 index 000000000..52df83cd4 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java @@ -0,0 +1,68 @@ +/** + * 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import java.util.Comparator; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.stream.Stream; + +/** + * A variant of {@link DependencyDrivenHeuristic} that prefers to choose atoms representing bodies of rules whose heads + * are assigned {@link at.ac.tuwien.kr.alpha.solver.ThriceTruth#MBT}. + */ +public class AlphaHeadMustBeTrueHeuristic extends DependencyDrivenHeuristic { + + private int rememberedAtom; + + public AlphaHeadMustBeTrueHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { + super(assignment, choiceManager, decayPeriod, decayFactor, random, BodyActivityType.DEFAULT); + } + + public AlphaHeadMustBeTrueHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { + super(assignment, choiceManager, random); + } + + @Override + public int chooseLiteral() { + Set heads = headToBodies.keySet(); + Stream bodiesOfMbtHeads = heads.stream().filter(a -> assignment.getTruth(a) == ThriceTruth.MBT).flatMap(h -> headToBodies.get(h).stream()); + Optional mostActiveBody = bodiesOfMbtHeads.filter(this::isUnassigned).filter(choiceManager::isActiveChoiceAtom) + .max(Comparator.comparingDouble(bodyActivity::get)); + if (mostActiveBody.isPresent()) { + rememberedAtom = mostActiveBody.get(); + return rememberedAtom; + } + return super.chooseLiteral(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java new file mode 100644 index 000000000..f14a96b17 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2017 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import java.util.Random; + +import static at.ac.tuwien.kr.alpha.solver.Atoms.isAtom; + +public class AlphaRandomSignHeuristic extends DependencyDrivenHeuristic { + + public AlphaRandomSignHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { + super(assignment, choiceManager, decayPeriod, decayFactor, random, BodyActivityType.DEFAULT); + } + + public AlphaRandomSignHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { + super(assignment, choiceManager, random); + } + + @Override + protected void incrementSignCounter(Integer literal) { + LOGGER.trace("AlphaRandomSignHeuristic does NOT increment sign counters because they are not needed."); + } + + @Override + public boolean chooseSign(int atom) { + if (!isAtom(atom)) { + throw new IllegalArgumentException("Atom must be a positive integer."); + } + + if (assignment.getTruth(atom) == ThriceTruth.MBT) { + return true; + } + + return rand.nextBoolean(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java new file mode 100644 index 000000000..48e523932 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java @@ -0,0 +1,280 @@ +/** + * Copyright (c) 2016-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.Literals; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.stream.Stream; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; + +/** + * The BerkMin heuristic, as described in (but adapted for lazy grounding): + * Goldberg, E.; Novikov, Y. (2002): BerkMin: A fast and robust SAT-solver. + * In : Design, Automation and Test in Europe Conference and Exhibition, 2002. Proceedings. IEEE, pp. 142-149. + * + * Copyright (c) 2016-2018 Siemens AG + */ +public class BerkMin implements ActivityBasedBranchingHeuristic { + private static final Logger LOGGER = LoggerFactory.getLogger(BerkMin.class); + + static final double DEFAULT_ACTIVITY = 0.0; + static final int DEFAULT_SIGN_COUNTER = 0; + + static final int DEFAULT_DECAY_PERIOD = 10; + static final double DEFAULT_DECAY_FACTOR = 0.25; + + final Assignment assignment; + final ChoiceManager choiceManager; + final Random rand; + + private Map activityCounters = new LinkedHashMap<>(); + private Map signCounters = new LinkedHashMap<>(); + private Deque stackOfNoGoods = new ArrayDeque<>(); + private int decayPeriod; + private double decayFactor; + private int stepsSinceLastDecay; + + BerkMin(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { + this.assignment = assignment; + this.choiceManager = choiceManager; + this.decayPeriod = decayPeriod; + this.decayFactor = decayFactor; + this.rand = random; + } + + BerkMin(Assignment assignment, ChoiceManager choiceManager, Random random) { + this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, random); + } + + /** + * Gets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. + */ + public int getDecayPeriod() { + return decayPeriod; + } + + /** + * Sets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. + */ + public void setDecayPeriod(int decayPeriod) { + this.decayPeriod = decayPeriod; + } + + /** + * Gets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. + */ + public double getDecayFactor() { + return decayFactor; + } + + /** + * Sets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. + */ + public void setDecayFactor(double decayFactor) { + this.decayFactor = decayFactor; + } + + @Override + public void violatedNoGood(NoGood violatedNoGood) { + pushToStack(violatedNoGood); + } + + @Override + public void analyzedConflict(ConflictAnalysisResult analysisResult) { + pushToStack(analysisResult.learnedNoGood); + if (analysisResult.resolutionAtoms != null) { + for (int resolutionAtom : analysisResult.resolutionAtoms) { + incrementActivityCounter(atomToLiteral(resolutionAtom, true)); + incrementActivityCounter(atomToLiteral(resolutionAtom, false)); + } + } + if (analysisResult.learnedNoGood != null) { + for (int literal : analysisResult.learnedNoGood) { + incrementActivityCounter(literal); + } + } + decayAllIfTimeHasCome(); + } + + @Override + public void newNoGood(NoGood newNoGood) { + pushToStack(newNoGood); + for (Integer literal : newNoGood) { + incrementSignCounter(literal); + } + } + + private int numChoicePoints(NoGood noGood) { + int numChoicePoints = 0; + for (Integer literal : noGood) { + if (choiceManager.isAtomChoice(literal)) { + numChoicePoints++; + } + } + return numChoicePoints; + } + + @Override + public double getActivity(int literal) { + return activityCounters.getOrDefault(atomOf(literal), DEFAULT_ACTIVITY); + } + + /** + * {@inheritDoc} + * In BerkMin, the atom to choose on is the most active atom in the current top clause. + * Here, we can only consider atoms which are currently active choice points. If we do + * not find such an atom in the current top clause, we consider the next undefined + * nogood in the stack, then the one after that and so on. + */ + @Override + public int chooseLiteral() { + int atom = chooseAtom(); + boolean sign = chooseSign(atom); + return atomToLiteral(atom, sign); + } + + protected int chooseAtom() { + for (NoGood noGood : stackOfNoGoods) { + if (assignment.isUndefined(noGood)) { + int mostActiveAtom = getMostActiveChoosableAtom(noGood); + if (mostActiveAtom != DEFAULT_CHOICE_ATOM) { + return mostActiveAtom; + } + } + } + return DEFAULT_CHOICE_ATOM; + } + + private boolean chooseSign(int atom) { + if (assignment.getTruth(atom) == ThriceTruth.MBT) { + return true; + } + + int positiveCounter = signCounters.getOrDefault(+atom, DEFAULT_SIGN_COUNTER); + int negativeCounter = signCounters.getOrDefault(-atom, DEFAULT_SIGN_COUNTER); + + if (positiveCounter > negativeCounter) { + return false; + } else if (negativeCounter > positiveCounter) { + return true; + } else { + return atom == DEFAULT_CHOICE_ATOM || rand.nextBoolean(); + } + } + + protected void pushToStack(NoGood noGood) { + if (noGood != null) { + stackOfNoGoods.push(noGood); + } + } + + private void incrementActivityCounter(int literal) { + int atom = atomOf(literal); + if (choiceManager.isAtomChoice(atom)) { + activityCounters.compute(atom, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); + } + // TODO: check performance + // note that here (and in incrementSignCounter) we only count atoms that are + // choice points, which might affect performance. + // alternative approaches: + // 1. count everything and from time to time do a garbage collection (i.e. + // remove atoms that are no choice points) + // 2. make check cheaper, e.g. by using dedicated atom IDs (e.g. even + // integers for rule bodies, uneven for other atoms) + } + + private void incrementSignCounter(Integer literal) { + if (choiceManager.isAtomChoice(atomOf(literal))) { + signCounters.compute(literal, (k, v) -> (v == null ? DEFAULT_SIGN_COUNTER : v) + 1); + } + } + + private void decayAllIfTimeHasCome() { + stepsSinceLastDecay++; + if (stepsSinceLastDecay >= decayPeriod) { + // Decay all: + activityCounters.replaceAll((k, v) -> v * decayFactor); + stepsSinceLastDecay = 0; + } + } + + /** + * Gets the most recent conflict that is still violated. + * @return the violated nogood closest to the top of the stack of nogoods. + */ + NoGood getCurrentTopClause() { + for (NoGood noGood : stackOfNoGoods) { + if (assignment.isUndefined(noGood)) { + return noGood; + } + } + return null; + } + + /** + * If {@code noGood != null}, returns the most active unassigned literal from {@code noGood}. Else, returns the most active atom of all the known atoms. + * @param noGood + * @return + */ + private int getMostActiveChoosableAtom(NoGood noGood) { + if (noGood != null) { + return getMostActiveChoosableAtom(noGood.stream().boxed().map(Literals::atomOf)); + } else { + return getMostActiveChoosableAtom(activityCounters.keySet().stream()); + } + } + + protected int getMostActiveChoosableAtom(Stream streamOfLiterals) { + return streamOfLiterals + .map(Literals::atomOf) + .filter(this::isUnassigned) + .filter(choiceManager::isActiveChoiceAtom) + .max(Comparator.comparingDouble(this::getActivity)) + .orElse(DEFAULT_CHOICE_ATOM); + } + + private boolean isUnassigned(int atom) { + ThriceTruth truth = assignment.getTruth(atom); + return truth != FALSE && truth != TRUE; // do not use assignment.isAssigned(atom) because we may also choose MBTs + } + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java new file mode 100644 index 000000000..b916b1b7c --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2017-2018, 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.Random; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +/** + * A BerkMin-like heuristics that uses activity of literals and a fixed-size queue instead of a stack of NoGoods. + * Copyright (c) 2017-2018, the Alpha Team. + */ +public class BerkMinLiteral extends BerkMin { + + private Deque activeLiterals = new LinkedList<>(); + private static final int DEFAULT_QUEUE_SIZE = 32; + private final int queueSize; + + BerkMinLiteral(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, int queueSize) { + super(assignment, choiceManager, decayPeriod, decayFactor, random); + this.queueSize = queueSize; + } + + BerkMinLiteral(Assignment assignment, ChoiceManager choiceManager, Random random) { + this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, random, DEFAULT_QUEUE_SIZE); + } + + @Override + public int chooseAtom() { + return getMostActiveChoosableAtom(activeLiterals.stream()); + } + + private void pushToStack(Integer literal) { + if (choiceManager.isAtomChoice(atomOf(literal))) { + activeLiterals.addFirst(literal); + // Restrict the size of the queue. + if (activeLiterals.size() > queueSize) { + activeLiterals.removeLast(); + } + } + } + + @Override + protected void pushToStack(NoGood noGood) { + if (noGood != null) { + for (Integer literal : noGood) { + pushToStack(literal); + } + } + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java new file mode 100644 index 000000000..78be2e6de --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2016, 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner; + +import java.util.Collection; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; + +/** + * A heuristic that selects an atom to choose on. + * + * Copyright (c) 2016, 2018 Siemens AG + * + */ +public interface BranchingHeuristic { + int DEFAULT_CHOICE_ATOM = 0; + int DEFAULT_CHOICE_LITERAL = atomToLiteral(DEFAULT_CHOICE_ATOM); + + /** + * Stores a newly violated {@link NoGood} and updates associated activity and sign counters. + * + * @param violatedNoGood + */ + void violatedNoGood(NoGood violatedNoGood); + + /** + * Processes the result of a conflict analysis, i.e. counts literals in + * {@link NoGood}s responsible for the conflict and stores a newly learned + * {@link NoGood}. + * + * @param analysisResult + */ + void analyzedConflict(GroundConflictNoGoodLearner.ConflictAnalysisResult analysisResult); + + /** + * Stores a newly grounded {@link NoGood} and updates associated activity counters. + * + * @param newNoGood + */ + void newNoGood(NoGood newNoGood); + + /** + * @see #newNoGood(NoGood) + */ + default void newNoGoods(Collection newNoGoods) { + newNoGoods.forEach(this::newNoGood); + } + + /** + * Determines a literal (= atom + sign) to choose. + * + * @return the literal to choose, or {@link BranchingHeuristic#DEFAULT_CHOICE_LITERAL} if no such atom can be determined. + */ + int chooseLiteral(); + + default void growForMaxAtomId(int maxAtomId) { + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java new file mode 100644 index 000000000..87afa8c6a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017-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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +public final class BranchingHeuristicFactory { + + public static BranchingHeuristic getInstance(HeuristicsConfiguration heuristicsConfiguration, Grounder grounder, WritableAssignment assignment, ChoiceManager choiceManager, Random random) { + BranchingHeuristic heuristicWithoutReplay = getInstanceWithoutReplay(heuristicsConfiguration, grounder, assignment, choiceManager, random); + List replayChoices = heuristicsConfiguration.getReplayChoices(); + if (replayChoices != null && !replayChoices.isEmpty()) { + return ChainedBranchingHeuristics.chainOf( + new ReplayHeuristic(replayChoices, choiceManager), + heuristicWithoutReplay); + } + return heuristicWithoutReplay; + } + + private static BranchingHeuristic getInstanceWithoutReplay(HeuristicsConfiguration heuristicsConfiguration, Grounder grounder, WritableAssignment assignment, ChoiceManager choiceManager, Random random) { + switch (heuristicsConfiguration.getHeuristic()) { + case NAIVE: + return new NaiveHeuristic(choiceManager); + case BERKMIN: + return new BerkMin(assignment, choiceManager, random); + case BERKMINLITERAL: + return new BerkMinLiteral(assignment, choiceManager, random); + case DD: + return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); + case DD_SUM: + return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.SUM); + case DD_AVG: + return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.AVG); + case DD_MAX: + return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MAX); + case DD_MIN: + return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MIN); + case DD_PYRO: + return new DependencyDrivenPyroHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); + case GDD: + return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); + case GDD_SUM: + return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.SUM); + case GDD_AVG: + return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.AVG); + case GDD_MAX: + return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MAX); + case GDD_MIN: + return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MIN); + case GDD_PYRO: + return new GeneralizedDependencyDrivenPyroHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); + case ALPHA_ACTIVE_RULE: + return new AlphaActiveRuleHeuristic(assignment, choiceManager, random); + case ALPHA_HEAD_MBT: + return new AlphaHeadMustBeTrueHeuristic(assignment, choiceManager, random); + case VSIDS: + return new VSIDS(assignment, choiceManager, heuristicsConfiguration.getMomsStrategy()); + case GDD_VSIDS: + return new DependencyDrivenVSIDS(assignment, choiceManager, random, heuristicsConfiguration.getMomsStrategy()); + } + throw new IllegalArgumentException("Unknown branching heuristic requested."); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java new file mode 100644 index 000000000..6d6eb8761 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; + +import java.util.*; + +import static at.ac.tuwien.kr.alpha.Util.oops; + +/** + * A "chained" list of branching heuristics in which the entry at position n+1 is used as a fallback if the entry at position n cannot make a decision. + */ +public class ChainedBranchingHeuristics implements BranchingHeuristic { + + private List chain = new LinkedList<>(); + private int[] decisionCounters; + + private ChainedBranchingHeuristics(BranchingHeuristic... branchingHeuristics) { + for (BranchingHeuristic element : branchingHeuristics) { + add(element); + } + this.decisionCounters = new int[chain.size()]; + } + + @Override + public void violatedNoGood(NoGood violatedNoGood) { + for (BranchingHeuristic element : chain) { + element.violatedNoGood(violatedNoGood); + } + } + + @Override + public void analyzedConflict(ConflictAnalysisResult analysisResult) { + for (BranchingHeuristic element : chain) { + element.analyzedConflict(analysisResult); + } + } + + @Override + public void newNoGood(NoGood newNoGood) { + for (BranchingHeuristic element : chain) { + element.newNoGood(newNoGood); + } + } + + @Override + public int chooseLiteral() { + for (int i = 0; i < chain.size(); i++) { + BranchingHeuristic element = chain.get(i); + int chosenLiteral = element.chooseLiteral(); + if (chosenLiteral != DEFAULT_CHOICE_LITERAL) { + decisionCounters[i]++; + return chosenLiteral; + } + } + return DEFAULT_CHOICE_LITERAL; + } + + @Override + public void growForMaxAtomId(int maxAtomId) { + for (BranchingHeuristic element : chain) { + element.growForMaxAtomId(maxAtomId); + } + } + + public void add(BranchingHeuristic element) { + if (chain.contains(element)) { + throw oops("Cycle detected in chain of branching heuristics"); + } + chain.add(element); + if (decisionCounters != null) { + decisionCounters = Arrays.copyOf(decisionCounters, decisionCounters.length + 1); + } + } + + public BranchingHeuristic getLastElement() { + return chain.get(chain.size() - 1); + } + + public static ChainedBranchingHeuristics chainOf(BranchingHeuristic... branchingHeuristics) { + return new ChainedBranchingHeuristics(branchingHeuristics); + } + + /** + * Returns a mapping from individual heuristics to number of decisions made by them. + */ + public Map getNumberOfDecisions() { + Map map = new HashMap<>(); + for (int i = 0; i < chain.size(); i++) { + map.put(chain.get(i), decisionCounters[i]); + } + return map; + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + chain; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java new file mode 100644 index 000000000..e24f29da0 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java @@ -0,0 +1,361 @@ +/** + * Copyright (c) 2017-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.Literals; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProvider; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.multimap.HashSetValuedHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; + +/** + * The BerkMin variants {@link BerkMin} and {@link BerkMinLiteral} suffer from the fact that choice points + * comprise only a small portion of all the literals occuring in nogoods and therefore do not influence + * activity and sign counters as much as other atoms. + * The basic idea of {@link DependencyDrivenHeuristic} is therefore to find dependent atoms that can + * enrich the information available for a choice point. Intuitively, all atoms occurring in the head or the + * body of a rule depend on a choice point representing the body of this rule. + * + * Copyright (c) 2017-2018 Siemens AG + */ +public class DependencyDrivenHeuristic implements ActivityBasedBranchingHeuristic { + protected static final Logger LOGGER = LoggerFactory.getLogger(DependencyDrivenHeuristic.class); + + public static final double DEFAULT_ACTIVITY = 0.0; + public static final int DEFAULT_SIGN_COUNTER = 0; + + public static final int DEFAULT_DECAY_AGE = 10; + public static final double DEFAULT_DECAY_FACTOR = 0.25; + + protected final Assignment assignment; + protected final ChoiceManager choiceManager; + protected final Random rand; + protected final BodyActivityProvider bodyActivity; + + protected final Map activityCounters = new HashMap<>(); + protected final Map signCounters = new HashMap<>(); + protected final Deque stackOfNoGoods = new ArrayDeque<>(); + private int decayPeriod; + private double decayFactor; + private int stepsSinceLastDecay; + + /** + * Maps body-representing atoms to rule heads. + */ + protected final Map bodyAtomToHeadAtom = new HashMap<>(); + + /** + * Maps rule heads to atoms representing corresponding bodies. + */ + protected final MultiValuedMap headToBodies = new HashSetValuedHashMap<>(); + + /** + * Maps body-representing atoms to literals occuring in the rule body. + */ + protected final MultiValuedMap bodyAtomToLiterals = new HashSetValuedHashMap<>(); + + /** + * Maps atoms to atoms representing bodies of rules in which the former atoms occur (in the head or the body). + */ + protected final MultiValuedMap atomsToBodiesAtoms = new HashSetValuedHashMap<>(); + + public DependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BodyActivityType bodyActivityType) { + this.assignment = assignment; + this.choiceManager = choiceManager; + this.decayPeriod = decayPeriod; + this.decayFactor = decayFactor; + this.rand = random; + this.bodyActivity = BodyActivityProviderFactory.getInstance(bodyActivityType, bodyAtomToLiterals, activityCounters, DEFAULT_ACTIVITY); + } + + public DependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { + this(assignment, choiceManager, DEFAULT_DECAY_AGE, DEFAULT_DECAY_FACTOR, random, bodyActivityType); + } + + public DependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { + this(assignment, choiceManager, random, BodyActivityType.DEFAULT); + } + + /** + * Gets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. + */ + public int getDecayPeriod() { + return decayPeriod; + } + + /** + * Sets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. + */ + public void setDecayPeriod(int decayPeriod) { + this.decayPeriod = decayPeriod; + } + + /** + * Gets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. + */ + public double getDecayFactor() { + return decayFactor; + } + + /** + * Sets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. + */ + public void setDecayFactor(double decayFactor) { + this.decayFactor = decayFactor; + } + + @Override + public void violatedNoGood(NoGood violatedNoGood) { + pushToStack(violatedNoGood); + } + + @Override + public void analyzedConflict(ConflictAnalysisResult analysisResult) { + pushToStack(analysisResult.learnedNoGood); + for (int resolutionAtom : analysisResult.resolutionAtoms) { + incrementActivityCounter(atomToLiteral(resolutionAtom, true)); + incrementActivityCounter(atomToLiteral(resolutionAtom, false)); + } + if (analysisResult.learnedNoGood != null) { + for (Integer literal : analysisResult.learnedNoGood) { + incrementSignCounter(literal); + } + } + decayAllIfTimeHasCome(); + } + + @Override + public void newNoGood(NoGood newNoGood) { + recordAtomRelationships(newNoGood); + pushToStack(newNoGood); + for (Integer literal : newNoGood) { + incrementSignCounter(literal); + } + } + + @Override + public void newNoGoods(Collection newNoGoods) { + newNoGoods.forEach(this::newNoGood); + } + + @Override + public double getActivity(int literal) { + return activityCounters.getOrDefault(atomOf(literal), DEFAULT_ACTIVITY); + } + + /** + * {@link DependencyDrivenHeuristic} manages a stack of nogoods in the fashion of {@link BerkMin} + * and starts by looking at the most active atom a in the nogood currently at the top of the stack. + * If a is an active choice point (i.e. representing the body of an applicable rule), it is immediately chosen; + * else the most active choice point dependent on a is. + * If there is no such atom, we continue further down the stack. + * When choosing between dependent atoms, a {@link BodyActivityProvider} is employed to define the activity of a choice point. + */ + @Override + public int chooseLiteral() { + int atom = chooseAtom(); + if (atom == DEFAULT_CHOICE_ATOM) { + return DEFAULT_CHOICE_LITERAL; + } + boolean sign = chooseSign(atom); + return atomToLiteral(atom, sign); + } + + protected int chooseAtom() { + for (NoGood noGood : stackOfNoGoods) { + int mostActiveAtom = getMostActiveAtom(noGood); + if (choiceManager.isActiveChoiceAtom(mostActiveAtom)) { + return mostActiveAtom; + } + + Collection bodies = atomsToBodiesAtoms.get(mostActiveAtom); + Optional mostActiveBody = bodies.stream().filter(this::isUnassigned).filter(choiceManager::isActiveChoiceAtom) + .max(Comparator.comparingDouble(bodyActivity::get)); + if (mostActiveBody.isPresent()) { + return mostActiveBody.get(); + } + } + return DEFAULT_CHOICE_ATOM; + } + + protected boolean chooseSign(int atom) { + atom = getAtomForChooseSign(atom); + + if (assignment.getTruth(atom) == ThriceTruth.MBT) { + return true; + } + + int positiveCounter = signCounters.getOrDefault(atomToLiteral(atom, true), DEFAULT_SIGN_COUNTER); + int negativeCounter = signCounters.getOrDefault(atomToLiteral(atom, false), DEFAULT_SIGN_COUNTER); + + if (positiveCounter > negativeCounter) { + return false; + } else if (negativeCounter > positiveCounter) { + return true; + } else { + return rand.nextBoolean(); + } + } + + protected int getAtomForChooseSign(int atom) { + Integer head = bodyAtomToHeadAtom.get(atom); + if (head != null) { + atom = head; // head atom can give more relevant information than atom representing rule body + } + return atom; + } + + protected void recordAtomRelationships(NoGood noGood) { + if (isBodyNotHead(noGood, choiceManager::isAtomChoice)) { + int body = atomOf(noGood.getLiteral(1)); + int head = atomOf(noGood.getHead()); + bodyAtomToHeadAtom.put(body, head); + headToBodies.put(head, body); + atomsToBodiesAtoms.put(head, body); + } else if (isBodyElementsNotBody(noGood, choiceManager::isAtomChoice)) { + Set literals = new HashSet<>(); + int bodyAtom = atomOf(noGood.getHead()); + for (int i = 0; i < noGood.size(); i++) { + int literal = noGood.getLiteral(i); + literals.add(literal); + if (bodyAtom != 0) { + atomsToBodiesAtoms.put(atomOf(literal), bodyAtom); + } // else { + // TODO + // } + } + assert bodyAtom != 0; + bodyAtomToLiterals.putAll(bodyAtom, literals); + } + } + + private void pushToStack(NoGood noGood) { + if (noGood != null) { + stackOfNoGoods.push(noGood); + } + } + + protected void incrementActivityCounter(int literal) { + int atom = atomOf(literal); + if (choiceManager.isAtomChoice(atom)) { + activityCounters.compute(atom, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); + } + // TODO: check performance + // note that here (and in incrementSignCounter) we only count atoms that are + // choice points, which might affect performance. + // alternative approaches: + // 1. count everything and from time to time do a garbage collection (i.e. + // remove atoms that are no choice points) + // 2. make check cheaper, e.g. by using dedicated atom IDs (e.g. even + // integers for rule bodies, uneven for other atoms) + } + + protected void incrementSignCounter(Integer literal) { + signCounters.compute(literal, (k, v) -> (v == null ? DEFAULT_SIGN_COUNTER : v) + 1); + } + + private void decayAllIfTimeHasCome() { + stepsSinceLastDecay++; + if (stepsSinceLastDecay >= decayPeriod) { + // Decay all: + activityCounters.replaceAll((k, v) -> v * decayFactor); + stepsSinceLastDecay = 0; + } + } + + /** + * Gets the most recent conflict that is still violated. + * @return the violated nogood closest to the top of the stack of nogoods. + */ + NoGood getCurrentTopClause() { + for (NoGood noGood : stackOfNoGoods) { + if (assignment.isUndefined(noGood)) { + return noGood; + } + } + return null; + } + + protected boolean isUnassigned(int atom) { + ThriceTruth truth = assignment.getTruth(atom); + return truth != FALSE && truth != TRUE; // do not use assignment.isAssigned(atom) because we may also choose MBTs + } + + private int getMostActiveAtom(NoGood noGood) { + if (noGood != null) { + return getMostActiveAtom(noGood.stream().boxed()); + } else { + return getMostActiveAtom(activityCounters.keySet().stream()); + } + } + + private int getMostActiveAtom(Stream streamOfLiterals) { + return streamOfLiterals.map(Literals::atomOf).max(Comparator.comparingDouble(this::getActivity)).orElse(DEFAULT_CHOICE_ATOM); + // TODO: exploit synergy with getMostActiveChoosableAtom + } + + /** + * Analyzes the type of this NoGood and checks if it is the so-called "body, not head" type. Uses the given {@code isRuleBody} predicate to check whether an + * atom represents a rule body. + * + * @return {@code true} iff: the NoGood is binary, and it has a head, and its tail is an atom representing a rule body. + */ + public static boolean isBodyNotHead(NoGood noGood, Predicate isRuleBody) { + return noGood.isBinary() && noGood.hasHead() && isRuleBody.test(atomOf(noGood.getLiteral(1))); + } + + /** + * Analyzes the type of this NoGood and checks if it is the so-called "body elements, not body" type. Uses the given {@code isRuleBody} predicate to check + * whether an atom represents a rule body. + * + * @return {@code true} iff: the NoGood contains at least two literals, and the head is a negative literal whose atom represents a rule body. + */ + public static boolean isBodyElementsNotBody(NoGood noGood, Predicate isRuleBody) { + return noGood.size() > 1 && noGood.hasHead() && isNegated(noGood.getHead()) && isRuleBody.test(atomOf(noGood.getHead())); + } + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java new file mode 100644 index 000000000..181a2299b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2017 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import java.util.Random; + +/** + * One weakness of Alpha that has to be addressed in future work is its lack of support nogoods (except in one special case). + * This means that the solver cannot recognize when an atom occurring negatively in a rule body cannot be satisfied anymore, + * thus exploring large portions of the search space in search for a witness. + * Therefore, Alpha currently benefits in many cases from heuristics that assign true to choice points whenever they can. + * We apply this modification to {@link DependencyDrivenHeuristic}, which then always assigns true first and tries false + * only when backtracking, and call these variants pyromaniacal since they prefer the firing of a rule over its non-firing. + + * Copyright (c) 2017 Siemens AG + * + */ +public class DependencyDrivenPyroHeuristic extends DependencyDrivenHeuristic { + + public DependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BodyActivityType bodyActivityType) { + super(assignment, choiceManager, decayPeriod, decayFactor, random, bodyActivityType); + } + + public DependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { + super(assignment, choiceManager, random, bodyActivityType); + } + + public DependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { + super(assignment, choiceManager, random); + } + + @Override + public boolean chooseSign(int atom) { + return true; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java new file mode 100644 index 000000000..b2d8b194e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; + +import java.util.Random; + +/** + * Non-dependency-driven heuristics like {@link BerkMin}, {@link BerkMinLiteral}, and {@link VSIDS} + * suffer from the fact that choice points comprise only a small portion of all the literals + * occurring in nogoods and therefore do not influence activity and sign counters as much as + * other atoms. + *

      + * The basic idea of {@link DependencyDrivenVSIDS} is therefore to find dependent atoms that can + * enrich the information available for a choice point. Intuitively, all atoms occurring in the head or the + * body of a rule depend on a choice point representing the body of this rule. + *

      + * In contrast to {@link DependencyDrivenHeuristic} and {@link GeneralizedDependencyDrivenHeuristic}, + * this heuristic is based on ideas from VSIDS instead of BerkMin. + */ +public class DependencyDrivenVSIDS extends VSIDS { + + public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + super(assignment, choiceManager, new HeapOfActiveChoicePoints(decayPeriod, decayFactor, choiceManager), momsStrategy); + } + + public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, Random random, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, random, momsStrategy); + } + + /** + * Returns the head derived by the rule corresponding to the given choice point, + * since the head atom may give more relevant information than the atom representing rule body. + */ + @Override + protected int getAtomForChooseSign(int atom) { + Integer head = choiceManager.getHeadDerivedByChoiceAtom(atom); + if (head != null) { + atom = head; + } + return atom; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java new file mode 100644 index 000000000..3b6defcf1 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2017 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +/** + * {@link DependencyDrivenHeuristic} needs to know a lot about the structure of nogoods, i.e. the role their members play in rules. + * However, the solving component of Alpha usually deals only with nogoods and cannot naturally access this information. + * Therefore, {@link GeneralizedDependencyDrivenHeuristic} both generalizes and simplifies {@link DependencyDrivenHeuristic} + * by redefining the set of atoms dependent on a choice point. + * This set is constructed by adding to it, every time a new nogood containing a choice point is added to the stack, + * all other atoms in the nogood. + * To choose an atom, {@link GeneralizedDependencyDrivenHeuristic} then proceeds as {@link DependencyDrivenHeuristic}. + * Because {@link GeneralizedDependencyDrivenHeuristic} does not know the head belonging to a choice point, + * it just uses the {@link BerkMin} method to choose a truth value. + + * Copyright (c) 2017 Siemens AG + * + */ +public class GeneralizedDependencyDrivenHeuristic extends DependencyDrivenHeuristic { + + public GeneralizedDependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BodyActivityType bodyActivityType) { + super(assignment, choiceManager, decayPeriod, decayFactor, random, bodyActivityType); + } + + public GeneralizedDependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { + super(assignment, choiceManager, random, bodyActivityType); + } + + public GeneralizedDependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { + super(assignment, choiceManager, random); + } + + @Override + protected void recordAtomRelationships(NoGood noGood) { + // TODO: use HeapOfActiveChoicePoints.recordAtomRelationships, which does similar things + int body = DEFAULT_CHOICE_ATOM; + Set others = new HashSet<>(); + for (int literal : noGood) { + int atom = atomOf(literal); + if (body == DEFAULT_CHOICE_ATOM && choiceManager.isAtomChoice(atom)) { + body = atom; + } else { + others.add(atom); + } + } + for (Integer atom : others) { + atomsToBodiesAtoms.put(atom, body); + bodyAtomToLiterals.put(body, atom); + } + } + + @Override + protected int getAtomForChooseSign(int atom) { + return atom; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java new file mode 100644 index 000000000..e8deefa8b --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2017 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import java.util.Random; + +/** + * One weakness of Alpha that has to be addressed in future work is its lack of support nogoods (except in one special case). + * This means that the solver cannot recognize when an atom occurring negatively in a rule body cannot be satisfied anymore, + * thus exploring large portions of the search space in search for a witness. + * Therefore, Alpha currently benefits in many cases from heuristics that assign true to choice points whenever they can. + * We apply this modification to {@link GeneralizedDependencyDrivenHeuristic}, which then always assigns true first and tries false + * only when backtracking, and call these variants pyromaniacal since they prefer the firing of a rule over its non-firing. + + * Copyright (c) 2017 Siemens AG + * + */ +public class GeneralizedDependencyDrivenPyroHeuristic extends GeneralizedDependencyDrivenHeuristic { + + public GeneralizedDependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, + BodyActivityType bodyActivityType) { + super(assignment, choiceManager, decayPeriod, decayFactor, random, bodyActivityType); + } + + public GeneralizedDependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { + super(assignment, choiceManager, random, bodyActivityType); + } + + public GeneralizedDependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { + super(assignment, choiceManager, random); + } + + @Override + public boolean chooseSign(int atom) { + return true; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java new file mode 100644 index 000000000..45f9faf43 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java @@ -0,0 +1,283 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.ChoiceInfluenceManager; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.PriorityQueue; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +/** + * Manages a heap of atoms that are assigned an activity, such that the most active atom + * resides at the top of the heap. + * In contrast to standard heuristics like VSIDS, activities are not periodically decayed but + * the increment added when increasing activities is constantly increased itself, which has the + * same effect. + * + */ +public class HeapOfActiveAtoms { + protected static final Logger LOGGER = LoggerFactory.getLogger(HeapOfActiveAtoms.class); + + private static final double NORMALIZATION_THRESHOLD = 1E100; + private static final double INCREMENT_TO_AVOID_DENORMALS = Double.MIN_VALUE * NORMALIZATION_THRESHOLD; + private static final double SCORE_EPSILON = 1E-100; + + private boolean[] incrementedActivityScores = new boolean[0]; + protected double[] activityScores = new double[0]; + protected final PriorityQueue heap = new PriorityQueue<>(new AtomActivityComparator().reversed()); + + protected ChoiceManager choiceManager; + private int decayPeriod; + private double decayFactor; + private int stepsSinceLastDecay; + private double currentActivityIncrement = 1.0; + private int numberOfNormalizations; + + private final MOMs moms; + + public HeapOfActiveAtoms(int decayPeriod, double decayFactor, ChoiceManager choiceManager) { + this.decayPeriod = decayPeriod; + this.decayFactor = decayFactor; + this.choiceManager = choiceManager; + this.choiceManager.setChoicePointActivityListener(new ChoicePointActivityListener()); + BinaryNoGoodPropagationEstimation bnpEstimation = choiceManager.getBinaryNoGoodPropagationEstimation(); + this.moms = bnpEstimation == null ? null : new MOMs(bnpEstimation); + } + + public double getActivity(int literal) { + return activityScores[atomOf(literal)]; + } + + /** + * Gets the number of steps after which activity scores are decayed. + */ + public int getDecayPeriod() { + return decayPeriod; + } + + /** + * @see #getDecayPeriod() + */ + public void setDecayPeriod(int decayPeriod) { + this.decayPeriod = decayPeriod; + } + + /** + * Gets the factor by which the activity increment is multiplied every {@link #getDecayPeriod()} steps. + */ + public double getDecayFactor() { + return decayFactor; + } + + /** + * @see #getDecayFactor() + */ + public void setDecayFactor(double decayFactor) { + this.decayFactor = decayFactor; + } + + /** + * Updates the current activity increment by multiplying it with the decay factor, if time for decay has come. + * + * Time for decay has come if the number of conflicts since the last decay has reached the decay period. + */ + void decayIfTimeHasCome() { + stepsSinceLastDecay++; + if (stepsSinceLastDecay >= decayPeriod) { + currentActivityIncrement *= decayFactor; + stepsSinceLastDecay = 0; + } + } + + /** + * Stores newly grounded {@link NoGood}s and updates associated activity counters. + */ + public void newNoGoods(Collection newNoGoods) { + for (NoGood newNoGood : newNoGoods) { + Type type = newNoGood.getType(); + if (type != Type.LEARNT && type != Type.INTERNAL) { + analyzeNewNoGood(newNoGood); + initActivity(newNoGood); + } + } + } + + /** + * May be implemented in subclasses to add specific analysis of nogoods. + */ + protected void analyzeNewNoGood(NoGood newNoGood) { + } + + /** + * Computes and stores initial activity values for the atoms occurring in the given nogood. + */ + protected void initActivity(NoGood newNoGood) { + if (moms != null) { + initActivityMOMs(newNoGood); + } else { + initActivityNaive(newNoGood); + } + } + + /** + * Uses {@link MOMs} to initialize activity scores, which are then scaled to the interval [0,1]. + * This is done by computing 1 - 1/log(s+1.01) for original score s. + * This guarantees a normalized score between 0 and 1 and retains relative order. + * 1.01 is added to avoid computing the logarithm of a number between 0 and 1 (input scores have to be greater or equal to 0!) + * @param newNoGood a new nogood, the atoms occurring in which will be initialized + */ + private void initActivityMOMs(NoGood newNoGood) { + LOGGER.debug("Initializing activity scores with MOMs"); + for (int literal : newNoGood) { + int atom = atomOf(literal); + if (!incrementedActivityScores[atom]) { // update initial value as long as not incremented yet by VSIDS + double score = moms.getScore(atom); + if (score > 0.0) { + double newActivity = 1 - 1 / (Math.log(score + 1.01)); + if (newActivity - activityScores[atom] > SCORE_EPSILON) { // avoid computation overhead if score does not increase + if (numberOfNormalizations > 0) { + newActivity = normalizeNewActivityScore(newActivity); + } + setActivity(atom, newActivity); + } + } + } + } + } + + void growToCapacity(int newCapacity) { + activityScores = Arrays.copyOf(activityScores, newCapacity); + incrementedActivityScores = Arrays.copyOf(incrementedActivityScores, newCapacity); + } + + private void initActivityNaive(NoGood newNoGood) { + LOGGER.debug("Initializing activity scores naively"); + for (Integer literal : newNoGood) { + int atom = atomOf(literal); + incrementActivity(atom); + } + } + + /** + * Returns the atom with the highest activity score and removes it from the heap. + */ + public Integer getMostActiveAtom() { + return heap.poll(); + } + + /** + * Increments the activity of the given atom + * + * by adding to it the current activity increment times the increment factor. + * If the new value exceeds a certain threshold, all activity scores are normalized. + */ + public void incrementActivity(int atom) { + incrementActivity(atom, currentActivityIncrement); + } + + protected void incrementActivity(int atom, double increment) { + // newActivity := oldActivity + increment + double newActivity = activityScores[atom] + increment; + setActivity(atom, newActivity); + incrementedActivityScores[atom] = true; + } + + private void setActivity(int atom, double newActivity) { + activityScores[atom] = newActivity; + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Activity of atom {} set to {}", atom, newActivity); + } + + if (newActivity > NORMALIZATION_THRESHOLD) { + normalizeActivityScores(); + } + + heap.add(atom); // ignores the fact that atom may already be in the heap for performance reasons (may be revised in future) + } + + /** + * Makes all activity scores smaller if they get too high. + * + * Avoids denormal numbers similarly as done in clasp. + */ + private void normalizeActivityScores() { + LOGGER.debug("Normalizing activity scores"); + numberOfNormalizations++; + currentActivityIncrement /= NORMALIZATION_THRESHOLD; + for (int atom = 1; atom < activityScores.length; atom++) { + activityScores[atom] = (activityScores[atom] + INCREMENT_TO_AVOID_DENORMALS) / NORMALIZATION_THRESHOLD; + } + } + + private double normalizeNewActivityScore(double newActivity) { + for (int i = 0; i < numberOfNormalizations; i++) { + newActivity = (newActivity + INCREMENT_TO_AVOID_DENORMALS) / NORMALIZATION_THRESHOLD; + } + return newActivity; + } + + private class AtomActivityComparator implements Comparator { + + @Override + public int compare(Integer a1, Integer a2) { + return Double.compare(activityScores[a1], activityScores[a2]); + } + + } + + private class ChoicePointActivityListener implements ChoiceInfluenceManager.ActivityListener { + + @Override + public void callbackOnChanged(int atom, boolean active) { + if (active && choiceManager.isActiveChoiceAtom(atom)) { + if (atom < activityScores.length) { + /* if atom has no activity score, probably the atom is still being buffered + by DependencyDrivenVSIDSHeuristic and will get an initial activity + when the buffer is ingested */ + heap.add(atom); + } + } + } + } + + public void setMOMsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + if (moms != null) { + moms.setStrategy(momsStrategy); + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java new file mode 100644 index 000000000..94c768bee --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.multimap.HashSetValuedHashMap; + +import java.util.HashSet; +import java.util.Set; + +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +/** + * Extends {@code HeapOfActiveAtoms} by a mechanism that, + * when the activity of an atom is increased, the increase counts towards dependent choice point + * if the given atom is not a choice point itself. + * Also, only choice points are maintained in the heap and only choice points are returned by + * {@link #getMostActiveAtom()}. + * + */ +public class HeapOfActiveChoicePoints extends HeapOfActiveAtoms { + + /** + * Maps atoms to choice points representing bodies of rules in which the former atoms occur + * (in the head or the body). + */ + protected final MultiValuedMap atomsToChoicePoints = new HashSetValuedHashMap<>(); + + public HeapOfActiveChoicePoints(int decayPeriod, double decayFactor, ChoiceManager choiceManager) { + super(decayPeriod, decayFactor, choiceManager); + } + + @Override + public void incrementActivity(int atom, double increment) { + if (choiceManager.isAtomChoice(atom)) { + super.incrementActivity(atom, increment); + } else { + for (Integer dependentBody : atomsToChoicePoints.get(atom)) { + super.incrementActivity(dependentBody, increment); + } + } + } + + /** + * Records the dependency relationships between atoms occurring in the given nogood. + * @param noGood + */ + private void recordAtomRelationships(NoGood noGood) { + final int none = -1; + int body = none; + Set others = new HashSet<>(); + + for (int literal : noGood) { + int atom = atomOf(literal); + if (body == none && choiceManager.isAtomChoice(atom)) { + body = atom; + } else { + if (choiceManager.isChecksEnabled() && choiceManager.isAtomChoice(atom)) { + throw oops("More than one choice point in a nogood: " + body + ", " + atom); + } + others.add(atom); + } + } + + if (body == none) { + return; + } + + for (Integer atom : others) { + atomsToChoicePoints.put(atom, body); + } + } + + @Override + public void analyzeNewNoGood(NoGood newNoGood) { + recordAtomRelationships(newNoGood); + } + + @Override + public String toString() { + return heap.toString(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java new file mode 100644 index 000000000..26d3d74a4 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; + +import java.util.List; + +/** + * Configuration class holding parameters for {@link BranchingHeuristic}s. + */ +public class HeuristicsConfiguration { + + private Heuristic heuristic; + private BinaryNoGoodPropagationEstimationStrategy momsStrategy; + private List replayChoices; + /** + * @param heuristic + * @param momsStrategy + * @param replayChoices + */ + public HeuristicsConfiguration(Heuristic heuristic, BinaryNoGoodPropagationEstimationStrategy momsStrategy, List replayChoices) { + super(); + this.heuristic = heuristic; + this.momsStrategy = momsStrategy; + this.replayChoices = replayChoices; + } + + /** + * @return the heuristic + */ + public Heuristic getHeuristic() { + return heuristic; + } + + /** + * @param heuristic the heuristic to set + */ + public void setHeuristic(Heuristic heuristic) { + this.heuristic = heuristic; + } + + /** + * @return the momsStrategy + */ + public BinaryNoGoodPropagationEstimationStrategy getMomsStrategy() { + return momsStrategy; + } + + /** + * @param momsStrategy the momsStrategy to set + */ + public void setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + this.momsStrategy = momsStrategy; + } + + /** + * @return the replayChoices + */ + public List getReplayChoices() { + return replayChoices; + } + + /** + * @param replayChoices the replayChoices to set + */ + public void setReplayChoices(List replayChoices) { + this.replayChoices = replayChoices; + } + + public static HeuristicsConfigurationBuilder builder() { + return new HeuristicsConfigurationBuilder(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java new file mode 100644 index 000000000..b1ee79ccf --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; + +import java.util.List; + +/** + * Builder for {@link HeuristicsConfiguration} objects + */ +public class HeuristicsConfigurationBuilder { + + private Heuristic heuristic; + private BinaryNoGoodPropagationEstimationStrategy momsStrategy; + private List replayChoices; + + /** + * @param heuristic the heuristic to set + */ + public HeuristicsConfigurationBuilder setHeuristic(Heuristic heuristic) { + this.heuristic = heuristic; + return this; + } + + /** + * @param momsStrategy the momsStrategy to set + */ + public HeuristicsConfigurationBuilder setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + this.momsStrategy = momsStrategy; + return this; + } + + /** + * @param replayChoices the replayChoices to set + */ + public HeuristicsConfigurationBuilder setReplayChoices(List replayChoices) { + this.replayChoices = replayChoices; + return this; + } + + public HeuristicsConfiguration build() { + return new HeuristicsConfiguration(heuristic, momsStrategy, replayChoices); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java new file mode 100644 index 000000000..223cb7ad7 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; + +/** + * The well-known MOMs (Maximum Occurrences in clauses of Minimum size) heuristic + * used to initialize atom scores. + * This implementation is inspired by the MOMs implementation in clasp + * but differs from it in several ways, e.g.: + *

        + *
      • The default strategy is {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches}, not {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation}.
      • + *
      • {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation} does not do only one iteration of propagation, but exhaustive propagation.
      • + *
      + * + */ +public class MOMs { + + static final BinaryNoGoodPropagationEstimationStrategy DEFAULT_STRATEGY = BinaryNoGoodPropagationEstimationStrategy.CountBinaryWatches; + + private BinaryNoGoodPropagationEstimation bnpEstimation; + private BinaryNoGoodPropagationEstimationStrategy strategy = DEFAULT_STRATEGY; + + public MOMs(BinaryNoGoodPropagationEstimation bnpEstimation) { + super(); + this.bnpEstimation = bnpEstimation; + } + + /** + * @param atom + * @return + */ + public double getScore(Integer atom) { + int s1 = bnpEstimation.estimate(atom, true, strategy); + int s2 = bnpEstimation.estimate(atom, false, strategy); + return ((s1 * s2) << 10) + s1 + s2; + } + + public void setStrategy(BinaryNoGoodPropagationEstimationStrategy strategy) { + this.strategy = strategy != null ? strategy : DEFAULT_STRATEGY; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java new file mode 100644 index 000000000..506cc345c --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2016-2018, 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; + +import java.util.Collection; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; + +/** + * The default heuristic that had been used by {@link at.ac.tuwien.kr.alpha.solver.DefaultSolver} before {@link BerkMin} was implemented. + * + */ +public class NaiveHeuristic implements BranchingHeuristic { + + private final ChoiceManager choiceManager; + + public NaiveHeuristic(ChoiceManager choiceManager) { + this.choiceManager = choiceManager; + } + + @Override + public void violatedNoGood(NoGood violatedNoGood) { + } + + @Override + public void analyzedConflict(ConflictAnalysisResult analysisResult) { + } + + @Override + public void newNoGood(NoGood newNoGood) { + } + + @Override + public void newNoGoods(Collection newNoGoods) { + } + + @Override + public int chooseLiteral() { + return atomToLiteral(choiceManager.getNextActiveChoiceAtom()); + } + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java new file mode 100644 index 000000000..cda9f35ac --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Literals; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; + +import java.util.Iterator; +import java.util.List; + +/** + * A heuristic that replays a fixed list of choices. + */ +public class ReplayHeuristic implements BranchingHeuristic { + + private final Iterator choicesIterator; + private final ChoiceManager choiceManager; + + /** + * Initializes the heuristic + * @param choices a list of signed atoms (positive if atom shall be made true, negative otherwise) + * @param choiceManager + */ + public ReplayHeuristic(List choices, ChoiceManager choiceManager) { + super(); + this.choicesIterator = choices.iterator(); + this.choiceManager = choiceManager; + } + + @Override + public void violatedNoGood(NoGood violatedNoGood) { + } + + @Override + public void analyzedConflict(ConflictAnalysisResult analysisResult) { + } + + @Override + public void newNoGood(NoGood newNoGood) { + } + + @Override + public int chooseLiteral() { + if (!choicesIterator.hasNext()) { + return DEFAULT_CHOICE_LITERAL; + } + int replayChoiceSignedAtom = choicesIterator.next(); + if (replayChoiceSignedAtom == 0) { + // Use 0 to signal no more choices. + return DEFAULT_CHOICE_LITERAL; + } + int replayChoiceAtom = Math.abs(replayChoiceSignedAtom); + int replayChoiceLiteral = Literals.atomToLiteral(replayChoiceAtom, replayChoiceSignedAtom > 0); + if (!choiceManager.isActiveChoiceAtom(replayChoiceAtom)) { + throw new IllegalStateException("Replay choice is not an active choice point: " + replayChoiceAtom); + } + return replayChoiceLiteral; + } + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java new file mode 100644 index 000000000..7b8b60232 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java @@ -0,0 +1,252 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProvider; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.multimap.HashSetValuedHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.common.Literals.*; + +/** + * This implementation is inspired by the VSIDS implementation in clasp. + * Therefore, for example, decay is not realized by decreasing activity scores with age, but by + * steadily increasing the increment added to the score of active atoms + * (such that the activity score of older atoms does not have to be changed later). + *

      + * The implementation is simplified in some ways, e.g. it is not possible to specify a frequency in which the activity + * increment is updated (which corresponds to decay), but it is updated after every conflict. + *

      + * Reference for VSIDS: + * Moskewicz, Matthew W.; Madigan, Conor F.; Zhao, Ying; Zhang, Lintao; Malik, Sharad (2001): + * Chaff: engineering an efficient SAT solver. + * In: Proceedings of the 38th Design Automation Conference. IEEE, pp. 530–535. + */ +public class VSIDS implements ActivityBasedBranchingHeuristic { + protected static final Logger LOGGER = LoggerFactory.getLogger(VSIDS.class); + + public static final int DEFAULT_DECAY_PERIOD = 1; + + /** + * The default factor by which VSID's activity increment will be multiplied when the decay period has expired. + * The value is taken from clasp's tweety configuration which clasp uses by default. + */ + public static final double DEFAULT_DECAY_FACTOR = 1 / 0.92; + + protected final Assignment assignment; + protected final ChoiceManager choiceManager; + + protected final HeapOfActiveAtoms heapOfActiveAtoms; + protected int[] signBalances = new int[0]; + + private final Collection bufferedNoGoods = new ArrayList<>(); + + private int nChoicesTrue; + private int nChoicesFalse; + private int nChoicesRand; + + /** + * Maps rule heads to atoms representing corresponding bodies. + */ + protected final MultiValuedMap headToBodies = new HashSetValuedHashMap<>(); + + protected VSIDS(Assignment assignment, ChoiceManager choiceManager, HeapOfActiveAtoms heapOfActiveAtoms, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + this.assignment = assignment; + this.choiceManager = choiceManager; + this.heapOfActiveAtoms = heapOfActiveAtoms; + this.heapOfActiveAtoms.setMOMsStrategy(momsStrategy); + } + + public VSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + this(assignment, choiceManager, new HeapOfActiveAtoms(decayPeriod, decayFactor, choiceManager), momsStrategy); + } + + public VSIDS(Assignment assignment, ChoiceManager choiceManager, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { + this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, momsStrategy); + } + + @Override + public void violatedNoGood(NoGood violatedNoGood) { + } + + @Override + public void analyzedConflict(ConflictAnalysisResult analysisResult) { + ingestBufferedNoGoods(); //analysisResult may contain new atoms whose activity must be initialized + for (int resolutionAtom : analysisResult.resolutionAtoms) { + heapOfActiveAtoms.incrementActivity(resolutionAtom); + } + if (analysisResult.learnedNoGood != null) { + for (int literal : analysisResult.learnedNoGood) { + incrementSignCounter(literal); + heapOfActiveAtoms.incrementActivity(atomOf(literal)); + } + } + heapOfActiveAtoms.decayIfTimeHasCome(); + } + + @Override + public void newNoGood(NoGood newNoGood) { + this.bufferedNoGoods.add(newNoGood); + } + + @Override + public void newNoGoods(Collection newNoGoods) { + this.bufferedNoGoods.addAll(newNoGoods); + } + + private void ingestBufferedNoGoods() { + heapOfActiveAtoms.newNoGoods(bufferedNoGoods); + bufferedNoGoods.clear(); + } + + /** + * {@link VSIDS} manages a stack of nogoods in the fashion of {@link BerkMin} + * and starts by looking at the most active atom a in the nogood currently at the top of the stack. + * If a is an active choice point (i.e. representing the body of an applicable rule), it is immediately chosen; + * else the most active choice point dependent on a is. + * If there is no such atom, we continue further down the stack. + * When choosing between dependent atoms, a {@link BodyActivityProvider} is employed to define the activity of a choice point. + */ + @Override + public int chooseLiteral() { + int atom = chooseAtom(); + if (atom == DEFAULT_CHOICE_ATOM) { + return DEFAULT_CHOICE_LITERAL; + } + boolean sign = chooseSign(atom); + return atomToLiteral(atom, sign); + } + + protected int chooseAtom() { + ingestBufferedNoGoods(); + Integer mostActiveAtom; + while ((mostActiveAtom = heapOfActiveAtoms.getMostActiveAtom()) != null) { + if (choiceManager.isActiveChoiceAtom(mostActiveAtom)) { + return mostActiveAtom; + } + } + return DEFAULT_CHOICE_ATOM; + } + + /** + * Chooses a sign (truth value) to assign to the given atom. + * + * To make this decision, sign counters are maintained that reflect how often an atom + * occurs positively or negatively in learnt nogoods. + * If the sign balance for the given atom is positive, {@code true} will be chosen. + * If it is negative, {@code false} will be chosen. + * If the sign balance is zero, the default sign is selected, which is {@code true} + * iff the atom represents a rule body (which is currently always the case for atoms chosen in Alpha). + * + * @param atom + * the chosen atom + * @return the truth value to assign to the given atom + */ + protected boolean chooseSign(int atom) { + atom = getAtomForChooseSign(atom); + + if (assignment.getTruth(atom) == ThriceTruth.MBT) { + return true; + } + + int signBalance = getSignBalance(atom); + if (LOGGER.isDebugEnabled() && (nChoicesFalse + nChoicesTrue + nChoicesRand) % 100 == 0) { + LOGGER.debug("chooseSign stats: f={}, t={}, r={}", nChoicesFalse, nChoicesTrue, nChoicesRand); + LOGGER.debug("chooseSign stats: signBalance={}", signBalance); + } + + if (signBalance >= 0) { + nChoicesTrue++; + return true; + } else { + nChoicesFalse++; + return false; + } + } + + /** + * This method just returns {@code atom} by default but can be overridden in subclasses. + * @param atom the atom chosen by VSIDS + * @return the atom to base the choice of sign upon + */ + protected int getAtomForChooseSign(int atom) { + return atom; + } + + protected void incrementSignCounter(int literal) { + int atom = atomOf(literal); + boolean sign = isPositive(literal); + growForMaxAtomId(atom); + signBalances[atom] += sign ? 1 : -1; + } + + public void growForMaxAtomId(int maxAtomId) { + // Grow arrays only if needed. + if (signBalances.length > maxAtomId) { + return; + } + // Grow to default size, except if bigger array is required due to maxAtomId. + int newCapacity = arrayGrowthSize(signBalances.length); + if (newCapacity < maxAtomId + 1) { + newCapacity = maxAtomId + 1; + } + signBalances = Arrays.copyOf(signBalances, newCapacity); + heapOfActiveAtoms.growToCapacity(newCapacity); + } + + @Override + public double getActivity(int literal) { + return heapOfActiveAtoms.getActivity(literal); + } + + /** + * Returns the sign balance for the given atom in learnt nogoods. + * @param atom + * @return the number of times the given atom occurrs positively more often than negatively (which may be negative) + */ + int getSignBalance(int atom) { + return signBalances.length > atom ? signBalances[atom] : 0; + } + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java new file mode 100644 index 000000000..35a5c1f0e --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017 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.solver.heuristics.activity; + +import org.apache.commons.collections4.MultiValuedMap; + +import java.util.Map; + +public class AvgBodyActivityProvider extends BodyActivityProvider { + + public AvgBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { + super(bodyToLiterals, activityCounters, defaultActivity); + } + + @Override + public double get(int bodyRepresentingAtom) { + return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).average().orElse(defaultActivity); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java new file mode 100644 index 000000000..7591eea47 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2017 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.solver.heuristics.activity; + +import org.apache.commons.collections4.MultiValuedMap; + +import java.util.Map; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; + +public abstract class BodyActivityProvider { + + protected final MultiValuedMap bodyToLiterals; + protected final Map activityCounters; + protected final double defaultActivity; + + public BodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { + this.bodyToLiterals = bodyToLiterals; + this.activityCounters = activityCounters; + this.defaultActivity = defaultActivity; + } + + public abstract double get(int bodyRepresentingAtom); + + protected double getActivity(int literal) { + return activityCounters.getOrDefault(atomOf(literal), defaultActivity); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java new file mode 100644 index 000000000..f3ded2a85 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2017 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.solver.heuristics.activity; + +import org.apache.commons.collections4.MultiValuedMap; + +import java.util.Map; + +public final class BodyActivityProviderFactory { + + public enum BodyActivityType { + DEFAULT, SUM, AVG, MAX, MIN + } + + public static BodyActivityProvider getInstance(BodyActivityType type, MultiValuedMap bodyToLiterals, Map activityCounters, + double defaultActivity) { + switch (type) { + case DEFAULT: + return new DefaultBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); + case SUM: + return new SumBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); + case AVG: + return new AvgBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); + case MAX: + return new MaxBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); + case MIN: + return new MinBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); + default: + throw new IllegalArgumentException("Unknown body activity type requested."); + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java new file mode 100644 index 000000000..a2e599790 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017 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.solver.heuristics.activity; + +import org.apache.commons.collections4.MultiValuedMap; + +import java.util.Map; + +public class DefaultBodyActivityProvider extends BodyActivityProvider { + + public DefaultBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { + super(bodyToLiterals, activityCounters, defaultActivity); + } + + @Override + public double get(int bodyRepresentingAtom) { + return activityCounters.getOrDefault(bodyRepresentingAtom, defaultActivity); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java new file mode 100644 index 000000000..324c4ccce --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017 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.solver.heuristics.activity; + +import org.apache.commons.collections4.MultiValuedMap; + +import java.util.Map; + +public class MaxBodyActivityProvider extends BodyActivityProvider { + + public MaxBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { + super(bodyToLiterals, activityCounters, defaultActivity); + } + + @Override + public double get(int bodyRepresentingAtom) { + return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).max().orElse(defaultActivity); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java new file mode 100644 index 000000000..33d73c237 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017 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.solver.heuristics.activity; + +import org.apache.commons.collections4.MultiValuedMap; + +import java.util.Map; + +public class MinBodyActivityProvider extends BodyActivityProvider { + + public MinBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { + super(bodyToLiterals, activityCounters, defaultActivity); + } + + @Override + public double get(int bodyRepresentingAtom) { + return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).min().orElse(defaultActivity); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java new file mode 100644 index 000000000..4cb116748 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017 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.solver.heuristics.activity; + +import org.apache.commons.collections4.MultiValuedMap; + +import java.util.Map; + +public class SumBodyActivityProvider extends BodyActivityProvider { + + public SumBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { + super(bodyToLiterals, activityCounters, defaultActivity); + } + + @Override + public double get(int bodyRepresentingAtom) { + return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).sum(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java new file mode 100644 index 000000000..d5b26f9bf --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java @@ -0,0 +1,361 @@ +/** + * Copyright (c) 2016-2018, 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.solver.learning; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.Antecedent; +import at.ac.tuwien.kr.alpha.solver.TrailAssignment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static at.ac.tuwien.kr.alpha.solver.NoGoodStore.LBD_NO_VALUE; + +/** + * Conflict-driven learning on ground clauses. + * + * Copyright (c) 2016-2020, the Alpha Team. + */ +public class GroundConflictNoGoodLearner { + private static final Logger LOGGER = LoggerFactory.getLogger(GroundConflictNoGoodLearner.class); + + private final Assignment assignment; + private final AtomStore atomStore; + + /** + * Given a conflicting NoGood, computes a conflict-free backjumping level such that the given NoGood is not + * violated. + * + * @param violatedNoGood the conflicting NoGood. + * @return -1 if the violatedNoGood cannot be satisfied, otherwise + * 0 if violatedNoGood is unary, and else + * the highest backjumping level such that the NoGood is no longer violated. + */ + public int computeConflictFreeBackjumpingLevel(NoGood violatedNoGood) { + // If violatedNoGood is unary, backjump to decision level 0 if it can be satisfied. + if (violatedNoGood.isUnary()) { + int literal = violatedNoGood.getLiteral(0); + int literalDecisionLevel = assignment.getRealWeakDecisionLevel(atomOf(literal)); + if (literalDecisionLevel > 0) { + return 0; + } else { + return -1; + } + } + int highestDecisionLevel = -1; + int secondHighestDecisionLevel = -1; + int numAtomsInHighestLevel = 0; + int[] reasonLiterals = violatedNoGood.asAntecedent().getReasonLiterals(); + for (int literal : reasonLiterals) { + int literalDecisionLevel = assignment.getRealWeakDecisionLevel(atomOf(literal)); + if (literalDecisionLevel == highestDecisionLevel) { + numAtomsInHighestLevel++; + } else if (literalDecisionLevel > highestDecisionLevel) { + secondHighestDecisionLevel = highestDecisionLevel; + highestDecisionLevel = literalDecisionLevel; + numAtomsInHighestLevel = 1; + } else if (literalDecisionLevel > secondHighestDecisionLevel) { + secondHighestDecisionLevel = literalDecisionLevel; + } + } + if (numAtomsInHighestLevel == 1) { + return secondHighestDecisionLevel; + } + return highestDecisionLevel - 1; + } + + public static class ConflictAnalysisResult { + public static final ConflictAnalysisResult UNSAT = new ConflictAnalysisResult(); + + public final NoGood learnedNoGood; + public final int backjumpLevel; + public final Collection resolutionAtoms; + public final int lbd; + + private ConflictAnalysisResult() { + learnedNoGood = null; + backjumpLevel = -1; + resolutionAtoms = null; + lbd = LBD_NO_VALUE; + } + + public ConflictAnalysisResult(NoGood learnedNoGood, int backjumpLevel, Collection resolutionAtoms) { + this(learnedNoGood, backjumpLevel, resolutionAtoms, LBD_NO_VALUE); + } + + public ConflictAnalysisResult(NoGood learnedNoGood, int backjumpLevel, Collection resolutionAtoms, int lbd) { + if (backjumpLevel < 0) { + throw oops("Backjumping level is smaller than 0"); + } + + this.learnedNoGood = learnedNoGood; + this.backjumpLevel = backjumpLevel; + this.resolutionAtoms = resolutionAtoms; + this.lbd = lbd; + } + + @Override + public String toString() { + if (this == UNSAT) { + return "UNSATISFIABLE"; + } + return learnedNoGood + "@" + backjumpLevel; + } + } + + public GroundConflictNoGoodLearner(Assignment assignment, AtomStore atomStore) { + this.assignment = assignment; + this.atomStore = atomStore; + } + + public ConflictAnalysisResult analyzeConflictingNoGood(Antecedent violatedNoGood) { + LOGGER.trace("Analyzing violated nogood: {}", violatedNoGood); + return analyzeTrailBased(violatedNoGood); + } + + public ConflictAnalysisResult analyzeConflictFromAddingNoGood(Antecedent violatedNoGood) { + LOGGER.trace("Analyzing conflict caused by adding the (violated) nogood: {}", violatedNoGood); + // Simply compute appropriate backjumping level. + int removingConflict = backjumpLevelRemovingConflict(violatedNoGood); + if (removingConflict < 0) { + return ConflictAnalysisResult.UNSAT; + } + return new ConflictAnalysisResult(null, removingConflict, Collections.emptyList(), LBD_NO_VALUE); + } + + private int backjumpLevelRemovingConflict(Antecedent violatedNoGood) { + int highestDL = 0; + int[] reasonLiterals = violatedNoGood.getReasonLiterals(); + for (int literal : reasonLiterals) { + int literalDL = assignment.getWeakDecisionLevel(atomOf(literal)); + if (literalDL > highestDL) { + highestDL = literalDL; + } + } + return highestDL - 1; + } + + private String reasonsToString(Collection reasons) { + StringBuilder sb = new StringBuilder("{"); + for (int reasonLiteral : reasons) { + sb.append(isPositive(reasonLiteral) ? "+" + atomOf(reasonLiteral) : "-" + atomOf(reasonLiteral)); + sb.append("@"); + sb.append(assignment.getWeakDecisionLevel(atomOf(reasonLiteral))); + sb.append(", "); + } + sb.append("}"); + return sb.toString(); + } + + private String reasonsToString(int[] reasons) { + return reasonsToString(IntStream.of(reasons != null ? reasons : new int[0]).boxed().collect(Collectors.toList())); + } + + private ConflictAnalysisResult analyzeTrailBased(Antecedent conflictReason) { + LOGGER.trace("Analyzing trail based."); + if (assignment.getDecisionLevel() == 0) { + LOGGER.trace("Conflict on decision level 0."); + return ConflictAnalysisResult.UNSAT; + } + int numLiteralsInConflictLevel = 0; + List resolutionLiterals = new ArrayList<>(); + List resolutionAtoms = new ArrayList<>(); + int currentDecisionLevel = assignment.getDecisionLevel(); + Set seenAtoms = new HashSet<>(); // NOTE: other solvers use a global array for seen atoms, this might be slightly faster (initial tests with local arrays showed no significant improvement). + Set processedAtoms = new HashSet<>(); // Since trail contains 2 entries for MBT->TRUE assigned atoms, explicitly record which seen atoms have ben processed to avoid processing seen atoms twice. + int[] currentConflictReason = conflictReason.getReasonLiterals(); + int backjumpLevel = -1; + conflictReason.bumpActivity(); + TrailAssignment.TrailBackwardsWalker trailWalker = ((TrailAssignment)assignment).getTrailBackwardsWalker(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Current trail is: {}", trailWalker); + LOGGER.trace("Violated nogood is: {}", reasonsToString(conflictReason.getReasonLiterals())); + } + int nextAtom = -1; + do { + // Add current conflict reasons; only add those of lower decision levels, since from current one, only the 1UIP literal will be added. + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Atom {} implied by {}, resolving with that nogood", nextAtom, reasonsToString(currentConflictReason)); + } + for (int literal : currentConflictReason) { + // Seen atoms have already been dealt with. + if (!seenAtoms.contains(atomOf(literal))) { + seenAtoms.add(atomOf(literal)); + int literalDecisionLevel = assignment.getWeakDecisionLevel(atomOf(literal)); + if (literalDecisionLevel == currentDecisionLevel) { + numLiteralsInConflictLevel++; + } else { + resolutionLiterals.add(literal); + if (literalDecisionLevel > backjumpLevel) { + backjumpLevel = literalDecisionLevel; + } + } + resolutionAtoms.add(atomOf(literal)); + } + } + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("LiteralsInConflictLevel now: {}", numLiteralsInConflictLevel); + LOGGER.trace("Seen atoms are {}.", seenAtoms); + LOGGER.trace("Intermediate learned literals: {}", reasonsToString(resolutionLiterals)); + } + // Find next literal, i.e. first from top of trail that has been seen but is not yet processed, also skip atoms whose TRUE assignment is on current level but their MBT/weak assignment is lower. + do { + int nextLiteral = trailWalker.getNextLowerLiteral(); + nextAtom = atomOf(nextLiteral); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Next literal on trail is: {}", isPositive(nextLiteral) ? "+" + nextAtom : "-" + nextAtom); + } + } while (assignment.getWeakDecisionLevel(nextAtom) != currentDecisionLevel || !seenAtoms.contains(nextAtom) || processedAtoms.contains(nextAtom)); + Antecedent impliedBy = assignment.getImpliedBy(nextAtom); + if (impliedBy != null) { + currentConflictReason = impliedBy.getReasonLiterals(); + impliedBy.bumpActivity(); + } + processedAtoms.add(nextAtom); + } while (numLiteralsInConflictLevel-- > 1); + // Add the 1UIP literal. + resolutionLiterals.add(atomToLiteral(nextAtom, assignment.getTruth(nextAtom).toBoolean())); + + int[] learnedLiterals = minimizeLearnedLiterals(resolutionLiterals, seenAtoms); + + NoGood learnedNoGood = NoGood.learnt(learnedLiterals); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Learned NoGood is: {}", atomStore.noGoodToString(learnedNoGood)); + } + + int backjumpingDecisionLevel = computeBackjumpingDecisionLevel(learnedNoGood); + if (backjumpingDecisionLevel < 0) { + // Due to out-of-order assigned literals, the learned nogood may be not assigning. + backjumpingDecisionLevel = computeConflictFreeBackjumpingLevel(learnedNoGood); + if (backjumpingDecisionLevel < 0) { + return ConflictAnalysisResult.UNSAT; + } + } + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Backjumping decision level: {}", backjumpingDecisionLevel); + } + return new ConflictAnalysisResult(learnedNoGood, backjumpingDecisionLevel, resolutionAtoms, computeLBD(learnedLiterals)); + } + + private int[] minimizeLearnedLiterals(List resolutionLiterals, Set seenAtoms) { + int[] learnedLiterals = new int[resolutionLiterals.size()]; + int i = 0; + // Do local clause minimization: if an implied literal has all its antecedents seen (i.e., in the clause already), it can be removed. + learnedLiteralsLoop: + for (Integer resolutionLiteral : resolutionLiterals) { + if (assignment.getWeakDecisionLevel(atomOf(resolutionLiteral)) == 0) { + // Skip literals from decision level 0. + continue; + } + Antecedent antecedent = assignment.getImpliedBy(atomOf(resolutionLiteral)); + if (antecedent == null) { + // The resolutionLiteral is a decision, keep it. + learnedLiterals[i++] = resolutionLiteral; + } else { + for (int antecedentReasonLiteral : antecedent.getReasonLiterals()) { + // Only add current resolutionLiteral if at least one of its antecedents has not been seen already. + if (!seenAtoms.contains(atomOf(antecedentReasonLiteral))) { + learnedLiterals[i++] = resolutionLiteral; + continue learnedLiteralsLoop; + } + } + } + } + // Shrink array if we did not copy over all literals from resolutionLiterals. + if (i < resolutionLiterals.size()) { + learnedLiterals = Arrays.copyOf(learnedLiterals, i); + } + return learnedLiterals; + } + + private int computeLBD(int[] literals) { + HashSet occurringDecisionLevels = new HashSet<>(); + for (int literal : literals) { + if (!assignment.isAssigned(atomOf(literal))) { + throw oops("Atom is not assigned: " + atomOf(literal)); + } + occurringDecisionLevels.add(assignment.getWeakDecisionLevel(atomOf(literal))); + } + return occurringDecisionLevels.size(); + } + + /** + * Compute the backjumping decision level, i.e., the decision level on which the learned NoGood is assigning (NoGood is unit and propagates). + * This usually is the second highest decision level occurring in the learned NoGood, but due to assignments of MBT no such decision level may exist. + * @param learnedNoGood + * @return -1 if there is no decisionLevel such that backjumping to it makes the learnedNoGood unit. + */ + private int computeBackjumpingDecisionLevel(NoGood learnedNoGood) { + LOGGER.trace("Computing backjumping decision level for {}.", learnedNoGood); + int highestDecisionLevel = -1; + int secondHighestDecisionLevel = -1; + int numLiteralsOfHighestDecisionLevel = -1; + if (learnedNoGood.isUnary()) { + // Singleton NoGoods induce a backjump to the decision level before the NoGood got violated. + int singleLiteralDecisionLevel = assignment.get(atomOf(learnedNoGood.getLiteral(0))).getDecisionLevel(); + if (assignment instanceof TrailAssignment) { + singleLiteralDecisionLevel = Math.min(singleLiteralDecisionLevel, ((TrailAssignment) assignment).getOutOfOrderDecisionLevel(learnedNoGood.getPositiveLiteral(0))); + } + int singleLiteralBackjumpingLevel = singleLiteralDecisionLevel - 1 >= 0 ? singleLiteralDecisionLevel - 1 : 0; + LOGGER.trace("NoGood has only one literal, backjumping to level: {}", singleLiteralBackjumpingLevel); + return singleLiteralBackjumpingLevel; + } + int[] reasonLiterals = learnedNoGood.asAntecedent().getReasonLiterals(); + for (int integer : reasonLiterals) { + int atomDecisionLevel = assignment.getWeakDecisionLevel(atomOf(integer)); + if (assignment instanceof TrailAssignment) { + atomDecisionLevel = Math.min(atomDecisionLevel, ((TrailAssignment) assignment).getOutOfOrderDecisionLevel(atomOf(integer))); + } + if (atomDecisionLevel == highestDecisionLevel) { + numLiteralsOfHighestDecisionLevel++; + } + if (atomDecisionLevel > highestDecisionLevel) { + secondHighestDecisionLevel = highestDecisionLevel; + highestDecisionLevel = atomDecisionLevel; + numLiteralsOfHighestDecisionLevel = 1; + } else { + if (atomDecisionLevel < highestDecisionLevel && atomDecisionLevel > secondHighestDecisionLevel) { + secondHighestDecisionLevel = atomDecisionLevel; + } + } + } + if (numLiteralsOfHighestDecisionLevel != 1) { + LOGGER.trace("NoGood contains not just one literal in the second-highest decision level. Backjumping decision level is -1."); + return -1; + } + LOGGER.trace("Backjumping decision level is: {}", secondHighestDecisionLevel); + return secondHighestDecisionLevel; + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java new file mode 100644 index 000000000..66f870674 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java @@ -0,0 +1,7 @@ +package at.ac.tuwien.kr.alpha.solver.learning; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public class ResolutionSequence { +} diff --git a/alpha-solver/build.gradle b/alpha-solver/build.gradle new file mode 100644 index 000000000..ab728fd91 --- /dev/null +++ b/alpha-solver/build.gradle @@ -0,0 +1,10 @@ +plugins { + id 'alpha.java-library-conventions' +} + +dependencies { + + api project(":alpha-api") + implementation project(":alpha-core") +} + 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 new file mode 100644 index 000000000..532167e9c --- /dev/null +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -0,0 +1,228 @@ +/** + * 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. + * + * 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.api.impl; + +import java.io.IOException; +import java.nio.charset.CodingErrorAction; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.Util; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.config.InputConfig; +import at.ac.tuwien.kr.alpha.config.SystemConfig; +import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.grounder.GrounderFactory; +import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.grounder.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation; +import at.ac.tuwien.kr.alpha.solver.Solver; +import at.ac.tuwien.kr.alpha.solver.SolverFactory; + +public class AlphaImpl { + + private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); + + private SystemConfig config = new SystemConfig(); // The config is initialized with default values. + + public AlphaImpl(SystemConfig cfg) { + this.config = cfg; + } + + public AlphaImpl() { + } + + public InputProgram readProgram(InputConfig cfg) throws IOException { + InputProgram.Builder prgBuilder = InputProgram.builder(); + InputProgram tmpProg; + if (!cfg.getFiles().isEmpty()) { + tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); + prgBuilder.accumulate(tmpProg); + } + if (!cfg.getAspStrings().isEmpty()) { + tmpProg = readProgramString(StringUtils.join(cfg.getAspStrings(), System.lineSeparator()), cfg.getPredicateMethods()); + prgBuilder.accumulate(tmpProg); + } + return prgBuilder.build(); + } + + 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[] {})); + } + + public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { + ProgramParser parser = new ProgramParser(externals); + InputProgram.Builder prgBuilder = InputProgram.builder(); + InputProgram tmpProg; + for (Path path : paths) { + CharStream stream; + if (!literate) { + stream = CharStreams.fromPath(path); + } else { + stream = CharStreams.fromChannel(Util.streamToChannel(Util.literate(Files.lines(path))), 4096, CodingErrorAction.REPLACE, path.toString()); + } + tmpProg = parser.parse(stream); + prgBuilder.accumulate(tmpProg); + } + return prgBuilder.build(); + } + + public InputProgram readProgramString(String aspString, Map externals) { + ProgramParser parser = new ProgramParser(externals); + return parser.parse(aspString); + } + + public InputProgram readProgramString(String aspString) { + return readProgramString(aspString, null); + } + + public NormalProgram normalizeProgram(InputProgram program) { + return new NormalizeProgramTransformation(config.isUseNormalizationGrid()).apply(program); + } + + public InternalProgram performProgramPreprocessing(InternalProgram program) { + LOGGER.debug("Preprocessing InternalProgram!"); + InternalProgram retVal = program; + if (config.isEvaluateStratifiedPart()) { + AnalyzedProgram analyzed = new AnalyzedProgram(program.getRules(), program.getFacts()); + retVal = new StratifiedEvaluation().apply(analyzed); + } + return retVal; + } + + public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { + LOGGER.debug("Preprocessing AnalyzedProgram!"); + InternalProgram retVal = program; + if (config.isEvaluateStratifiedPart()) { + retVal = new StratifiedEvaluation().apply(program); + } + return retVal; + } + + /** + * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the + * program analysis and normalization aren't of interest. + */ + public Stream solve(InputProgram program) { + return solve(program, InputConfig.DEFAULT_FILTER); + } + + /** + * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where + * details of the program analysis and normalization aren't of interest. + */ + public Stream solve(InputProgram program, java.util.function.Predicate filter) { + NormalProgram normalized = normalizeProgram(program); + return solve(normalized, filter); + } + + /** + * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the + * program analysis aren't of interest. + */ + public Stream solve(NormalProgram program, java.util.function.Predicate filter) { + InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); + return solve(preprocessed, filter); + } + + /** + * Overloaded version of solve({@link InternalProgram}, {@link Predicate}) that uses a default filter (accept + * everything). + * + * @param program the program to solve + * @return a stream of answer sets + */ + public Stream solve(InternalProgram program) { + return solve(program, InputConfig.DEFAULT_FILTER); + } + + /** + * 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 + * @return a Stream of answer sets representing stable models of the given program + */ + public Stream solve(InternalProgram program, java.util.function.Predicate filter) { + Stream retVal = prepareSolverFor(program, filter).stream(); + return config.isSortAnswerSets() ? retVal.sorted() : retVal; + } + + /** + * 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. + * @return a solver (and accompanying grounder) instance pre-loaded with the given program. + */ + public Solver prepareSolverFor(InternalProgram 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 SystemConfig getConfig() { + return config; + } + + public void setConfig(SystemConfig config) { + this.config = config; + } + +} diff --git a/settings.gradle b/settings.gradle index aafbb5363..8058001c5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ rootProject.name = "alpha" -include("api", "cli", "core") +include("alpha-api", "alpha-cli-app", "alpha-core", "alpha-solver") From 60c1bcf78e135f7ad569e5122caf38035161bf89 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 19 Dec 2020 19:49:21 +0100 Subject: [PATCH 010/111] adapt package names in alpha-core --- alpha-cli-app/build.gradle | 3 +- .../kr/alpha/AnswerSetToXlsxWriter.java | 6 +- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 51 ++++++++-------- .../kr/alpha/app}/ComponentGraphWriter.java | 10 ++-- .../kr/alpha/app}/DependencyGraphWriter.java | 10 ++-- alpha-core/build.gradle | 2 + .../kr/alpha/common/AnswerSetFormatter.java | 6 -- .../kr/alpha/common/terms/ArithmeticTerm.java | 5 +- .../alpha/common/terms/CoreConstantTerm.java | 4 +- .../kr/alpha/common/terms/CoreTerm.java | 4 +- .../kr/alpha/common/terms/FunctionTerm.java | 8 +-- .../kr/alpha/common/terms/IntervalTerm.java | 8 +-- .../kr/alpha/common/terms/VariableTerm.java | 6 +- .../{common => core}/atoms/AggregateAtom.java | 12 ++-- .../atoms/AggregateLiteral.java | 6 +- .../{common => core}/atoms/BasicAtom.java | 8 +-- .../{common => core}/atoms/BasicLiteral.java | 5 +- .../{grounder => core}/atoms/ChoiceAtom.java | 10 ++-- .../atoms/ComparisonAtom.java | 15 +++-- .../atoms/ComparisonLiteral.java | 7 ++- .../{common => core}/atoms/CoreAtom.java | 8 +-- .../{common => core}/atoms/CoreLiteral.java | 7 ++- .../atoms/EnumerationAtom.java | 9 ++- .../atoms/EnumerationLiteral.java | 5 +- .../{common => core}/atoms/ExternalAtom.java | 10 ++-- .../atoms/ExternalLiteral.java | 5 +- .../atoms/FixedInterpretationLiteral.java | 6 +- .../atoms/IntervalAtom.java | 12 ++-- .../atoms/IntervalLiteral.java | 8 +-- .../{grounder => core}/atoms/RuleAtom.java | 10 ++-- .../atoms/VariableNormalizableAtom.java | 2 +- .../{ => core}/common/AnswerSetBuilder.java | 26 ++++---- .../alpha/core/common/AnswerSetFormatter.java | 6 ++ .../alpha/{ => core}/common/Assignment.java | 10 ++-- .../kr/alpha/{ => core}/common/AtomStore.java | 11 ++-- .../{ => core}/common/AtomStoreImpl.java | 13 ++-- .../{ => core}/common/BasicAnswerSet.java | 32 +++++----- .../{ => core}/common/ComparisonOperator.java | 4 +- .../kr/alpha/core/common/CoreAnswerSet.java | 13 ++++ .../{ => core}/common/CorePredicate.java | 2 +- .../alpha/{ => core}/common/IntIterator.java | 2 +- .../kr/alpha/{ => core}/common/Interner.java | 2 +- .../kr/alpha/{ => core}/common/Literals.java | 2 +- .../kr/alpha/{ => core}/common/NoGood.java | 12 ++-- .../{ => core}/common/NoGoodInterface.java | 4 +- .../common/SimpleAnswerSetFormatter.java | 8 +-- .../kr/alpha/{ => core}/common/Truth.java | 2 +- .../BinaryPredicateInterpretation.java | 2 +- .../BindingMethodPredicateInterpretation.java | 3 +- .../IntPredicateInterpretation.java | 2 +- .../LongPredicateInterpretation.java | 2 +- .../MethodPredicateInterpretation.java | 2 +- .../NonBindingPredicateInterpretation.java | 3 +- .../PredicateInterpretationImpl.java | 3 +- .../SuppliedPredicateInterpretation.java | 3 +- .../UnaryPredicateInterpretation.java | 2 +- .../depgraph/ComponentGraph.java | 7 ++- .../depgraph/DependencyGraph.java | 12 ++-- .../depgraph/DepthFirstSearchAlgorithm.java | 2 +- .../alpha/{common => core}/depgraph/Edge.java | 2 +- .../alpha/{common => core}/depgraph/Node.java | 4 +- .../depgraph/StratificationAlgorithm.java | 5 +- .../StronglyConnectedComponentsAlgorithm.java | 2 +- .../externals}/AspStandardLibrary.java | 2 +- .../{api => core}/externals/Externals.java | 16 +++-- .../{ => core}/grounder/AbstractGrounder.java | 4 +- .../{ => core}/grounder/BridgedGrounder.java | 12 ++-- .../{ => core}/grounder/ChoiceRecorder.java | 15 ++--- .../grounder/FactIntervalEvaluator.java | 4 +- .../grounder/FilteringGrounder.java | 4 +- .../alpha/{ => core}/grounder/Grounder.java | 19 +++--- .../{ => core}/grounder/GrounderFactory.java | 10 ++-- .../grounder/IndexedInstanceStorage.java | 6 +- .../alpha/{ => core}/grounder/Instance.java | 8 +-- .../{ => core}/grounder/IntIdGenerator.java | 4 +- .../{ => core}/grounder/NaiveGrounder.java | 55 +++++++++-------- .../{ => core}/grounder/NoGoodGenerator.java | 29 +++++---- .../{ => core}/grounder/NogoodRegistry.java | 6 +- .../grounder/ProgramAnalyzingGrounder.java | 10 ++-- .../grounder/RuleGroundingOrder.java | 6 +- .../grounder/RuleGroundingOrders.java | 8 +-- .../{ => core}/grounder/Substitution.java | 14 ++--- .../{ => core}/grounder/Unification.java | 13 ++-- .../kr/alpha/{ => core}/grounder/Unifier.java | 4 +- .../{ => core}/grounder/WorkingMemory.java | 8 +-- .../alpha/core/grounder/bridges/Bridge.java | 12 ++++ .../AbstractLiteralInstantiationStrategy.java | 10 +++- .../instantiation/AssignmentStatus.java | 6 +- .../grounder/instantiation/BindingResult.java | 6 +- ...ultLazyGroundingInstantiationStrategy.java | 27 ++++----- .../LiteralInstantiationResult.java | 16 ++--- .../LiteralInstantiationStrategy.java | 7 +-- .../instantiation/LiteralInstantiator.java | 13 ++-- ...rkingMemoryBasedInstantiationStrategy.java | 10 ++-- .../structure/AnalyzeUnjustified.java | 29 +++++---- .../{ => core}/grounder/structure/LitSet.java | 12 ++-- .../parser}/CustomErrorListener.java | 2 +- .../parser/InlineDirectives.java | 2 +- .../parser/ParseTreeVisitor.java | 39 +++++++----- .../parser/ProgramParser.java | 5 +- .../parser/ProgramPartParser.java | 5 +- .../programs}/AbstractProgram.java | 12 ++-- .../programs}/AnalyzedProgram.java | 22 +++---- .../programs}/InputProgram.java | 15 +++-- .../programs}/InternalProgram.java | 29 +++++---- .../programs}/NormalProgram.java | 13 ++-- .../program => core/programs}/Programs.java | 4 +- .../CardinalityNormalization.java | 25 ++++---- .../transformation/ChoiceHeadToNormal.java | 17 +++--- .../transformation/EnumerationRewriting.java | 22 +++---- .../IntervalTermToIntervalAtom.java | 14 ++--- .../NormalizeProgramTransformation.java | 8 +-- .../transformation/PredicateInternalizer.java | 20 +++---- .../transformation/ProgramTransformation.java | 4 +- .../transformation/StratifiedEvaluation.java | 44 +++++++------- .../transformation/SumNormalization.java | 24 ++++---- .../VariableEqualityRemoval.java | 16 ++--- .../rule => core/rules}/AbstractRule.java | 8 +-- .../rule => core/rules}/BasicRule.java | 6 +- .../rule => core/rules}/InternalRule.java | 18 +++--- .../rule => core/rules}/NormalRule.java | 10 ++-- .../head => core/rules/heads}/ChoiceHead.java | 23 ++++--- .../rules/heads}/DisjunctiveHead.java | 12 ++-- .../rule/head => core/rules/heads}/Head.java | 2 +- .../head => core/rules/heads}/NormalHead.java | 4 +- .../{ => core}/solver/AbstractSolver.java | 18 +++--- .../alpha/{ => core}/solver/Antecedent.java | 4 +- .../alpha/{ => core}/solver/AtomCounter.java | 9 ++- .../kr/alpha/{ => core}/solver/Atoms.java | 2 +- .../BinaryNoGoodPropagationEstimation.java | 4 +- .../kr/alpha/{ => core}/solver/Checkable.java | 2 +- .../kr/alpha/{ => core}/solver/Choice.java | 6 +- .../solver/ChoiceInfluenceManager.java | 10 ++-- .../{ => core}/solver/ChoiceManager.java | 11 ++-- .../{ => core}/solver/ConflictCause.java | 2 +- .../{ => core}/solver/DefaultSolver.java | 60 +++++++++---------- .../solver/LearnedNoGoodDeletion.java | 9 +-- .../{ => core}/solver/NaiveNoGoodStore.java | 9 +-- .../alpha/{ => core}/solver/NaiveSolver.java | 21 +++---- .../{ => core}/solver/NoGoodCounter.java | 10 ++-- .../alpha/{ => core}/solver/NoGoodStore.java | 4 +- .../solver/NoGoodStoreAlphaRoaming.java | 34 ++++++----- .../{ => core}/solver/PerformanceLog.java | 2 +- .../{ => core}/solver/ShallowAntecedent.java | 4 +- .../kr/alpha/{ => core}/solver/Solver.java | 14 ++--- .../{ => core}/solver/SolverFactory.java | 10 ++-- .../solver/SolverMaintainingStatistics.java | 2 +- .../alpha/{ => core}/solver/ThriceTruth.java | 4 +- .../{ => core}/solver/TrailAssignment.java | 21 +++---- .../{ => core}/solver/WatchedNoGood.java | 12 ++-- .../{ => core}/solver/WritableAssignment.java | 10 ++-- .../ActivityBasedBranchingHeuristic.java | 2 +- .../heuristics/AlphaActiveRuleHeuristic.java | 12 ++-- .../AlphaHeadMustBeTrueHeuristic.java | 12 ++-- .../heuristics/AlphaRandomSignHeuristic.java | 14 ++--- .../{ => core}/solver/heuristics/BerkMin.java | 23 +++---- .../solver/heuristics/BerkMinLiteral.java | 12 ++-- .../solver/heuristics/BranchingHeuristic.java | 10 ++-- .../heuristics/BranchingHeuristicFactory.java | 10 ++-- .../ChainedBranchingHeuristics.java | 10 ++-- .../heuristics/DependencyDrivenHeuristic.java | 29 ++++----- .../DependencyDrivenPyroHeuristic.java | 8 +-- .../heuristics/DependencyDrivenVSIDS.java | 6 +- .../GeneralizedDependencyDrivenHeuristic.java | 14 ++--- ...eralizedDependencyDrivenPyroHeuristic.java | 8 +-- .../solver/heuristics/HeapOfActiveAtoms.java | 17 +++--- .../heuristics/HeapOfActiveChoicePoints.java | 11 ++-- .../heuristics/HeuristicsConfiguration.java | 3 +- .../HeuristicsConfigurationBuilder.java | 3 +- .../{ => core}/solver/heuristics/MOMs.java | 4 +- .../solver/heuristics/NaiveHeuristic.java | 14 ++--- .../solver/heuristics/ReplayHeuristic.java | 10 ++-- .../{ => core}/solver/heuristics/VSIDS.java | 32 +++++----- .../activity/AvgBodyActivityProvider.java | 2 +- .../activity/BodyActivityProvider.java | 6 +- .../activity/BodyActivityProviderFactory.java | 2 +- .../activity/DefaultBodyActivityProvider.java | 2 +- .../activity/MaxBodyActivityProvider.java | 2 +- .../activity/MinBodyActivityProvider.java | 2 +- .../activity/SumBodyActivityProvider.java | 2 +- .../learning/GroundConflictNoGoodLearner.java | 19 +++--- .../solver/learning/ResolutionSequence.java | 2 +- .../tuwien/kr/alpha/{ => core/util}/Util.java | 2 +- .../kr/alpha/grounder/bridges/Bridge.java | 12 ---- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 44 +++++++------- 185 files changed, 1015 insertions(+), 943 deletions(-) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio => alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app}/ComponentGraphWriter.java (94%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio => alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app}/DependencyGraphWriter.java (94%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/AggregateAtom.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/AggregateLiteral.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/BasicAtom.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/BasicLiteral.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/atoms/ChoiceAtom.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/ComparisonAtom.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/ComparisonLiteral.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/CoreAtom.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/CoreLiteral.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/atoms/EnumerationAtom.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/atoms/EnumerationLiteral.java (90%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/ExternalAtom.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/ExternalLiteral.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/FixedInterpretationLiteral.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/atoms/IntervalAtom.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/atoms/IntervalLiteral.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/atoms/RuleAtom.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/atoms/VariableNormalizableAtom.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/AnswerSetBuilder.java (84%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/Assignment.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/AtomStore.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/AtomStoreImpl.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/BasicAnswerSet.java (71%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/ComparisonOperator.java (86%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/CorePredicate.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/IntIterator.java (88%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/Interner.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/Literals.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/NoGood.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/NoGoodInterface.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/SimpleAnswerSetFormatter.java (83%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/Truth.java (81%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/BinaryPredicateInterpretation.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/BindingMethodPredicateInterpretation.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/IntPredicateInterpretation.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/LongPredicateInterpretation.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/MethodPredicateInterpretation.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/NonBindingPredicateInterpretation.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/PredicateInterpretationImpl.java (68%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/SuppliedPredicateInterpretation.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/fixedinterpretations/UnaryPredicateInterpretation.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/depgraph/ComponentGraph.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/depgraph/DependencyGraph.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/depgraph/DepthFirstSearchAlgorithm.java (99%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/depgraph/Edge.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/depgraph/Node.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/depgraph/StratificationAlgorithm.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common => core}/depgraph/StronglyConnectedComponentsAlgorithm.java (99%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{api/externals/stdlib => core/externals}/AspStandardLibrary.java (99%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{api => core}/externals/Externals.java (86%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/AbstractGrounder.java (77%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/BridgedGrounder.java (69%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/ChoiceRecorder.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/FactIntervalEvaluator.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/FilteringGrounder.java (77%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/Grounder.java (88%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/GrounderFactory.java (90%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/IndexedInstanceStorage.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/Instance.java (84%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/IntIdGenerator.java (86%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/NaiveGrounder.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/NoGoodGenerator.java (90%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/NogoodRegistry.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/ProgramAnalyzingGrounder.java (78%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/RuleGroundingOrder.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/RuleGroundingOrders.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/Substitution.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/Unification.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/Unifier.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/WorkingMemory.java (94%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/bridges/Bridge.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/AbstractLiteralInstantiationStrategy.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/AssignmentStatus.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/BindingResult.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/LiteralInstantiationResult.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/LiteralInstantiationStrategy.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/LiteralInstantiator.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/structure/AnalyzeUnjustified.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/grounder/structure/LitSet.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core/parser}/CustomErrorListener.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/parser/InlineDirectives.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/parser/ParseTreeVisitor.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/parser/ProgramParser.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core}/parser/ProgramPartParser.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/program => core/programs}/AbstractProgram.java (80%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/program => core/programs}/AnalyzedProgram.java (63%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/program => core/programs}/InputProgram.java (88%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/program => core/programs}/InternalProgram.java (76%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/program => core/programs}/NormalProgram.java (58%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/program => core/programs}/Programs.java (84%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/CardinalityNormalization.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/ChoiceHeadToNormal.java (90%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/EnumerationRewriting.java (82%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/IntervalTermToIntervalAtom.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/NormalizeProgramTransformation.java (85%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/PredicateInternalizer.java (76%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/ProgramTransformation.java (63%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/StratifiedEvaluation.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/SumNormalization.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{grounder => core/programs}/transformation/VariableEqualityRemoval.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule => core/rules}/AbstractRule.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule => core/rules}/BasicRule.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule => core/rules}/InternalRule.java (90%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule => core/rules}/NormalRule.java (83%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule/head => core/rules/heads}/ChoiceHead.java (82%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule/head => core/rules/heads}/DisjunctiveHead.java (79%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule/head => core/rules/heads}/Head.java (89%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{common/rule/head => core/rules/heads}/NormalHead.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AbstractSolver.java (50%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/Antecedent.java (83%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AtomCounter.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/Atoms.java (69%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/BinaryNoGoodPropagationEstimation.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/Checkable.java (88%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/Choice.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ChoiceInfluenceManager.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ChoiceManager.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ConflictCause.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/DefaultSolver.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/LearnedNoGoodDeletion.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/NaiveNoGoodStore.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/NaiveSolver.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/NoGoodCounter.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/NoGoodStore.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/NoGoodStoreAlphaRoaming.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/PerformanceLog.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ShallowAntecedent.java (88%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/Solver.java (59%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/SolverFactory.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/SolverMaintainingStatistics.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ThriceTruth.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/TrailAssignment.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/WatchedNoGood.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/WritableAssignment.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/ActivityBasedBranchingHeuristic.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/AlphaActiveRuleHeuristic.java (87%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java (87%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/AlphaRandomSignHeuristic.java (85%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/BerkMin.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/BerkMinLiteral.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/BranchingHeuristic.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/BranchingHeuristicFactory.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/ChainedBranchingHeuristics.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/DependencyDrivenHeuristic.java (93%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/DependencyDrivenPyroHeuristic.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/DependencyDrivenVSIDS.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java (90%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java (91%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/HeapOfActiveAtoms.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/HeapOfActiveChoicePoints.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/HeuristicsConfiguration.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/HeuristicsConfigurationBuilder.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/MOMs.java (95%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/NaiveHeuristic.java (84%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/ReplayHeuristic.java (90%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/VSIDS.java (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/activity/AvgBodyActivityProvider.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/activity/BodyActivityProvider.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/activity/BodyActivityProviderFactory.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/activity/DefaultBodyActivityProvider.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/activity/MaxBodyActivityProvider.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/activity/MinBodyActivityProvider.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/activity/SumBodyActivityProvider.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/learning/GroundConflictNoGoodLearner.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/solver/learning/ResolutionSequence.java (61%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core/util}/Util.java (99%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java diff --git a/alpha-cli-app/build.gradle b/alpha-cli-app/build.gradle index 907a683a9..026138ba4 100644 --- a/alpha-cli-app/build.gradle +++ b/alpha-cli-app/build.gradle @@ -3,8 +3,7 @@ plugins { } dependencies { - implementation project(':alpha-core') - implementation project(':alpha-api') + implementation project(':alpha-solver') implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' } diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java index fc61c4b9b..6041f05af 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java @@ -16,9 +16,9 @@ import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToObjectMapper; import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToWorkbookMapper; -import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; -public class AnswerSetToXlsxWriter implements BiConsumer { +public class AnswerSetToXlsxWriter implements BiConsumer { private String targetBasePath; private AnswerSetToObjectMapper answerSetMapper; @@ -29,7 +29,7 @@ public AnswerSetToXlsxWriter(String targetBasePath) { } @Override - public void accept(Integer num, AnswerSet as) { + public void accept(Integer num, CoreAnswerSet as) { try { Path outputPath = Paths.get(this.targetBasePath + "." + num + ".xlsx"); OutputStream os = Files.newOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); 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 da7d22a12..6b640134a 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 @@ -27,27 +27,6 @@ */ package at.ac.tuwien.kr.alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetFormatter; -import at.ac.tuwien.kr.alpha.common.SimpleAnswerSetFormatter; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.graphio.ComponentGraphWriter; -import at.ac.tuwien.kr.alpha.common.graphio.DependencyGraphWriter; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.config.AlphaConfig; -import at.ac.tuwien.kr.alpha.config.CommandLineParser; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.solver.Solver; -import at.ac.tuwien.kr.alpha.solver.SolverMaintainingStatistics; -import org.antlr.v4.runtime.RecognitionException; -import org.apache.commons.cli.ParseException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -59,6 +38,28 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.antlr.v4.runtime.RecognitionException; +import org.apache.commons.cli.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.app.ComponentGraphWriter; +import at.ac.tuwien.kr.alpha.app.DependencyGraphWriter; +import at.ac.tuwien.kr.alpha.config.AlphaConfig; +import at.ac.tuwien.kr.alpha.config.CommandLineParser; +import at.ac.tuwien.kr.alpha.config.InputConfig; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetFormatter; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.SimpleAnswerSetFormatter; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.core.solver.Solver; +import at.ac.tuwien.kr.alpha.core.solver.SolverMaintainingStatistics; + /** * Main entry point for Alpha. */ @@ -172,7 +173,7 @@ private static void writeInternalProgram(InternalProgram prg, String path) { private static void computeAndConsumeAnswerSets(AlphaImpl alpha, InputConfig inputCfg, InternalProgram program) { Solver solver = alpha.prepareSolverFor(program, inputCfg.getFilter()); - Stream stream = solver.stream(); + Stream stream = solver.stream(); if (alpha.getConfig().isSortAnswerSets()) { stream = stream.sorted(); } @@ -184,13 +185,13 @@ private static void computeAndConsumeAnswerSets(AlphaImpl alpha, InputConfig inp if (!alpha.getConfig().isQuiet()) { AtomicInteger counter = new AtomicInteger(0); - final BiConsumer answerSetHandler; + final BiConsumer answerSetHandler; final AnswerSetFormatter fmt = new SimpleAnswerSetFormatter(alpha.getConfig().getAtomSeparator()); - BiConsumer stdoutPrinter = (n, as) -> { + BiConsumer stdoutPrinter = (n, as) -> { System.out.println("Answer set " + Integer.toString(n) + ":" + System.lineSeparator() + fmt.format(as)); }; if (inputCfg.isWriteAnswerSetsAsXlsx()) { - BiConsumer xlsxWriter = new AnswerSetToXlsxWriter(inputCfg.getAnswerSetFileOutputPath()); + BiConsumer xlsxWriter = new AnswerSetToXlsxWriter(inputCfg.getAnswerSetFileOutputPath()); answerSetHandler = stdoutPrinter.andThen(xlsxWriter); } else { answerSetHandler = stdoutPrinter; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriter.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java rename to alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriter.java index de315f778..41962e017 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriter.java @@ -23,17 +23,17 @@ * 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.common.graphio; - -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; -import at.ac.tuwien.kr.alpha.common.depgraph.Node; +package at.ac.tuwien.kr.alpha.app; import java.io.OutputStream; import java.io.PrintStream; import java.util.List; import java.util.Map.Entry; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.Node; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph.SCComponent; + public class ComponentGraphWriter { private static final String GRAPH_HEADING = "digraph componentGraph"; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriter.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java rename to alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriter.java index 7d838f8ca..033cf4968 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriter.java @@ -23,11 +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.common.graphio; - -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.Edge; -import at.ac.tuwien.kr.alpha.common.depgraph.Node; +package at.ac.tuwien.kr.alpha.app; import java.io.OutputStream; import java.io.PrintStream; @@ -37,6 +33,10 @@ import java.util.Set; import java.util.function.BiFunction; +import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.Edge; +import at.ac.tuwien.kr.alpha.core.depgraph.Node; + public class DependencyGraphWriter { private static final String DEFAULT_GRAPH_HEADING = "digraph dependencyGraph"; diff --git a/alpha-core/build.gradle b/alpha-core/build.gradle index 292152bba..9cdcf3d0b 100644 --- a/alpha-core/build.gradle +++ b/alpha-core/build.gradle @@ -20,6 +20,8 @@ configurations { dependencies { + api project(":alpha-api") + // We need to give the ANTLR Plugin a hint. antlr group: 'org.antlr', name: 'antlr4', version: "${antlrVersion}" diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java deleted file mode 100644 index 8467cc19b..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java +++ /dev/null @@ -1,6 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -@FunctionalInterface -public interface AnswerSetFormatter { - T format(AnswerSet answerSet); -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java index 3c6d525c0..8efd36688 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java @@ -27,8 +27,9 @@ */ package at.ac.tuwien.kr.alpha.common.terms; -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + import com.google.common.math.IntMath; import java.util.ArrayList; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java index dd64324dc..7e2038416 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.common.terms; -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.Collections; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java index 7f740aa37..3c55c2ef1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.List; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; //@formatter:off /** @@ -45,7 +45,7 @@ public abstract class CoreTerm implements Comparable { private static int priority(CoreTerm term) { final Class clazz = term.getClass(); - if (clazz.equals(ConstantTerm.class)) { + if (clazz.equals(CoreConstantTerm.class)) { return 1; } else if (clazz.equals(FunctionTerm.class)) { return 2; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java index e2529258a..7a8f9224b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java @@ -1,11 +1,11 @@ package at.ac.tuwien.kr.alpha.common.terms; -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; -import java.util.*; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; -import static at.ac.tuwien.kr.alpha.Util.join; +import java.util.*; /** * Copyright (c) 2016-2017, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java index 3a801e7a8..22d922993 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java @@ -1,13 +1,13 @@ package at.ac.tuwien.kr.alpha.common.terms; -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.LinkedList; import java.util.List; -import static at.ac.tuwien.kr.alpha.Util.oops; - /** * An IntervalTerm represents the shorthand notation for a set of rules where all elements in this interval occur once, e.g., fact(2..5). * An IntervalTerm is a meta-term and the grounder must replace it with its corresponding set of facts or rules. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java index 0fd29c5e8..d81c75bfc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java @@ -1,8 +1,8 @@ package at.ac.tuwien.kr.alpha.common.terms; -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.Collections; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index f37e0acc8..fc789bb54 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -25,20 +25,20 @@ * 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.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.Util.join; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; public class AggregateAtom extends CoreAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index a2d6123cc..6b33fac7d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -1,12 +1,12 @@ -package at.ac.tuwien.kr.alpha.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; import java.util.HashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Copyright (c) 2018, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java index 746abc051..48b035e07 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java @@ -25,18 +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. */ -package at.ac.tuwien.kr.alpha.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.Util.join; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Represents ordinary ASP atoms. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java index 173e9befc..b4bfd6247 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java @@ -25,11 +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.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.Collections; import java.util.HashSet; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java index 3ce4e494e..8ba553004 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java @@ -25,19 +25,17 @@ * 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.grounder.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.Util.join; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; public class ChoiceAtom extends CoreAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java index c94b8e231..99b81886d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java @@ -25,18 +25,17 @@ * 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.common.atoms; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +package at.ac.tuwien.kr.alpha.core.atoms; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + /** * Represents a builtin comparison atom according to the standard. */ @@ -61,7 +60,7 @@ public CorePredicate getPredicate() { } @Override - public List getTerms() { + public List getTerms() { return terms; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index 836cd21be..927daa3ad 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.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.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; import static at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm.evaluateGroundTerm; @@ -35,12 +35,13 @@ import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Contains a potentially negated {@link ComparisonAtom}. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index d8fe2ee7e..82d40f359 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -25,16 +25,16 @@ * 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.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.Unifier; /** * An Atom is the common superclass of all representations of ASP atoms used by Alpha. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java index b87bafc64..092da5550 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java @@ -25,12 +25,13 @@ * 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.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + import org.apache.commons.collections4.SetUtils; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 80d310fad..8c38af9c9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -1,16 +1,15 @@ -package at.ac.tuwien.kr.alpha.grounder.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.HashMap; import java.util.List; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Represents a ground-instance enumeration atom of form: diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java index 99c1735fd..1c81a8408 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java @@ -1,13 +1,12 @@ -package at.ac.tuwien.kr.alpha.grounder.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; import java.util.Collections; import java.util.HashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Copyright (c) 2018, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index 50a62cf63..005fbcc9a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -25,20 +25,20 @@ * 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.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; + +import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import static at.ac.tuwien.kr.alpha.Util.join; - public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { private final List input; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java index 29dfffed6..806a6953c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java @@ -25,10 +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.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.terms.*; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.*; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java index fc318944e..a98798777 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java @@ -25,12 +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.common.atoms; - -import at.ac.tuwien.kr.alpha.grounder.Substitution; +package at.ac.tuwien.kr.alpha.core.atoms; import java.util.List; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + /** * Represents a literal whose ground truth value(s) are independent of the * current assignment. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java index 5d1b96580..d8d614a61 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java @@ -25,20 +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. */ -package at.ac.tuwien.kr.alpha.grounder.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.Util.join; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Helper for treating IntervalTerms in rules. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index 5b6505c5f..7f74bff26 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.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.grounder.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; import java.util.ArrayList; import java.util.Collections; @@ -34,13 +34,11 @@ import com.google.common.collect.Sets; -import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * @see IntervalAtom @@ -77,7 +75,7 @@ private List getIntervalSubstitutions(Substitution partialSubstitu return substitutions; } else { // The intervalRepresentingVariable is bound already, check if it is in the interval. - if (!(intervalRepresentingVariable instanceof ConstantTerm) + if (!(intervalRepresentingVariable instanceof CoreConstantTerm) || !(((CoreConstantTerm) intervalRepresentingVariable).getObject() instanceof Integer)) { // Term is not bound to an integer constant, not in the interval. return Collections.emptyList(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java index cbe2f5a66..964aa0a7b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java @@ -25,20 +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. */ -package at.ac.tuwien.kr.alpha.grounder.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; import static at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm.getInstance; import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Atoms corresponding to rule bodies use this predicate, first term is rule number, diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java index 7c63cf0b9..8e4ae2dcb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.atoms; +package at.ac.tuwien.kr.alpha.core.atoms; /** * Interface for atom whose variables can be normalized, i.e., enumerated from diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java similarity index 84% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java index e7c091951..f3f24f3fc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java @@ -1,25 +1,27 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import static java.util.Collections.singletonList; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.Stream; -import static java.util.Collections.singletonList; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; public class AnswerSetBuilder { private boolean firstInstance = true; private String predicateSymbol; private CorePredicate predicate; private SortedSet predicates = new TreeSet<>(); - private SortedSet instances = new TreeSet<>(); - private Map> predicateInstances = new HashMap<>(); + private SortedSet instances = new TreeSet<>(); + private Map> predicateInstances = new HashMap<>(); public AnswerSetBuilder() { } @@ -41,7 +43,7 @@ private void flush() { predicates.add(predicate); predicateInstances.put(predicate, new TreeSet<>(singletonList(new BasicAtom(predicate)))); } else { - SortedSet atoms = predicateInstances.get(predicate); + SortedSet atoms = predicateInstances.get(predicate); if (atoms == null) { predicateInstances.put(predicate, new TreeSet<>(instances)); } else { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java new file mode 100644 index 000000000..6f58ff695 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java @@ -0,0 +1,6 @@ +package at.ac.tuwien.kr.alpha.core.common; + +@FunctionalInterface +public interface AnswerSetFormatter { + T format(CoreAnswerSet answerSet); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Assignment.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Assignment.java index d8b4fb7cf..59d61370d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Assignment.java @@ -25,15 +25,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.common; +package at.ac.tuwien.kr.alpha.core.common; -import at.ac.tuwien.kr.alpha.solver.Antecedent; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; import java.util.Set; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; +import at.ac.tuwien.kr.alpha.core.solver.Antecedent; +import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; public interface Assignment { Entry get(int atom); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStore.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStore.java index 2581cb11b..daaefc7ad 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStore.java @@ -25,16 +25,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.common; +package at.ac.tuwien.kr.alpha.core.common; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.solver.AtomCounter; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; import java.util.Iterator; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; /** * Translates atoms between integer (solver) and object (grounder) representation. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java index 67994c90a..780cad94a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java @@ -25,20 +25,19 @@ * 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.common; +package at.ac.tuwien.kr.alpha.core.common; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.solver.AtomCounter; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; /** * This class stores ground atoms and provides the translation from an (integer) atomId to a (structured) predicate instance. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java similarity index 71% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java index 1bd486460..0899e6a5d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java @@ -1,38 +1,38 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySortedSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.SortedSet; -import static java.util.Collections.emptyMap; -import static java.util.Collections.emptySortedSet; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.util.Util; /** * Copyright (c) 2016, the Alpha Team. */ // TODO bring this into public non-core API by using something like an "answer-set-view" -public class BasicAnswerSet implements AnswerSet { +public class BasicAnswerSet implements CoreAnswerSet { public static final BasicAnswerSet EMPTY = new BasicAnswerSet(emptySortedSet(), emptyMap()); private final SortedSet predicates; - private final Map> predicateInstances; + private final Map> predicateInstances; - public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { + public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { this.predicates = predicates; this.predicateInstances = predicateInstances; } @Override - public SortedSet getPredicates() { + public SortedSet getPredicates() { return predicates; } @Override - public SortedSet getPredicateInstances(Predicate predicate) { + public SortedSet getPredicateInstances(CorePredicate predicate) { return predicateInstances.get(predicate); } @@ -49,15 +49,15 @@ public String toString() { final StringBuilder sb = new StringBuilder("{ "); for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { - Predicate predicate = iterator.next(); - Set instances = getPredicateInstances(predicate); + CorePredicate predicate = iterator.next(); + Set instances = getPredicateInstances(predicate); if (instances == null || instances.isEmpty()) { sb.append(predicate.getName()); continue; } - for (Iterator instanceIterator = instances.iterator(); instanceIterator.hasNext();) { + for (Iterator instanceIterator = instances.iterator(); instanceIterator.hasNext();) { sb.append(instanceIterator.next()); if (instanceIterator.hasNext()) { sb.append(", "); @@ -96,15 +96,15 @@ public int hashCode() { } @Override - public int compareTo(AnswerSet other) { - final SortedSet predicates = this.getPredicates(); + public int compareTo(CoreAnswerSet other) { + final SortedSet predicates = this.getPredicates(); int result = Util.compareSortedSets(predicates, other.getPredicates()); if (result != 0) { return result; } - for (Predicate predicate : predicates) { + for (CorePredicate predicate : predicates) { result = Util.compareSortedSets(this.getPredicateInstances(predicate), other.getPredicateInstances(predicate)); if (result != 0) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java similarity index 86% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java index b9a61571a..5ae12a8c0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; public enum ComparisonOperator { EQ("="), diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java new file mode 100644 index 000000000..ca7e29c29 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java @@ -0,0 +1,13 @@ +package at.ac.tuwien.kr.alpha.core.common; + +import java.util.SortedSet; + +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; + +public interface CoreAnswerSet extends Comparable { + SortedSet getPredicates(); + + SortedSet getPredicateInstances(CorePredicate predicate); + + boolean isEmpty(); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java index 670241c1c..9453c8095 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; /** * A predicate as used by the Alpha solver internally. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/IntIterator.java similarity index 88% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/IntIterator.java index 0e7c0790e..0b0eba55c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/IntIterator.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; /** * An iterator returning raw int integers instead of Integer objects (for efficiency). diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Interner.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Interner.java index debfa2423..117191d79 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Interner.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; import java.lang.ref.WeakReference; import java.util.WeakHashMap; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Literals.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Literals.java index 8c703a54b..aa13adce0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Literals.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.common; +package at.ac.tuwien.kr.alpha.core.common; /** * Provides methods to convert atoms to literals and vice versa, diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java index 84e70cd0e..367df5dc0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java @@ -25,18 +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. */ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.solver.Antecedent; +package at.ac.tuwien.kr.alpha.core.common; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.IntStream; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.*; +import at.ac.tuwien.kr.alpha.core.solver.Antecedent; + +import static at.ac.tuwien.kr.alpha.core.common.Literals.*; +import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.*; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; public class NoGood implements NoGoodInterface, Comparable { public static final int HEAD = 0; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGoodInterface.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGoodInterface.java index 95157630e..1832098c7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGoodInterface.java @@ -25,9 +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.common; +package at.ac.tuwien.kr.alpha.core.common; -import at.ac.tuwien.kr.alpha.solver.Antecedent; +import at.ac.tuwien.kr.alpha.core.solver.Antecedent; public interface NoGoodInterface extends Iterable { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java similarity index 83% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java index f705ca4be..de9271401 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java @@ -1,11 +1,11 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; import java.util.ArrayList; import java.util.List; import java.util.SortedSet; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; public class SimpleAnswerSetFormatter implements AnswerSetFormatter { @@ -16,10 +16,10 @@ public SimpleAnswerSetFormatter(String atomSeparator) { } @Override - public String format(AnswerSet answerSet) { + public String format(CoreAnswerSet answerSet) { List predicateInstanceStrings = new ArrayList<>(); for (CorePredicate p : answerSet.getPredicates()) { - SortedSet instances; + SortedSet instances; if ((instances = answerSet.getPredicateInstances(p)) == null || instances.isEmpty()) { predicateInstanceStrings.add(p.getName()); } else { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Truth.java similarity index 81% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Truth.java index 58283a094..2a1f017be 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Truth.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.core.common; /** * Represents truth value that can be converted to a Boolean truth value. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java index aabd4f55b..922c7db56 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java index 081de663b..40c535674 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.StringUtils; @@ -35,6 +35,7 @@ import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.BindingPredicateInterpretation; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java index 908f34a35..d6460c689 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java index e572b78db..add4ac3ca 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java index 622efdaa4..82aff6249 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import org.apache.commons.lang3.ClassUtils; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java index 9ff2080a6..81479a845 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java similarity index 68% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java index 1e2011898..4eb484758 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java @@ -1,8 +1,9 @@ -package at.ac.tuwien.kr.alpha.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java index d440837b8..301be3bd5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; +import at.ac.tuwien.kr.alpha.common.fixedinterpretations.BindingPredicateInterpretation; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.Term; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java index fca1f5484..aa813ac2b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/ComponentGraph.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/ComponentGraph.java index 34096e4f6..b6ce62d2b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/ComponentGraph.java @@ -23,11 +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.common.depgraph; +package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import org.apache.commons.lang3.StringUtils; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -39,7 +40,7 @@ /** * Representation of an {@link InternalProgram}'s component graph, i.e. the directed acyclic graph resulting from condensing the program's * {@link DependencyGraph} into its strongly connected components. Needed in order to calculate stratifications from which an evaluation order for the - * {@link at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation} transformation can be derived. + * {@link at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation} transformation can be derived. * * Copyright (c) 2019-2020, the Alpha Team. */ diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java index 395daeb4a..c0cc010df 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java @@ -23,11 +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.common.depgraph; +package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +43,7 @@ import java.util.Map; /** - * Internal representation of an {@link at.ac.tuwien.kr.alpha.common.program.InternalProgram}'s dependency graph. The dependency graph tracks dependencies + * Internal representation of an {@link at.ac.tuwien.kr.alpha.core.programs.InternalProgram}'s dependency graph. The dependency graph tracks dependencies * between rules of a program. Each {@link Node} of the graph represents a {@link CorePredicate} occurring in the program. A node has an incoming {@link Edge} for * every {@link Literal} in some rule body that depends on it, i.e. the predicate of the literal in question is the same as that of the node. The "sign" flag of * an {@link Edge} indicates whether the dependency is a positive or negative one, i.e. if the atom in question is preceded by a "not". diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DepthFirstSearchAlgorithm.java similarity index 99% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DepthFirstSearchAlgorithm.java index 02b0347e1..b0072679b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DepthFirstSearchAlgorithm.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.common.depgraph; +package at.ac.tuwien.kr.alpha.core.depgraph; import java.util.ArrayList; import java.util.Deque; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Edge.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Edge.java index f286020b7..41b2a0117 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Edge.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.common.depgraph; +package at.ac.tuwien.kr.alpha.core.depgraph; /** * An edge in a dependency graph to be used in adjacency lists (i.e., only the target of the edge is recorded). Edges diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java index f7f041aba..af0864e88 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.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.common.depgraph; +package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; /** * A node in a dependency graph. One node references exactly one predicate. This means that all rule heads deriving the diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithm.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithm.java index cab16a8a9..e07953b00 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithm.java @@ -23,12 +23,13 @@ * 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.common.depgraph; +package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph.SCComponent; + import java.util.ArrayList; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/StronglyConnectedComponentsAlgorithm.java similarity index 99% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/StronglyConnectedComponentsAlgorithm.java index 0854e7f3d..48e9c67f7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/StronglyConnectedComponentsAlgorithm.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.common.depgraph; +package at.ac.tuwien.kr.alpha.core.depgraph; import java.util.ArrayList; import java.util.Deque; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java similarity index 99% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java index 973e738de..79d0398ee 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/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.api.externals.stdlib; +package at.ac.tuwien.kr.alpha.core.externals; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java similarity index 86% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java index 0bb017067..5e8480df2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java @@ -23,14 +23,22 @@ * 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.externals; +package at.ac.tuwien.kr.alpha.core.externals; -import at.ac.tuwien.kr.alpha.api.externals.stdlib.AspStandardLibrary; +import at.ac.tuwien.kr.alpha.api.externals.Predicate; import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.*; import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +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; @@ -135,7 +143,7 @@ public static > List asFacts(Class classOfExtFa String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. for (T instance : extFacts) { // TODO use properly wrapped BasicAtoms here - retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.CorePredicate.getInstance(name, 1), CoreConstantTerm.getInstance(instance))); + retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.core.common.CorePredicate.getInstance(name, 1), CoreConstantTerm.getInstance(instance))); } return retVal; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java similarity index 77% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java index f37739534..4c6291cb4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; /** * Copyright (c) 2016, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/BridgedGrounder.java similarity index 69% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/BridgedGrounder.java index 98b18eb5b..ade4911a3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/BridgedGrounder.java @@ -1,13 +1,13 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.HashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; public abstract class BridgedGrounder extends AbstractGrounder { protected final Bridge[] bridges; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java index c807e0bae..322bc1e86 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java @@ -25,19 +25,20 @@ * 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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; + +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.NoGood; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import java.util.*; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom.off; -import static at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom.on; +import static at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom.off; +import static at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom.on; +import static at.ac.tuwien.kr.alpha.core.common.Literals.*; import static java.util.Collections.emptyList; public class ChoiceRecorder { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index 7f762c773..a61bfc403 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -1,7 +1,7 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import java.util.ArrayList; import java.util.Collections; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FilteringGrounder.java similarity index 77% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FilteringGrounder.java index 03aac3274..a40e7326f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FilteringGrounder.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; /** * Copyright (c) 2016, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Grounder.java similarity index 88% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Grounder.java index 41849fa53..e9958dcde 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Grounder.java @@ -25,25 +25,26 @@ * 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.grounder; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import org.apache.commons.lang3.tuple.Pair; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.tuple.Pair; + +import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.IntIterator; +import at.ac.tuwien.kr.alpha.core.common.NoGood; + public interface Grounder { /** * Translates an answer-set represented by true atom IDs into its logical representation. * @param trueAtoms * @return */ - AnswerSet assignmentToAnswerSet(Iterable trueAtoms); + CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms); /** * Applies lazy grounding and returns all newly derived (fully ground) NoGoods. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java index a24c9c8a8..a4f4126a9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java @@ -25,13 +25,13 @@ * 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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; public final class GrounderFactory { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorage.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorage.java index 578596886..b70716f9a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorage.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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.ArrayList; import java.util.Collections; @@ -36,9 +36,9 @@ import java.util.Map; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; /** * A storage for instances with a certain arity, where each position of the instance can be indexed. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java similarity index 84% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java index 9897b5a03..a314a6f3a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java @@ -1,13 +1,13 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.Util.join; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.util.Util; /** * An instance is a positional association of terms, e.g., representing a variable substitution, or a ground instance of diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java similarity index 86% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java index 7e5aade1d..3b9c09691 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * Generates unique, sequential integers starting at 0, i.e., it maintains a counter that is incremented for each getNextId(). diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java index cb19e5cb3..b0e003dd4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java @@ -25,10 +25,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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.ArrayList; import java.util.Collection; @@ -48,32 +48,31 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; +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.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +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.common.NoGoodInterface; +import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.BindingResult; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.DefaultLazyGroundingInstantiationStrategy; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationResult; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiator; +import at.ac.tuwien.kr.alpha.core.grounder.structure.AnalyzeUnjustified; +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.util.Util; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; -import at.ac.tuwien.kr.alpha.grounder.instantiation.BindingResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.DefaultLazyGroundingInstantiationStrategy; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; -import at.ac.tuwien.kr.alpha.grounder.structure.AnalyzeUnjustified; /** * A semi-naive grounder. @@ -227,7 +226,7 @@ private void registerLiteralAtWorkingMemory(CoreLiteral literal, InternalRule no } @Override - public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { + public CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms) { Map> predicateInstances = new LinkedHashMap<>(); SortedSet knownPredicates = new TreeSet<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java index 69996e2e6..8733a0f94 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java @@ -25,11 +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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.negateLiteral; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.core.common.Literals.negateLiteral; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -40,17 +40,16 @@ import java.util.Map; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Class to generate ground NoGoods out of non-ground rules and grounding substitutions. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NogoodRegistry.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NogoodRegistry.java index 43fdd9fce..be67855a6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NogoodRegistry.java @@ -1,10 +1,10 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import at.ac.tuwien.kr.alpha.common.NoGood; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.LinkedHashMap; import java.util.Map; +import at.ac.tuwien.kr.alpha.core.common.NoGood; + public class NogoodRegistry { private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java similarity index 78% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java index ec99f727d..99dd82276 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java @@ -1,11 +1,11 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Copyright (c) 2017, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java index a3a7c16d7..1af3a4985 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java @@ -23,13 +23,13 @@ * 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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * A grounding order computed by {@link RuleGroundingOrders} for a specific {@link InternalRule} and a specific starting literal. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java index a3e022aa3..8571abcee 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.ArrayList; import java.util.Collection; @@ -37,10 +37,10 @@ import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Provides the grounder with information on the order to ground the literals in the body of a rule. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java index 7cc35a992..f67f92b5f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java @@ -25,9 +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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.List; import java.util.Map; @@ -35,13 +35,13 @@ import java.util.Set; import java.util.TreeMap; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; public class Substitution { @@ -97,7 +97,7 @@ boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution par if (termNonGround == termGround) { // Both terms are either the same constant or the same variable term return true; - } else if (termNonGround instanceof ConstantTerm) { + } else if (termNonGround instanceof CoreConstantTerm) { // Since right term is ground, both terms differ return false; } else if (termNonGround instanceof VariableTerm) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index a188d7adf..5cb8dfa54 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -25,17 +25,16 @@ * 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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.Set; -import static at.ac.tuwien.kr.alpha.Util.oops; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; /** * Copyright (c) 2017, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java index 92a3df759..884232f22 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.ArrayList; import java.util.HashSet; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java index b5ba106f2..743579b0b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.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.grounder; +package at.ac.tuwien.kr.alpha.core.grounder; import java.util.HashMap; import java.util.HashSet; @@ -34,9 +34,9 @@ import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; public class WorkingMemory { protected HashMap> workingMemory = new HashMap<>(); 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 new file mode 100644 index 000000000..a4897eb34 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/bridges/Bridge.java @@ -0,0 +1,12 @@ +package at.ac.tuwien.kr.alpha.core.grounder.bridges; + +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.IntIdGenerator; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; + +import java.util.Collection; + +public interface Bridge { + Collection getRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator); +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java index 79026fdcc..5678a6b96 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -23,11 +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.grounder.instantiation; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + import org.apache.commons.lang3.tuple.ImmutablePair; import java.util.ArrayList; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AssignmentStatus.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AssignmentStatus.java index 8555e91c6..2f9290d51 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AssignmentStatus.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.grounder.instantiation; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.core.grounder.Grounder; +import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; /** * Helper type to represent truth values as understood by a {@link Grounder} and {@link LiteralInstantiator}. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/BindingResult.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/BindingResult.java index 34ff021bf..370038df4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/BindingResult.java @@ -23,13 +23,13 @@ * 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.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.grounder.Substitution; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + /** * Contains substitutions produced for generating ground substitutions of a rule, * and for every substitution the number of positive body atoms still unassigned in the respective ground rule. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java index 21f30e40b..f0dd352db 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java @@ -23,24 +23,23 @@ * 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.grounder.instantiation; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; import java.util.LinkedHashSet; import java.util.Map; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.solver.Solver; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; +import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.core.solver.Solver; +import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.core.util.Util; /** * Implementation of {@link AbstractLiteralInstantiationStrategy} designed for use in {@link NaiveGrounder}. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationResult.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationResult.java index 42d7be9f1..4e6567edc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationResult.java @@ -23,25 +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. */ -package at.ac.tuwien.kr.alpha.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import org.apache.commons.lang3.tuple.ImmutablePair; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import at.ac.tuwien.kr.alpha.core.grounder.Grounder; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Representation of the result of instantiating, i.e. finding ground instances for a literal, as performed by * {@link LiteralInstantiator#instantiateLiteral(Literal, Substitution)}. * * 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}. + * together with status information that can be used by a {@link Grounder} to determine how to proceed when grounding an + * {@link InternalRule}. * * Copyright (c) 2020, the Alpha Team. */ diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationStrategy.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationStrategy.java index 5a8489f77..5b0fdf017 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationStrategy.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.grounder.instantiation; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * A {@link LiteralInstantiationStrategy} finds and validates {@link Substitution}s for {@link Literal}s based on a specific definition of diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiator.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiator.java index 607f3ac63..68e0e615d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiator.java @@ -23,12 +23,17 @@ * 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.grounder.instantiation; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationLiteral; -import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.IntervalLiteral; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + import org.apache.commons.lang3.tuple.ImmutablePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java index 3f98f3695..9c86709ab 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java @@ -23,12 +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.grounder.instantiation; +package at.ac.tuwien.kr.alpha.core.grounder.instantiation; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; /** * A very basic implementation of {@link AbstractLiteralInstantiationStrategy} that determines truth of an atom solely based on the atom's diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java index 52be979bb..da5bea321 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java @@ -1,23 +1,28 @@ -package at.ac.tuwien.kr.alpha.grounder.structure; +package at.ac.tuwien.kr.alpha.core.grounder.structure; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.Unification; -import at.ac.tuwien.kr.alpha.grounder.Unifier; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.grounder.Unification; +import at.ac.tuwien.kr.alpha.core.grounder.Unifier; +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.solver.ThriceTruth; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; -import static at.ac.tuwien.kr.alpha.Util.oops; +import java.util.*; /** * Copyright (c) 2018-2020, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java index e599f42b8..daa3eb128 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java @@ -1,16 +1,16 @@ -package at.ac.tuwien.kr.alpha.grounder.structure; +package at.ac.tuwien.kr.alpha.core.grounder.structure; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; -import at.ac.tuwien.kr.alpha.grounder.Unification; -import at.ac.tuwien.kr.alpha.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.VariableNormalizableAtom; +import at.ac.tuwien.kr.alpha.core.grounder.Unification; +import at.ac.tuwien.kr.alpha.core.grounder.Unifier; /** * Copyright (c) 2018, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/CustomErrorListener.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/CustomErrorListener.java index 29b9adf3f..c13992bb5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/CustomErrorListener.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha; +package at.ac.tuwien.kr.alpha.core.parser; import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.RecognitionException; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectives.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectives.java index f6fc42ffb..8a10e93d6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectives.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.grounder.parser; +package at.ac.tuwien.kr.alpha.core.parser; import java.util.LinkedHashMap; import java.util.Map; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 3571d961b..c6875d2e4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -25,23 +25,34 @@ * 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.grounder.parser; +package at.ac.tuwien.kr.alpha.core.parser; import at.ac.tuwien.kr.alpha.antlr.ASPCore2BaseVisitor; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; +import at.ac.tuwien.kr.alpha.core.common.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.Head; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; + import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.tree.TerminalNode; @@ -82,13 +93,13 @@ public InputProgram translate(ASPCore2Parser.ProgramContext input) { /** * Translates a context for answer sets (referring to a node in an ATN specific to ANTLR) to the representation that Alpha uses. */ - public Set translate(ASPCore2Parser.Answer_setsContext input) { + public Set translate(ASPCore2Parser.Answer_setsContext input) { return visitAnswer_sets(input); } @Override - public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { - Set result = new TreeSet<>(); + public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { + Set result = new TreeSet<>(); for (ASPCore2Parser.Answer_setContext answerSetContext : ctx.answer_set()) { result.add(visitAnswer_set(answerSetContext)); @@ -98,7 +109,7 @@ public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { } @Override - public AnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { + public CoreAnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { SortedSet predicates = new TreeSet<>(); Map> predicateInstances = new TreeMap<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java index 7bea8f5a2..1f20e1ef2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.grounder.parser; +package at.ac.tuwien.kr.alpha.core.parser; import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.CharStream; @@ -13,11 +13,10 @@ import java.util.Collections; import java.util.Map; -import at.ac.tuwien.kr.alpha.CustomErrorListener; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; public class ProgramParser { private final Map externals; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java index a7cc0f152..7a7b17df2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramPartParser.java @@ -26,13 +26,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.grounder.parser; +package at.ac.tuwien.kr.alpha.core.parser; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.common.atoms.Literal; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; + import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java similarity index 80% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java index 0043b5e7b..e090da23b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java @@ -1,10 +1,10 @@ -package at.ac.tuwien.kr.alpha.common.program; +package at.ac.tuwien.kr.alpha.core.programs; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.AbstractRule; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.rules.AbstractRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.Head; +import at.ac.tuwien.kr.alpha.core.util.Util; import java.util.Collections; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java similarity index 63% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java index 6a7437c36..d9f4a1205 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java @@ -1,15 +1,15 @@ -package at.ac.tuwien.kr.alpha.common.program; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.StronglyConnectedComponentsAlgorithm; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import org.apache.commons.lang3.tuple.ImmutablePair; +package at.ac.tuwien.kr.alpha.core.programs; import java.util.List; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.StronglyConnectedComponentsAlgorithm; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; + /** * An {@link InternalProgram} with dependency information. @@ -21,14 +21,14 @@ public class AnalyzedProgram extends InternalProgram { private final DependencyGraph dependencyGraph; private final ComponentGraph componentGraph; - public AnalyzedProgram(List rules, List facts) { + public AnalyzedProgram(List rules, List facts) { super(rules, facts); dependencyGraph = DependencyGraph.buildDependencyGraph(getRulesById()); componentGraph = buildComponentGraph(dependencyGraph); } public static AnalyzedProgram analyzeNormalProgram(NormalProgram prog) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); return new AnalyzedProgram(rulesAndFacts.left, rulesAndFacts.right); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java similarity index 88% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java index 3bb1d8190..30ada5a7b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java @@ -25,27 +25,26 @@ * 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.common.program; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; +package at.ac.tuwien.kr.alpha.core.programs; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; + /** * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. *

      * Copyright (c) 2017-2019, the Alpha Team. */ -public class InputProgram extends AbstractProgram implements Program { +public class InputProgram extends AbstractProgram { public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectives()); - public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java similarity index 76% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java index dd8f88f53..3fa131b22 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InternalProgram.java @@ -1,15 +1,20 @@ -package at.ac.tuwien.kr.alpha.common.program; +package at.ac.tuwien.kr.alpha.core.programs; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.grounder.FactIntervalEvaluator; -import at.ac.tuwien.kr.alpha.grounder.Instance; import org.apache.commons.lang3.tuple.ImmutablePair; -import java.util.*; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.FactIntervalEvaluator; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.NormalRule; /** * A program in the internal representation needed for grounder and solver, i.e.: rules must have normal heads, all @@ -24,13 +29,13 @@ public class InternalProgram extends AbstractProgram { private final Map> factsByPredicate = new LinkedHashMap<>(); private final Map rulesById = new LinkedHashMap<>(); - public InternalProgram(List rules, List facts) { + public InternalProgram(List rules, List facts) { super(rules, facts, null); recordFacts(facts); recordRules(rules); } - static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { + static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { List internalRules = new ArrayList<>(); List facts = new ArrayList<>(normalProgram.getFacts()); for (NormalRule r : normalProgram.getRules()) { @@ -47,7 +52,7 @@ static ImmutablePair, List> internalizeRu } public static InternalProgram fromNormalProgram(NormalProgram normalProgram) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); return new InternalProgram(rulesAndFacts.left, rulesAndFacts.right); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java similarity index 58% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java index d6d1b18e9..c7680703a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java @@ -1,13 +1,12 @@ -package at.ac.tuwien.kr.alpha.common.program; +package at.ac.tuwien.kr.alpha.core.programs; import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.core.rules.NormalRule; /** * A program that only contains NormalRules. @@ -16,7 +15,7 @@ */ public class NormalProgram extends AbstractProgram { - public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java similarity index 84% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java index 1353864ef..42257785e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.program; +package at.ac.tuwien.kr.alpha.core.programs; import org.antlr.v4.runtime.CharStreams; @@ -7,7 +7,7 @@ import java.util.Map; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; public class Programs { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index 5ff468496..0df4e4922 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; import java.util.ArrayList; import java.util.Collection; @@ -7,22 +7,21 @@ import java.util.LinkedHashSet; import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.Unifier; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; /** * Copyright (c) 2017-2020, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java index 8dfe872e0..1376f1e2d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java @@ -25,16 +25,19 @@ * 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.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.Head; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; import java.util.ArrayList; import java.util.Iterator; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java similarity index 82% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java index 54b78535c..ed601937c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java @@ -1,21 +1,21 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; /** * Rewrites the ordinary atom whose name is given in the input program by the enumeration directive #enum_atom_is into diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java index 0307133cf..c9606d6af 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/IntervalTermToIntervalAtom.java @@ -25,23 +25,23 @@ * 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.grounder.transformation; +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 at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.core.rules.NormalRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; /** * Rewrites all interval terms in a rule into a new variable and an IntervalAtom. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java similarity index 85% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java index 3d68d7e06..534247068 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java @@ -1,8 +1,8 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; /** * Encapsulates all transformations necessary to transform a given program into a @{link NormalProgram} that is understood by Alpha internally diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java similarity index 76% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index 956296bdd..33159bdde 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -1,17 +1,17 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.Head; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; /** * diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java similarity index 63% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java index 6aa85027c..3d6e87eec 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformation.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.common.program.AbstractProgram; +import at.ac.tuwien.kr.alpha.core.programs.AbstractProgram; /** * Copyright (c) 2017-2019, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 4c7b470ef..7e8bd71e6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; import java.util.ArrayList; import java.util.Collections; @@ -16,27 +16,27 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; -import at.ac.tuwien.kr.alpha.common.depgraph.Node; -import at.ac.tuwien.kr.alpha.common.depgraph.StratificationAlgorithm; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrder; -import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrders; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; -import at.ac.tuwien.kr.alpha.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.Node; +import at.ac.tuwien.kr.alpha.core.depgraph.StratificationAlgorithm; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph.SCComponent; +import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrder; +import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationResult; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiator; +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.rules.InternalRule; /** * Evaluates the stratifiable part of a given (analyzed) ASP program. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index c12827fa7..65bf6aa0f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -1,26 +1,26 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; -import static at.ac.tuwien.kr.alpha.grounder.transformation.PredicateInternalizer.makePredicatesInternal; +import static at.ac.tuwien.kr.alpha.core.programs.transformation.PredicateInternalizer.makePredicatesInternal; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Unifier; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; /** * Rewrites #sum aggregates into normal rules. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 7a86941fc..1218cb39a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.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.grounder.transformation; +package at.ac.tuwien.kr.alpha.core.programs.transformation; import java.util.ArrayList; import java.util.Arrays; @@ -37,15 +37,15 @@ import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.core.rules.NormalRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; /** * Removes variable equalities from rules by replacing one variable with the other. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java index a4c41973e..71c6e61c8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.rule; +package at.ac.tuwien.kr.alpha.core.rules; import java.util.Collections; import java.util.LinkedHashSet; @@ -8,9 +8,9 @@ import org.apache.commons.collections4.SetUtils; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.rules.heads.Head; +import at.ac.tuwien.kr.alpha.core.util.Util; /** * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java index db05e1164..9a6a47bd2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/BasicRule.java @@ -25,12 +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.common.rule; +package at.ac.tuwien.kr.alpha.core.rules; import java.util.List; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.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. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java index ace3930f3..d073fe9a2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/InternalRule.java @@ -25,22 +25,22 @@ * 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.common.rule; +package at.ac.tuwien.kr.alpha.core.rules; import java.util.ArrayList; import java.util.List; import com.google.common.annotations.VisibleForTesting; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrders; -import at.ac.tuwien.kr.alpha.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; +import at.ac.tuwien.kr.alpha.core.grounder.Unifier; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; /** * Represents a normal rule or a constraint for the semi-naive grounder. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java similarity index 83% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java index db9f8ac7e..a56d32e2f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java @@ -1,12 +1,12 @@ -package at.ac.tuwien.kr.alpha.common.rule; +package at.ac.tuwien.kr.alpha.core.rules; import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.util.Util; /** * A rule that has a normal head, i.e. just one head atom, no disjunction or choice heads allowed. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java similarity index 82% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java index 6a43cb24d..014b0c1ae 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java @@ -1,14 +1,13 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; +package at.ac.tuwien.kr.alpha.core.rules.heads; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.List; -import static at.ac.tuwien.kr.alpha.Util.join; +import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; /** * Represents the head of a choice rule. @@ -18,10 +17,10 @@ public class ChoiceHead extends Head { private final List choiceElements; - private final Term lowerBound; + private final CoreTerm lowerBound; private final ComparisonOperator lowerOp; - private final Term upperBound; + private final CoreTerm upperBound; private final ComparisonOperator upperOp; public static class ChoiceElement { @@ -57,15 +56,15 @@ public List getChoiceElements() { return choiceElements; } - public Term getLowerBound() { + public CoreTerm getLowerBound() { return lowerBound; } - public Term getUpperBound() { + public CoreTerm getUpperBound() { return upperBound; } - public ChoiceHead(List choiceElements, Term lowerBound, ComparisonOperator lowerOp, Term upperBound, ComparisonOperator upperOp) { + public ChoiceHead(List choiceElements, CoreTerm lowerBound, ComparisonOperator lowerOp, CoreTerm upperBound, ComparisonOperator upperOp) { this.choiceElements = choiceElements; this.lowerBound = lowerBound; this.lowerOp = lowerOp; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHead.java similarity index 79% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHead.java index 11f0e365d..6de31830a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHead.java @@ -1,18 +1,18 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; +package at.ac.tuwien.kr.alpha.core.rules.heads; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.List; -import static at.ac.tuwien.kr.alpha.Util.join; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; /** * Copyright (c) 2017, the Alpha Team. */ public class DisjunctiveHead extends Head { - public final List disjunctiveAtoms; + public final List disjunctiveAtoms; - public DisjunctiveHead(List disjunctiveAtoms) { + public DisjunctiveHead(List disjunctiveAtoms) { this.disjunctiveAtoms = disjunctiveAtoms; if (disjunctiveAtoms != null && disjunctiveAtoms.size() > 1) { throw new UnsupportedOperationException("Disjunction in rule heads is not yet supported"); @@ -25,7 +25,7 @@ public String toString() { } public boolean isGround() { - for (Atom atom : disjunctiveAtoms) { + for (CoreAtom atom : disjunctiveAtoms) { if (!atom.isGround()) { return false; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/Head.java similarity index 89% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/Head.java index 535466cb6..3b813f89d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/Head.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; +package at.ac.tuwien.kr.alpha.core.rules.heads; /** * Represents the head of a rule, i.e., either a choice or a disjunction of atoms, but not both. For normal rules the disjunction contains only one atom. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHead.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHead.java index 650eadbc2..af596b4cd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHead.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; +package at.ac.tuwien.kr.alpha.core.rules.heads; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; /** * Represents a normal head, i.e., a head that is an Atom. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java similarity index 50% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java index 254d0ed05..f1fa10674 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java @@ -1,8 +1,8 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.grounder.Grounder; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; +import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import java.util.Spliterator; import java.util.Spliterators; @@ -20,17 +20,17 @@ protected AbstractSolver(AtomStore atomStore, Grounder grounder) { this.grounder = grounder; } - protected AnswerSet translate(Iterable assignment) { + protected CoreAnswerSet translate(Iterable assignment) { return grounder.assignmentToAnswerSet(assignment); } - protected abstract boolean tryAdvance(Consumer action); + protected abstract boolean tryAdvance(Consumer action); @Override - public Spliterator spliterator() { - return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 0) { + public Spliterator spliterator() { + return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 0) { @Override - public boolean tryAdvance(Consumer action) { + public boolean tryAdvance(Consumer action) { return AbstractSolver.this.tryAdvance(action); } }; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Antecedent.java similarity index 83% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Antecedent.java index c841ecc0e..e62b1aa3e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Antecedent.java @@ -1,7 +1,7 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; /** - * An interface to reasons of implications as used internally by the solver. This is a lightweight {@link at.ac.tuwien.kr.alpha.common.NoGood} that only + * An interface to reasons of implications as used internally by the solver. This is a lightweight {@link at.ac.tuwien.kr.alpha.core.common.NoGood} that only * provides an array of literals (in some order) and has an activity that may change. * * Copyright (c) 2019, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounter.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounter.java index 506dddbcd..8504ec567 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounter.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.solver; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; +package at.ac.tuwien.kr.alpha.core.solver; import java.util.ArrayList; import java.util.Collections; @@ -34,6 +31,8 @@ import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; + /** * Counts the number of ground atoms stored for each type (i.e., subclass of {@link CoreAtom}. * For every atom, only the counter for one class (the most specific one) is incremented, @@ -51,7 +50,7 @@ public void add(CoreAtom atom) { * @param type the class of atoms to count * @return the number of atoms of the given type */ - public int getNumberOfAtoms(Class type) { + public int getNumberOfAtoms(Class type) { return countByType.getOrDefault(type, 0); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Atoms.java similarity index 69% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Atoms.java index de6f02a6a..9ba91dbfa 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Atoms.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; public final class Atoms { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/BinaryNoGoodPropagationEstimation.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/BinaryNoGoodPropagationEstimation.java index edf3423fc..1d7376753 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/BinaryNoGoodPropagationEstimation.java @@ -23,7 +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.solver; +package at.ac.tuwien.kr.alpha.core.solver; + +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; /** * Offers methods to estimate the effect of propagating binary nogoods. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Checkable.java similarity index 88% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Checkable.java index 369389d50..cb9040063 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Checkable.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; /** * Marks classes that implement some "checking" logic that can perform diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Choice.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Choice.java index eb70acd5d..b1a9345a1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Choice.java @@ -25,10 +25,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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; class Choice { private final int atom; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceInfluenceManager.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceInfluenceManager.java index 62624eecd..500413366 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceInfluenceManager.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; @@ -33,10 +33,10 @@ import java.util.*; -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; +import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * Manages influence of atoms on the activity of certain other atoms. Can be used for either choice points or heuristic atoms. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManager.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManager.java index 5feb085a3..2519fc29c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManager.java @@ -25,20 +25,21 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.NoGood; + import java.util.*; import java.util.Map.Entry; import java.util.stream.Collectors; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * This class provides functionality for choice point management, detection of active choice points, etc. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ConflictCause.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ConflictCause.java index b9b72ca58..a459b49fd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ConflictCause.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; /** * Indicates the presence of a conflict and contains its reason in terms of a violated Antecedent. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java index 34560c693..8b23becd4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java @@ -25,16 +25,16 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToNegatedLiteral; -import static at.ac.tuwien.kr.alpha.solver.NoGoodStore.LBD_NO_VALUE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; -import static at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToNegatedLiteral; +import static at.ac.tuwien.kr.alpha.core.solver.NoGoodStore.LBD_NO_VALUE; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; +import static at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; +import static at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.ArrayList; import java.util.Iterator; @@ -50,27 +50,27 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.ProgramAnalyzingGrounder; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; -import at.ac.tuwien.kr.alpha.solver.heuristics.ChainedBranchingHeuristics; -import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.solver.heuristics.NaiveHeuristic; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; +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.CoreAnswerSet; +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.ProgramAnalyzingGrounder; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristic; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristicFactory; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.ChainedBranchingHeuristics; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.NaiveHeuristic; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner; /** * The new default solver employed in Alpha. @@ -122,7 +122,7 @@ private BranchingHeuristic chainFallbackHeuristic(Grounder grounder, WritableAss } @Override - protected boolean tryAdvance(Consumer action) { + protected boolean tryAdvance(Consumer action) { boolean didChange = false; // Initially, get NoGoods from grounder. @@ -210,7 +210,7 @@ protected boolean tryAdvance(Consumer action) { afterAllAtomsAssigned = true; } else if (assignment.getMBTCount() == 0) { // NOTE: If we would do optimization, we would now have a guaranteed upper bound. - AnswerSet as = translate(assignment.getTrueAssignments()); + CoreAnswerSet as = translate(assignment.getTrueAssignments()); LOGGER.debug("Answer-Set found: {}", as); action.accept(as); logStats(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/LearnedNoGoodDeletion.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/LearnedNoGoodDeletion.java index a17264654..f5b5a422b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/LearnedNoGoodDeletion.java @@ -1,16 +1,17 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.Assignment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.core.common.Assignment; + +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; + import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - /** * Realizes a learned NoGood deletion strategy based on LBD and activity of NoGoods. * diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStore.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStore.java index 28af2719c..f2f0785c4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStore.java @@ -25,16 +25,17 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.NoGood; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.core.common.NoGood; + import java.util.HashMap; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; +import static at.ac.tuwien.kr.alpha.core.common.Literals.*; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.*; public class NaiveNoGoodStore implements NoGoodStore { private static final Logger LOGGER = LoggerFactory.getLogger(NaiveNoGoodStore.class); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveSolver.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveSolver.java index bf8f08268..de4d82a36 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveSolver.java @@ -25,13 +25,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.solver; +package at.ac.tuwien.kr.alpha.core.solver; + +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; +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.grounder.Grounder; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.grounder.Grounder; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +40,7 @@ import java.util.*; import java.util.function.Consumer; -import static at.ac.tuwien.kr.alpha.common.Literals.*; +import static at.ac.tuwien.kr.alpha.core.common.Literals.*; import static java.lang.Math.abs; /** @@ -77,7 +78,7 @@ public class NaiveSolver extends AbstractSolver { } @Override - protected boolean tryAdvance(Consumer action) { + protected boolean tryAdvance(Consumer action) { // Get basic rules and facts from grounder if (doInit) { obtainNoGoodsFromGrounder(); @@ -113,7 +114,7 @@ protected boolean tryAdvance(Consumer action) { assignUnassignedToFalse(); didChange = true; } else if (noMBTValuesReamining()) { - AnswerSet as = getAnswerSetFromAssignment(); + CoreAnswerSet as = getAnswerSetFromAssignment(); LOGGER.debug("Answer-Set found: {}", as); LOGGER.trace("Choice stack: {}", choiceStack); action.accept(as); @@ -192,7 +193,7 @@ private boolean propagationFixpointReached() { return !changeCopy; } - private AnswerSet getAnswerSetFromAssignment() { + private CoreAnswerSet getAnswerSetFromAssignment() { ArrayList trueAtoms = new ArrayList<>(); for (Map.Entry atomAssignment : truthAssignments.entrySet()) { if (atomAssignment.getValue()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodCounter.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodCounter.java index 432419ab1..3ff15e8e8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodCounter.java @@ -23,15 +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.solver; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; +package at.ac.tuwien.kr.alpha.core.solver; import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface; +import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type; + /** * Maintains statistics on numbers of various types of {@link NoGood}s. */ diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStore.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStore.java index 7cd516b40..ec70069c1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStore.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.NoGood; /** * An interface defining the use of a NoGood store. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java index 125b70976..eea788f99 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java @@ -25,32 +25,34 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface; +import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; + import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; -import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; -import static at.ac.tuwien.kr.alpha.common.Literals.literalToString; -import static at.ac.tuwien.kr.alpha.common.NoGood.HEAD; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; +import static at.ac.tuwien.kr.alpha.core.common.Literals.literalToString; +import static at.ac.tuwien.kr.alpha.core.common.NoGood.HEAD; +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; +import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * NoGoodStore using for each NoGood three watches, two ordinary ones and an alpha watch. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/PerformanceLog.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/PerformanceLog.java index 9c4d74601..a64a40f96 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/PerformanceLog.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import org.slf4j.Logger; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ShallowAntecedent.java similarity index 88% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ShallowAntecedent.java index 54be1ceca..595804f21 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ShallowAntecedent.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import static at.ac.tuwien.kr.alpha.Util.oops; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * Represents a shallow {@link Antecedent} that must be instantiated before use. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Solver.java similarity index 59% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Solver.java index d6900d382..396c72f22 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Solver.java @@ -1,6 +1,4 @@ -package at.ac.tuwien.kr.alpha.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; +package at.ac.tuwien.kr.alpha.core.solver; import java.util.List; import java.util.Set; @@ -9,19 +7,21 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; + @FunctionalInterface public interface Solver { - Spliterator spliterator(); + Spliterator spliterator(); - default Stream stream() { + default Stream stream() { return StreamSupport.stream(spliterator(), false); } - default Set collectSet() { + default Set collectSet() { return stream().collect(Collectors.toSet()); } - default List collectList() { + default List collectList() { return stream().collect(Collectors.toList()); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java index 36bbe668d..4485453cf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java @@ -25,13 +25,13 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.AtomStore; import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfigurationBuilder; +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; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverMaintainingStatistics.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverMaintainingStatistics.java index 0c29abef7..40a709149 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverMaintainingStatistics.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import java.io.PrintStream; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ThriceTruth.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ThriceTruth.java index ade2ccb9c..929d93ec0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ThriceTruth.java @@ -25,9 +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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.Truth; +import at.ac.tuwien.kr.alpha.core.common.Truth; public enum ThriceTruth implements Truth { TRUE("T", true), diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java index 4e2974d51..edeace8db 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignment.java @@ -25,22 +25,23 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; + +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +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.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.Atoms.isAtom; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; +import static at.ac.tuwien.kr.alpha.core.common.Literals.*; +import static at.ac.tuwien.kr.alpha.core.solver.Atoms.isAtom; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.*; +import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * An implementation of Assignment using a trail (of literals) and arrays as underlying structures for storing diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WatchedNoGood.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WatchedNoGood.java index 4395d9ed5..b4346a2ee 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WatchedNoGood.java @@ -25,15 +25,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.solver; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; +package at.ac.tuwien.kr.alpha.core.solver; import java.util.Iterator; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.literalToString; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface; + +import static at.ac.tuwien.kr.alpha.core.common.Literals.literalToString; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; public final class WatchedNoGood implements NoGoodInterface, Antecedent { private int activity; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WritableAssignment.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WritableAssignment.java index 806a29957..3decfcdd3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WritableAssignment.java @@ -25,13 +25,13 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.NoGood; public interface WritableAssignment extends Assignment { /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ActivityBasedBranchingHeuristic.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ActivityBasedBranchingHeuristic.java index dd17bb114..161f03bc4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ActivityBasedBranchingHeuristic.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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; /** * A heuristic that selects an atom to choose on by maintaining activity values for literals. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaActiveRuleHeuristic.java similarity index 87% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaActiveRuleHeuristic.java index b2b76ba26..0cf0e7990 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaActiveRuleHeuristic.java @@ -23,15 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; -import java.util.Random; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import java.util.Random; /** * A variant of {@link DependencyDrivenHeuristic} that counts the activity of non-body-representing atoms towards bodies of rules in which they occur. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java similarity index 87% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java index 52df83cd4..b14bc9d1e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java @@ -23,12 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +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 java.util.Comparator; import java.util.Optional; @@ -38,7 +38,7 @@ /** * A variant of {@link DependencyDrivenHeuristic} that prefers to choose atoms representing bodies of rules whose heads - * are assigned {@link at.ac.tuwien.kr.alpha.solver.ThriceTruth#MBT}. + * are assigned {@link at.ac.tuwien.kr.alpha.core.solver.ThriceTruth#MBT}. */ public class AlphaHeadMustBeTrueHeuristic extends DependencyDrivenHeuristic { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaRandomSignHeuristic.java similarity index 85% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaRandomSignHeuristic.java index f14a96b17..4e2cbc238 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaRandomSignHeuristic.java @@ -23,16 +23,16 @@ * 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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +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 java.util.Random; +import static at.ac.tuwien.kr.alpha.core.solver.Atoms.isAtom; -import static at.ac.tuwien.kr.alpha.solver.Atoms.isAtom; +import java.util.Random; public class AlphaRandomSignHeuristic extends DependencyDrivenHeuristic { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMin.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMin.java index 48e523932..49b910f36 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMin.java @@ -23,24 +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. */ -package at.ac.tuwien.kr.alpha.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; + +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +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.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; import java.util.stream.Stream; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.FALSE; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; /** * The BerkMin heuristic, as described in (but adapted for lazy grounding): diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMinLiteral.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMinLiteral.java index b916b1b7c..2a021e61e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMinLiteral.java @@ -25,18 +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. */ -package at.ac.tuwien.kr.alpha.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; + +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; import java.util.Deque; import java.util.LinkedList; import java.util.Random; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - /** * A BerkMin-like heuristics that uses activity of literals and a fixed-size queue instead of a stack of NoGoods. * Copyright (c) 2017-2018, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristic.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristic.java index 78be2e6de..3e08a5802 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristic.java @@ -23,14 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner; -import java.util.Collection; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import java.util.Collection; /** * A heuristic that selects an atom to choose on. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactory.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactory.java index 87afa8c6a..4ca447bcf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactory.java @@ -23,12 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.grounder.Grounder; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; import java.util.Arrays; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ChainedBranchingHeuristics.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ChainedBranchingHeuristics.java index 6d6eb8761..eac27790d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ChainedBranchingHeuristics.java @@ -23,14 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import java.util.*; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; -import static at.ac.tuwien.kr.alpha.Util.oops; +import java.util.*; /** * A "chained" list of branching heuristics in which the entry at position n+1 is used as a fallback if the entry at position n cannot make a decision. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenHeuristic.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenHeuristic.java index e24f29da0..87f9b078c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenHeuristic.java @@ -23,17 +23,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. */ -package at.ac.tuwien.kr.alpha.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProvider; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; + +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +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.BodyActivityProvider; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; + import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.collections4.multimap.HashSetValuedHashMap; import org.slf4j.Logger; @@ -43,9 +44,9 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; +import static at.ac.tuwien.kr.alpha.core.common.Literals.*; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.FALSE; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; /** * The BerkMin variants {@link BerkMin} and {@link BerkMinLiteral} suffer from the fact that choice points diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenPyroHeuristic.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenPyroHeuristic.java index 181a2299b..ce73f0d6d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenPyroHeuristic.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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; import java.util.Random; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenVSIDS.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenVSIDS.java index b2d8b194e..88f9be6ed 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenVSIDS.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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; import java.util.Random; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java index 3b6defcf1..f247b0852 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java @@ -23,19 +23,19 @@ * 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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; + +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; import java.util.HashSet; import java.util.Random; import java.util.Set; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - /** * {@link DependencyDrivenHeuristic} needs to know a lot about the structure of nogoods, i.e. the role their members play in rules. * However, the solving component of Alpha usually deals only with nogoods and cannot naturally access this information. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java index e8deefa8b..f4c8e71f7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; import java.util.Random; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtoms.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtoms.java index 45f9faf43..1f542fede 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtoms.java @@ -23,24 +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. */ -package at.ac.tuwien.kr.alpha.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type; +import at.ac.tuwien.kr.alpha.core.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceInfluenceManager; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.ChoiceInfluenceManager; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; + import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.PriorityQueue; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - /** * Manages a heap of atoms that are assigned an activity, such that the most active atom * resides at the top of the heap. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveChoicePoints.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveChoicePoints.java index 94c768bee..7a0174238 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveChoicePoints.java @@ -23,18 +23,19 @@ * 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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; + +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.collections4.multimap.HashSetValuedHashMap; import java.util.HashSet; import java.util.Set; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * Extends {@code HeapOfActiveAtoms} by a mechanism that, diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfiguration.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfiguration.java index 26d3d74a4..7980046b9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfiguration.java @@ -23,9 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfigurationBuilder.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfigurationBuilder.java index b1ee79ccf..1b6aae211 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfigurationBuilder.java @@ -23,9 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/MOMs.java similarity index 95% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/MOMs.java index 223cb7ad7..9c490b2c2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/MOMs.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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; +import at.ac.tuwien.kr.alpha.core.solver.BinaryNoGoodPropagationEstimation; import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/NaiveHeuristic.java similarity index 84% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/NaiveHeuristic.java index 506cc345c..27962aab3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/NaiveHeuristic.java @@ -25,18 +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. */ -package at.ac.tuwien.kr.alpha.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import java.util.Collection; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import java.util.Collection; /** - * The default heuristic that had been used by {@link at.ac.tuwien.kr.alpha.solver.DefaultSolver} before {@link BerkMin} was implemented. + * The default heuristic that had been used by {@link at.ac.tuwien.kr.alpha.core.solver.DefaultSolver} before {@link BerkMin} was implemented. * */ public class NaiveHeuristic implements BranchingHeuristic { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ReplayHeuristic.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ReplayHeuristic.java index cda9f35ac..60c694e42 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ReplayHeuristic.java @@ -23,12 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import at.ac.tuwien.kr.alpha.core.common.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; import java.util.Iterator; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java index 7b8b60232..0eebfc44c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java @@ -23,26 +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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProvider; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.HashSetValuedHashMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; +import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.common.Literals.*; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.multimap.HashSetValuedHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.core.common.Assignment; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +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.BodyActivityProvider; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; /** * This implementation is inspired by the VSIDS implementation in clasp. @@ -216,6 +219,7 @@ protected void incrementSignCounter(int literal) { signBalances[atom] += sign ? 1 : -1; } + @Override public void growForMaxAtomId(int maxAtomId) { // Grow arrays only if needed. if (signBalances.length > maxAtomId) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/AvgBodyActivityProvider.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/AvgBodyActivityProvider.java index 35a5c1f0e..21a60b594 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/AvgBodyActivityProvider.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.solver.heuristics.activity; +package at.ac.tuwien.kr.alpha.core.solver.heuristics.activity; import org.apache.commons.collections4.MultiValuedMap; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/BodyActivityProvider.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/BodyActivityProvider.java index 7591eea47..0426d1cc9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/BodyActivityProvider.java @@ -23,13 +23,13 @@ * 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.solver.heuristics.activity; +package at.ac.tuwien.kr.alpha.core.solver.heuristics.activity; import org.apache.commons.collections4.MultiValuedMap; -import java.util.Map; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import java.util.Map; public abstract class BodyActivityProvider { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/BodyActivityProviderFactory.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/BodyActivityProviderFactory.java index f3ded2a85..185553c55 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/BodyActivityProviderFactory.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.solver.heuristics.activity; +package at.ac.tuwien.kr.alpha.core.solver.heuristics.activity; import org.apache.commons.collections4.MultiValuedMap; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/DefaultBodyActivityProvider.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/DefaultBodyActivityProvider.java index a2e599790..f2d20ccfb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/DefaultBodyActivityProvider.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.solver.heuristics.activity; +package at.ac.tuwien.kr.alpha.core.solver.heuristics.activity; import org.apache.commons.collections4.MultiValuedMap; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/MaxBodyActivityProvider.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/MaxBodyActivityProvider.java index 324c4ccce..6ae1c23e7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/MaxBodyActivityProvider.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.solver.heuristics.activity; +package at.ac.tuwien.kr.alpha.core.solver.heuristics.activity; import org.apache.commons.collections4.MultiValuedMap; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/MinBodyActivityProvider.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/MinBodyActivityProvider.java index 33d73c237..9542ff912 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/MinBodyActivityProvider.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.solver.heuristics.activity; +package at.ac.tuwien.kr.alpha.core.solver.heuristics.activity; import org.apache.commons.collections4.MultiValuedMap; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/SumBodyActivityProvider.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/SumBodyActivityProvider.java index 4cb116748..0388f60ea 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/activity/SumBodyActivityProvider.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.solver.heuristics.activity; +package at.ac.tuwien.kr.alpha.core.solver.heuristics.activity; import org.apache.commons.collections4.MultiValuedMap; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearner.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearner.java index d5b26f9bf..85fb5affa 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearner.java @@ -25,13 +25,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.solver.learning; +package at.ac.tuwien.kr.alpha.core.solver.learning; + +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.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.Antecedent; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.Antecedent; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,9 +40,9 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.NoGoodStore.LBD_NO_VALUE; +import static at.ac.tuwien.kr.alpha.core.common.Literals.*; +import static at.ac.tuwien.kr.alpha.core.solver.NoGoodStore.LBD_NO_VALUE; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; /** * Conflict-driven learning on ground clauses. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/ResolutionSequence.java similarity index 61% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/ResolutionSequence.java index 66f870674..060773dc0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/ResolutionSequence.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.solver.learning; +package at.ac.tuwien.kr.alpha.core.solver.learning; /** * Copyright (c) 2016, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/Util.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Util.java similarity index 99% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/Util.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Util.java index b8e9efde0..16da43143 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/Util.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Util.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; +package at.ac.tuwien.kr.alpha.core.util; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java deleted file mode 100644 index 15e30600b..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.bridges; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; - -import java.util.Collection; - -public interface Bridge { - Collection getRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator); -} 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 532167e9c..649f0fa47 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 @@ -43,27 +43,27 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.CorePredicate; import at.ac.tuwien.kr.alpha.common.Predicate; import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; import at.ac.tuwien.kr.alpha.config.InputConfig; import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.GrounderFactory; +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.CoreAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +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.ProgramParser; +import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +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.Solver; +import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; +import at.ac.tuwien.kr.alpha.core.util.Util; import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.grounder.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation; -import at.ac.tuwien.kr.alpha.solver.Solver; -import at.ac.tuwien.kr.alpha.solver.SolverFactory; public class AlphaImpl { @@ -149,7 +149,7 @@ public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the * program analysis and normalization aren't of interest. */ - public Stream solve(InputProgram program) { + public Stream solve(InputProgram program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -157,7 +157,7 @@ public Stream solve(InputProgram program) { * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where * details of the program analysis and normalization aren't of interest. */ - public Stream solve(InputProgram program, java.util.function.Predicate filter) { + public Stream solve(InputProgram program, java.util.function.Predicate filter) { NormalProgram normalized = normalizeProgram(program); return solve(normalized, filter); } @@ -166,7 +166,7 @@ public Stream solve(InputProgram program, java.util.function.Predicat * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the * program analysis aren't of interest. */ - public Stream solve(NormalProgram program, java.util.function.Predicate filter) { + public Stream solve(NormalProgram program, java.util.function.Predicate filter) { InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); return solve(preprocessed, filter); } @@ -178,7 +178,7 @@ public Stream solve(NormalProgram program, java.util.function.Predica * @param program the program to solve * @return a stream of answer sets */ - public Stream solve(InternalProgram program) { + public Stream solve(InternalProgram program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -189,8 +189,8 @@ public Stream solve(InternalProgram program) { * @param filter {@link Predicate} filtering {@at.ac.tuwien.kr.alpha.common.Predicate}s in the returned answer sets * @return a Stream of answer sets representing stable models of the given program */ - public Stream solve(InternalProgram program, java.util.function.Predicate filter) { - Stream retVal = prepareSolverFor(program, filter).stream(); + public Stream solve(InternalProgram program, java.util.function.Predicate filter) { + Stream retVal = prepareSolverFor(program, filter).stream(); return config.isSortAnswerSets() ? retVal.sorted() : retVal; } From fdf165f7302ce65f66ce2e8105952853ab024c0f Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 19 Dec 2020 21:55:14 +0100 Subject: [PATCH 011/111] WIP: decouple core/public API --- .../kr/alpha/{common => api}/AnswerSet.java | 7 ++-- .../BindingPredicateInterpretation.java | 2 +- .../PredicateInterpretation.java | 8 ++--- .../alpha/{ => api}/config/AlphaConfig.java | 2 +- .../alpha/{ => api}/config/InputConfig.java | 6 ++-- .../alpha/{ => api}/config/SystemConfig.java | 8 ++--- .../GrounderHeuristicsConfiguration.java | 2 +- .../api/mapper/AnswerSetToObjectMapper.java | 2 +- .../api/mapper/AnswerSetToWorkbookMapper.java | 8 ++--- .../{common/atoms => api/program}/Atom.java | 8 ++--- .../atoms => api/program}/Literal.java | 7 ++-- .../{common => api/program}/Predicate.java | 2 +- .../tuwien/kr/alpha/api/program/Program.java | 4 +++ .../at/ac/tuwien/kr/alpha/api/rules/Head.java | 4 +++ .../at/ac/tuwien/kr/alpha/api/rules/Rule.java | 4 +++ ...ryNoGoodPropagationEstimationStrategy.java | 2 +- .../solver/heuristics/Heuristic.java | 2 +- .../kr/alpha/api/terms/ConstantTerm.java | 7 ++++ .../kr/alpha/{common => api}/terms/Term.java | 4 ++- .../kr/alpha/api/terms/VariableTerm.java | 5 +++ .../kr/alpha/common/program/Program.java | 4 --- .../ac/tuwien/kr/alpha/common/rules/Head.java | 4 --- .../ac/tuwien/kr/alpha/common/rules/Rule.java | 4 --- .../kr/alpha/common/terms/ConstantTerm.java | 4 --- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 10 +++--- .../kr/alpha/config/CommandLineParser.java | 8 +++-- .../alpha/core/api/CoreToPublicApiMapper.java | 11 ++++++ .../kr/alpha/core/api/PredicateWrapper.java | 34 +++++++++++++++++++ .../alpha/core/api/PublicToCoreApiMapper.java | 18 ++++++++++ .../kr/alpha/core/atoms/AggregateAtom.java | 4 +-- .../kr/alpha/core/atoms/AggregateLiteral.java | 4 +-- .../tuwien/kr/alpha/core/atoms/BasicAtom.java | 2 +- .../kr/alpha/core/atoms/BasicLiteral.java | 6 ++-- .../kr/alpha/core/atoms/ChoiceAtom.java | 4 +-- .../kr/alpha/core/atoms/ComparisonAtom.java | 2 +- .../alpha/core/atoms/ComparisonLiteral.java | 12 +++---- .../tuwien/kr/alpha/core/atoms/CoreAtom.java | 4 +-- .../kr/alpha/core/atoms/CoreLiteral.java | 4 +-- .../kr/alpha/core/atoms/EnumerationAtom.java | 6 ++-- .../alpha/core/atoms/EnumerationLiteral.java | 4 +-- .../kr/alpha/core/atoms/ExternalAtom.java | 6 ++-- .../kr/alpha/core/atoms/ExternalLiteral.java | 7 ++-- .../kr/alpha/core/atoms/IntervalAtom.java | 4 +-- .../kr/alpha/core/atoms/IntervalLiteral.java | 8 ++--- .../tuwien/kr/alpha/core/atoms/RuleAtom.java | 6 ++-- .../alpha/core/common/AnswerSetBuilder.java | 4 +-- .../BinaryPredicateInterpretation.java | 4 +-- .../BindingMethodPredicateInterpretation.java | 6 ++-- .../IntPredicateInterpretation.java | 4 +-- .../LongPredicateInterpretation.java | 4 +-- .../MethodPredicateInterpretation.java | 3 +- .../NonBindingPredicateInterpretation.java | 6 ++-- .../PredicateInterpretationImpl.java | 6 ++-- .../SuppliedPredicateInterpretation.java | 6 ++-- .../UnaryPredicateInterpretation.java | 4 +-- .../common/terms/ArithmeticTerm.java | 2 +- .../common/terms/CoreConstantTerm.java | 2 +- .../{ => core}/common/terms/CoreTerm.java | 3 +- .../{ => core}/common/terms/FunctionTerm.java | 2 +- .../{ => core}/common/terms/IntervalTerm.java | 2 +- .../alpha/{ => core}/common/terms/Terms.java | 2 +- .../{ => core}/common/terms/VariableTerm.java | 2 +- .../alpha/core/depgraph/DependencyGraph.java | 2 +- .../core/externals/AspStandardLibrary.java | 4 +-- .../kr/alpha/core/externals/Externals.java | 8 ++--- .../core/grounder/FactIntervalEvaluator.java | 6 +++- .../alpha/core/grounder/GrounderFactory.java | 8 +++-- .../core/grounder/IndexedInstanceStorage.java | 2 +- .../kr/alpha/core/grounder/Instance.java | 2 +- .../kr/alpha/core/grounder/NaiveGrounder.java | 4 +-- .../core/grounder/RuleGroundingOrders.java | 2 +- .../kr/alpha/core/grounder/Substitution.java | 8 ++--- .../kr/alpha/core/grounder/Unification.java | 6 ++-- .../kr/alpha/core/grounder/Unifier.java | 4 +-- .../AbstractLiteralInstantiationStrategy.java | 2 +- .../instantiation/LiteralInstantiator.java | 2 +- .../structure/AnalyzeUnjustified.java | 6 ++-- .../alpha/core/parser/ParseTreeVisitor.java | 12 +++++-- .../kr/alpha/core/parser/ProgramParser.java | 2 +- .../alpha/core/parser/ProgramPartParser.java | 4 +-- .../kr/alpha/core/programs/Programs.java | 2 +- .../CardinalityNormalization.java | 8 ++--- .../transformation/ChoiceHeadToNormal.java | 7 ++-- .../IntervalTermToIntervalAtom.java | 8 ++--- .../transformation/SumNormalization.java | 8 ++--- .../VariableEqualityRemoval.java | 4 +-- .../kr/alpha/core/rules/InternalRule.java | 2 +- .../kr/alpha/core/rules/heads/ChoiceHead.java | 2 +- .../BinaryNoGoodPropagationEstimation.java | 2 +- .../kr/alpha/core/solver/DefaultSolver.java | 4 +-- .../core/solver/NoGoodStoreAlphaRoaming.java | 2 +- .../kr/alpha/core/solver/SolverFactory.java | 2 +- .../heuristics/DependencyDrivenVSIDS.java | 2 +- .../solver/heuristics/HeapOfActiveAtoms.java | 2 +- .../heuristics/HeuristicsConfiguration.java | 4 +-- .../HeuristicsConfigurationBuilder.java | 4 +-- .../kr/alpha/core/solver/heuristics/MOMs.java | 2 +- .../alpha/core/solver/heuristics/VSIDS.java | 2 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 20 ++++++----- 99 files changed, 304 insertions(+), 203 deletions(-) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{common => api}/AnswerSet.java (62%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/common/fixedinterpretations/BindingPredicateInterpretation.java (77%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/common/fixedinterpretations/PredicateInterpretation.java (92%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/config/AlphaConfig.java (92%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/config/InputConfig.java (96%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/config/SystemConfig.java (97%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/grounder/heuristics/GrounderHeuristicsConfiguration.java (99%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{common/atoms => api/program}/Atom.java (81%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{common/atoms => api/program}/Literal.java (58%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{common => api/program}/Predicate.java (69%) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Head.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/solver/BinaryNoGoodPropagationEstimationStrategy.java (94%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{ => api}/solver/heuristics/Heuristic.java (94%) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ConstantTerm.java rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/{common => api}/terms/Term.java (61%) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java delete mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java delete mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java delete mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java delete mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/terms/ArithmeticTerm.java (99%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/terms/CoreConstantTerm.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/terms/CoreTerm.java (97%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/terms/FunctionTerm.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/terms/IntervalTerm.java (98%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/terms/Terms.java (94%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/{ => core}/common/terms/VariableTerm.java (98%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java similarity index 62% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java index 11c98b9e6..63e9baefc 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/AnswerSet.java @@ -1,9 +1,10 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; +package at.ac.tuwien.kr.alpha.api; import java.util.SortedSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; + public interface AnswerSet extends Comparable { SortedSet getPredicates(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/BindingPredicateInterpretation.java similarity index 77% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/BindingPredicateInterpretation.java index e354d35a5..4517fa0f2 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/BindingPredicateInterpretation.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.fixedinterpretations; +package at.ac.tuwien.kr.alpha.api.common.fixedinterpretations; /** * This interface is used to mark predicate interpretations that might generate diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/PredicateInterpretation.java similarity index 92% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/PredicateInterpretation.java index 96f454b8e..4ee5cda19 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/common/fixedinterpretations/PredicateInterpretation.java @@ -25,14 +25,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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +package at.ac.tuwien.kr.alpha.api.common.fixedinterpretations; import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; + import static java.util.Collections.*; @FunctionalInterface diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/AlphaConfig.java similarity index 92% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/AlphaConfig.java index 86fbf473a..b0fb36409 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/AlphaConfig.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.config; +package at.ac.tuwien.kr.alpha.api.config; /** * Wrapper type for AlphaConfig and InputConfig. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/InputConfig.java similarity index 96% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/InputConfig.java index 12e5d3167..11ec4a41c 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/InputConfig.java @@ -1,7 +1,7 @@ -package at.ac.tuwien.kr.alpha.config; +package at.ac.tuwien.kr.alpha.api.config; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import java.util.*; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java similarity index 97% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java index 4f38c37ba..882c8ed18 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java @@ -25,11 +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.config; +package at.ac.tuwien.kr.alpha.api.config; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; +import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; import java.util.Arrays; import java.util.Collections; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/heuristics/GrounderHeuristicsConfiguration.java similarity index 99% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/heuristics/GrounderHeuristicsConfiguration.java index 9348af476..dec9e7334 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/heuristics/GrounderHeuristicsConfiguration.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.grounder.heuristics; +package at.ac.tuwien.kr.alpha.api.grounder.heuristics; /** * Contains configuration parameters for heuristics used by {@link at.ac.tuwien.kr.alpha.grounder.Grounder}s. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java index 8f745e556..2d45ff5b2 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.api.mapper; -import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.api.AnswerSet; /** * Copyright (c) 2020, the Alpha Team. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java index 4b7af303a..840d51243 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java @@ -39,10 +39,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; /** * Implementation of {@link AnswerSetToObjectMapper} that generates an office open xml workbook ("excel file") from a given answer set. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java similarity index 81% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java index 41bf3da32..4feea79ff 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java @@ -1,10 +1,10 @@ -package at.ac.tuwien.kr.alpha.common.atoms; - -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; +package at.ac.tuwien.kr.alpha.api.program; import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; + public interface Atom extends Comparable { Predicate getPredicate(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java similarity index 58% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java index 12b583fd2..c095a50f8 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java @@ -1,10 +1,9 @@ -package at.ac.tuwien.kr.alpha.common.atoms; - -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; +package at.ac.tuwien.kr.alpha.api.program; import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.Term; + public interface Literal { Atom getAtom(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java similarity index 69% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java index 28d5811e4..a6fb56a7b 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.api.program; public interface Predicate extends Comparable { String getName(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java new file mode 100644 index 000000000..e429d0280 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.api.program; + +public interface Program { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Head.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Head.java new file mode 100644 index 000000000..581841ef8 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Head.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.api.rules; + +public interface Head { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java new file mode 100644 index 000000000..521baf919 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java @@ -0,0 +1,4 @@ +package at.ac.tuwien.kr.alpha.api.rules; + +public interface Rule { +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/solver/BinaryNoGoodPropagationEstimationStrategy.java similarity index 94% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/solver/BinaryNoGoodPropagationEstimationStrategy.java index bf3ad5242..ba4396cea 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/solver/BinaryNoGoodPropagationEstimationStrategy.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.api.solver; import java.util.Arrays; import java.util.stream.Collectors; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/solver/heuristics/Heuristic.java similarity index 94% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/solver/heuristics/Heuristic.java index f9aa16953..9fa008f99 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/solver/heuristics/Heuristic.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.solver.heuristics; +package at.ac.tuwien.kr.alpha.api.solver.heuristics; import java.util.Arrays; import java.util.stream.Collectors; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ConstantTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ConstantTerm.java new file mode 100644 index 000000000..c946bd6e5 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ConstantTerm.java @@ -0,0 +1,7 @@ +package at.ac.tuwien.kr.alpha.api.terms; + +public interface ConstantTerm> extends Term { + + T getObject(); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/Term.java similarity index 61% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/Term.java index 9aae02494..5c95dfe6d 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/Term.java @@ -1,5 +1,7 @@ -package at.ac.tuwien.kr.alpha.common.terms; +package at.ac.tuwien.kr.alpha.api.terms; public interface Term extends Comparable { + boolean isGround(); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java new file mode 100644 index 000000000..78eab1ea4 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.api.terms; + +public interface VariableTerm { + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java deleted file mode 100644 index 4327a4c0e..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.program; - -public interface Program { -} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java deleted file mode 100644 index 0b16a5ecf..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rules; - -public interface Head { -} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java deleted file mode 100644 index 35778c7fb..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rules; - -public interface Rule { -} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java deleted file mode 100644 index 795680347..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -public interface ConstantTerm> { -} 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 6b640134a..8c072c836 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 @@ -43,11 +43,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.Alpha; +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.impl.AlphaImpl; import at.ac.tuwien.kr.alpha.app.ComponentGraphWriter; import at.ac.tuwien.kr.alpha.app.DependencyGraphWriter; -import at.ac.tuwien.kr.alpha.config.AlphaConfig; import at.ac.tuwien.kr.alpha.config.CommandLineParser; -import at.ac.tuwien.kr.alpha.config.InputConfig; import at.ac.tuwien.kr.alpha.core.common.AnswerSetFormatter; import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.SimpleAnswerSetFormatter; @@ -79,7 +81,7 @@ public static void main(String[] args) { Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); } - AlphaImpl alpha = new AlphaImpl(cfg.getSystemConfig()); + Alpha alpha = new AlphaImpl(cfg.getSystemConfig()); InputProgram program = null; try { @@ -152,7 +154,7 @@ private static void writeComponentGraph(ComponentGraph cg, String path) { /** * Writes the given {@link InternalProgram} to the destination passed as the second parameter * - * @param prg the program to write + * @param prg the program to write * @param path the path to write the program to */ private static void writeInternalProgram(InternalProgram prg, String path) { diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java index dca1d5d90..100ceb974 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java @@ -27,8 +27,12 @@ */ package at.ac.tuwien.kr.alpha.config; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; +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.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; + import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java new file mode 100644 index 000000000..00a4e0543 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java @@ -0,0 +1,11 @@ +package at.ac.tuwien.kr.alpha.core.api; + +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; + +public class CoreToPublicApiMapper { + + public static Predicate mapPredicate(CorePredicate corePredicate) { + return new PredicateWrapper(corePredicate); + } +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.java new file mode 100644 index 000000000..860fc1f1f --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.kr.alpha.core.api; + +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; + +public class PredicateWrapper implements Predicate { + + private CorePredicate wrapped; + + public PredicateWrapper(CorePredicate corePredicate) { + this.wrapped = corePredicate; + } + + @Override + public int compareTo(Predicate o) { + return wrapped.compareTo(PublicToCoreApiMapper.mapPredicate(o)); + } + + @Override + public String getName() { + return wrapped.getName(); + } + + @Override + public int getArity() { + return wrapped.getArity(); + } + + @Override + public String toString() { + return wrapped.toString(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java new file mode 100644 index 000000000..bca0a8a72 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java @@ -0,0 +1,18 @@ +package at.ac.tuwien.kr.alpha.core.api; + +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; + +public class PublicToCoreApiMapper { + + public static CorePredicate mapPredicate(Predicate predicate) { + return CorePredicate.getInstance(predicate.getName(), predicate.getArity()); + } + + public static java.util.function.Predicate mapPredicateFilter(java.util.function.Predicate filter) { + return (coreApiPredicate) -> { + return filter.test(CoreToPublicApiMapper.mapPredicate(coreApiPredicate)); + }; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index fc789bb54..d3367fab8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -34,10 +34,10 @@ import java.util.LinkedList; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; public class AggregateAtom extends CoreAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index 6b33fac7d..d804e74ce 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -3,9 +3,9 @@ import java.util.HashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java index 48b035e07..5587ab9e0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java @@ -34,8 +34,8 @@ import java.util.List; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java index b4bfd6247..cae112a40 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java @@ -27,9 +27,9 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.Collections; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java index 8ba553004..dd8a2cb60 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java @@ -32,9 +32,9 @@ import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; public class ChoiceAtom extends CoreAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java index 99b81886d..229dfac0b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java @@ -31,9 +31,9 @@ import java.util.List; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index 927daa3ad..e7dd19bd6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm.evaluateGroundTerm; +import static at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm.evaluateGroundTerm; import java.util.Collections; import java.util.HashSet; @@ -35,12 +35,12 @@ import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index 82d40f359..981d8ffd6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -30,9 +30,9 @@ import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java index 092da5550..73a5607ff 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java @@ -27,9 +27,9 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import org.apache.commons.collections4.SetUtils; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 8c38af9c9..12437ff92 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -5,10 +5,10 @@ import java.util.HashMap; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java index 1c81a8408..7170fd55d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java @@ -4,8 +4,8 @@ import java.util.HashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index 005fbcc9a..1e93e749d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -27,11 +27,11 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.Term; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.terms.Term; import static at.ac.tuwien.kr.alpha.core.util.Util.join; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java index 806a6953c..87095b9b7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java @@ -27,8 +27,11 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.*; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.*; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java index d8d614a61..5fb846375 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java @@ -33,9 +33,9 @@ import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index 7f74bff26..9cfd77bd3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java @@ -34,10 +34,10 @@ import com.google.common.collect.Sets; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java index 964aa0a7b..f7171a9ac 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java @@ -27,14 +27,14 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm.getInstance; +import static at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm.getInstance; import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java index f3f24f3fc..7bd2c5481 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java @@ -10,10 +10,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; public class AnswerSetBuilder { private boolean firstInstance = true; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java index 922c7db56..d0f62b756 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BinaryPredicateInterpretation.java @@ -27,10 +27,10 @@ */ package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; + public class BinaryPredicateInterpretation extends NonBindingPredicateInterpretation { private final java.util.function.BiPredicate predicate; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java index 40c535674..aa62ee003 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java @@ -35,9 +35,9 @@ import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.BindingPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.BindingPredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; public class BindingMethodPredicateInterpretation implements BindingPredicateInterpretation { private final Method method; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java index d6460c689..dd8acc05e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/IntPredicateInterpretation.java @@ -27,10 +27,10 @@ */ package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; + public class IntPredicateInterpretation extends NonBindingPredicateInterpretation { private final java.util.function.IntPredicate predicate; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java index add4ac3ca..e5ef94663 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/LongPredicateInterpretation.java @@ -27,10 +27,10 @@ */ package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; + public class LongPredicateInterpretation extends NonBindingPredicateInterpretation { private final java.util.function.LongPredicate predicate; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java index 82aff6249..ff7dc78f6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/MethodPredicateInterpretation.java @@ -27,9 +27,10 @@ */ package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; import org.apache.commons.lang3.ClassUtils; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java index 81479a845..b6b25aacd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java @@ -27,9 +27,9 @@ */ package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +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; import java.util.ArrayList; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java index 4eb484758..f318557d8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java @@ -3,9 +3,9 @@ import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +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; public interface PredicateInterpretationImpl extends PredicateInterpretation { @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java index 301be3bd5..9c7fd4734 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java @@ -27,9 +27,9 @@ */ package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.BindingPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.BindingPredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; import java.util.List; import java.util.Set; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java index aa813ac2b..5e90b4712 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/UnaryPredicateInterpretation.java @@ -27,10 +27,10 @@ */ package at.ac.tuwien.kr.alpha.core.common.fixedinterpretations; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; + public class UnaryPredicateInterpretation extends NonBindingPredicateInterpretation { private final java.util.function.Predicate predicate; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java similarity index 99% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java index 8efd36688..27ad6e004 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.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.common.terms; +package at.ac.tuwien.kr.alpha.core.common.terms; import at.ac.tuwien.kr.alpha.core.common.Interner; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java index 7e2038416..4b31a2ebc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.terms; +package at.ac.tuwien.kr.alpha.core.common.terms; import at.ac.tuwien.kr.alpha.core.common.Interner; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java similarity index 97% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java index 3c55c2ef1..4f8a1083a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java @@ -1,9 +1,10 @@ -package at.ac.tuwien.kr.alpha.common.terms; +package at.ac.tuwien.kr.alpha.core.common.terms; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; //@formatter:off diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java index 7a8f9224b..61e638a05 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.terms; +package at.ac.tuwien.kr.alpha.core.common.terms; import at.ac.tuwien.kr.alpha.core.common.Interner; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java index 22d922993..577a4d088 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.terms; +package at.ac.tuwien.kr.alpha.core.common.terms; import at.ac.tuwien.kr.alpha.core.common.Interner; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java similarity index 94% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java index 7ba67d17a..e150dd7a5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.terms; +package at.ac.tuwien.kr.alpha.core.common.terms; import java.util.ArrayList; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTerm.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTerm.java index d81c75bfc..69f2b494c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common.terms; +package at.ac.tuwien.kr.alpha.core.common.terms; import at.ac.tuwien.kr.alpha.core.common.Interner; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java index c0cc010df..98bd02fed 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.api.program.*; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java index 79d0398ee..62c7c8bd2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java @@ -32,8 +32,8 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.externals.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Terms; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** * Collection of methods that can be used as external atoms from ASP programs. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java index 5e8480df2..9ad964735 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java @@ -25,11 +25,10 @@ */ package at.ac.tuwien.kr.alpha.core.externals; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.*; import at.ac.tuwien.kr.alpha.api.externals.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.*; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BinaryPredicateInterpretation; import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BindingMethodPredicateInterpretation; @@ -38,6 +37,7 @@ 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 at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import org.reflections.Reflections; import org.reflections.scanners.MethodAnnotationsScanner; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index a61bfc403..dff9ecf50 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -1,7 +1,11 @@ package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.api.terms.*; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import java.util.ArrayList; import java.util.Collections; 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 a4f4126a9..84b94b2c3 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 @@ -27,12 +27,13 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.config.InputConfig; +import at.ac.tuwien.kr.alpha.api.config.InputConfig; +import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.core.api.PublicToCoreApiMapper; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; public final class GrounderFactory { public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, @@ -50,6 +51,7 @@ public static Grounder getInstance(String name, InternalProgram program, AtomSto } public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, new GrounderHeuristicsConfiguration(), debugInternalChecks); + return getInstance(name, program, atomStore, PublicToCoreApiMapper.mapPredicateFilter(InputConfig.DEFAULT_FILTER), + new GrounderHeuristicsConfiguration(), debugInternalChecks); } } 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 b70716f9a..912355491 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 @@ -36,9 +36,9 @@ import java.util.Map; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; /** * A storage for instances with a certain arity, where each position of the instance can be indexed. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java index a314a6f3a..0686e439e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java @@ -5,8 +5,8 @@ import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.util.Util; /** 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 b0e003dd4..9262e5546 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 @@ -48,7 +48,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; @@ -62,6 +62,7 @@ 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.common.NoGoodInterface; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.BindingResult; @@ -72,7 +73,6 @@ 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.util.Util; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; /** * A semi-naive grounder. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java index 8571abcee..94faf9c12 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java @@ -37,9 +37,9 @@ import java.util.List; import java.util.Set; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java index f67f92b5f..84e431eac 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java @@ -35,12 +35,12 @@ import java.util.Set; import java.util.TreeMap; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; public class Substitution { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index 5cb8dfa54..e5d905044 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -31,10 +31,10 @@ import java.util.Set; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; /** * Copyright (c) 2017, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java index 884232f22..e2d7a39a9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java @@ -9,8 +9,8 @@ import java.util.Set; import java.util.TreeMap; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; /** * A variable substitution allowing variables to occur on the right-hand side. Chains of variable substitutions are diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java index 5678a6b96..d4c0a3701 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.core.grounder.instantiation; -import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.api.program.*; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; 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 68e0e615d..2de02f7a1 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 @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.core.grounder.instantiation; -import at.ac.tuwien.kr.alpha.common.atoms.*; +import at.ac.tuwien.kr.alpha.api.program.*; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationLiteral; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java index da5bea321..4fe6888ad 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java @@ -1,8 +1,6 @@ package at.ac.tuwien.kr.alpha.core.grounder.structure; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.api.program.*; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; @@ -10,6 +8,8 @@ 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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.Unification; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; 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 c6875d2e4..1cd0fe699 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 @@ -30,9 +30,9 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2BaseVisitor; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.program.*; +import at.ac.tuwien.kr.alpha.api.terms.*; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; @@ -47,6 +47,12 @@ import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHead; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java index 1f20e1ef2..58fbdb43f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java @@ -15,7 +15,7 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; public class ProgramParser { 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 7a7b17df2..384c2c3b5 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 @@ -30,9 +30,9 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; 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 42257785e..522efa1c4 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 @@ -6,7 +6,7 @@ import java.io.InputStream; import java.util.Map; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; public class Programs { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index 0df4e4922..5e66890cb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -7,15 +7,15 @@ import java.util.LinkedHashSet; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; 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 1376f1e2d..b6848a2f4 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,12 +27,15 @@ */ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.terms.*; +import at.ac.tuwien.kr.alpha.api.program.*; +import at.ac.tuwien.kr.alpha.api.terms.*; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHead; 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 c9606d6af..2ffb4e8ab 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 @@ -32,13 +32,13 @@ import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index 65bf6aa0f..cfbe97f21 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -7,15 +7,15 @@ import java.util.Iterator; import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; 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 1218cb39a..f4a3e8c5a 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,11 +37,11 @@ import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; 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 d073fe9a2..8d821cedc 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 @@ -32,11 +32,11 @@ import com.google.common.annotations.VisibleForTesting; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java index 014b0c1ae..4fd96bf73 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java @@ -4,10 +4,10 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; /** * Represents the head of a choice rule. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/BinaryNoGoodPropagationEstimation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/BinaryNoGoodPropagationEstimation.java index 1d7376753..326f1d866 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/BinaryNoGoodPropagationEstimation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/BinaryNoGoodPropagationEstimation.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; /** * Offers methods to estimate the effect of propagating binary nogoods. 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 8b23becd4..90971d645 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 @@ -50,8 +50,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; @@ -61,6 +60,7 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.ProgramAnalyzingGrounder; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java index eea788f99..cc7af5db8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java @@ -30,11 +30,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.NoGood; import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface; import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import java.util.ArrayList; import java.util.Arrays; 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 4485453cf..a89f1cc06 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 @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.config.SystemConfig; +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; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenVSIDS.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenVSIDS.java index 88f9be6ed..0732e794c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenVSIDS.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/DependencyDrivenVSIDS.java @@ -25,9 +25,9 @@ */ package at.ac.tuwien.kr.alpha.core.solver.heuristics; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import java.util.Random; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtoms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtoms.java index 1f542fede..bed2c8ccc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtoms.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtoms.java @@ -25,12 +25,12 @@ */ package at.ac.tuwien.kr.alpha.core.solver.heuristics; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.core.common.NoGood; import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type; import at.ac.tuwien.kr.alpha.core.solver.BinaryNoGoodPropagationEstimation; import at.ac.tuwien.kr.alpha.core.solver.ChoiceInfluenceManager; import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfiguration.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfiguration.java index 7980046b9..0351d1f04 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfiguration.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfiguration.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfigurationBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfigurationBuilder.java index 1b6aae211..cf0de642b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfigurationBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicsConfigurationBuilder.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/MOMs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/MOMs.java index 9c490b2c2..b2af4a40e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/MOMs.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/MOMs.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.core.solver.heuristics; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.core.solver.BinaryNoGoodPropagationEstimation; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; /** * The well-known MOMs (Maximum Occurrences in clauses of Minimum size) heuristic diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java index 0eebfc44c..cf67f4f32 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java @@ -39,13 +39,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.solver.BinaryNoGoodPropagationEstimationStrategy; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.NoGood; 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.BodyActivityProvider; import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; /** * This implementation is inspired by the VSIDS implementation in clasp. 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 649f0fa47..756e7eb1a 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 @@ -43,10 +43,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.Alpha; +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.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.api.PublicToCoreApiMapper; 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.CoreAnswerSet; @@ -63,9 +66,8 @@ import at.ac.tuwien.kr.alpha.core.solver.Solver; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; import at.ac.tuwien.kr.alpha.core.util.Util; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -public class AlphaImpl { +public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); @@ -168,7 +170,7 @@ public Stream solve(InputProgram program, java.util.function.Pred */ public Stream solve(NormalProgram program, java.util.function.Predicate filter) { InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); - return solve(preprocessed, filter); + return solve(preprocessed, PublicToCoreApiMapper.mapPredicateFilter(filter)); } /** @@ -179,14 +181,14 @@ public Stream solve(NormalProgram program, java.util.function.Pre * @return a stream of answer sets */ public Stream solve(InternalProgram program) { - return solve(program, InputConfig.DEFAULT_FILTER); + return solve(program, PublicToCoreApiMapper.mapPredicateFilter(InputConfig.DEFAULT_FILTER)); } /** * 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 {@at.ac.tuwien.kr.alpha.common.Predicate}s in the returned answer sets * @return a Stream of answer sets representing stable models of the given program */ public Stream solve(InternalProgram program, java.util.function.Predicate filter) { From 0fbd63e41c819d7be7ba806682126762a134dda3 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 4 Jan 2021 19:04:38 +0100 Subject: [PATCH 012/111] WIP: design published API --- .../PredicateInterpretation.java | 2 +- .../ac/tuwien/kr/alpha/api/program/Atom.java | 2 +- .../alpha/api/program/InlineDirectives.java | 5 +++ .../kr/alpha/api/program/InputProgram.java | 20 +++++++++ .../kr/alpha/api/program/Predicate.java | 11 +++++ .../kr/alpha/api/program/ProgramParser.java | 42 +++++++++++++++++++ .../tuwien/kr/alpha/api/rules/ChoiceHead.java | 5 +++ .../kr/alpha/api/rules/DisjunctiveHead.java | 5 +++ .../tuwien/kr/alpha/api/rules/NormalHead.java | 5 +++ .../at/ac/tuwien/kr/alpha/api/rules/Rule.java | 10 ++++- .../alpha/core/api/CoreToPublicApiMapper.java | 11 ----- .../kr/alpha/core/api/PredicateWrapper.java | 34 --------------- .../alpha/core/api/PublicToCoreApiMapper.java | 21 +++++++--- .../kr/alpha/core/atoms/ExternalAtom.java | 31 +++++++------- .../kr/alpha/core/common/CorePredicate.java | 15 ++----- .../BindingMethodPredicateInterpretation.java | 2 +- .../NonBindingPredicateInterpretation.java | 2 +- .../PredicateInterpretationImpl.java | 2 +- .../SuppliedPredicateInterpretation.java | 2 +- .../alpha/core/grounder/AbstractGrounder.java | 6 +-- .../alpha/core/grounder/BridgedGrounder.java | 4 +- .../alpha/core/grounder/GrounderFactory.java | 11 +++-- .../kr/alpha/core/grounder/NaiveGrounder.java | 3 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 21 +++++----- 24 files changed, 165 insertions(+), 107 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/DisjunctiveHead.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.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 4ee5cda19..655fff135 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 @@ -42,5 +42,5 @@ public interface PredicateInterpretation { 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-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java index 4feea79ff..e7e0a283d 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java @@ -8,7 +8,7 @@ public interface Atom extends Comparable { Predicate getPredicate(); - List getTerms(); + List getTerms(); /** * Returns whether this atom is ground, i.e., variable-free. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java new file mode 100644 index 000000000..fc17bc531 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.api.program; + +public interface InlineDirectives { + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java new file mode 100644 index 000000000..68a5f2d24 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java @@ -0,0 +1,20 @@ +package at.ac.tuwien.kr.alpha.api.program; + +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; +import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; + +public interface InputProgram extends Program{ + + InlineDirectives getInlineDirectives(); + + Set> getChoiceRules(); + + Set> getDisjunctiveRules(); + + Set> getNormalRules(); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java index a6fb56a7b..085259bd3 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java @@ -4,4 +4,15 @@ public interface Predicate extends Comparable { String getName(); int getArity(); + + @Override + default int compareTo(Predicate other) { + int result = getName().compareTo(other.getName()); + + if (result != 0) { + return result; + } + + return Integer.compare(getArity(), other.getArity()); + } } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java new file mode 100644 index 000000000..9e6b7c20a --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java @@ -0,0 +1,42 @@ +package at.ac.tuwien.kr.alpha.api.program; + +import java.io.InputStream; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; + +public interface ProgramParser { + + default Program parse(String programString) { + return parse(programString, Collections.emptyMap()); + } + + default Program parse(InputStream programSource) { + return parse(programSource, Collections.emptyMap()); + } + + default Program parse(Path programPath) { + return parse(programPath, Collections.emptyMap()); + } + + default Program parse(Path... programSources) { + return parse(Collections.emptyMap(), programSources); + } + + default Program parse(Iterable programSources) { + return parse(programSources, Collections.emptyMap()); + } + + Program parse(String programString, Map externalPredicateDefinitions); + + Program parse(InputStream programSource, Map externalPredicateDefinitions); + + Program parse(Path programPath, Map externalPredicateDefinitions); + + Program parse(Map externalPredicateDefinitions, Path... programSources); + + Program parse(Iterable programSources, Map externalPredicateDefinitions); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java new file mode 100644 index 000000000..893295604 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.api.rules; + +public interface ChoiceHead extends Head{ + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/DisjunctiveHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/DisjunctiveHead.java new file mode 100644 index 000000000..13ef2fd94 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/DisjunctiveHead.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.api.rules; + +public interface DisjunctiveHead extends Head{ + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java new file mode 100644 index 000000000..ed4d33679 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.api.rules; + +public interface NormalHead extends Head{ + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java index 521baf919..315d769bd 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java @@ -1,4 +1,12 @@ package at.ac.tuwien.kr.alpha.api.rules; -public interface Rule { +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.program.Literal; + +public interface Rule { + + H getHead(); + + Set getBody(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java deleted file mode 100644 index 00a4e0543..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/CoreToPublicApiMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.api; - -import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; - -public class CoreToPublicApiMapper { - - public static Predicate mapPredicate(CorePredicate corePredicate) { - return new PredicateWrapper(corePredicate); - } -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.java deleted file mode 100644 index 860fc1f1f..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PredicateWrapper.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.api; - -import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; - -public class PredicateWrapper implements Predicate { - - private CorePredicate wrapped; - - public PredicateWrapper(CorePredicate corePredicate) { - this.wrapped = corePredicate; - } - - @Override - public int compareTo(Predicate o) { - return wrapped.compareTo(PublicToCoreApiMapper.mapPredicate(o)); - } - - @Override - public String getName() { - return wrapped.getName(); - } - - @Override - public int getArity() { - return wrapped.getArity(); - } - - @Override - public String toString() { - return wrapped.toString(); - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java index bca0a8a72..4cd3b887b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java @@ -1,18 +1,29 @@ package at.ac.tuwien.kr.alpha.core.api; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +/** + * Maps between public (i.e. published) API types residing in the alpha-api module and implementations used by the solver + * internally. + * + * Copyright (c) 2020-2021, the Alpha Team. + */ public class PublicToCoreApiMapper { public static CorePredicate mapPredicate(Predicate predicate) { - return CorePredicate.getInstance(predicate.getName(), predicate.getArity()); + if (predicate instanceof CorePredicate) { + return (CorePredicate) predicate; + } else { + return CorePredicate.getInstance(predicate.getName(), predicate.getArity()); + } } - public static java.util.function.Predicate mapPredicateFilter(java.util.function.Predicate filter) { - return (coreApiPredicate) -> { - return filter.test(CoreToPublicApiMapper.mapPredicate(coreApiPredicate)); - }; + public static CoreAtom mapAtom(Atom atom) { + // TODO + return null; } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index 1e93e749d..718ab820c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -27,27 +27,26 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.terms.Term; - import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { - private final List input; - private final List output; + private final List input; + private final List output; protected final CorePredicate predicate; protected final PredicateInterpretation interpretation; - public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { + public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { if (predicate == null) { throw new IllegalArgumentException("predicate must not be null!"); } @@ -79,16 +78,16 @@ public PredicateInterpretation getInterpretation() { return interpretation; } - public List getInput() { + public List getInput() { return Collections.unmodifiableList(input); } - public List getOutput() { + public List getOutput() { return Collections.unmodifiableList(output); } @Override - public List getTerms() { + public List getTerms() { return input; } @@ -109,8 +108,8 @@ public boolean isGround() { @Override public ExternalAtom 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()); + 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 ExternalAtom(predicate, interpretation, substitutedInput, substitutedOutput); } @@ -172,8 +171,8 @@ public boolean equals(Object obj) { @Override public ExternalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedInput = CoreTerm.renameTerms(this.input, prefix + "_IN_", counterStartingValue); - List renamedOutput = CoreTerm.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); + List renamedInput = CoreTerm.renameTerms(this.input, prefix + "_IN_", counterStartingValue); + List renamedOutput = CoreTerm.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); return new ExternalAtom(this.predicate, this.interpretation, renamedInput, renamedOutput); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java index 9453c8095..ff16f9163 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java @@ -1,11 +1,13 @@ package at.ac.tuwien.kr.alpha.core.common; +import at.ac.tuwien.kr.alpha.api.program.Predicate; + /** * A predicate as used by the Alpha solver internally. * * Copyright (c) 2016-2020, the Alpha Team. */ -public class CorePredicate implements Comparable { +public class CorePredicate implements Predicate { private static final Interner INTERNER = new Interner<>(); @@ -82,20 +84,11 @@ public boolean isSolverInternal() { } @Override - public int compareTo(CorePredicate other) { - int result = getName().compareTo(other.getName()); - - if (result != 0) { - return result; - } - - return Integer.compare(getArity(), other.getArity()); - } - public String getName() { return name; } + @Override public int getArity() { return arity; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java index aa62ee003..a73aae4b2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/BindingMethodPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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() + ". " + diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java index b6b25aacd..53ad2350b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/NonBindingPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/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-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java index f318557d8..c1ec0df75 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/PredicateInterpretationImpl.java @@ -9,5 +9,5 @@ public interface PredicateInterpretationImpl extends PredicateInterpretation { @Override - Set>> evaluate(List terms); + Set>> evaluate(List terms); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java index 9c7fd4734..a29adffbf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/fixedinterpretations/SuppliedPredicateInterpretation.java @@ -43,7 +43,7 @@ public SuppliedPredicateInterpretation(Supplier>>> supp } @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-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java index 4c6291cb4..1280e5728 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java @@ -1,14 +1,14 @@ package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.api.program.Predicate; /** * Copyright (c) 2016, the Alpha Team. */ public abstract class AbstractGrounder implements Grounder { - protected final java.util.function.Predicate filter; + protected final java.util.function.Predicate filter; - protected AbstractGrounder(java.util.function.Predicate filter) { + protected AbstractGrounder(java.util.function.Predicate filter) { this.filter = filter; } 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 ade4911a3..6914bb1c4 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 @@ -3,16 +3,16 @@ import java.util.HashSet; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.CorePredicate; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; public abstract class BridgedGrounder extends AbstractGrounder { protected final Bridge[] bridges; - protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { + protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { super(filter); this.bridges = bridges; } 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 84b94b2c3..99172fd66 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 @@ -29,14 +29,13 @@ import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.core.api.PublicToCoreApiMapper; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; public final class GrounderFactory { - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { switch (name.toLowerCase()) { case "naive": @@ -44,14 +43,14 @@ public static Grounder getInstance(String name, InternalProgram program, AtomSto } throw new IllegalArgumentException("Unknown grounder requested."); } - - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + + public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { return getInstance(name, program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); } public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, PublicToCoreApiMapper.mapPredicateFilter(InputConfig.DEFAULT_FILTER), + return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, new GrounderHeuristicsConfiguration(), debugInternalChecks); } } 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 9262e5546..9c2d89df4 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 @@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; @@ -113,7 +114,7 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, bridges); } - NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { super(filter, bridges); this.atomStore = atomStore; this.heuristicsConfiguration = heuristicsConfiguration; 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 756e7eb1a..c43948683 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 @@ -44,16 +44,15 @@ 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.common.fixedinterpretations.PredicateInterpretation; 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.grounder.heuristics.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.core.api.PublicToCoreApiMapper; 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.CoreAnswerSet; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; 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.ProgramParser; @@ -151,7 +150,7 @@ public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the * program analysis and normalization aren't of interest. */ - public Stream solve(InputProgram program) { + public Stream solve(InputProgram program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -159,7 +158,7 @@ public Stream solve(InputProgram program) { * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where * details of the program analysis and normalization aren't of interest. */ - public Stream solve(InputProgram program, java.util.function.Predicate filter) { + public Stream solve(InputProgram program, java.util.function.Predicate filter) { NormalProgram normalized = normalizeProgram(program); return solve(normalized, filter); } @@ -168,9 +167,9 @@ public Stream solve(InputProgram program, java.util.function.Pred * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the * program analysis aren't of interest. */ - public Stream solve(NormalProgram program, java.util.function.Predicate filter) { + public Stream solve(NormalProgram program, java.util.function.Predicate filter) { InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); - return solve(preprocessed, PublicToCoreApiMapper.mapPredicateFilter(filter)); + return solve(preprocessed, filter); } /** @@ -180,8 +179,8 @@ public Stream solve(NormalProgram program, java.util.function.Pre * @param program the program to solve * @return a stream of answer sets */ - public Stream solve(InternalProgram program) { - return solve(program, PublicToCoreApiMapper.mapPredicateFilter(InputConfig.DEFAULT_FILTER)); + public Stream solve(InternalProgram program) { + return solve(program, InputConfig.DEFAULT_FILTER); } /** @@ -191,8 +190,8 @@ public Stream solve(InternalProgram program) { * @param filter {@link Predicate} filtering {@at.ac.tuwien.kr.alpha.common.Predicate}s in the returned answer sets * @return a Stream of answer sets representing stable models of the given program */ - public Stream solve(InternalProgram program, java.util.function.Predicate filter) { - Stream retVal = prepareSolverFor(program, filter).stream(); + public Stream solve(InternalProgram program, java.util.function.Predicate filter) { + Stream retVal = prepareSolverFor(program, filter).stream(); return config.isSortAnswerSets() ? retVal.sorted() : retVal; } @@ -205,7 +204,7 @@ public Stream solve(InternalProgram program, java.util.function.P * set stream from the solver. * @return a solver (and accompanying grounder) instance pre-loaded with the given program. */ - public Solver prepareSolverFor(InternalProgram program, java.util.function.Predicate filter) { + public Solver prepareSolverFor(InternalProgram program, java.util.function.Predicate filter) { String grounderName = config.getGrounderName(); boolean doDebugChecks = config.isDebugInternalChecks(); From 5e38c33db360cbfdb9143618bac4a3dddb502760 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 22 Jan 2021 16:25:00 +0100 Subject: [PATCH 013/111] WIP: make parser conform to public API --- .../tuwien/kr/alpha/api/program/Program.java | 10 + .../kr/alpha/api/program/ProgramParser.java | 20 +- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 4 +- .../tuwien/kr/alpha/core/atoms/CoreAtom.java | 7 +- .../kr/alpha/core/atoms/CoreLiteral.java | 13 +- .../kr/alpha/core/common/terms/CoreTerm.java | 7 +- .../alpha/core/parser/ParseTreeVisitor.java | 139 +++++++------ ...gramParser.java => ProgramParserImpl.java} | 54 +++++- .../alpha/core/parser/ProgramPartParser.java | 2 +- .../alpha/core/programs/AbstractProgram.java | 45 ++--- .../kr/alpha/core/programs/InputProgram.java | 116 ----------- .../alpha/core/programs/InputProgramImpl.java | 183 ++++++++++++++++++ .../kr/alpha/core/programs/NormalProgram.java | 2 +- .../kr/alpha/core/programs/Programs.java | 6 +- .../CardinalityNormalization.java | 24 +-- .../transformation/ChoiceHeadToNormal.java | 14 +- .../transformation/EnumerationRewriting.java | 14 +- .../IntervalTermToIntervalAtom.java | 6 +- .../NormalizeProgramTransformation.java | 8 +- .../transformation/PredicateInternalizer.java | 12 +- .../transformation/SumNormalization.java | 24 +-- .../VariableEqualityRemoval.java | 4 +- .../kr/alpha/core/rules/InternalRule.java | 8 +- .../kr/alpha/core/rules/NormalRule.java | 12 +- .../ac/tuwien/kr/alpha/core/rules/Rules.java | 30 +++ .../{NormalHead.java => NormalHeadImpl.java} | 18 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 32 +-- 27 files changed, 486 insertions(+), 328 deletions(-) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{ProgramParser.java => ProgramParserImpl.java} (73%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/{NormalHead.java => NormalHeadImpl.java} (70%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java index e429d0280..859899561 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java @@ -1,4 +1,14 @@ package at.ac.tuwien.kr.alpha.api.program; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; + public interface Program { + + Set getFacts(); + + Set> getRules(); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java index 9e6b7c20a..d2fe80171 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java @@ -9,34 +9,34 @@ public interface ProgramParser { - default Program parse(String programString) { + default InputProgram parse(String programString) { return parse(programString, Collections.emptyMap()); } - default Program parse(InputStream programSource) { + default InputProgram parse(InputStream programSource) { return parse(programSource, Collections.emptyMap()); } - default Program parse(Path programPath) { + default InputProgram parse(Path programPath) { return parse(programPath, Collections.emptyMap()); } - default Program parse(Path... programSources) { + default InputProgram parse(Path... programSources) { return parse(Collections.emptyMap(), programSources); } - default Program parse(Iterable programSources) { + default InputProgram parse(Iterable programSources) { return parse(programSources, Collections.emptyMap()); } - Program parse(String programString, Map externalPredicateDefinitions); + InputProgram parse(String programString, Map externalPredicateDefinitions); - Program parse(InputStream programSource, Map externalPredicateDefinitions); + InputProgram parse(InputStream programSource, Map externalPredicateDefinitions); - Program parse(Path programPath, Map externalPredicateDefinitions); + InputProgram parse(Path programPath, Map externalPredicateDefinitions); - Program parse(Map externalPredicateDefinitions, Path... programSources); + InputProgram parse(Map externalPredicateDefinitions, Path... programSources); - Program parse(Iterable programSources, Map externalPredicateDefinitions); + InputProgram parse(Iterable programSources, Map externalPredicateDefinitions); } 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 8c072c836..f2e2ae8fb 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 @@ -56,7 +56,7 @@ import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -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.NormalProgram; import at.ac.tuwien.kr.alpha.core.solver.Solver; @@ -83,7 +83,7 @@ public static void main(String[] args) { Alpha alpha = new AlphaImpl(cfg.getSystemConfig()); - InputProgram program = null; + InputProgramImpl program = null; try { program = alpha.readProgram(cfg.getInputConfig()); } catch (RecognitionException e) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index 981d8ffd6..2cbf02e3b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; @@ -39,7 +40,7 @@ /** * An Atom is the common superclass of all representations of ASP atoms used by Alpha. */ -public abstract class CoreAtom implements Comparable{ +public abstract class CoreAtom implements Atom, Comparable { /** * Creates a new Atom that represents this Atom, but has the given term list instead. @@ -74,8 +75,8 @@ public Set getOccurringVariables() { * * @return true iff the terms of this atom contain no {@link VariableTerm}. */ - public abstract boolean isGround(); - + public abstract boolean isGround(); + /** * Creates a non-negated literal containing this atom. */ diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java index 73a5607ff..bb1250682 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java @@ -27,22 +27,23 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; +import java.util.List; +import java.util.Set; + +import org.apache.commons.collections4.SetUtils; + +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; -import org.apache.commons.collections4.SetUtils; - -import java.util.List; -import java.util.Set; - /** * A potentially negated {@link CoreAtom} * * Copyright (c) 2017-2018, the Alpha Team. */ -public abstract class CoreLiteral { +public abstract class CoreLiteral implements Literal { protected final CoreAtom atom; protected final boolean positive; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java index 4f8a1083a..8371b27fb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java @@ -5,6 +5,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; //@formatter:off @@ -32,7 +33,7 @@ * Copyright (c) 2016-2020, the Alpha Team. */ //@formatter:on -public abstract class CoreTerm implements Comparable { +public abstract class CoreTerm implements Term { public abstract List getOccurringVariables(); @@ -57,12 +58,12 @@ private static int priority(CoreTerm term) { } @Override - public int compareTo(CoreTerm o) { + public int compareTo(Term o) { return o == null ? 1 : Integer.compare(priority(this), priority(o)); } public abstract boolean isGround(); - + /** * Rename all variables occurring in this Term by prefixing their name. * 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 1cd0fe699..45702f739 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 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016-2018, the Alpha Team. + * Copyright (c) 2016-2021, the Alpha Team. * All rights reserved. *

      * Additional changes made by Siemens. @@ -27,12 +27,32 @@ */ package at.ac.tuwien.kr.alpha.core.parser; +import static java.util.Collections.emptyList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.tree.TerminalNode; + import at.ac.tuwien.kr.alpha.antlr.ASPCore2BaseVisitor; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.program.*; -import at.ac.tuwien.kr.alpha.api.terms.*; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +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.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; @@ -52,28 +72,18 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHead; -import at.ac.tuwien.kr.alpha.core.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; - -import org.antlr.v4.runtime.RuleContext; -import org.antlr.v4.runtime.tree.TerminalNode; - -import java.util.*; - -import static java.util.Collections.emptyList; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.core.rules.Rules; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** - * Copyright (c) 2016-2018, the Alpha Team. + * Copyright (c) 2016-2021, the Alpha Team. */ 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) { @@ -92,7 +102,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 InputProgram translate(ASPCore2Parser.ProgramContext input) { + public InputProgramImpl translate(ASPCore2Parser.ProgramContext input) { return visitProgram(input); } @@ -142,19 +152,19 @@ public String visitTerminal(TerminalNode node) { } @Override - public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { + public InputProgramImpl visitProgram(ASPCore2Parser.ProgramContext ctx) { // program : statements? query?; if (ctx.query() != null) { throw notSupported(ctx.query()); } if (ctx.statements() == null) { - return InputProgram.EMPTY; + return InputProgramImpl.EMPTY; } inlineDirectives = new InlineDirectives(); - programBuilder = InputProgram.builder(); + programBuilder = InputProgramImpl.builder(); visitStatements(ctx.statements()); - programBuilder.addInlineDirectives(inlineDirectives); + programBuilder.addInlineDirectives(inlineDirectives); // TODO inline directives return programBuilder.build(); } @@ -170,27 +180,52 @@ public Object visitStatements(ASPCore2Parser.StatementsContext ctx) { @Override public Object visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { // head DOT - Head head = visitHead(ctx.head()); - if (head instanceof NormalHead) { - programBuilder.addFact(((NormalHead) head).getAtom()); + if (ctx.head().disjunction() != null) { + if (ctx.head().disjunction().disjunction() != null) { + // more than one disjunctive element + notSupported(ctx); + } else { + programBuilder.addFact(visitClassical_literal(ctx.head().disjunction().classical_literal())); + } } else { - // Treat facts with choice or disjunction in the head like a rule. - programBuilder.addRule(new BasicRule(head, emptyList())); + handleRule(ctx.head(), null); } return null; } + private void handleRule(ASPCore2Parser.HeadContext headCtx, ASPCore2Parser.BodyContext bodyCtx) { + List body = null; // TODO + if (headCtx == null) { + // constraint + programBuilder.addNormalRule(Rules.newConstraint(body)); + } else if (headCtx.disjunction() != null) { + // normal or disjunctive rule + if (headCtx.disjunction().disjunction() != null) { + // more than one disjunctive element + notSupported(headCtx); + } else { + programBuilder.addNormalRule(Rules.newNormalRule(visitClassical_literal(headCtx.disjunction().classical_literal()), body)); + } + } else if (headCtx.choice() != null) { + // choice rule + ChoiceHead head = visitChoice(headCtx.choice()); + programBuilder.addChoiceRule(Rules.newChoiceRule(head, body)); + } else { + notSupported(headCtx); + } + } + @Override public Object visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx) { // CONS body DOT - programBuilder.addRule(new BasicRule(null, visitBody(ctx.body()))); + handleRule(null, 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()))); + handleRule(ctx.head(), ctx.body()); return null; } @@ -209,25 +244,7 @@ public Object visitStatement_directive(ASPCore2Parser.Statement_directiveContext } @Override - public Head visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { - // disjunction : classical_literal (OR disjunction)?; - if (ctx.disjunction() != null) { - throw notSupported(ctx); - } - return new NormalHead(visitClassical_literal(ctx.classical_literal())); - } - - @Override - public Head visitHead(ASPCore2Parser.HeadContext ctx) { - // head : disjunction | choice; - if (ctx.choice() != null) { - return visitChoice(ctx.choice()); - } - return visitDisjunction(ctx.disjunction()); - } - - @Override - public Head visitChoice(ASPCore2Parser.ChoiceContext ctx) { + public ChoiceHead visitChoice(ASPCore2Parser.ChoiceContext ctx) { // choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; Term lt = null; ComparisonOperator lop = null; @@ -437,10 +454,9 @@ public ComparisonOperator visitBinop(ASPCore2Parser.BinopContext ctx) { public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { // builtin_atom : term binop term; return new ComparisonAtom( - (CoreTerm) visit(ctx.term(0)), - (CoreTerm) visit(ctx.term(1)), - visitBinop(ctx.binop()) - ); + (CoreTerm) visit(ctx.term(0)), + (CoreTerm) visit(ctx.term(1)), + visitBinop(ctx.binop())); } @Override @@ -546,11 +562,10 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) List outputTerms = visitTerms(ctx.output); return new ExternalAtom( - CorePredicate.getInstance(predicateName, outputTerms.size()), - interpretation, - visitTerms(ctx.input), - outputTerms - ); + CorePredicate.getInstance(predicateName, outputTerms.size()), + interpretation, + visitTerms(ctx.input), + outputTerms); } @Override @@ -559,8 +574,10 @@ public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) ASPCore2Parser.IntervalContext ictx = ctx.interval(); String lowerText = ictx.lower.getText(); String upperText = ictx.upper.getText(); - CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) : VariableTerm.getInstance(lowerText); - CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) : VariableTerm.getInstance(upperText); + CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) + : VariableTerm.getInstance(lowerText); + CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) + : VariableTerm.getInstance(upperText); return IntervalTerm.getInstance(lower, upper); } @@ -574,7 +591,7 @@ public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { // | term (TIMES | DIV | MODULO) term ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES - : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; + : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java similarity index 73% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java index 58fbdb43f..7a4f49ab7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParser.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java @@ -1,5 +1,11 @@ package at.ac.tuwien.kr.alpha.core.parser; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Map; + import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; @@ -9,27 +15,25 @@ import org.antlr.v4.runtime.atn.PredictionMode; import org.antlr.v4.runtime.misc.ParseCancellationException; -import java.io.IOException; -import java.util.Collections; -import java.util.Map; - import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.program.InputProgram; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -public class ProgramParser { +public class ProgramParserImpl implements ProgramParser { private final Map externals; - public ProgramParser(Map externals) { + public ProgramParserImpl(Map externals) { this.externals = externals; } - public ProgramParser() { + public ProgramParserImpl() { this(Collections.emptyMap()); } - public InputProgram parse(String s) { + public InputProgramImpl parse(String s) { try { return parse(CharStreams.fromString(s)); } catch (IOException e) { @@ -45,7 +49,7 @@ public InputProgram parse(String s) { } } - public InputProgram parse(CharStream stream) throws IOException { + public InputProgramImpl parse(CharStream stream) throws IOException { //@formatter:off /* * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. @@ -107,4 +111,34 @@ public InputProgram parse(CharStream stream) throws IOException { ParseTreeVisitor visitor = new ParseTreeVisitor(externals); return visitor.translate(programContext); } + + @Override + public InputProgram parse(String programString, Map externalPredicateDefinitions) { + // TODO Auto-generated method stub + return null; + } + + @Override + public InputProgram parse(InputStream programSource, Map externalPredicateDefinitions) { + // TODO Auto-generated method stub + return null; + } + + @Override + public InputProgram parse(Path programPath, Map externalPredicateDefinitions) { + // TODO Auto-generated method stub + return null; + } + + @Override + public InputProgram parse(Map externalPredicateDefinitions, Path... programSources) { + // TODO Auto-generated method stub + return null; + } + + @Override + public InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) { + // TODO Auto-generated method stub + return null; + } } 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 384c2c3b5..c23623ef4 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 java.util.Collections; /** - * 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 ProgramParserImpl}, does not parse full programs but only program parts like * atoms, terms and such. */ public class ProgramPartParser { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java index e090da23b..c36820296 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java @@ -1,52 +1,45 @@ package at.ac.tuwien.kr.alpha.core.programs; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; +import java.util.Collections; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.program.Program; import at.ac.tuwien.kr.alpha.core.rules.AbstractRule; import at.ac.tuwien.kr.alpha.core.rules.heads.Head; import at.ac.tuwien.kr.alpha.core.util.Util; -import java.util.Collections; -import java.util.List; - /** * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives) * - * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an implementation permits - * Copyright (c) 2019, the Alpha Team. + * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an + * implementation permits + * Copyright (c) 2019-2021, the Alpha Team. */ -public abstract class AbstractProgram> { +public abstract class AbstractProgram> implements Program { - private final List rules; - private final List facts; + private final Set facts; private final InlineDirectives inlineDirectives; - public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { - this.rules = rules; - this.facts = facts; + protected AbstractProgram(Set facts, InlineDirectives inlineDirectives) { + this.facts = Collections.unmodifiableSet(facts); this.inlineDirectives = inlineDirectives; } - public List getRules() { - return Collections.unmodifiableList(rules); - } - - public List getFacts() { - return Collections.unmodifiableList(facts); - } - - public InlineDirectives getInlineDirectives() { - return inlineDirectives; + @Override + public Set getFacts() { + return this.facts; } @Override public String toString() { final String ls = System.lineSeparator(); - final String result = facts.isEmpty() ? "" : Util.join("", facts, "." + ls, "." + ls); - if (rules.isEmpty()) { + final String result = this.getFacts().isEmpty() ? "" : Util.join("", this.getFacts(), "." + ls, "." + ls); + if (this.getRules().isEmpty()) { return result; } - return Util.join(result, rules, ls, ls); + return Util.join(result, this.getRules(), ls, ls); } } 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/InputProgram.java deleted file mode 100644 index 30ada5a7b..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright (c) 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.programs; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; - -/** - * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. - *

      - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class InputProgram extends AbstractProgram { - - public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectives()); - - public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { - super(rules, facts, inlineDirectives); - } - - public InputProgram() { - super(new ArrayList<>(), new ArrayList<>(), new InlineDirectives()); - } - - public static Builder builder() { - return new Builder(); - } - - public static Builder builder(InputProgram prog) { - return new Builder(prog); - } - - /** - * Builder for more complex program construction scenarios, ensuring that an {@link InputProgram} is immutable - */ - public static class Builder { - - private List rules = new ArrayList<>(); - private List facts = new ArrayList<>(); - private InlineDirectives inlineDirectives = new InlineDirectives(); - - public Builder(InputProgram prog) { - this.addRules(prog.getRules()); - this.addFacts(prog.getFacts()); - this.addInlineDirectives(prog.getInlineDirectives()); - } - - public Builder() { - - } - - public Builder addRules(List rules) { - this.rules.addAll(rules); - return this; - } - - public Builder addRule(BasicRule r) { - this.rules.add(r); - return this; - } - - public Builder addFacts(List facts) { - this.facts.addAll(facts); - return this; - } - - public Builder addFact(CoreAtom fact) { - this.facts.add(fact); - return this; - } - - public Builder addInlineDirectives(InlineDirectives inlineDirectives) { - this.inlineDirectives.accumulate(inlineDirectives); - return this; - } - - 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); - } - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java new file mode 100644 index 000000000..4e0d14fcc --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java @@ -0,0 +1,183 @@ +/** + * Copyright (c) 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.programs; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.commons.collections4.SetUtils; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.program.InputProgram; +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; +import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; + +/** + * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. + *

      + * Copyright (c) 2017-2021, the Alpha Team. + */ +public class InputProgramImpl extends AbstractProgram implements InputProgram { + + public static final InputProgramImpl EMPTY = null; // TODO + + private final Set> disjunctiveRules; + private final Set> choiceRules; + private final Set> normalRules; + + public InputProgramImpl(Set facts, Set> disjunctiveRules, Set> choiceRules, Set> normalRules, + InlineDirectives inlineDirectives) { + super(facts, inlineDirectives); + this.disjunctiveRules = Collections.unmodifiableSet(disjunctiveRules); + this.choiceRules = Collections.unmodifiableSet(choiceRules); + this.normalRules = Collections.unmodifiableSet(normalRules); + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(InputProgramImpl prog) { + return new Builder(prog); + } + + /** + * Builder for more complex program construction scenarios, ensuring that an {@link InputProgramImpl} is immutable + */ + public static class Builder { + + private Set> disjunctiveRules = new LinkedHashSet<>(); + private Set> choiceRules = new LinkedHashSet<>(); + private Set> normalRules = new LinkedHashSet<>(); + private Set facts = new LinkedHashSet<>(); + private InlineDirectives inlineDirectives = null; // TODO do inline directives properly + + public Builder(InputProgramImpl prog) { + this.addDisjunctiveRules(prog.getDisjunctiveRules()); + this.addChoiceRules(prog.getChoiceRules()); + this.addNormalRules(prog.getNormalRules()); + this.addFacts(prog.getFacts()); + this.addInlineDirectives(prog.getInlineDirectives()); + } + + public Builder() { + + } + + public Builder addDisjunctiveRules(Set> rules) { + this.disjunctiveRules.addAll(rules); + return this; + } + + public Builder addChoiceRules(Set> rules) { + this.choiceRules.addAll(rules); + return this; + } + + public Builder addNormalRules(Set> rules) { + this.normalRules.addAll(rules); + return this; + } + + public Builder addDisjunctiveRule(Rule r) { + this.disjunctiveRules.add(r); + return this; + } + + public Builder addChoiceRule(Rule r) { + this.choiceRules.add(r); + return this; + } + + public Builder addNormalRule(Rule r) { + this.normalRules.add(r); + return this; + } + + public Builder addFacts(Set facts) { + this.facts.addAll(facts); + return this; + } + + public Builder addFact(CoreAtom fact) { + this.facts.add(fact); + return this; + } + + public Builder addInlineDirectives(InlineDirectives inlineDirectives) { + // this.inlineDirectives.accumulate(inlineDirectives); TODO + return this; + } + + public Builder accumulate(InputProgramImpl prog) { + this.addDisjunctiveRules(prog.getDisjunctiveRules()); + this.addChoiceRules(prog.getChoiceRules()); + this.addNormalRules(prog.getNormalRules()); + this.addFacts(prog.getFacts()); + this.addInlineDirectives(prog.getInlineDirectives()); + return this; + } + + public InputProgramImpl build() { + return new InputProgramImpl(this.facts, this.disjunctiveRules, this.choiceRules, this.normalRules, this.inlineDirectives); + } + } + + @Override + public Set> getRules() { + return SetUtils.union(SetUtils.union(this.disjunctiveRules, this.choiceRules), this.normalRules); + } + + @Override + public at.ac.tuwien.kr.alpha.api.program.InlineDirectives getInlineDirectives() { + return this.getInlineDirectives(); + } + + @Override + public Set> getChoiceRules() { + return this.getChoiceRules(); + } + + @Override + public Set> getDisjunctiveRules() { + return this.getDisjunctiveRules(); + } + + @Override + public Set> getNormalRules() { + return this.getNormalRules(); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java index c7680703a..9bd061ab1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java @@ -19,7 +19,7 @@ public NormalProgram(List rules, List facts, InlineDirecti super(rules, facts, inlineDirectives); } - public static NormalProgram fromInputProgram(InputProgram inputProgram) { + public static NormalProgram fromInputProgram(InputProgramImpl inputProgram) { List normalRules = new ArrayList<>(); for (BasicRule r : inputProgram.getRules()) { normalRules.add(NormalRule.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 522efa1c4..e5d7d3329 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 java.util.Map; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; public class Programs { @@ -15,8 +15,8 @@ private Programs() { throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); } - public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { - ProgramParser parser = new ProgramParser(externals); + public static InputProgramImpl fromInputStream(InputStream is, Map externals) throws IOException { + ProgramParserImpl parser = new ProgramParserImpl(externals); return parser.parse(CharStreams.fromStream(is)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index 5e66890cb..31a297e45 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -18,18 +18,18 @@ import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +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.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Copyright (c) 2017-2020, the Alpha Team. */ -public class CardinalityNormalization extends ProgramTransformation { +public class CardinalityNormalization extends ProgramTransformation { private int aggregateCount; - private ProgramParser parser = new ProgramParser(); + private ProgramParserImpl parser = new ProgramParserImpl(); private final boolean useSortingCircuitEncoding; public CardinalityNormalization() { @@ -40,16 +40,16 @@ public CardinalityNormalization(boolean useSortingCircuitEncoding) { this.useSortingCircuitEncoding = useSortingCircuitEncoding; } - private InputProgram parse(String program) { + private InputProgramImpl parse(String program) { return parser.parse(program); } @Override - public InputProgram apply(InputProgram inputProgram) { + public InputProgramImpl apply(InputProgramImpl inputProgram) { if (!this.rewritingNecessary(inputProgram)) { return inputProgram; } - InputProgram.Builder programBuilder = InputProgram.builder(); + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); programBuilder.addFacts(inputProgram.getFacts()); programBuilder.addInlineDirectives(inputProgram.getInlineDirectives()); //@formatter:off @@ -92,7 +92,7 @@ public InputProgram apply(InputProgram inputProgram) { List rewrittenRules = rewriteAggregates(inputProgram.getRules()); String usedCardinalityEncoding = useSortingCircuitEncoding ? cardinalitySortingCircuit : cardinalityCountingGrid; - InputProgram cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParser().parse(usedCardinalityEncoding)); + InputProgramImpl cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParserImpl().parse(usedCardinalityEncoding)); programBuilder.addRules(rewrittenRules); // Add enumeration rule that uses the special EnumerationAtom. @@ -117,7 +117,7 @@ public InputProgram apply(InputProgram inputProgram) { * @param program the program. * @return true if count aggregates occur, false otherwise. */ - private boolean rewritingNecessary(InputProgram program) { + private boolean rewritingNecessary(InputProgramImpl program) { for (BasicRule rule : program.getRules()) { for (CoreLiteral lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { @@ -220,14 +220,14 @@ private List rewriteAggregatesInRule(BasicRule rule) { if (!globalVariables.isEmpty()) { elementLiterals.addAll(rewrittenBody); } - BasicRule inputRule = new BasicRule(new NormalHead(inputHeadAtom), elementLiterals); + BasicRule inputRule = new BasicRule(new NormalHeadImpl(inputHeadAtom), elementLiterals); additionalRules.add(inputRule); } // Create lower bound for the aggregate. BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateSubstitution); List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. - additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); + additionalRules.add(new BasicRule(new NormalHeadImpl(lowerBoundHeadAtom), lowerBoundBody)); } rewrittenBody.addAll(aggregateOutputAtoms); 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 b6848a2f4..0d61b17f6 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 @@ -36,11 +36,11 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -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.core.rules.heads.ChoiceHead; import at.ac.tuwien.kr.alpha.core.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; import java.util.ArrayList; import java.util.Iterator; @@ -49,12 +49,12 @@ /** * Copyright (c) 2017-2020, the Alpha Team. */ -public class ChoiceHeadToNormal extends ProgramTransformation { +public class ChoiceHeadToNormal extends ProgramTransformation { private final static String PREDICATE_NEGATION_PREFIX = "_n"; @Override - public InputProgram apply(InputProgram inputProgram) { - InputProgram.Builder programBuilder = InputProgram.builder(); + public InputProgramImpl apply(InputProgramImpl inputProgram) { + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); List additionalRules = new ArrayList<>(); List srcRules = new ArrayList<>(inputProgram.getRules()); @@ -102,11 +102,11 @@ public InputProgram apply(InputProgram inputProgram) { // Construct two guessing rules. List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); guessingRuleBodyWithNegHead.add(new BasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); - additionalRules.add(new BasicRule(new NormalHead(negHead), guessingRuleBodyWithNegHead)); + additionalRules.add(new BasicRule(new NormalHeadImpl(negHead), guessingRuleBodyWithNegHead)); List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); guessingRuleBodyWithHead.add(new BasicAtom(negPredicate, headTerms).toLiteral(false)); - additionalRules.add(new BasicRule(new NormalHead(head), guessingRuleBodyWithHead)); + additionalRules.add(new BasicRule(new NormalHeadImpl(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 ed601937c..bedacbb75 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 @@ -13,9 +13,9 @@ import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; -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.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Rewrites the ordinary atom whose name is given in the input program by the enumeration directive #enum_atom_is into @@ -23,10 +23,10 @@ * * Copyright (c) 2017-2020, the Alpha Team. */ -public class EnumerationRewriting extends ProgramTransformation { +public class EnumerationRewriting extends ProgramTransformation { @Override - public InputProgram apply(InputProgram inputProgram) { + public InputProgramImpl apply(InputProgramImpl inputProgram) { // Read enumeration predicate from directive. String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectives.DIRECTIVE.enum_predicate_is); if (enumDirective == null) { @@ -35,7 +35,7 @@ public InputProgram apply(InputProgram inputProgram) { } CorePredicate enumPredicate = CorePredicate.getInstance(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()); @@ -56,10 +56,10 @@ private void checkFactsAreEnumerationFree(List srcFacts, CorePredicate private List rewriteRules(List srcRules, CorePredicate enumPredicate) { List rewrittenRules = new ArrayList<>(); for (BasicRule rule : srcRules) { - if (rule.getHead() != null && !(rule.getHead() instanceof NormalHead)) { + if (rule.getHead() != null && !(rule.getHead() instanceof NormalHeadImpl)) { throw oops("Encountered rule whose head is not normal: " + rule); } - if (rule.getHead() != null && ((NormalHead) rule.getHead()).getAtom().getPredicate().equals(enumPredicate)) { + if (rule.getHead() != null && ((NormalHeadImpl) 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()); 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 2ffb4e8ab..7a88b3997 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 @@ -41,7 +41,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Rewrites all interval terms in a rule into a new variable and an IntervalAtom. @@ -65,8 +65,8 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { for (CoreLiteral literal : rule.getBody()) { rewrittenBody.add(rewriteLiteral(literal, intervalReplacements)); } - NormalHead rewrittenHead = rule.isConstraint() ? null : - new NormalHead(rewriteLiteral(rule.getHeadAtom().toLiteral(), intervalReplacements).getAtom()); + NormalHeadImpl rewrittenHead = rule.isConstraint() ? null : + new NormalHeadImpl(rewriteLiteral(rule.getHeadAtom().toLiteral(), intervalReplacements).getAtom()); // If intervalReplacements is empty, no IntervalTerms have been found, keep rule as is. if (intervalReplacements.isEmpty()) { 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 534247068..2b4bc7576 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.core.atoms.EnumerationAtom; -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.NormalProgram; /** @@ -9,7 +9,7 @@ * * Copyright (c) 2019-2020, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformation { +public class NormalizeProgramTransformation extends ProgramTransformation { private boolean useNormalizationGrid; @@ -18,8 +18,8 @@ public NormalizeProgramTransformation(boolean useNormalizationGrid) { } @Override - public NormalProgram apply(InputProgram inputProgram) { - InputProgram tmpPrg; + public NormalProgram apply(InputProgramImpl inputProgram) { + InputProgramImpl tmpPrg; // Transform choice rules. tmpPrg = new ChoiceHeadToNormal().apply(inputProgram); // Transform cardinality aggregates. 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 33159bdde..c72179f9b 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 @@ -8,10 +8,10 @@ import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -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.core.rules.heads.Head; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * @@ -21,8 +21,8 @@ */ public class PredicateInternalizer { - static InputProgram makePredicatesInternal(InputProgram program) { - InputProgram.Builder prgBuilder = InputProgram.builder(); + static InputProgramImpl makePredicatesInternal(InputProgramImpl program) { + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); for (CoreAtom atom : program.getFacts()) { prgBuilder.addFact(PredicateInternalizer.makePredicateInternal(atom)); } @@ -36,10 +36,10 @@ static InputProgram makePredicatesInternal(InputProgram program) { private static BasicRule makePredicateInternal(BasicRule rule) { Head newHead = null; if (rule.getHead() != null) { - if (!(rule.getHead() instanceof NormalHead)) { + if (!(rule.getHead() instanceof NormalHeadImpl)) { throw new UnsupportedOperationException("Cannot make predicates in rules internal whose head is not normal."); } - newHead = new NormalHead(makePredicateInternal(((NormalHead) rule.getHead()).getAtom())); + newHead = new NormalHeadImpl(makePredicateInternal(((NormalHeadImpl) rule.getHead()).getAtom())); } List newBody = new ArrayList<>(); for (CoreLiteral bodyElement : rule.getBody()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index cfbe97f21..96bfd5b6e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -17,10 +17,10 @@ import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +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.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Rewrites #sum aggregates into normal rules. @@ -28,17 +28,17 @@ * * Copyright (c) 2018-2020, the Alpha Team. */ -public class SumNormalization extends ProgramTransformation { +public class SumNormalization extends ProgramTransformation { private int aggregateCount; - private ProgramParser parser = new ProgramParser(); + private ProgramParserImpl parser = new ProgramParserImpl(); - private InputProgram parse(String program) { + private InputProgramImpl parse(String program) { return parser.parse(program); } @Override - public InputProgram apply(InputProgram inputProgram) { + public InputProgramImpl apply(InputProgramImpl inputProgram) { if (!rewritingNecessary(inputProgram)) { return inputProgram; } @@ -52,9 +52,9 @@ public InputProgram apply(InputProgram inputProgram) { // Connect/Rewrite every aggregate in each rule. List rewrittenRules = rewriteAggregates(inputProgram.getRules()); - InputProgram.Builder prgBuilder = InputProgram.builder(); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); prgBuilder.addFacts(inputProgram.getFacts()); - InputProgram summationEncoding = makePredicatesInternal(new ProgramParser().parse(summationSubprogram)); + InputProgramImpl summationEncoding = makePredicatesInternal(new ProgramParserImpl().parse(summationSubprogram)); prgBuilder.accumulate(summationEncoding); prgBuilder.addRules(rewrittenRules); @@ -76,7 +76,7 @@ public InputProgram apply(InputProgram inputProgram) { * @param program the program. * @return true if sum aggregates occur, false otherwise. */ - private boolean rewritingNecessary(InputProgram program) { + private boolean rewritingNecessary(InputProgramImpl program) { for (BasicRule rule : program.getRules()) { for (CoreLiteral lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { @@ -180,14 +180,14 @@ private List rewriteAggregatesInRule(BasicRule rule) { if (!globalVariables.isEmpty()) { elementLiterals.addAll(rewrittenBody); } - BasicRule inputRule = new BasicRule(new NormalHead(inputHeadAtom), elementLiterals); + BasicRule inputRule = new BasicRule(new NormalHeadImpl(inputHeadAtom), elementLiterals); additionalRules.add(inputRule); } // Create lower bound for the aggregate. BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateUnifier); List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. - additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); + additionalRules.add(new BasicRule(new NormalHeadImpl(lowerBoundHeadAtom), lowerBoundBody)); } if (aggregatesInRule > 0) { rewrittenBody.addAll(aggregateOutputAtoms); 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 f4a3e8c5a..dec0ed294 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 @@ -45,7 +45,7 @@ import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Removes variable equalities from rules by replacing one variable with the other. @@ -108,7 +108,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { } List rewrittenBody = new ArrayList<>(rule.getBody()); - NormalHead rewrittenHead = rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()); + NormalHeadImpl rewrittenHead = rule.isConstraint() ? null : new NormalHeadImpl(rule.getHeadAtom()); // Use substitution for actual replacement. Unifier replacementSubstitution = new Unifier(); 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 8d821cedc..5610d8594 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 @@ -40,7 +40,7 @@ import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Represents a normal rule or a constraint for the semi-naive grounder. @@ -56,7 +56,7 @@ public class InternalRule extends NormalRule { private final RuleGroundingOrders groundingOrders; - public InternalRule(NormalHead head, List body) { + public InternalRule(NormalHeadImpl head, List body) { super(head, body); if (body.isEmpty()) { throw new IllegalArgumentException( @@ -90,7 +90,7 @@ public static void resetIdGenerator() { } public static InternalRule fromNormalRule(NormalRule rule) { - return new InternalRule(rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()), new ArrayList<>(rule.getBody())); + return new InternalRule(rule.isConstraint() ? null : new NormalHeadImpl(rule.getHeadAtom()), new ArrayList<>(rule.getBody())); } /** @@ -117,7 +117,7 @@ public InternalRule renameVariables(String newVariablePostfix) { for (CoreLiteral literal : this.getBody()) { renamedBody.add(literal.substitute(variableReplacement)); } - return new InternalRule(new NormalHead(renamedHeadAtom), renamedBody); + return new InternalRule(new NormalHeadImpl(renamedHeadAtom), renamedBody); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java index a56d32e2f..5eadce6c0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java @@ -5,7 +5,7 @@ import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; import at.ac.tuwien.kr.alpha.core.util.Util; /** @@ -14,21 +14,21 @@ * * Copyright (c) 2019, the Alpha Team. */ -public class NormalRule extends AbstractRule { +public class NormalRule extends AbstractRule { - public NormalRule(NormalHead head, List body) { + public NormalRule(NormalHeadImpl head, List body) { super(head, body); } public static NormalRule fromBasicRule(BasicRule rule) { CoreAtom headAtom = null; if (!rule.isConstraint()) { - if (!(rule.getHead() instanceof NormalHead)) { + if (!(rule.getHead() instanceof NormalHeadImpl)) { 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(); + headAtom = ((NormalHeadImpl) rule.getHead()).getAtom(); } - return new NormalRule(headAtom != null ? new NormalHead(headAtom) : null, new ArrayList<>(rule.getBody())); + return new NormalRule(headAtom != null ? new NormalHeadImpl(headAtom) : null, new ArrayList<>(rule.getBody())); } public boolean isGround() { 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..150711de3 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java @@ -0,0 +1,30 @@ +package at.ac.tuwien.kr.alpha.core.rules; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; +import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; + +public class Rules { + + public static Rule newDisjunctiveRule(List disjunctiveAtoms, List body) { + return null; // TODO + } + + public static Rule newChoiceRule(ChoiceHead head, List body) { + return null; // TODO (also better params) + } + + public static Rule newNormalRule(Atom headAtom, List body) { + return null; // TODO + } + + public static Rule newConstraint(List body) { + return null; // TODO + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java similarity index 70% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHead.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java index af596b4cd..8d5c00802 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHead.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java @@ -1,25 +1,29 @@ package at.ac.tuwien.kr.alpha.core.rules.heads; +import java.util.Optional; + +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; /** * Represents a normal head, i.e., a head that is an Atom. * Copyright (c) 2019, the Alpha Team. */ -public class NormalHead extends Head { +public class NormalHeadImpl implements NormalHead { - private final CoreAtom atom; + private final Optional atom; - public NormalHead(CoreAtom atom) { + public NormalHeadImpl(Optional atom) { this.atom = atom; } // Note that at some point in the future it might make sense to have this method directly in Head public boolean isGround() { - return atom.isGround(); + // return atom.isGround(); TODO + return false; } - public CoreAtom getAtom() { + public Optional getAtom() { return atom; } @@ -44,10 +48,10 @@ public boolean equals(Object obj) { if (obj == null) { return false; } - if (!(obj instanceof NormalHead)) { + if (!(obj instanceof NormalHeadImpl)) { return false; } - NormalHead other = (NormalHead) obj; + NormalHeadImpl other = (NormalHeadImpl) obj; if (this.atom == null) { if (other.atom != null) { return false; 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 c43948683..c82447564 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 @@ -55,9 +55,9 @@ import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; 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.ProgramParser; +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.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.NormalProgram; import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; @@ -79,9 +79,9 @@ public AlphaImpl(SystemConfig cfg) { public AlphaImpl() { } - public InputProgram readProgram(InputConfig cfg) throws IOException { - InputProgram.Builder prgBuilder = InputProgram.builder(); - InputProgram tmpProg; + public InputProgramImpl readProgram(InputConfig cfg) throws IOException { + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); + InputProgramImpl tmpProg; if (!cfg.getFiles().isEmpty()) { tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); prgBuilder.accumulate(tmpProg); @@ -93,14 +93,14 @@ public InputProgram readProgram(InputConfig cfg) throws IOException { return prgBuilder.build(); } - public InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException { + public InputProgramImpl readProgramFiles(boolean literate, Map externals, List paths) throws IOException { return readProgramFiles(literate, externals, paths.stream().map(Paths::get).collect(Collectors.toList()).toArray(new Path[] {})); } - public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - ProgramParser parser = new ProgramParser(externals); - InputProgram.Builder prgBuilder = InputProgram.builder(); - InputProgram tmpProg; + public InputProgramImpl readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { + ProgramParserImpl parser = new ProgramParserImpl(externals); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); + InputProgramImpl tmpProg; for (Path path : paths) { CharStream stream; if (!literate) { @@ -114,16 +114,16 @@ public InputProgram readProgramFiles(boolean literate, Map externals) { - ProgramParser parser = new ProgramParser(externals); + public InputProgramImpl readProgramString(String aspString, Map externals) { + ProgramParserImpl parser = new ProgramParserImpl(externals); return parser.parse(aspString); } - public InputProgram readProgramString(String aspString) { + public InputProgramImpl readProgramString(String aspString) { return readProgramString(aspString, null); } - public NormalProgram normalizeProgram(InputProgram program) { + public NormalProgram normalizeProgram(InputProgramImpl program) { return new NormalizeProgramTransformation(config.isUseNormalizationGrid()).apply(program); } @@ -150,7 +150,7 @@ public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the * program analysis and normalization aren't of interest. */ - public Stream solve(InputProgram program) { + public Stream solve(InputProgramImpl program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -158,7 +158,7 @@ public Stream solve(InputProgram program) { * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where * details of the program analysis and normalization aren't of interest. */ - public Stream solve(InputProgram program, java.util.function.Predicate filter) { + public Stream solve(InputProgramImpl program, java.util.function.Predicate filter) { NormalProgram normalized = normalizeProgram(program); return solve(normalized, filter); } From a91b28225702f2760c8a1df6e3a2146d7857a168 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Sat, 23 Jan 2021 11:51:18 +0100 Subject: [PATCH 014/111] WIP: ParseTreeVisitor and Alpha conforming to new public API --- .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 26 + .../kr/alpha/core/atoms/AggregateAtom.java | 14 +- .../kr/alpha/core/atoms/AggregateLiteral.java | 18 +- .../kr/alpha/core/atoms/BasicLiteral.java | 10 +- .../alpha/core/atoms/ComparisonLiteral.java | 24 +- .../tuwien/kr/alpha/core/atoms/CoreAtom.java | 10 +- .../kr/alpha/core/atoms/CoreLiteral.java | 8 +- .../kr/alpha/core/atoms/EnumerationAtom.java | 6 +- .../alpha/core/atoms/EnumerationLiteral.java | 18 +- .../kr/alpha/core/atoms/ExternalLiteral.java | 22 +- .../kr/alpha/core/atoms/IntervalLiteral.java | 14 +- .../core/common/terms/ArithmeticTerm.java | 6 +- .../core/common/terms/CoreConstantTerm.java | 2 +- .../kr/alpha/core/common/terms/CoreTerm.java | 7 +- .../alpha/core/common/terms/FunctionTerm.java | 4 +- .../alpha/core/common/terms/IntervalTerm.java | 14 +- ...ariableTerm.java => VariableTermImpl.java} | 39 +- .../kr/alpha/core/grounder/NaiveGrounder.java | 6 +- .../core/grounder/RuleGroundingOrders.java | 8 +- .../kr/alpha/core/grounder/Substitution.java | 26 +- .../kr/alpha/core/grounder/Unification.java | 20 +- .../kr/alpha/core/grounder/Unifier.java | 30 +- .../structure/AnalyzeUnjustified.java | 4 +- ...ectives.java => InlineDirectivesImpl.java} | 8 +- .../alpha/core/parser/ParseTreeVisitor.java | 76 +- .../kr/alpha/core/programs/NormalProgram.java | 4 +- .../CardinalityNormalization.java | 10 +- .../transformation/ChoiceHeadToNormal.java | 8 +- .../transformation/EnumerationRewriting.java | 4 +- .../IntervalTermToIntervalAtom.java | 14 +- .../transformation/SumNormalization.java | 12 +- .../VariableEqualityRemoval.java | 24 +- .../kr/alpha/core/rules/InternalRule.java | 8 +- .../{ChoiceHead.java => ChoiceHeadImpl.java} | 9 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 8 + api/build.gradle | 11 - .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 4 - .../kr/alpha/api/externals/Predicate.java | 27 - .../api/mapper/AnswerSetToObjectMapper.java | 41 - .../api/mapper/AnswerSetToWorkbookMapper.java | 137 - .../ac/tuwien/kr/alpha/common/AnswerSet.java | 13 - .../ac/tuwien/kr/alpha/common/Predicate.java | 7 - .../ac/tuwien/kr/alpha/common/atoms/Atom.java | 29 - .../tuwien/kr/alpha/common/atoms/Literal.java | 20 - .../BindingPredicateInterpretation.java | 9 - .../PredicateInterpretation.java | 46 - .../kr/alpha/common/program/Program.java | 4 - .../ac/tuwien/kr/alpha/common/rules/Head.java | 4 - .../ac/tuwien/kr/alpha/common/rules/Rule.java | 4 - .../kr/alpha/common/terms/ConstantTerm.java | 4 - .../ac/tuwien/kr/alpha/common/terms/Term.java | 5 - .../tuwien/kr/alpha/config/AlphaConfig.java | 27 - .../tuwien/kr/alpha/config/InputConfig.java | 170 -- .../tuwien/kr/alpha/config/SystemConfig.java | 258 -- .../GrounderHeuristicsConfiguration.java | 148 - ...ryNoGoodPropagationEstimationStrategy.java | 27 - .../kr/alpha/solver/heuristics/Heuristic.java | 52 - cli/build.gradle | 40 - .../kr/alpha/AnswerSetToXlsxWriter.java | 60 - .../main/java/at/ac/tuwien/kr/alpha/Main.java | 234 -- .../kr/alpha/config/CliOptionHandler.java | 11 - .../kr/alpha/config/CommandLineParser.java | 482 --- cli/src/main/resources/logback.xml | 15 - core/build.gradle | 58 - .../kr/alpha/antlr/ASPCore2BaseVisitor.java | 350 --- .../tuwien/kr/alpha/antlr/ASPCore2Lexer.java | 218 -- .../tuwien/kr/alpha/antlr/ASPCore2Parser.java | 2632 ----------------- .../kr/alpha/antlr/ASPCore2Visitor.java | 319 -- .../at/ac/tuwien/kr/alpha/antlr/ASPLexer.java | 209 -- .../at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 | 90 - .../at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 | 50 - .../java/at/ac/tuwien/kr/alpha/AlphaImpl.java | 226 -- .../tuwien/kr/alpha/CustomErrorListener.java | 28 - .../main/java/at/ac/tuwien/kr/alpha/Util.java | 121 - .../kr/alpha/api/externals/Externals.java | 143 - .../externals/stdlib/AspStandardLibrary.java | 214 -- .../kr/alpha/common/AnswerSetBuilder.java | 99 - .../kr/alpha/common/AnswerSetFormatter.java | 6 - .../ac/tuwien/kr/alpha/common/Assignment.java | 184 -- .../ac/tuwien/kr/alpha/common/AtomStore.java | 120 - .../tuwien/kr/alpha/common/AtomStoreImpl.java | 132 - .../kr/alpha/common/BasicAnswerSet.java | 117 - .../kr/alpha/common/ComparisonOperator.java | 39 - .../tuwien/kr/alpha/common/CorePredicate.java | 107 - .../tuwien/kr/alpha/common/IntIterator.java | 20 - .../ac/tuwien/kr/alpha/common/Interner.java | 26 - .../ac/tuwien/kr/alpha/common/Literals.java | 83 - .../at/ac/tuwien/kr/alpha/common/NoGood.java | 288 -- .../kr/alpha/common/NoGoodInterface.java | 95 - .../common/SimpleAnswerSetFormatter.java | 33 - .../at/ac/tuwien/kr/alpha/common/Truth.java | 10 - .../kr/alpha/common/atoms/AggregateAtom.java | 269 -- .../alpha/common/atoms/AggregateLiteral.java | 64 - .../kr/alpha/common/atoms/BasicAtom.java | 166 -- .../kr/alpha/common/atoms/BasicLiteral.java | 105 - .../kr/alpha/common/atoms/ComparisonAtom.java | 128 - .../alpha/common/atoms/ComparisonLiteral.java | 218 -- .../kr/alpha/common/atoms/CoreAtom.java | 132 - .../kr/alpha/common/atoms/CoreLiteral.java | 122 - .../kr/alpha/common/atoms/ExternalAtom.java | 180 -- .../alpha/common/atoms/ExternalLiteral.java | 209 -- .../atoms/FixedInterpretationLiteral.java | 62 - .../atoms/VariableNormalizableAtom.java | 20 - .../alpha/common/depgraph/ComponentGraph.java | 201 -- .../common/depgraph/DependencyGraph.java | 167 -- .../depgraph/DepthFirstSearchAlgorithm.java | 117 - .../tuwien/kr/alpha/common/depgraph/Edge.java | 79 - .../tuwien/kr/alpha/common/depgraph/Node.java | 70 - .../depgraph/StratificationAlgorithm.java | 126 - .../StronglyConnectedComponentsAlgorithm.java | 118 - .../BinaryPredicateInterpretation.java | 50 - .../BindingMethodPredicateInterpretation.java | 97 - .../IntPredicateInterpretation.java | 48 - .../LongPredicateInterpretation.java | 48 - .../MethodPredicateInterpretation.java | 81 - .../NonBindingPredicateInterpretation.java | 78 - .../PredicateInterpretationImpl.java | 12 - .../SuppliedPredicateInterpretation.java | 51 - .../UnaryPredicateInterpretation.java | 46 - .../common/graphio/ComponentGraphWriter.java | 101 - .../common/graphio/DependencyGraphWriter.java | 98 - .../alpha/common/program/AbstractProgram.java | 52 - .../alpha/common/program/AnalyzedProgram.java | 48 - .../kr/alpha/common/program/InputProgram.java | 117 - .../alpha/common/program/InternalProgram.java | 89 - .../alpha/common/program/NormalProgram.java | 31 - .../kr/alpha/common/program/Programs.java | 23 - .../kr/alpha/common/rule/AbstractRule.java | 128 - .../kr/alpha/common/rule/BasicRule.java | 45 - .../kr/alpha/common/rule/InternalRule.java | 139 - .../kr/alpha/common/rule/NormalRule.java | 50 - .../kr/alpha/common/rule/head/ChoiceHead.java | 147 - .../common/rule/head/DisjunctiveHead.java | 66 - .../kr/alpha/common/rule/head/Head.java | 19 - .../kr/alpha/common/rule/head/NormalHead.java | 61 - .../kr/alpha/common/terms/ArithmeticTerm.java | 268 -- .../alpha/common/terms/CoreConstantTerm.java | 154 - .../kr/alpha/common/terms/CoreTerm.java | 100 - .../kr/alpha/common/terms/FunctionTerm.java | 157 - .../kr/alpha/common/terms/IntervalTerm.java | 160 - .../tuwien/kr/alpha/common/terms/Terms.java | 33 - .../kr/alpha/common/terms/VariableTerm.java | 108 - .../kr/alpha/grounder/AbstractGrounder.java | 18 - .../kr/alpha/grounder/BridgedGrounder.java | 34 - .../kr/alpha/grounder/ChoiceRecorder.java | 128 - .../alpha/grounder/FactIntervalEvaluator.java | 67 - .../kr/alpha/grounder/FilteringGrounder.java | 18 - .../ac/tuwien/kr/alpha/grounder/Grounder.java | 82 - .../kr/alpha/grounder/GrounderFactory.java | 55 - .../grounder/IndexedInstanceStorage.java | 222 -- .../ac/tuwien/kr/alpha/grounder/Instance.java | 57 - .../kr/alpha/grounder/IntIdGenerator.java | 33 - .../kr/alpha/grounder/NaiveGrounder.java | 639 ---- .../kr/alpha/grounder/NoGoodGenerator.java | 204 -- .../kr/alpha/grounder/NogoodRegistry.java | 44 - .../grounder/ProgramAnalyzingGrounder.java | 36 - .../kr/alpha/grounder/RuleGroundingOrder.java | 132 - .../alpha/grounder/RuleGroundingOrders.java | 229 -- .../kr/alpha/grounder/Substitution.java | 248 -- .../tuwien/kr/alpha/grounder/Unification.java | 116 - .../ac/tuwien/kr/alpha/grounder/Unifier.java | 134 - .../kr/alpha/grounder/WorkingMemory.java | 113 - .../kr/alpha/grounder/atoms/ChoiceAtom.java | 140 - .../alpha/grounder/atoms/EnumerationAtom.java | 95 - .../grounder/atoms/EnumerationLiteral.java | 59 - .../kr/alpha/grounder/atoms/IntervalAtom.java | 136 - .../alpha/grounder/atoms/IntervalLiteral.java | 119 - .../kr/alpha/grounder/atoms/RuleAtom.java | 122 - .../kr/alpha/grounder/bridges/Bridge.java | 12 - .../AbstractLiteralInstantiationStrategy.java | 131 - .../instantiation/AssignmentStatus.java | 57 - .../grounder/instantiation/BindingResult.java | 74 - ...ultLazyGroundingInstantiationStrategy.java | 177 -- .../LiteralInstantiationResult.java | 140 - .../LiteralInstantiationStrategy.java | 65 - .../instantiation/LiteralInstantiator.java | 187 -- ...rkingMemoryBasedInstantiationStrategy.java | 69 - .../grounder/parser/InlineDirectives.java | 34 - .../grounder/parser/ParseTreeVisitor.java | 583 ---- .../alpha/grounder/parser/ProgramParser.java | 111 - .../grounder/parser/ProgramPartParser.java | 80 - .../kr/alpha/grounder/rete/TupleIndex.java | 7 - .../kr/alpha/grounder/rete/TupleStore.java | 10 - .../structure/AnalyzeUnjustified.java | 409 --- .../kr/alpha/grounder/structure/LitSet.java | 143 - .../CardinalityNormalization.java | 259 -- .../transformation/ChoiceHeadToNormal.java | 120 - .../transformation/EnumerationRewriting.java | 86 - .../IntervalTermToIntervalAtom.java | 157 - .../NormalizeProgramTransformation.java | 42 - .../transformation/PredicateInternalizer.java | 61 - .../transformation/ProgramTransformation.java | 12 - .../transformation/StratifiedEvaluation.java | 369 --- .../transformation/SumNormalization.java | 201 -- .../VariableEqualityRemoval.java | 146 - .../kr/alpha/solver/AbstractSolver.java | 38 - .../ac/tuwien/kr/alpha/solver/Antecedent.java | 17 - .../tuwien/kr/alpha/solver/AtomCounter.java | 70 - .../at/ac/tuwien/kr/alpha/solver/Atoms.java | 9 - .../BinaryNoGoodPropagationEstimation.java | 52 - .../ac/tuwien/kr/alpha/solver/Checkable.java | 12 - .../at/ac/tuwien/kr/alpha/solver/Choice.java | 64 - .../alpha/solver/ChoiceInfluenceManager.java | 235 -- .../tuwien/kr/alpha/solver/ChoiceManager.java | 325 -- .../tuwien/kr/alpha/solver/ConflictCause.java | 26 - .../tuwien/kr/alpha/solver/DefaultSolver.java | 599 ---- .../alpha/solver/LearnedNoGoodDeletion.java | 116 - .../kr/alpha/solver/NaiveNoGoodStore.java | 231 -- .../tuwien/kr/alpha/solver/NaiveSolver.java | 432 --- .../tuwien/kr/alpha/solver/NoGoodCounter.java | 129 - .../tuwien/kr/alpha/solver/NoGoodStore.java | 58 - .../alpha/solver/NoGoodStoreAlphaRoaming.java | 1003 ------- .../kr/alpha/solver/PerformanceLog.java | 73 - .../kr/alpha/solver/ShallowAntecedent.java | 33 - .../at/ac/tuwien/kr/alpha/solver/Solver.java | 27 - .../tuwien/kr/alpha/solver/SolverFactory.java | 76 - .../solver/SolverMaintainingStatistics.java | 68 - .../tuwien/kr/alpha/solver/ThriceTruth.java | 77 - .../kr/alpha/solver/TrailAssignment.java | 783 ----- .../tuwien/kr/alpha/solver/WatchedNoGood.java | 213 -- .../kr/alpha/solver/WritableAssignment.java | 97 - .../ActivityBasedBranchingHeuristic.java | 42 - .../heuristics/AlphaActiveRuleHeuristic.java | 61 - .../AlphaHeadMustBeTrueHeuristic.java | 68 - .../heuristics/AlphaRandomSignHeuristic.java | 65 - .../kr/alpha/solver/heuristics/BerkMin.java | 280 -- .../solver/heuristics/BerkMinLiteral.java | 82 - .../solver/heuristics/BranchingHeuristic.java | 84 - .../heuristics/BranchingHeuristicFactory.java | 94 - .../ChainedBranchingHeuristics.java | 125 - .../heuristics/DependencyDrivenHeuristic.java | 361 --- .../DependencyDrivenPyroHeuristic.java | 64 - .../heuristics/DependencyDrivenVSIDS.java | 70 - .../GeneralizedDependencyDrivenHeuristic.java | 91 - ...eralizedDependencyDrivenPyroHeuristic.java | 65 - .../solver/heuristics/HeapOfActiveAtoms.java | 283 -- .../heuristics/HeapOfActiveChoicePoints.java | 110 - .../heuristics/HeuristicsConfiguration.java | 98 - .../HeuristicsConfigurationBuilder.java | 69 - .../kr/alpha/solver/heuristics/MOMs.java | 68 - .../solver/heuristics/NaiveHeuristic.java | 75 - .../solver/heuristics/ReplayHeuristic.java | 90 - .../kr/alpha/solver/heuristics/VSIDS.java | 252 -- .../activity/AvgBodyActivityProvider.java | 43 - .../activity/BodyActivityProvider.java | 52 - .../activity/BodyActivityProviderFactory.java | 56 - .../activity/DefaultBodyActivityProvider.java | 43 - .../activity/MaxBodyActivityProvider.java | 43 - .../activity/MinBodyActivityProvider.java | 43 - .../activity/SumBodyActivityProvider.java | 43 - .../learning/GroundConflictNoGoodLearner.java | 361 --- .../solver/learning/ResolutionSequence.java | 7 - 252 files changed, 282 insertions(+), 28576 deletions(-) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/{VariableTerm.java => VariableTermImpl.java} (63%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/{InlineDirectives.java => InlineDirectivesImpl.java} (78%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/{ChoiceHead.java => ChoiceHeadImpl.java} (90%) delete mode 100644 api/build.gradle delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java delete mode 100644 api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java delete mode 100644 cli/build.gradle delete mode 100644 cli/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java delete mode 100644 cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java delete mode 100644 cli/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java delete mode 100644 cli/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java delete mode 100644 cli/src/main/resources/logback.xml delete mode 100644 core/build.gradle delete mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java delete mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java delete mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java delete mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java delete mode 100644 core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java delete mode 100644 core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 delete mode 100644 core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/Util.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java delete mode 100644 core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.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 a267fc6f4..a54275099 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,4 +1,30 @@ package at.ac.tuwien.kr.alpha.api; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +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.program.InputProgram; +import at.ac.tuwien.kr.alpha.api.program.Predicate; + public interface Alpha { + + InputProgram readProgram(InputConfig cfg) throws IOException; + + InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException; + + InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; + + InputProgram readProgramString(String aspString, Map externals); + + InputProgram readProgramString(String aspString); + + Stream solve(InputProgram program); + + Stream solve(InputProgram program, java.util.function.Predicate filter); + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index d3367fab8..5f70e3fc1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -37,7 +37,7 @@ import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; public class AggregateAtom extends CoreAtom { @@ -100,8 +100,8 @@ public CorePredicate getPredicate() { * Returns all variables occurring inside the aggregate, between { ... }. * @return each variable occurring in some aggregate element. */ - public List getAggregateVariables() { - List occurringVariables = new LinkedList<>(); + public List getAggregateVariables() { + List occurringVariables = new LinkedList<>(); for (AggregateElement aggregateElement : aggregateElements) { occurringVariables.addAll(aggregateElement.getOccurringVariables()); } @@ -222,11 +222,11 @@ public boolean isGround() { return true; } - public List getOccurringVariables() { - List occurringVariables = new LinkedList<>(); + public List getOccurringVariables() { + List occurringVariables = new LinkedList<>(); for (CoreTerm term : elementTerms) { - if (term instanceof VariableTerm) { - occurringVariables.add((VariableTerm) term); + if (term instanceof VariableTermImpl) { + occurringVariables.add((VariableTermImpl) term); } } for (CoreLiteral literal : elementLiterals) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index d804e74ce..f91d9a383 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -5,7 +5,7 @@ import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** @@ -35,28 +35,28 @@ public AggregateLiteral substitute(Substitution substitution) { } @Override - public Set getBindingVariables() { - Set bindingVariables = new HashSet<>(); + public Set getBindingVariables() { + Set bindingVariables = new HashSet<>(); if (boundBindingVariable(getAtom().getLowerBoundOperator(), getAtom().getLowerBoundTerm(), positive) != null) { - bindingVariables.add((VariableTerm) getAtom().getLowerBoundTerm()); + bindingVariables.add((VariableTermImpl) getAtom().getLowerBoundTerm()); } if (boundBindingVariable(getAtom().getUpperBoundOperator(), getAtom().getUpperBoundTerm(), positive) != null) { - bindingVariables.add((VariableTerm) getAtom().getUpperBoundTerm()); + bindingVariables.add((VariableTermImpl) getAtom().getUpperBoundTerm()); } return bindingVariables; } @Override - public Set getNonBindingVariables() { + public Set getNonBindingVariables() { // Note: every local variable that also occurs globally in the rule is a nonBindingVariable, hence an // aggregate literal alone cannot detect its non-binding (i.e. global) variables. throw new UnsupportedOperationException(); } - private static VariableTerm boundBindingVariable(ComparisonOperator op, CoreTerm bound, boolean positive) { + private static VariableTermImpl boundBindingVariable(ComparisonOperator op, CoreTerm bound, boolean positive) { boolean isNormalizedEquality = op == ComparisonOperator.EQ && positive || op == ComparisonOperator.NE && !positive; - if (isNormalizedEquality && bound instanceof VariableTerm) { - return (VariableTerm) bound; + if (isNormalizedEquality && bound instanceof VariableTermImpl) { + return (VariableTermImpl) bound; } return null; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java index cae112a40..6559fcd59 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java @@ -29,7 +29,7 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.Collections; @@ -74,12 +74,12 @@ public BasicLiteral substitute(Substitution substitution) { * @return */ @Override - public Set getBindingVariables() { + public Set getBindingVariables() { if (!positive) { // Negative literal has no binding variables. return Collections.emptySet(); } - Set bindingVariables = new HashSet<>(); + Set bindingVariables = new HashSet<>(); for (CoreTerm term : atom.getTerms()) { bindingVariables.addAll(term.getOccurringVariables()); } @@ -92,12 +92,12 @@ public Set getBindingVariables() { * @return */ @Override - public Set getNonBindingVariables() { + public Set getNonBindingVariables() { if (positive) { // Positive literal has only binding variables. return Collections.emptySet(); } - Set nonbindingVariables = new HashSet<>(); + Set nonbindingVariables = new HashSet<>(); for (CoreTerm term : atom.getTerms()) { nonbindingVariables.addAll(term.getOccurringVariables()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index e7dd19bd6..04d00e921 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -40,7 +40,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** @@ -82,11 +82,11 @@ public ComparisonLiteral substitute(Substitution substitution) { } private boolean assignable(CoreTerm term) { - return isNormalizedEquality && term instanceof VariableTerm; + return isNormalizedEquality && term instanceof VariableTermImpl; } @Override - public Set getBindingVariables() { + public Set getBindingVariables() { final CoreTerm left = getTerms().get(0); final CoreTerm right = getTerms().get(1); if (assignable(left) && assignable(right)) { @@ -95,21 +95,21 @@ public Set getBindingVariables() { throw new RuntimeException("Builtin equality with left and right side being variables encountered. Should not happen."); } if (assignable(left)) { - return Collections.singleton((VariableTerm) left); + return Collections.singleton((VariableTermImpl) left); } if (assignable(right)) { - return Collections.singleton((VariableTerm) right); + return Collections.singleton((VariableTermImpl) right); } return Collections.emptySet(); } @Override - public Set getNonBindingVariables() { + public Set getNonBindingVariables() { final CoreTerm left = getTerms().get(0); final CoreTerm right = getTerms().get(1); - HashSet occurringVariables = new HashSet<>(); - List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); - List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); + HashSet occurringVariables = new HashSet<>(); + List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); + List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); if (assignable(left)) { leftOccurringVariables.remove(left); } @@ -149,14 +149,14 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit } } // Treat case that this is X = t or t = X. - VariableTerm variable = null; + VariableTermImpl variable = null; CoreTerm expression = null; if (leftAssigning) { - variable = (VariableTerm) left; + variable = (VariableTermImpl) left; expression = right; } if (rightAssigning) { - variable = (VariableTerm) right; + variable = (VariableTermImpl) right; expression = left; } CoreTerm groundTerm = expression.substitute(partialSubstitution); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index 2cbf02e3b..2ad6c4221 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -33,7 +33,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; @@ -53,7 +53,7 @@ public abstract class CoreAtom implements Atom, Comparable { /** * Returns the set of all variables occurring in the Atom. */ - public Set getOccurringVariables() { + public Set getOccurringVariables() { return toLiteral().getOccurringVariables(); } @@ -73,7 +73,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 VariableTerm}. + * @return true iff the terms of this atom contain no {@link VariableTermImpl}. */ public abstract boolean isGround(); @@ -89,8 +89,8 @@ public CoreLiteral toLiteral() { public CoreAtom renameVariables(String newVariablePrefix) { Unifier renamingSubstitution = new Unifier(); int counter = 0; - for (VariableTerm variable : getOccurringVariables()) { - renamingSubstitution.put(variable, VariableTerm.getInstance(newVariablePrefix + counter++)); + for (VariableTermImpl variable : getOccurringVariables()) { + renamingSubstitution.put(variable, VariableTermImpl.getInstance(newVariablePrefix + counter++)); } return this.substitute(renamingSubstitution); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java index bb1250682..10be39e43 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java @@ -35,7 +35,7 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** @@ -65,14 +65,14 @@ public boolean isNegated() { public abstract CoreLiteral substitute(Substitution substitution); - public abstract Set getBindingVariables(); + public abstract Set getBindingVariables(); - public abstract Set getNonBindingVariables(); + public abstract Set getNonBindingVariables(); /** * Union of {@link #getBindingVariables()} and {@link #getNonBindingVariables()} */ - public Set getOccurringVariables() { + public Set getOccurringVariables() { return SetUtils.union(getBindingVariables(), getNonBindingVariables()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 12437ff92..5289a65fc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** @@ -31,7 +31,7 @@ public EnumerationAtom(List terms) { if (terms.size() != 3) { throw new RuntimeException("EnumerationAtom must have arity three. Given terms are of wrong size: " + terms); } - if (!(getTerms().get(2) instanceof VariableTerm)) { + if (!(getTerms().get(2) instanceof VariableTermImpl)) { throw new RuntimeException("Third parameter of EnumerationAtom must be a variable: " + terms); } } @@ -70,7 +70,7 @@ public Substitution addEnumerationIndexToSubstitution(Substitution substitution) } Integer enumerationIndex = getEnumerationIndex(idTerm, enumerationTerm); Substitution retVal = new Substitution(substitution); - retVal.put((VariableTerm) getTerms().get(2), CoreConstantTerm.getInstance(enumerationIndex)); + retVal.put((VariableTermImpl) getTerms().get(2), CoreConstantTerm.getInstance(enumerationIndex)); return retVal; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java index 7170fd55d..16ad53420 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java @@ -5,7 +5,7 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** @@ -33,20 +33,20 @@ public EnumerationLiteral substitute(Substitution substitution) { } @Override - public Set getBindingVariables() { - return Collections.singleton((VariableTerm)getTerms().get(2)); + public Set getBindingVariables() { + return Collections.singleton((VariableTermImpl)getTerms().get(2)); } @Override - public Set getNonBindingVariables() { - Set ret = new HashSet<>(2); + public Set getNonBindingVariables() { + Set ret = new HashSet<>(2); CoreTerm idTerm = getTerms().get(0); CoreTerm enumTerm = getTerms().get(1); - if (idTerm instanceof VariableTerm) { - ret.add((VariableTerm) idTerm); + if (idTerm instanceof VariableTermImpl) { + ret.add((VariableTermImpl) idTerm); } - if (enumTerm instanceof VariableTerm) { - ret.add((VariableTerm) enumTerm); + if (enumTerm instanceof VariableTermImpl) { + ret.add((VariableTermImpl) enumTerm); } return ret; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java index 87095b9b7..5a494c3e1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java @@ -31,7 +31,7 @@ import at.ac.tuwien.kr.alpha.api.terms.*; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import java.util.*; @@ -68,7 +68,7 @@ public ExternalLiteral substitute(Substitution substitution) { } @Override - public Set getBindingVariables() { + 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. @@ -79,11 +79,11 @@ public Set getBindingVariables() { List output = getAtom().getOutput(); - Set binding = new HashSet<>(output.size()); + Set binding = new HashSet<>(output.size()); for (CoreTerm out : output) { - if (out instanceof VariableTerm) { - binding.add((VariableTerm) out); + if (out instanceof VariableTermImpl) { + binding.add((VariableTermImpl) out); } } @@ -91,13 +91,13 @@ public Set getBindingVariables() { } @Override - public Set getNonBindingVariables() { + 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<>(); + Set nonbindingVariables = new HashSet<>(); for (CoreTerm term : input) { nonbindingVariables.addAll(term.getOccurringVariables()); } @@ -106,8 +106,8 @@ public Set getNonBindingVariables() { // non-binding. if (!positive) { for (CoreTerm out : output) { - if (out instanceof VariableTerm) { - nonbindingVariables.add((VariableTerm) out); + if (out instanceof VariableTermImpl) { + nonbindingVariables.add((VariableTermImpl) out); } } } @@ -194,8 +194,8 @@ private List buildSubstitutionsForOutputs(Substitution partialSubs for (int i = 0; i < externalAtomOutputTerms.size(); i++) { CoreTerm out = externalAtomOutputTerms.get(i); - if (out instanceof VariableTerm) { - ith.put((VariableTerm) out, bindings.get(i)); + if (out instanceof VariableTermImpl) { + ith.put((VariableTermImpl) out, bindings.get(i)); } else { if (!bindings.get(i).equals(out)) { skip = true; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index 9cfd77bd3..34250f35c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java @@ -37,7 +37,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** @@ -65,11 +65,11 @@ private List getIntervalSubstitutions(Substitution partialSubstitu CoreTerm intervalRepresentingVariable = terms.get(1); IntervalTerm intervalTerm = (IntervalTerm) terms.get(0); // Check whether intervalRepresentingVariable is bound already. - if (intervalRepresentingVariable instanceof VariableTerm) { + if (intervalRepresentingVariable instanceof VariableTermImpl) { // Still a variable, generate all elements in the interval. for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) { Substitution ith = new Substitution(partialSubstitution); - ith.put((VariableTerm) intervalRepresentingVariable, CoreConstantTerm.getInstance(i)); + ith.put((VariableTermImpl) intervalRepresentingVariable, CoreConstantTerm.getInstance(i)); substitutions.add(ith); } return substitutions; @@ -89,16 +89,16 @@ private List getIntervalSubstitutions(Substitution partialSubstitu } @Override - public Set getBindingVariables() { + public Set getBindingVariables() { CoreTerm term = getTerms().get(1); - if (term instanceof VariableTerm) { - return Collections.singleton((VariableTerm) term); + if (term instanceof VariableTermImpl) { + return Collections.singleton((VariableTermImpl) term); } return Collections.emptySet(); } @Override - public Set getNonBindingVariables() { + public Set getNonBindingVariables() { return Sets.newHashSet(getTerms().get(0).getOccurringVariables()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java index 27ad6e004..320cf1539 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java @@ -68,8 +68,8 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { - LinkedHashSet occurringVariables = new LinkedHashSet<>(left.getOccurringVariables()); + public List getOccurringVariables() { + LinkedHashSet occurringVariables = new LinkedHashSet<>(left.getOccurringVariables()); occurringVariables.addAll(right.getOccurringVariables()); return new ArrayList<>(occurringVariables); } @@ -222,7 +222,7 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { + public List getOccurringVariables() { return left.getOccurringVariables(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java index 4b31a2ebc..d3b45ad13 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java @@ -36,7 +36,7 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { + public List getOccurringVariables() { return Collections.emptyList(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java index 8371b27fb..a359d2153 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java @@ -35,7 +35,7 @@ //@formatter:on public abstract class CoreTerm implements Term { - public abstract List getOccurringVariables(); + public abstract List getOccurringVariables(); /** * Applies a substitution, result may be nonground. @@ -45,13 +45,14 @@ public abstract class CoreTerm implements Term { */ public abstract CoreTerm substitute(Substitution substitution); + // TODO change this to work on interfaces and break out of this class private static int priority(CoreTerm term) { final Class clazz = term.getClass(); if (clazz.equals(CoreConstantTerm.class)) { return 1; } else if (clazz.equals(FunctionTerm.class)) { return 2; - } else if (clazz.equals(VariableTerm.class)) { + } else if (clazz.equals(VariableTermImpl.class)) { return 3; } throw new UnsupportedOperationException("Can only compare constant term, function terms and variable terms among each other."); @@ -76,7 +77,7 @@ public int compareTo(Term o) { public static class RenameCounter { int counter; - final HashMap renamedVariables; + final HashMap renamedVariables; public RenameCounter(int startingValue) { counter = startingValue; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java index 61e638a05..3840f9410 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java @@ -57,8 +57,8 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { - LinkedList vars = new LinkedList<>(); + public List getOccurringVariables() { + LinkedList vars = new LinkedList<>(); for (CoreTerm term : terms) { vars.addAll(term.getOccurringVariables()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java index 577a4d088..02d9f8305 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java @@ -28,7 +28,7 @@ private IntervalTerm(CoreTerm lowerBound, CoreTerm upperBound) { throw new IllegalArgumentException(); } - this.ground = !((lowerBound instanceof VariableTerm) || (upperBound instanceof VariableTerm)); + this.ground = !((lowerBound instanceof VariableTermImpl) || (upperBound instanceof VariableTermImpl)); this.lowerBoundTerm = lowerBound; this.upperBoundTerm = upperBound; @@ -66,13 +66,13 @@ public int getUpperBound() { } @Override - public List getOccurringVariables() { - LinkedList variables = new LinkedList<>(); - if (lowerBoundTerm instanceof VariableTerm) { - variables.add((VariableTerm) lowerBoundTerm); + public List getOccurringVariables() { + LinkedList variables = new LinkedList<>(); + if (lowerBoundTerm instanceof VariableTermImpl) { + variables.add((VariableTermImpl) lowerBoundTerm); } - if (upperBoundTerm instanceof VariableTerm) { - variables.add((VariableTerm) upperBoundTerm); + if (upperBoundTerm instanceof VariableTermImpl) { + variables.add((VariableTermImpl) upperBoundTerm); } return variables; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java similarity index 63% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTerm.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java index 69f2b494c..46af900fc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java @@ -1,32 +1,34 @@ package at.ac.tuwien.kr.alpha.core.common.terms; +import java.util.Collections; +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.Interner; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; -import java.util.Collections; -import java.util.List; - /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class VariableTerm extends CoreTerm { - private static final Interner INTERNER = new Interner<>(); +public class VariableTermImpl extends CoreTerm implements VariableTerm { + private static final Interner INTERNER = new Interner<>(); private static final String ANONYMOUS_VARIABLE_PREFIX = "_"; private static final IntIdGenerator ANONYMOUS_VARIABLE_COUNTER = new IntIdGenerator(); private final String variableName; - private VariableTerm(String variableName) { + private VariableTermImpl(String variableName) { this.variableName = variableName; } - public static VariableTerm getInstance(String variableName) { - return INTERNER.intern(new VariableTerm(variableName)); + public static VariableTermImpl getInstance(String variableName) { + return INTERNER.intern(new VariableTermImpl(variableName)); } - public static VariableTerm getAnonymousInstance() { + public static VariableTermImpl getAnonymousInstance() { return getInstance(ANONYMOUS_VARIABLE_PREFIX + ANONYMOUS_VARIABLE_COUNTER.getNextId()); } @@ -36,7 +38,7 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { + public List getOccurringVariables() { return Collections.singletonList(this); } @@ -47,7 +49,7 @@ public CoreTerm substitute(Substitution substitution) { // If variable is not substituted, keep term as is. return this; } - return groundTerm; + return groundTerm; } @Override @@ -65,7 +67,7 @@ public boolean equals(Object o) { return false; } - VariableTerm that = (VariableTerm) o; + VariableTermImpl that = (VariableTermImpl) o; return variableName.equals(that.variableName); } @@ -75,32 +77,33 @@ public int hashCode() { return variableName.hashCode(); } + // TODO not sure if this makes sense (cast to VariableTerm interface instead?) @Override - public int compareTo(CoreTerm o) { + public int compareTo(Term o) { if (this == o) { return 0; } - if (!(o instanceof VariableTerm)) { + if (!(o instanceof VariableTermImpl)) { return super.compareTo(o); } - VariableTerm other = (VariableTerm)o; + VariableTermImpl other = (VariableTermImpl) o; return variableName.compareTo(other.variableName); } @Override public CoreTerm renameVariables(String renamePrefix) { - return VariableTerm.getInstance(renamePrefix + variableName); + return VariableTermImpl.getInstance(renamePrefix + variableName); } @Override public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - VariableTerm renamedThis = counter.renamedVariables.get(this); + VariableTermImpl renamedThis = counter.renamedVariables.get(this); if (renamedThis != null) { return renamedThis; } else { - VariableTerm renamedVariable = VariableTerm.getInstance(renamePrefix + counter.counter++); + VariableTermImpl renamedVariable = VariableTermImpl.getInstance(renamePrefix + counter.counter++); counter.renamedVariables.put(this, renamedVariable); return renamedVariable; } 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 9c2d89df4..ccdb73ee0 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 @@ -63,7 +63,7 @@ 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.common.NoGoodInterface; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.BindingResult; @@ -198,8 +198,8 @@ private Set getRulesWithUniqueHead() { } // Collect head and body variables. - HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); - HashSet occurringVariablesBody = new HashSet<>(); + HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); + HashSet occurringVariablesBody = new HashSet<>(); for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { occurringVariablesBody.addAll(lit.getBindingVariables()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java index 94faf9c12..4b285b8bc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** @@ -166,7 +166,7 @@ public void computeGroundingOrders() { private void computeGroundingOrder(CoreLiteral startingLiteral) { Set bodyLiterals = internalRule.getBody(); - HashSet boundVariables = new HashSet<>(); + HashSet boundVariables = new HashSet<>(); boundVariables.addAll(startingLiteral.getBindingVariables()); LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); remainingLiterals.remove(startingLiteral); @@ -199,7 +199,7 @@ private void computeGroundingOrder(CoreLiteral startingLiteral) { groundingOrders.put(startingLiteral, new RuleGroundingOrder(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); } - private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { + private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { Float bestSelectivity = Float.MAX_VALUE; CoreLiteral bestLiteral = null; boolean bestLiteralSharesVariables = false; @@ -223,7 +223,7 @@ private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remain return bestLiteral; } - private boolean sharesVariables(Collection set1, Collection set2part1, Collection set2part2) { + private boolean sharesVariables(Collection set1, Collection set2part1, Collection set2part2) { return !Collections.disjoint(set1, set2part1) || !Collections.disjoint(set1, set2part2); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java index 84e431eac..b93ae5059 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java @@ -40,7 +40,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; public class Substitution { @@ -48,14 +48,14 @@ public class Substitution { private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); public static final Substitution EMPTY_SUBSTITUTION = new Substitution() { @Override - public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { + public > CoreTerm put(VariableTermImpl variableTerm, CoreTerm groundTerm) { throw oops("Should not be called on EMPTY_SUBSTITUTION"); } }; - protected TreeMap substitution; + protected TreeMap substitution; - private Substitution(TreeMap substitution) { + private Substitution(TreeMap substitution) { if (substitution == null) { throw oops("Substitution is null."); } @@ -100,8 +100,8 @@ boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution par } else if (termNonGround instanceof CoreConstantTerm) { // Since right term is ground, both terms differ return false; - } else if (termNonGround instanceof VariableTerm) { - VariableTerm variableTerm = (VariableTerm) termNonGround; + } else if (termNonGround instanceof VariableTermImpl) { + VariableTermImpl variableTerm = (VariableTermImpl) termNonGround; // Left term is variable, bind it to the right term. Use original substitution if it has // not been cloned yet. CoreTerm bound = (updatedSubstitution == null ? partialSubstitution : updatedSubstitution).eval(variableTerm); // Get variable binding, either from input substitution if it has not been updated yet, or from the cloned/updated substitution. @@ -160,16 +160,16 @@ public static Substitution specializeSubstitution(CoreAtom atom, Instance instan } /** - * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTerm} under this substitution. + * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTermImpl} under this substitution. * * @param variableTerm the variable term to substitute, if possible * @return a constant term if the substitution contains the given variable, {@code null} otherwise. */ - public CoreTerm eval(VariableTerm variableTerm) { + public CoreTerm eval(VariableTermImpl variableTerm) { return this.substitution.get(variableTerm); } - public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { + public > CoreTerm put(VariableTermImpl variableTerm, CoreTerm groundTerm) { if (!groundTerm.isGround()) { throw oops("Right-hand term is not ground."); } @@ -185,11 +185,11 @@ public boolean isEmpty() { return substitution.isEmpty(); } - public boolean isVariableSet(VariableTerm variable) { + public boolean isVariableSet(VariableTermImpl variable) { return substitution.get(variable) != null; } - public Set getMappedVariables() { + public Set getMappedVariables() { return substitution.keySet(); } @@ -202,7 +202,7 @@ public Set getMappedVariables() { public String toString() { final StringBuilder ret = new StringBuilder("{"); boolean isFirst = true; - for (Map.Entry e : substitution.entrySet()) { + for (Map.Entry e : substitution.entrySet()) { if (isFirst) { isFirst = false; } else { @@ -220,7 +220,7 @@ public static Substitution fromString(String substitution) { Substitution ret = new Substitution(); for (String assignment : assignments) { String[] keyVal = assignment.split("->"); - VariableTerm variable = VariableTerm.getInstance(keyVal[0]); + VariableTermImpl variable = VariableTermImpl.getInstance(keyVal[0]); CoreTerm assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); ret.put(variable, assignedTerm); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index e5d905044..cfaf9ad7a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -34,7 +34,7 @@ import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; /** * Copyright (c) 2017, the Alpha Team. @@ -56,12 +56,12 @@ public static Unifier instantiate(CoreAtom general, CoreAtom specific) { } private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLeftAsIs) { - Set leftOccurringVariables = left.getOccurringVariables(); - Set rightOccurringVaribles = right.getOccurringVariables(); + Set leftOccurringVariables = left.getOccurringVariables(); + Set rightOccurringVaribles = right.getOccurringVariables(); boolean leftSmaller = leftOccurringVariables.size() < rightOccurringVaribles.size(); - Set smallerSet = leftSmaller ? leftOccurringVariables : rightOccurringVaribles; - Set largerSet = leftSmaller ? rightOccurringVaribles : leftOccurringVariables; - for (VariableTerm variableTerm : smallerSet) { + Set smallerSet = leftSmaller ? leftOccurringVariables : rightOccurringVaribles; + Set largerSet = leftSmaller ? rightOccurringVaribles : leftOccurringVariables; + for (VariableTermImpl variableTerm : smallerSet) { if (largerSet.contains(variableTerm)) { throw oops("Left and right atom share variables."); } @@ -86,12 +86,12 @@ private static boolean unifyTerms(CoreTerm left, CoreTerm right, Unifier current if (leftSubs == rightSubs) { return true; } - if (!keepLeftAsIs && leftSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) leftSubs)) { - currentSubstitution.put((VariableTerm) leftSubs, rightSubs); + if (!keepLeftAsIs && leftSubs instanceof VariableTermImpl && !currentSubstitution.isVariableSet((VariableTermImpl) leftSubs)) { + currentSubstitution.put((VariableTermImpl) leftSubs, rightSubs); return true; } - if (rightSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) rightSubs)) { - currentSubstitution.put((VariableTerm) rightSubs, leftSubs); + if (rightSubs instanceof VariableTermImpl && !currentSubstitution.isVariableSet((VariableTermImpl) rightSubs)) { + currentSubstitution.put((VariableTermImpl) rightSubs, leftSubs); return true; } if (leftSubs instanceof FunctionTerm && rightSubs instanceof FunctionTerm) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java index e2d7a39a9..30753313c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java @@ -10,7 +10,7 @@ import java.util.TreeMap; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; /** * A variable substitution allowing variables to occur on the right-hand side. Chains of variable substitutions are @@ -19,9 +19,9 @@ */ public class Unifier extends Substitution { - private final TreeMap> rightHandVariableOccurrences; + private final TreeMap> rightHandVariableOccurrences; - private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { + private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { if (substitution == null) { throw oops("Substitution is null."); } @@ -43,7 +43,7 @@ public Unifier(Substitution clone) { public Unifier extendWith(Substitution extension) { - for (Map.Entry extensionVariable : extension.substitution.entrySet()) { + for (Map.Entry extensionVariable : extension.substitution.entrySet()) { this.put(extensionVariable.getKey(), extensionVariable.getValue()); } return this; @@ -54,9 +54,9 @@ public Unifier extendWith(Substitution extension) { * @return the list of variables occurring somewhere in the unifier. */ @Override - public Set getMappedVariables() { - Set ret = new HashSet<>(); - for (Map.Entry substitution : substitution.entrySet()) { + public Set getMappedVariables() { + Set ret = new HashSet<>(); + for (Map.Entry substitution : substitution.entrySet()) { ret.add(substitution.getKey()); ret.addAll(substitution.getValue().getOccurringVariables()); } @@ -65,10 +65,10 @@ public Set getMappedVariables() { @Override - public > CoreTerm put(VariableTerm variableTerm, CoreTerm term) { + public > CoreTerm put(VariableTermImpl variableTerm, CoreTerm term) { // If term is not ground, store it for right-hand side reverse-lookup. if (!term.isGround()) { - for (VariableTerm rightHandVariable : term.getOccurringVariables()) { + for (VariableTermImpl rightHandVariable : term.getOccurringVariables()) { rightHandVariableOccurrences.putIfAbsent(rightHandVariable, new ArrayList<>()); rightHandVariableOccurrences.get(rightHandVariable).add(variableTerm); } @@ -77,10 +77,10 @@ public > CoreTerm put(VariableTerm variableTerm, CoreTer CoreTerm ret = substitution.put(variableTerm, term); // Check if the just-assigned variable occurs somewhere in the right-hand side already. - List rightHandOccurrences = rightHandVariableOccurrences.get(variableTerm); + List rightHandOccurrences = rightHandVariableOccurrences.get(variableTerm); if (rightHandOccurrences != null) { // Replace all occurrences on the right-hand side with the just-assigned term. - for (VariableTerm rightHandOccurrence : rightHandOccurrences) { + for (VariableTermImpl rightHandOccurrence : rightHandOccurrences) { // Substitute the right hand where this assigned variable occurs with the new value and store it. CoreTerm previousRightHand = substitution.get(rightHandOccurrence); if (previousRightHand == null) { @@ -106,8 +106,8 @@ public > CoreTerm put(VariableTerm variableTerm, CoreTer public static Unifier mergeIntoLeft(Unifier left, Unifier right) { // Note: we assume both substitutions are free of chains, i.e., no A->B, B->C but A->C, B->C. Unifier ret = new Unifier(left); - for (Map.Entry mapping : right.substitution.entrySet()) { - VariableTerm variable = mapping.getKey(); + for (Map.Entry mapping : right.substitution.entrySet()) { + VariableTermImpl variable = mapping.getKey(); CoreTerm term = mapping.getValue(); // If variable is unset, simply add. if (!ret.isVariableSet(variable)) { @@ -116,10 +116,10 @@ public static Unifier mergeIntoLeft(Unifier left, Unifier right) { } // Variable is already set. CoreTerm setTerm = ret.eval(variable); - if (setTerm instanceof VariableTerm) { + if (setTerm instanceof VariableTermImpl) { // Variable maps to another variable in left. // Add a new mapping of the setTerm variable into our right-assigned term. - ret.put((VariableTerm) setTerm, term); + ret.put((VariableTermImpl) setTerm, term); // Note: Unifier.put takes care of resolving the chain variable->setTerm->term. continue; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java index 4fe6888ad..6a6bb1b52 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java @@ -9,7 +9,7 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.Unification; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; @@ -235,7 +235,7 @@ private Set unjustCover(List vB, Set vY, Set variablesOccurringInSigma = sigma.getMappedVariables(); + Set variablesOccurringInSigma = sigma.getMappedVariables(); if (Unification.instantiate(bSigmaY, bSigma) != null) { for (Unifier sigmaN : vN) { ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectives.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectivesImpl.java similarity index 78% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectives.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectivesImpl.java index 8a10e93d6..534b1874f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectives.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectivesImpl.java @@ -3,11 +3,13 @@ import java.util.LinkedHashMap; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; + /** * Stores directives appearing in the ASP program. Each directive starts with # and ends with . - * Copyright (c) 2017, the Alpha Team. + * Copyright (c) 2017 - 2021, the Alpha Team. */ -public class InlineDirectives { +public class InlineDirectivesImpl implements InlineDirectives { public enum DIRECTIVE { enum_predicate_is @@ -26,7 +28,7 @@ public void addDirective(DIRECTIVE directive, String value) { directives.put(directive, value); } - public void accumulate(InlineDirectives other) { + public void accumulate(InlineDirectivesImpl other) { for (Map.Entry directiveEntry : other.directives.entrySet()) { addDirective(directiveEntry.getKey(), directiveEntry.getValue()); } 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 45702f739..c1693a012 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 @@ -48,9 +48,6 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; -import at.ac.tuwien.kr.alpha.api.rules.Head; -import at.ac.tuwien.kr.alpha.api.rules.NormalHead; -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.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; @@ -72,9 +69,10 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.Rules; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; +import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHeadImpl; /** * Copyright (c) 2016-2021, the Alpha Team. @@ -84,7 +82,7 @@ public class ParseTreeVisitor extends ASPCore2BaseVisitor { private final boolean acceptVariables; private InputProgramImpl.Builder programBuilder; - private InlineDirectives inlineDirectives; + private InlineDirectivesImpl inlineDirectives; public ParseTreeVisitor(Map externals) { this(externals, true); @@ -161,7 +159,7 @@ public InputProgramImpl visitProgram(ASPCore2Parser.ProgramContext ctx) { if (ctx.statements() == null) { return InputProgramImpl.EMPTY; } - inlineDirectives = new InlineDirectives(); + inlineDirectives = new InlineDirectivesImpl(); programBuilder = InputProgramImpl.builder(); visitStatements(ctx.statements()); programBuilder.addInlineDirectives(inlineDirectives); // TODO inline directives @@ -246,25 +244,25 @@ public Object visitStatement_directive(ASPCore2Parser.Statement_directiveContext @Override public ChoiceHead visitChoice(ASPCore2Parser.ChoiceContext ctx) { // choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; - Term lt = null; + CoreTerm lt = null; ComparisonOperator lop = null; - Term ut = null; + CoreTerm ut = null; ComparisonOperator uop = null; if (ctx.lt != null) { - lt = (Term) visit(ctx.lt); + lt = (CoreTerm) visit(ctx.lt); lop = visitBinop(ctx.lop); } if (ctx.ut != null) { - ut = (Term) visit(ctx.ut); + ut = (CoreTerm) visit(ctx.ut); uop = visitBinop(ctx.uop); } - return new ChoiceHead(visitChoice_elements(ctx.choice_elements()), lt, lop, ut, uop); + return new ChoiceHeadImpl(visitChoice_elements(ctx.choice_elements()), lt, lop, ut, uop); } @Override - public List visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { + public List visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { // choice_elements : choice_element (SEMICOLON choice_elements)?; - List choiceElements; + List choiceElements; if (ctx.choice_elements() != null) { choiceElements = visitChoice_elements(ctx.choice_elements()); } else { @@ -275,13 +273,13 @@ public List visitChoice_elements(ASPCore2Parser.Choice } @Override - public ChoiceHead.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { + public ChoiceHeadImpl.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { // choice_element : classical_literal (COLON naf_literals?)?; BasicAtom atom = (BasicAtom) visitClassical_literal(ctx.classical_literal()); if (ctx.naf_literals() != null) { - return new ChoiceHead.ChoiceElement(atom, visitNaf_literals(ctx.naf_literals())); + return new ChoiceHeadImpl.ChoiceElement(atom, visitNaf_literals(ctx.naf_literals())); } else { - return new ChoiceHead.ChoiceElement(atom, Collections.emptyList()); + return new ChoiceHeadImpl.ChoiceElement(atom, Collections.emptyList()); } } @@ -301,7 +299,7 @@ public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ct @Override public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx) { // directive_enumeration : SHARP 'enum_predicate_is' ID DOT; - inlineDirectives.addDirective(InlineDirectives.DIRECTIVE.enum_predicate_is, ctx.ID().getText()); + inlineDirectives.addDirective(InlineDirectivesImpl.DIRECTIVE.enum_predicate_is, ctx.ID().getText()); return null; } @@ -331,14 +329,14 @@ public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { boolean isPositive = ctx.NAF() == null; CoreTerm lt = null; ComparisonOperator lop = null; - Term ut = null; + CoreTerm ut = null; ComparisonOperator uop = null; if (ctx.lt != null) { lt = (CoreTerm) visit(ctx.lt); lop = visitBinop(ctx.lop); } if (ctx.ut != null) { - ut = (Term) visit(ctx.ut); + ut = (CoreTerm) visit(ctx.ut); uop = visitBinop(ctx.uop); } AggregateAtom.AGGREGATEFUNCTION aggregateFunction = visitAggregate_function(ctx.aggregate_function()); @@ -360,7 +358,7 @@ public List visitAggregate_elements(ASPCore2Pars @Override public AggregateAtom.AggregateElement visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx) { // aggregate_element : basic_terms? (COLON naf_literals?)?; - List basicTerms = ctx.basic_terms() != null ? visitBasic_terms(ctx.basic_terms()) : null; + List basicTerms = ctx.basic_terms() != null ? visitBasic_terms(ctx.basic_terms()) : null; if (ctx.naf_literals() != null) { return new AggregateAtom.AggregateElement(basicTerms, visitNaf_literals(ctx.naf_literals())); } @@ -368,9 +366,9 @@ public AggregateAtom.AggregateElement visitAggregate_element(ASPCore2Parser.Aggr } @Override - public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { + public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { // basic_terms : basic_term (COMMA basic_terms)? ; - List termList = new ArrayList<>(); + List termList = new ArrayList<>(); do { termList.add(visitBasic_term(ctx.basic_term())); } while ((ctx = ctx.basic_terms()) != null); @@ -378,7 +376,7 @@ public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { } @Override - public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { + public CoreTerm visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { // basic_term : ground_term | variable_term; if (ctx.ground_term() != null) { return visitGround_term(ctx.ground_term()); @@ -388,7 +386,7 @@ public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { } @Override - public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { + public CoreTerm visitGround_term(ASPCore2Parser.Ground_termContext ctx) { // ground_term : ID | QUOTED_STRING | MINUS? NUMBER; if (ctx.ID() != null) { return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); @@ -405,12 +403,13 @@ public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { } @Override - public Term visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { + // TODO proper "core" type + public CoreTerm visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { // variable_term : VARIABLE | ANONYMOUS_VARIABLE; if (ctx.VARIABLE() != null) { - return VariableTerm.getInstance(ctx.VARIABLE().getText()); + return VariableTermImpl.getInstance(ctx.VARIABLE().getText()); } else { - return VariableTerm.getAnonymousInstance(); + return VariableTermImpl.getAnonymousInstance(); } } @@ -480,12 +479,12 @@ public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext throw notSupported(ctx); } - final List terms = visitTerms(ctx.terms()); + final List terms = visitTerms(ctx.terms()); return new BasicAtom(CorePredicate.getInstance(ctx.ID().getText(), terms.size()), terms); } @Override - public List visitTerms(ASPCore2Parser.TermsContext ctx) { + public List visitTerms(ASPCore2Parser.TermsContext ctx) { // terms : term (COMMA terms)?; if (ctx == null) { return emptyList(); @@ -501,17 +500,17 @@ public List visitTerms(ASPCore2Parser.TermsContext ctx) { } @Override - public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { + public CoreConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { return CoreConstantTerm.getInstance(Integer.parseInt(ctx.NUMBER().getText())); } @Override - public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { + public CoreConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); } @Override - public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { + public CoreConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { String quotedString = ctx.QUOTED_STRING().getText().replace("\\\"", "\""); return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); } @@ -522,21 +521,23 @@ public FunctionTerm visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { } @Override + // TODO proper "core" type public VariableTerm visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx) { if (!acceptVariables) { throw notSupported(ctx); } - return VariableTerm.getAnonymousInstance(); + return VariableTermImpl.getAnonymousInstance(); } @Override + // TODO proper "core" type public VariableTerm visitTerm_variable(ASPCore2Parser.Term_variableContext ctx) { if (!acceptVariables) { throw notSupported(ctx); } - return VariableTerm.getInstance(ctx.VARIABLE().getText()); + return VariableTermImpl.getInstance(ctx.VARIABLE().getText()); } @Override @@ -559,7 +560,7 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) throw new IllegalArgumentException("Unknown interpretation name encountered: " + predicateName); } - List outputTerms = visitTerms(ctx.output); + List outputTerms = visitTerms(ctx.output); return new ExternalAtom( CorePredicate.getInstance(predicateName, outputTerms.size()), @@ -569,15 +570,16 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) } @Override + // TODO proper "core" type public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) { // interval : lower = (NUMBER | VARIABLE) DOT DOT upper = (NUMBER | VARIABLE); ASPCore2Parser.IntervalContext ictx = ctx.interval(); String lowerText = ictx.lower.getText(); String upperText = ictx.upper.getText(); CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) - : VariableTerm.getInstance(lowerText); + : VariableTermImpl.getInstance(lowerText); CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) - : VariableTerm.getInstance(upperText); + : VariableTermImpl.getInstance(upperText); return IntervalTerm.getInstance(lower, upper); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java index 9bd061ab1..72bbc2d8b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java @@ -4,7 +4,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; @@ -15,7 +15,7 @@ */ public class NormalProgram extends AbstractProgram { - public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public NormalProgram(List rules, List facts, InlineDirectivesImpl inlineDirectives) { super(rules, facts, inlineDirectives); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index 31a297e45..f19cc317c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -15,7 +15,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -191,14 +191,14 @@ private List rewriteAggregatesInRule(BasicRule rule) { Substitution aggregateSubstitution = new Unifier(); Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); + aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); - aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); + aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); } - aggregateSubstitution.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); + aggregateSubstitution.put(VariableTermImpl.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); // Create new output atom for addition to rule body instead of the aggregate. aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateSubstitution).toLiteral()); @@ -209,7 +209,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { List elementTerms = aggregateElement.getElementTerms(); FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); Substitution elementSubstitution = new Unifier(aggregateSubstitution); - elementSubstitution.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); + elementSubstitution.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementSubstitution); 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 0d61b17f6..f11a094e4 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 @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHead; +import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHeadImpl; import at.ac.tuwien.kr.alpha.core.rules.heads.Head; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; @@ -63,7 +63,7 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { BasicRule rule = ruleIterator.next(); Head ruleHead = rule.getHead(); - if (!(ruleHead instanceof ChoiceHead)) { + if (!(ruleHead instanceof ChoiceHeadImpl)) { // Rule is constraint or without choice in the head. Leave as is. continue; } @@ -71,14 +71,14 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { // Remove this rule, as it will be transformed. ruleIterator.remove(); - ChoiceHead choiceHead = (ChoiceHead) ruleHead; + ChoiceHeadImpl choiceHead = (ChoiceHeadImpl) ruleHead; // Choice rules with boundaries are not yet supported. if (choiceHead.getLowerBound() != null || choiceHead.getUpperBound() != null) { throw new UnsupportedOperationException("Found choice rule with bounds, which are not yet supported. Rule is: " + rule); } // Only rewrite rules with a choice in their head. - for (ChoiceHead.ChoiceElement choiceElement : choiceHead.getChoiceElements()) { + for (ChoiceHeadImpl.ChoiceElement choiceElement : choiceHead.getChoiceElements()) { // Create two guessing rules for each choiceElement. // Construct common body to both rules. 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 bedacbb75..7e50d11e5 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 @@ -12,7 +12,7 @@ import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.parser.InlineDirectives; +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; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; @@ -28,7 +28,7 @@ public class EnumerationRewriting extends ProgramTransformation intervalReplacements = new LinkedHashMap<>(); + Map intervalReplacements = new LinkedHashMap<>(); List rewrittenBody = new ArrayList<>(); @@ -74,7 +74,7 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { } // Add new IntervalAtoms representing the interval specifications. - for (Map.Entry interval : intervalReplacements.entrySet()) { + for (Map.Entry interval : intervalReplacements.entrySet()) { rewrittenBody.add(new IntervalAtom(interval.getValue(), interval.getKey()).toLiteral()); } return new NormalRule(rewrittenHead, rewrittenBody); @@ -83,14 +83,14 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { /** * Replaces every IntervalTerm by a new variable and returns a mapping of the replaced VariableTerm -> IntervalTerm. */ - private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { + private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { CoreAtom atom = lit.getAtom(); List termList = new ArrayList<>(atom.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { CoreTerm term = termList.get(i); if (term instanceof IntervalTerm) { - VariableTerm replacementVariable = VariableTerm.getInstance(INTERVAL_VARIABLE_PREFIX + intervalReplacement.size()); + VariableTermImpl replacementVariable = VariableTermImpl.getInstance(INTERVAL_VARIABLE_PREFIX + intervalReplacement.size()); intervalReplacement.put(replacementVariable, (IntervalTerm) term); termList.set(i, replacementVariable); didChange = true; @@ -109,13 +109,13 @@ private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { + private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map intervalReplacement) { List termList = new ArrayList<>(functionTerm.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { CoreTerm term = termList.get(i); if (term instanceof IntervalTerm) { - VariableTerm replacementVariable = VariableTerm.getInstance("_Interval" + intervalReplacement.size()); + VariableTermImpl replacementVariable = VariableTermImpl.getInstance("_Interval" + intervalReplacement.size()); intervalReplacement.put(replacementVariable, (IntervalTerm) term); termList.set(i, replacementVariable); didChange = true; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index 96bfd5b6e..d46f694f9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -15,7 +15,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; @@ -151,14 +151,14 @@ private List rewriteAggregatesInRule(BasicRule rule) { Unifier aggregateUnifier = new Unifier(); Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); + aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); - aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); + aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); } - aggregateUnifier.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); + aggregateUnifier.put(VariableTermImpl.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); // Create new output atom for addition to rule body instead of the aggregate. aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateUnifier).toLiteral()); @@ -169,8 +169,8 @@ private List rewriteAggregatesInRule(BasicRule rule) { List elementTerms = aggregateElement.getElementTerms(); FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); Unifier elementUnifier = new Unifier(aggregateUnifier); - elementUnifier.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); - elementUnifier.put(VariableTerm.getInstance("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); + elementUnifier.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); + elementUnifier.put(VariableTermImpl.getInstance("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementUnifier); 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 dec0ed294..b70dde6cf 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 @@ -41,7 +41,7 @@ import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; @@ -65,7 +65,7 @@ public NormalProgram apply(NormalProgram inputProgram) { private NormalRule findAndReplaceVariableEquality(NormalRule rule) { // Collect all equal variables. - HashMap> variableToEqualVariables = new LinkedHashMap<>(); + HashMap> variableToEqualVariables = new LinkedHashMap<>(); HashSet equalitiesToRemove = new HashSet<>(); for (CoreLiteral bodyElement : rule.getBody()) { if (!(bodyElement instanceof ComparisonLiteral)) { @@ -75,13 +75,13 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { if (!comparisonLiteral.isNormalizedEquality()) { continue; } - if (comparisonLiteral.getTerms().get(0) instanceof VariableTerm && comparisonLiteral.getTerms().get(1) instanceof VariableTerm) { - VariableTerm leftVariable = (VariableTerm) comparisonLiteral.getTerms().get(0); - VariableTerm rightVariable = (VariableTerm) comparisonLiteral.getTerms().get(1); - HashSet leftEqualVariables = variableToEqualVariables.get(leftVariable); - HashSet rightEqualVariables = variableToEqualVariables.get(rightVariable); + if (comparisonLiteral.getTerms().get(0) instanceof VariableTermImpl && comparisonLiteral.getTerms().get(1) instanceof VariableTermImpl) { + VariableTermImpl leftVariable = (VariableTermImpl) comparisonLiteral.getTerms().get(0); + VariableTermImpl rightVariable = (VariableTermImpl) comparisonLiteral.getTerms().get(1); + HashSet leftEqualVariables = variableToEqualVariables.get(leftVariable); + HashSet rightEqualVariables = variableToEqualVariables.get(rightVariable); if (leftEqualVariables == null && rightEqualVariables == null) { - HashSet equalVariables = new LinkedHashSet<>(Arrays.asList(leftVariable, rightVariable)); + HashSet equalVariables = new LinkedHashSet<>(Arrays.asList(leftVariable, rightVariable)); variableToEqualVariables.put(leftVariable, equalVariables); variableToEqualVariables.put(rightVariable, equalVariables); } @@ -95,7 +95,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { } if (leftEqualVariables != null && rightEqualVariables != null) { leftEqualVariables.addAll(rightEqualVariables); - for (VariableTerm rightEqualVariable : rightEqualVariables) { + for (VariableTermImpl rightEqualVariable : rightEqualVariables) { variableToEqualVariables.put(rightEqualVariable, leftEqualVariables); } } @@ -113,9 +113,9 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { // Use substitution for actual replacement. Unifier replacementSubstitution = new Unifier(); // For each set of equal variables, take the first variable and replace all others by it. - for (Map.Entry> variableEqualityEntry : variableToEqualVariables.entrySet()) { - VariableTerm variableToReplace = variableEqualityEntry.getKey(); - VariableTerm replacementVariable = variableEqualityEntry.getValue().iterator().next(); + for (Map.Entry> variableEqualityEntry : variableToEqualVariables.entrySet()) { + VariableTermImpl variableToReplace = variableEqualityEntry.getKey(); + VariableTermImpl replacementVariable = variableEqualityEntry.getValue().iterator().next(); if (variableToReplace == replacementVariable) { continue; } 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 5610d8594..13499b968 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 @@ -36,7 +36,7 @@ import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; @@ -101,16 +101,16 @@ public static InternalRule fromNormalRule(NormalRule rule) { * @return */ public InternalRule renameVariables(String newVariablePostfix) { - List occurringVariables = new ArrayList<>(); + List occurringVariables = new ArrayList<>(); CoreAtom headAtom = this.getHeadAtom(); occurringVariables.addAll(headAtom.getOccurringVariables()); for (CoreLiteral literal : this.getBody()) { occurringVariables.addAll(literal.getOccurringVariables()); } Unifier variableReplacement = new Unifier(); - for (VariableTerm occurringVariable : occurringVariables) { + for (VariableTermImpl occurringVariable : occurringVariables) { final String newVariableName = occurringVariable.toString() + newVariablePostfix; - variableReplacement.put(occurringVariable, VariableTerm.getInstance(newVariableName)); + variableReplacement.put(occurringVariable, VariableTermImpl.getInstance(newVariableName)); } CoreAtom renamedHeadAtom = headAtom.substitute(variableReplacement); ArrayList renamedBody = new ArrayList<>(this.getBody().size()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java index 4fd96bf73..b3dfc2ebb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHead.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java @@ -4,6 +4,7 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; @@ -14,7 +15,7 @@ * * Copyright (c) 2017-2019, the Alpha Team. */ -public class ChoiceHead extends Head { +public class ChoiceHeadImpl implements ChoiceHead { private final List choiceElements; private final CoreTerm lowerBound; @@ -64,7 +65,7 @@ public CoreTerm getUpperBound() { return upperBound; } - public ChoiceHead(List choiceElements, CoreTerm lowerBound, ComparisonOperator lowerOp, CoreTerm upperBound, ComparisonOperator upperOp) { + public ChoiceHeadImpl(List choiceElements, CoreTerm lowerBound, ComparisonOperator lowerOp, CoreTerm upperBound, ComparisonOperator upperOp) { this.choiceElements = choiceElements; this.lowerBound = lowerBound; this.lowerOp = lowerOp; @@ -109,10 +110,10 @@ public boolean equals(Object obj) { if (obj == null) { return false; } - if (!(obj instanceof ChoiceHead)) { + if (!(obj instanceof ChoiceHeadImpl)) { return false; } - ChoiceHead other = (ChoiceHead) obj; + ChoiceHeadImpl other = (ChoiceHeadImpl) obj; if (this.choiceElements == null) { if (other.choiceElements != null) { return false; 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 c82447564..029df5b12 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 @@ -79,6 +79,7 @@ public AlphaImpl(SystemConfig cfg) { public AlphaImpl() { } + @Override public InputProgramImpl readProgram(InputConfig cfg) throws IOException { InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); InputProgramImpl tmpProg; @@ -93,10 +94,12 @@ public InputProgramImpl readProgram(InputConfig cfg) throws IOException { return prgBuilder.build(); } + @Override public InputProgramImpl 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 InputProgramImpl readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { ProgramParserImpl parser = new ProgramParserImpl(externals); InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); @@ -114,19 +117,23 @@ public InputProgramImpl readProgramFiles(boolean literate, Map externals) { ProgramParserImpl parser = new ProgramParserImpl(externals); return parser.parse(aspString); } + @Override public InputProgramImpl readProgramString(String aspString) { return readProgramString(aspString, null); } + // TODO make sure to adapt this without exposing internal imnplementation types public NormalProgram normalizeProgram(InputProgramImpl program) { return new NormalizeProgramTransformation(config.isUseNormalizationGrid()).apply(program); } + // TODO make sure to adapt this without exposing internal imnplementation types public InternalProgram performProgramPreprocessing(InternalProgram program) { LOGGER.debug("Preprocessing InternalProgram!"); InternalProgram retVal = program; @@ -137,6 +144,7 @@ public InternalProgram performProgramPreprocessing(InternalProgram program) { return retVal; } + // TODO make sure to adapt this without exposing internal imnplementation types public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { LOGGER.debug("Preprocessing AnalyzedProgram!"); InternalProgram retVal = program; diff --git a/api/build.gradle b/api/build.gradle deleted file mode 100644 index 105ea638a..000000000 --- a/api/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -plugins { - id 'alpha.java-library-conventions' -} - -dependencies { - implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7' - implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' - implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' - implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' -} - diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java deleted file mode 100644 index a267fc6f4..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.api; - -public interface Alpha { -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java deleted file mode 100644 index 928f2cf99..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java +++ /dev/null @@ -1,27 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.externals; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This annotation is used for discovery of method that represent - * external predicates at runtime. - * - * In order to have your method detected by Alpha, annotate it - * with this annotation and call {@link Externals#scan}. - * - * @see Externals#scan - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Predicate { - /** - * The name of the predicate that will be used to refer to - * the annotated method. If it is the empty string (which - * is also the default value), then the name of the annotated - * method will be used. - */ - String name() default ""; -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java deleted file mode 100644 index 8f745e556..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToObjectMapper.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.api.mapper; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; - -/** - * Copyright (c) 2020, the Alpha Team. - * - * Interface definition for an adapter that maps from an {@link AnswerSet} to an instance of the implementation's generic type T. - * - * @param the type to which to map answer sets - */ -public interface AnswerSetToObjectMapper { - - T mapFromAnswerSet(AnswerSet answerSet); - -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java b/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java deleted file mode 100644 index 4b7af303a..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.api.mapper; - -import java.util.List; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -/** - * Implementation of {@link AnswerSetToObjectMapper} that generates an office open xml workbook ("excel file") from a given answer set. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class AnswerSetToWorkbookMapper implements AnswerSetToObjectMapper { - - private static final Logger LOGGER = LoggerFactory.getLogger(AnswerSetToWorkbookMapper.class); - - /** - * Creates an xlsx workbook containing all the atoms from the given {@link AnswerSet} with one sheet per predicate. All predicates with arity 0 are listed - * in a special sheet called "flags". Caution, potential resource leak: note that the returned workbook needs to be closed by the caller once it has been - * processed (written to file etc). - */ - @Override - public Workbook mapFromAnswerSet(AnswerSet answerSet) { - LOGGER.debug("Start mapping answer set to workbook"); - Workbook workbook = new XSSFWorkbook(); - // create cell style for header cells - CellStyle headerStyle = this.createHeaderStyle(workbook); - - // first, create a worksheet for 0-arity predicates - Sheet flags = this.createSheetWithHeader(workbook, headerStyle, "Flags", "Flags"); - Sheet currentPredicateSheet; - String[] headerContent; - for (Predicate pred : answerSet.getPredicates()) { - if (pred.getArity() == 0) { - this.writeAtomToSheet(flags, answerSet.getPredicateInstances(pred).first()); - } else { - headerContent = new String[pred.getArity()]; - for (int i = 0; i < headerContent.length; i++) { - headerContent[i] = "Attribute " + Integer.toString(i + 1); - } - currentPredicateSheet = this.createSheetWithHeader(workbook, headerStyle, pred.getName() + "_" + pred.getArity(), headerContent); - for (Atom atom : answerSet.getPredicateInstances(pred)) { - this.writeAtomToSheet(currentPredicateSheet, atom); - } - } - } - return workbook; - } - - private void writeAtomToSheet(Sheet sheet, Atom atom) { - int rownum = -1; - if (sheet.getLastRowNum() == 0 && sheet.getRow(0) == null) { - // sheet is empty, start at row zero - rownum = 0; - } else { - rownum = sheet.getLastRowNum() + 1; - } - Row atomRow = sheet.createRow(rownum); - List terms = atom.getTerms(); - Cell currCell; - if (terms.isEmpty()) { - // 0-arity atom - currCell = atomRow.createCell(0); - currCell.setCellValue(atom.getPredicate().getName()); - sheet.autoSizeColumn(0); - } else { - for (int i = 0; i < terms.size(); i++) { - currCell = atomRow.createCell(i); - currCell.setCellValue(terms.get(i).toString()); - sheet.autoSizeColumn(i); - } - } - } - - private CellStyle createHeaderStyle(Workbook workbook) { - CellStyle headerStyle = workbook.createCellStyle(); - Font headerFont = workbook.createFont(); - headerFont.setFontHeightInPoints((short) 11); - headerFont.setBold(true); // (short) 0x74c4f2 - headerStyle.setFont(headerFont); - headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - return headerStyle; - } - - private Sheet createSheetWithHeader(Workbook wb, CellStyle headerStyle, String sheetName, String... headerContent) { - Sheet retVal = wb.createSheet(sheetName); - Row headerRow = retVal.createRow(0); - Cell cell; - for (int i = 0; i < headerContent.length; i++) { - cell = headerRow.createCell(i); - cell.setCellStyle(headerStyle); - cell.setCellValue(headerContent[i]); - } - return retVal; - } - -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java deleted file mode 100644 index 11c98b9e6..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSet.java +++ /dev/null @@ -1,13 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; - -import java.util.SortedSet; - -public interface AnswerSet extends Comparable { - SortedSet getPredicates(); - - SortedSet getPredicateInstances(Predicate predicate); - - boolean isEmpty(); -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java deleted file mode 100644 index 28d5811e4..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/Predicate.java +++ /dev/null @@ -1,7 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -public interface Predicate extends Comparable { - String getName(); - - int getArity(); -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java deleted file mode 100644 index 41bf3da32..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Atom.java +++ /dev/null @@ -1,29 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.atoms; - -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -import java.util.List; - -public interface Atom extends Comparable { - Predicate getPredicate(); - - List getTerms(); - - /** - * Returns whether this atom is ground, i.e., variable-free. - * - * @return true iff the terms of this atom contain no {@link VariableTerm}. - */ - boolean isGround(); - - Literal toLiteral(); - - /** - * Creates a literal containing this atom which will be negated if {@code positive} is {@code false}. - * - * @param positive the polarity of the resulting literal. - * @return a literal that is positive iff the given parameter is true. - */ - Literal toLiteral(boolean positive); -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java deleted file mode 100644 index 12b583fd2..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/Literal.java +++ /dev/null @@ -1,20 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.atoms; - -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -import java.util.List; - -public interface Literal { - Atom getAtom(); - - boolean isNegated(); - - Literal negate(); - - Predicate getPredicate(); - - List getTerms(); - - boolean isGround(); -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java deleted file mode 100644 index e354d35a5..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingPredicateInterpretation.java +++ /dev/null @@ -1,9 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.fixedinterpretations; - -/** - * This interface is used to mark predicate interpretations that might generate - * new bindings. - */ -@FunctionalInterface -public interface BindingPredicateInterpretation extends PredicateInterpretation { -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java deleted file mode 100644 index 96f454b8e..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretation.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -import java.util.List; -import java.util.Set; - -import static java.util.Collections.*; - -@FunctionalInterface -public interface PredicateInterpretation { - 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); -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java deleted file mode 100644 index 4327a4c0e..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/program/Program.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.program; - -public interface Program { -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java deleted file mode 100644 index 0b16a5ecf..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Head.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rules; - -public interface Head { -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java deleted file mode 100644 index 35778c7fb..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/rules/Rule.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rules; - -public interface Rule { -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java deleted file mode 100644 index 795680347..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ConstantTerm.java +++ /dev/null @@ -1,4 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -public interface ConstantTerm> { -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java b/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java deleted file mode 100644 index 9aae02494..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Term.java +++ /dev/null @@ -1,5 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -public interface Term extends Comparable { - boolean isGround(); -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java b/api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java deleted file mode 100644 index 86fbf473a..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/config/AlphaConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package at.ac.tuwien.kr.alpha.config; - -/** - * Wrapper type for AlphaConfig and InputConfig. - */ -public class AlphaConfig { - - private SystemConfig systemConfig; - private InputConfig inputConfig; - - public SystemConfig getSystemConfig() { - return this.systemConfig; - } - - public void setSystemConfig(SystemConfig alphaConfig) { - this.systemConfig = alphaConfig; - } - - public InputConfig getInputConfig() { - return this.inputConfig; - } - - public void setInputConfig(InputConfig inputConfig) { - this.inputConfig = inputConfig; - } - -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java b/api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java deleted file mode 100644 index 12e5d3167..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/config/InputConfig.java +++ /dev/null @@ -1,170 +0,0 @@ -package at.ac.tuwien.kr.alpha.config; - -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; - -import java.util.*; - -public class InputConfig { - - public static final java.util.function.Predicate DEFAULT_FILTER = p -> true; - public static final boolean DEFAULT_LITERATE = false; - public static final int DEFAULT_NUM_ANSWER_SETS = 0; - public static final boolean DEFAULT_WRITE_DEPENDENCY_GRAPH = false; - public static final String DEFAULT_DEPGRAPH_TARGET_FILE = "depgraph.dot"; - public static final boolean DEFAULT_WRITE_COMPONENT_GRAPH = false; - public static final String DEFAULT_COMPGRAPH_TARGET_FILE = "compgraph.dot"; - public static final boolean DEFAULT_WRITE_PREPROCESSED_PROG = false; - public static final String DEFAULT_PREPROC_TARGET_FILE = "input.preproc.asp"; - public static final String PREPROC_STDOUT_PATH = "---"; // indicator preprocessed program should be written to stdout - public static final boolean DEFAULT_WRITE_XLSX = false; - public static final String DEFAULT_XLSX_OUTFILE_PATH = "alphaAnswerSet"; // current directory, files named "alphaAnswerSet.{num}.{ext}" - - private List aspStrings = new ArrayList<>(); - private List files = new ArrayList<>(); - private boolean literate = InputConfig.DEFAULT_LITERATE; - private int numAnswerSets = InputConfig.DEFAULT_NUM_ANSWER_SETS; - private Set desiredPredicates = new HashSet<>(); - private boolean writeDependencyGraph = InputConfig.DEFAULT_WRITE_DEPENDENCY_GRAPH; - private String depgraphPath = InputConfig.DEFAULT_DEPGRAPH_TARGET_FILE; - private boolean writeComponentGraph = InputConfig.DEFAULT_WRITE_COMPONENT_GRAPH; - private String compgraphPath = InputConfig.DEFAULT_COMPGRAPH_TARGET_FILE; - private boolean writePreprocessed = InputConfig.DEFAULT_WRITE_PREPROCESSED_PROG; - private String preprocessedPath = InputConfig.DEFAULT_PREPROC_TARGET_FILE; - // TODO: standard library externals are NOT always loaded, but this was the case before introducing modules - private Map predicateMethods = new HashMap<>(); // Externals.getStandardLibraryExternals(); - private boolean writeAnswerSetsAsXlsx = InputConfig.DEFAULT_WRITE_XLSX; - private String answerSetFileOutputPath; - - public static InputConfig forString(String str) { - InputConfig retVal = new InputConfig(); - retVal.aspStrings.add(str); - return retVal; - } - - public List getAspStrings() { - return this.aspStrings; - } - - public void setAspStrings(List aspStrings) { - this.aspStrings = aspStrings; - } - - public boolean isLiterate() { - return this.literate; - } - - public void setLiterate(boolean literate) { - this.literate = literate; - } - - public int getNumAnswerSets() { - return this.numAnswerSets; - } - - public void setNumAnswerSets(int numAnswerSets) { - this.numAnswerSets = numAnswerSets; - } - - public java.util.function.Predicate getFilter() { - return this.desiredPredicates.isEmpty() ? InputConfig.DEFAULT_FILTER : p -> this.desiredPredicates.contains(p.getName()); - } - - public Map getPredicateMethods() { - return this.predicateMethods; - } - - public void addPredicateMethods(Map predicateMethods) { - for (Map.Entry entry : predicateMethods.entrySet()) { - if (this.predicateMethods.containsKey(entry.getKey())) { - throw new IllegalArgumentException("Input config already contains a predicate interpretation with name " + entry.getKey()); - } - this.predicateMethods.put(entry.getKey(), entry.getValue()); - } - } - - public void addPredicateMethod(String name, PredicateInterpretation interpretation) { - this.predicateMethods.put(name, interpretation); - } - - public List getFiles() { - return this.files; - } - - public void setFiles(List files) { - this.files = files; - } - - public Set getDesiredPredicates() { - return this.desiredPredicates; - } - - public void setDesiredPredicates(Set desiredPredicates) { - this.desiredPredicates = desiredPredicates; - } - - public boolean isWriteDependencyGraph() { - return this.writeDependencyGraph; - } - - public void setWriteDependencyGraph(boolean writeDependencyGraph) { - this.writeDependencyGraph = writeDependencyGraph; - } - - public boolean isWriteComponentGraph() { - return this.writeComponentGraph; - } - - public void setWriteComponentGraph(boolean writeComponentGraph) { - this.writeComponentGraph = writeComponentGraph; - } - - public boolean isWritePreprocessed() { - return this.writePreprocessed; - } - - public void setWritePreprocessed(boolean writePreprocessed) { - this.writePreprocessed = writePreprocessed; - } - - public String getDepgraphPath() { - return this.depgraphPath; - } - - public void setDepgraphPath(String depgraphPath) { - this.depgraphPath = depgraphPath; - } - - public String getCompgraphPath() { - return this.compgraphPath; - } - - public void setCompgraphPath(String compgraphPath) { - this.compgraphPath = compgraphPath; - } - - public String getPreprocessedPath() { - return this.preprocessedPath; - } - - public void setPreprocessedPath(String preprocessedPath) { - this.preprocessedPath = preprocessedPath; - } - - public boolean isWriteAnswerSetsAsXlsx() { - return this.writeAnswerSetsAsXlsx; - } - - public void setWriteAnswerSetsAsXlsx(boolean writeAnswerSetsAsXslx) { - this.writeAnswerSetsAsXlsx = writeAnswerSetsAsXslx; - } - - public String getAnswerSetFileOutputPath() { - return this.answerSetFileOutputPath; - } - - public void setAnswerSetFileOutputPath(String answerSetFileOutputPath) { - this.answerSetFileOutputPath = answerSetFileOutputPath; - } - -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java b/api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java deleted file mode 100644 index 4f38c37ba..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java +++ /dev/null @@ -1,258 +0,0 @@ -/** - * Copyright (c) 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.config; - -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -public class SystemConfig { - - // Note: Defining constants for default values here rather than just - // 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; - public static final boolean DEFAULT_DEBUG_INTERNAL_CHECKS = false; - public static final boolean DEFAULT_USE_NORMALIZATION_GRID = 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; - public static final boolean DEFAULT_GROUNDER_ACCUMULATOR_ENABLED = false; - public static final String DEFAULT_ATOM_SEPARATOR = ", "; - - private String grounderName = SystemConfig.DEFAULT_GROUNDER_NAME; - private String solverName = SystemConfig.DEFAULT_SOLVER_NAME; - private String nogoodStoreName = SystemConfig.DEFAULT_NOGOOD_STORE_NAME; - private boolean deterministic = SystemConfig.DEFAULT_DETERMINISTIC; - private long seed = SystemConfig.DEFAULT_SEED; - private boolean debugInternalChecks = SystemConfig.DEFAULT_DEBUG_INTERNAL_CHECKS; - private Heuristic branchingHeuristic = SystemConfig.DEFAULT_BRANCHING_HEURISTIC; - private BinaryNoGoodPropagationEstimationStrategy momsStrategy = SystemConfig.DEFAULT_MOMS_STRATEGY; - private boolean quiet = SystemConfig.DEFAULT_QUIET; - private boolean printStats = SystemConfig.DEFAULT_PRINT_STATS; - private boolean disableJustificationSearch = SystemConfig.DEFAULT_DISABLE_JUSTIFICATION_SEARCH; - private boolean useNormalizationGrid = SystemConfig.DEFAULT_USE_NORMALIZATION_GRID; - private boolean sortAnswerSets = SystemConfig.DEFAULT_SORT_ANSWER_SETS; - private List replayChoices = SystemConfig.DEFAULT_REPLAY_CHOICES; - private boolean evaluateStratifiedPart = SystemConfig.DEFAULT_STRATIFIED_EVALUATION; - private boolean disableNoGoodDeletion = SystemConfig.DEFAULT_DISABLE_NOGOOD_DELETION; - private String grounderToleranceConstraints = DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS; - private String grounderToleranceRules = DEFAULT_GROUNDER_TOLERANCE_RULES; - private boolean grounderAccumulatorEnabled = DEFAULT_GROUNDER_ACCUMULATOR_ENABLED; - private String atomSeparator = DEFAULT_ATOM_SEPARATOR; - - public String getGrounderName() { - return this.grounderName; - } - - public void setGrounderName(String grounderName) { - this.grounderName = grounderName; - } - - public String getSolverName() { - return this.solverName; - } - - public void setSolverName(String solverName) { - this.solverName = solverName; - } - - public String getNogoodStoreName() { - return this.nogoodStoreName; - } - - public void setNogoodStoreName(String nogoodStoreName) { - this.nogoodStoreName = nogoodStoreName; - } - - public boolean isDeterministic() { - return this.deterministic; - } - - public void setDeterministic(boolean deterministic) { - this.deterministic = deterministic; - } - - public long getSeed() { - return this.seed; - } - - public void setSeed(long seed) { - this.seed = seed; - } - - public boolean isDebugInternalChecks() { - return this.debugInternalChecks; - } - - public void setDebugInternalChecks(boolean debugInternalChecks) { - this.debugInternalChecks = debugInternalChecks; - } - - public Heuristic getBranchingHeuristic() { - return this.branchingHeuristic; - } - - public void setBranchingHeuristic(Heuristic branchingHeuristic) { - this.branchingHeuristic = branchingHeuristic; - } - - public void setBranchingHeuristicName(String branchingHeuristicName) { - this.branchingHeuristic = Heuristic.valueOf(branchingHeuristicName.replace("-", "_").toUpperCase()); - } - - public BinaryNoGoodPropagationEstimationStrategy getMomsStrategy() { - return momsStrategy; - } - - public void setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - this.momsStrategy = momsStrategy; - } - - public void setMomsStrategyName(String momsStrategyName) { - this.momsStrategy = BinaryNoGoodPropagationEstimationStrategy.valueOf(momsStrategyName); - } - - public boolean isQuiet() { - return this.quiet; - } - - public void setQuiet(boolean quiet) { - this.quiet = quiet; - } - - public boolean isPrintStats() { - return this.printStats; - } - - public void setPrintStats(boolean printStats) { - this.printStats = printStats; - } - - public boolean isDisableJustificationSearch() { - return this.disableJustificationSearch; - } - - public void setDisableJustificationSearch(boolean disableJustificationSearch) { - this.disableJustificationSearch = disableJustificationSearch; - } - - public boolean isUseNormalizationGrid() { - return this.useNormalizationGrid; - } - - public void setUseNormalizationGrid(boolean useNormalizationGrid) { - this.useNormalizationGrid = useNormalizationGrid; - } - - public boolean isSortAnswerSets() { - return this.sortAnswerSets; - } - - public void setSortAnswerSets(boolean sortAnswerSets) { - this.sortAnswerSets = sortAnswerSets; - } - - public List getReplayChoices() { - return replayChoices; - } - - public void setReplayChoices(List replayChoices) { - this.replayChoices = replayChoices; - } - - 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; - } - - public void setDisableNoGoodDeletion(boolean disableNoGoodDeletion) { - this.disableNoGoodDeletion = disableNoGoodDeletion; - } - - public String getGrounderToleranceConstraints() { - return grounderToleranceConstraints; - } - - public void setGrounderToleranceConstraints(String grounderToleranceConstraints) { - this.grounderToleranceConstraints = grounderToleranceConstraints; - } - - public String getGrounderToleranceRules() { - return grounderToleranceRules; - } - - public void setGrounderToleranceRules(String grounderToleranceRules) { - this.grounderToleranceRules = grounderToleranceRules; - } - - public boolean isGrounderAccumulatorEnabled() { - return grounderAccumulatorEnabled; - } - - public void setGrounderAccumulatorEnabled(boolean grounderAccumulatorEnabled) { - this.grounderAccumulatorEnabled = grounderAccumulatorEnabled; - } - - public String getAtomSeparator() { - return this.atomSeparator; - } - - public void setAtomSeparator(String atomSeparator) { - this.atomSeparator = atomSeparator; - } -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java b/api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java deleted file mode 100644 index 9348af476..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicsConfiguration.java +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Copyright (c) 2019 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.grounder.heuristics; - -/** - * Contains configuration parameters for heuristics used by {@link at.ac.tuwien.kr.alpha.grounder.Grounder}s. - * - * Both parameters {@link #toleranceConstraints} and {@link #toleranceRules} are interpreted as follows: - * A rule (or constraint) is grounded if the following conditions are satisfied: - *

        - *
      • All variables in the rule are bound (either by positive body literals that are already - * satisfied, or because the whole rule is ground).
      • - *
      • No atom occurring positively in the body is assigned F.
      • - *
      • No atom occurring negatively in the body is true as a fact. - * (Note: The rule is still grounded if an atom occurring negatively in the body is assigned true without - * being a fact, because the alternative would necessitate triggering re-grounding during backtracking.)
      • - *
      • At most {@code N} atoms occurring positively in the body are still unassigned.
      • - *
      - * - * The parameter {@link #toleranceConstraints} specifies {@code N} for constraints, while {@link #toleranceRules} - * specifies {@code N} for all other rules. Infinity is represented by the value {@code -1}. - * The default value for both parameters is {@code 0}, which means that only those rules and constraints are - * grounded whose positive body is already satisfied. - * - * The additional parameter {@link #accumulatorEnabled} is a switch for the accumulator grounding strategy - * which disables the removal of instances from the grounder memory in certain cases. - * - */ -public class GrounderHeuristicsConfiguration { - - public static final String STRICT_STRING = "strict"; - public static final int STRICT_INT = 0; - public static final String PERMISSIVE_STRING = "permissive"; - public static final int PERMISSIVE_INT = -1; - - private int toleranceConstraints; - private int toleranceRules; - private boolean accumulatorEnabled; - - public GrounderHeuristicsConfiguration() { - super(); - this.toleranceConstraints = STRICT_INT; - this.toleranceRules = STRICT_INT; - } - - /** - * @param toleranceConstraints - * @param toleranceRules - */ - private GrounderHeuristicsConfiguration(int toleranceConstraints, int toleranceRules) { - super(); - this.toleranceConstraints = toleranceConstraints; - this.toleranceRules = toleranceRules; - } - - /** - * @return the tolerance for constraints - */ - public int getToleranceConstraints() { - return toleranceConstraints; - } - - /** - * @return the tolerance for rules that are not constraints - */ - public int getToleranceRules() { - return toleranceRules; - } - - /** - * @param ruleIsConstraint {@code true} iff the parameter for constraints shall be returned - * @return {@link #getToleranceConstraints()} if {@code ruleIsConstraint}, otherwise {@link #getToleranceRules()} - */ - public int getTolerance(boolean ruleIsConstraint) { - return ruleIsConstraint ? getToleranceConstraints() : getToleranceRules(); - } - - /** - * @param ruleIsConstraint {@code true} iff the parameter for constraints shall be returned - * @return {@code true} iff the tolerance is not 0 - */ - public boolean isPermissive(boolean ruleIsConstraint) { - return getTolerance(ruleIsConstraint) != STRICT_INT; - } - - public boolean isAccumulatorEnabled() { - return accumulatorEnabled; - } - - public void setAccumulatorEnabled(boolean accumulatorEnabled) { - this.accumulatorEnabled = accumulatorEnabled; - } - - public static GrounderHeuristicsConfiguration strict() { - return new GrounderHeuristicsConfiguration(STRICT_INT, STRICT_INT); - } - - public static GrounderHeuristicsConfiguration permissive() { - return new GrounderHeuristicsConfiguration(PERMISSIVE_INT, PERMISSIVE_INT); - } - - public static GrounderHeuristicsConfiguration getInstance(int toleranceConstraints, int toleranceRules) { - return new GrounderHeuristicsConfiguration(toleranceConstraints, toleranceRules); - } - - public static GrounderHeuristicsConfiguration getInstance(String toleranceConstraints, String toleranceRules) { - return getInstance(parseTolerance(toleranceConstraints), parseTolerance(toleranceRules)); - } - - private static int parseTolerance(String tolerance) { - if (STRICT_STRING.equalsIgnoreCase(tolerance)) { - return STRICT_INT; - } else if (PERMISSIVE_STRING.equalsIgnoreCase(tolerance)) { - return PERMISSIVE_INT; - } else { - return Integer.parseInt(tolerance); - } - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "(toleranceConstraints=" + toleranceConstraints + ",toleranceRules=" + toleranceRules + ",disableInstanceRemoval=" + accumulatorEnabled + ")"; - } - -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java b/api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java deleted file mode 100644 index bf3ad5242..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimationStrategy.java +++ /dev/null @@ -1,27 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import java.util.Arrays; -import java.util.stream.Collectors; - -/** - * Strategies to estimate the amount of influence of a literal. - */ -public enum BinaryNoGoodPropagationEstimationStrategy { - /** - * Counts binary watches involving the literal under consideration - */ - CountBinaryWatches, - - /** - * Assigns true to the literal under consideration, then does propagation only on binary nogoods - * and counts how many other atoms are assigned during this process, then backtracks - */ - BinaryNoGoodPropagation; - - /** - * @return a comma-separated list of names of known heuristics - */ - public static String listAllowedValues() { - return Arrays.stream(values()).map(BinaryNoGoodPropagationEstimationStrategy::toString).collect(Collectors.joining(", ")); - } -} diff --git a/api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java b/api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java deleted file mode 100644 index f9aa16953..000000000 --- a/api/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/Heuristic.java +++ /dev/null @@ -1,52 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver.heuristics; - -import java.util.Arrays; -import java.util.stream.Collectors; - -/** - * The available domain-independent heuristics. - * Some are deprecated because they perform poorly and have not been improved for some time, - * however the code is kept for now so that it stays compatible when interfaces are refactored. - */ -public enum Heuristic { - NAIVE, - BERKMIN, - BERKMINLITERAL, - @Deprecated - DD, - @Deprecated - DD_SUM, - @Deprecated - DD_AVG, - @Deprecated - DD_MAX, - @Deprecated - DD_MIN, - @Deprecated - DD_PYRO, - @Deprecated - GDD, - @Deprecated - GDD_SUM, - @Deprecated - GDD_AVG, - @Deprecated - GDD_MAX, - @Deprecated - GDD_MIN, - @Deprecated - GDD_PYRO, - @Deprecated - ALPHA_ACTIVE_RULE, - @Deprecated - ALPHA_HEAD_MBT, - VSIDS, - GDD_VSIDS; - - /** - * @return a comma-separated list of names of known heuristics - */ - public static String listAllowedValues() { - return Arrays.stream(values()).map(Heuristic::toString).collect(Collectors.joining(", ")); - } -} diff --git a/cli/build.gradle b/cli/build.gradle deleted file mode 100644 index a89bb1994..000000000 --- a/cli/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ -plugins { - id 'alpha.java-application-conventions' -} - -dependencies { - implementation project(':core') - implementation project(':api') - - implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' -} - -def mainClassName = 'at.ac.tuwien.kr.alpha.Main' - -application { - mainClass = mainClassName -} - -task bundledJar(type: Jar) { - manifest { - attributes 'Main-Class': mainClassName - } - - from { - configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } - - archiveFileName = "${project.name}-bundled.jar" - - /* - * In order to make sure we don't overwrite NOTICE and LICENSE files coming from dependency - * jars with each other, number them while copying - */ - int i = 1 - rename { name -> (name.equals("NOTICE.txt") || name.equals("NOTICE")) ? "NOTICE." + (i++) + ".txt" : null } - - int j = 1 - rename { name -> (name.equals("LICENSE.txt") || name.equals("LICENSE")) ? "LICENSE." + (j++) + ".txt" : null } - - with jar -} diff --git a/cli/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java deleted file mode 100644 index fc61c4b9b..000000000 --- a/cli/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java +++ /dev/null @@ -1,60 +0,0 @@ -package at.ac.tuwien.kr.alpha; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.function.BiConsumer; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToObjectMapper; -import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToWorkbookMapper; -import at.ac.tuwien.kr.alpha.common.AnswerSet; - -public class AnswerSetToXlsxWriter implements BiConsumer { - - private String targetBasePath; - private AnswerSetToObjectMapper answerSetMapper; - - public AnswerSetToXlsxWriter(String targetBasePath) { - this.targetBasePath = targetBasePath; - this.answerSetMapper = new AnswerSetToWorkbookMapper(); - } - - @Override - public void accept(Integer num, AnswerSet as) { - try { - Path outputPath = Paths.get(this.targetBasePath + "." + num + ".xlsx"); - OutputStream os = Files.newOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); - Workbook wb = this.answerSetMapper.mapFromAnswerSet(as); - wb.write(os); - wb.close(); - os.close(); - System.out.println("Answer set written to file " + outputPath.toString()); - } catch (IOException ex) { - System.err.println("Failed writing answer set as xlsx file! (" + ex.getMessage() + ")"); - } - } - - public static void writeUnsatInfo(Path path) throws IOException { - Workbook workbook = new XSSFWorkbook(); - // first, create a worksheet for 0-arity predicates - Sheet sheet = workbook.createSheet("Unsatisfiable"); - Row row = sheet.createRow(0); - Cell cell = row.createCell(0); - cell.setCellValue("Input is unsatisfiable - No answer sets!"); - sheet.autoSizeColumn(0); - OutputStream os = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); - workbook.write(os); - workbook.close(); - os.close(); - } - -} diff --git a/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java deleted file mode 100644 index da7d22a12..000000000 --- a/cli/src/main/java/at/ac/tuwien/kr/alpha/Main.java +++ /dev/null @@ -1,234 +0,0 @@ -/** - * Copyright (c) 2016-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; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetFormatter; -import at.ac.tuwien.kr.alpha.common.SimpleAnswerSetFormatter; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.graphio.ComponentGraphWriter; -import at.ac.tuwien.kr.alpha.common.graphio.DependencyGraphWriter; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.config.AlphaConfig; -import at.ac.tuwien.kr.alpha.config.CommandLineParser; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.solver.Solver; -import at.ac.tuwien.kr.alpha.solver.SolverMaintainingStatistics; -import org.antlr.v4.runtime.RecognitionException; -import org.apache.commons.cli.ParseException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.nio.file.Paths; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiConsumer; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * Main entry point for Alpha. - */ -public class Main { - - private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); - - private static final String ALPHA_CALL_SYNTAX = "java -jar alpha-bundled.jar" + System.lineSeparator() + "java -jar alpha.jar"; - - public static void main(String[] args) { - CommandLineParser commandLineParser = new CommandLineParser(Main.ALPHA_CALL_SYNTAX, (msg) -> Main.exitWithMessage(msg, 0)); - AlphaConfig cfg = null; - try { - cfg = commandLineParser.parseCommandLine(args); - } catch (ParseException ex) { - System.err.println("Invalid usage: " + ex.getMessage()); - Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); - } - - AlphaImpl alpha = new AlphaImpl(cfg.getSystemConfig()); - - InputProgram program = null; - try { - program = alpha.readProgram(cfg.getInputConfig()); - } catch (RecognitionException e) { - // In case a recognition exception occurred, parseVisit will - // already have printed an error message, so we just exit - // at this point without further logging. - System.exit(1); - } catch (FileNotFoundException e) { - Main.bailOut(e.getMessage()); - } catch (IOException e) { - Main.bailOut("Failed to parse program.", e); - } - - NormalProgram normalized = alpha.normalizeProgram(program); - InternalProgram preprocessed; - InputConfig inputCfg = cfg.getInputConfig(); - if (!(inputCfg.isWriteDependencyGraph() || inputCfg.isWriteComponentGraph())) { - LOGGER.debug("Not writing dependency or component graphs, starting preprocessing..."); - preprocessed = alpha.performProgramPreprocessing(InternalProgram.fromNormalProgram(normalized)); - } else { - LOGGER.debug("Performing program analysis in preparation for writing dependency and/or component graph file..."); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalized); - if (cfg.getInputConfig().isWriteDependencyGraph()) { - Main.writeDependencyGraph(analyzed.getDependencyGraph(), cfg.getInputConfig().getDepgraphPath()); - } - if (cfg.getInputConfig().isWriteComponentGraph()) { - Main.writeComponentGraph(analyzed.getComponentGraph(), cfg.getInputConfig().getCompgraphPath()); - } - preprocessed = alpha.performProgramPreprocessing(analyzed); - } - if (cfg.getInputConfig().isWritePreprocessed()) { - Main.writeInternalProgram(preprocessed, cfg.getInputConfig().getPreprocessedPath()); - } - Main.computeAndConsumeAnswerSets(alpha, cfg.getInputConfig(), preprocessed); - } - - /** - * Writes the given {@link DependencyGraph} to the destination passed as the second parameter - * - * @param dg the dependency graph to write - * @param path the path to write the graph to - */ - private static void writeDependencyGraph(DependencyGraph dg, String path) { - DependencyGraphWriter depGraphWriter = new DependencyGraphWriter(); - try (FileOutputStream os = new FileOutputStream(new File(path))) { - depGraphWriter.writeAsDot(dg, os); - } catch (IOException ex) { - Main.bailOut("Error writing dependency graph: " + ex.getMessage()); - } - } - - /** - * Writes the given {@link ComponentGraph} to the destination passed as the second parameter - * - * @param cg the component graph to write - * @param path the path to write the graph to - */ - private static void writeComponentGraph(ComponentGraph cg, String path) { - ComponentGraphWriter compGraphWriter = new ComponentGraphWriter(); - try (FileOutputStream os = new FileOutputStream(new File(path))) { - compGraphWriter.writeAsDot(cg, os); - } catch (IOException ex) { - Main.bailOut("Error writing component graph: " + ex.getMessage()); - } - - } - - /** - * Writes the given {@link InternalProgram} to the destination passed as the second parameter - * - * @param prg the program to write - * @param path the path to write the program to - */ - private static void writeInternalProgram(InternalProgram prg, String path) { - LOGGER.debug("Writing preprocessed program to {}", path); - PrintStream ps; - try { - if (path.equals(InputConfig.PREPROC_STDOUT_PATH)) { - ps = System.out; - } else { - ps = new PrintStream(new File(path)); - } - ps.println(prg.toString()); - } catch (IOException ex) { - LOGGER.error("Failed writing preprocessed program file", ex); - Main.bailOut("Failed writing preprocessed program file " + ex.getMessage()); - } - } - - private static void computeAndConsumeAnswerSets(AlphaImpl alpha, InputConfig inputCfg, InternalProgram program) { - Solver solver = alpha.prepareSolverFor(program, inputCfg.getFilter()); - Stream stream = solver.stream(); - if (alpha.getConfig().isSortAnswerSets()) { - stream = stream.sorted(); - } - - int limit = inputCfg.getNumAnswerSets(); - if (limit > 0) { - stream = stream.limit(limit); - } - - if (!alpha.getConfig().isQuiet()) { - AtomicInteger counter = new AtomicInteger(0); - final BiConsumer answerSetHandler; - final AnswerSetFormatter fmt = new SimpleAnswerSetFormatter(alpha.getConfig().getAtomSeparator()); - BiConsumer stdoutPrinter = (n, as) -> { - System.out.println("Answer set " + Integer.toString(n) + ":" + System.lineSeparator() + fmt.format(as)); - }; - if (inputCfg.isWriteAnswerSetsAsXlsx()) { - BiConsumer xlsxWriter = new AnswerSetToXlsxWriter(inputCfg.getAnswerSetFileOutputPath()); - answerSetHandler = stdoutPrinter.andThen(xlsxWriter); - } else { - answerSetHandler = stdoutPrinter; - } - stream.forEach(as -> { - int cnt = counter.incrementAndGet(); - answerSetHandler.accept(cnt, as); - }); - if (counter.get() == 0) { - System.out.println("UNSATISFIABLE"); - if (inputCfg.isWriteAnswerSetsAsXlsx()) { - try { - AnswerSetToXlsxWriter.writeUnsatInfo(Paths.get(inputCfg.getAnswerSetFileOutputPath() + ".UNSAT.xlsx")); - } catch (IOException ex) { - System.err.println("Failed writing unsat file!"); - } - } - } else { - System.out.println("SATISFIABLE"); - } - } else { - // Note: Even though we are not consuming the result, we will still compute - // answer sets. - stream.collect(Collectors.toList()); - } - if (alpha.getConfig().isPrintStats()) { - ((SolverMaintainingStatistics) solver).printStatistics(); - } - } - - private static void exitWithMessage(String msg, int exitCode) { - System.out.println(msg); - System.exit(exitCode); - } - - private static void bailOut(String format, Object... arguments) { - LOGGER.error(format, arguments); - System.exit(1); - } - -} diff --git a/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java deleted file mode 100644 index 054f01654..000000000 --- a/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java +++ /dev/null @@ -1,11 +0,0 @@ -package at.ac.tuwien.kr.alpha.config; - -import org.apache.commons.cli.Option; -import org.apache.commons.cli.ParseException; - -@FunctionalInterface -public interface CliOptionHandler { - - void handleOption(Option opt, T dest) throws ParseException; - -} diff --git a/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java b/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java deleted file mode 100644 index dca1d5d90..000000000 --- a/cli/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java +++ /dev/null @@ -1,482 +0,0 @@ -/** - * Copyright (c) 2016-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.config; - -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.heuristics.Heuristic; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.text.StringEscapeUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; - -/** - * Parses given argument lists (as passed when Alpha is called from command line) into {@link SystemConfig}s and - * {@link InputConfig}s. - * - */ -public class CommandLineParser { - - private static final Logger LOGGER = LoggerFactory.getLogger(CommandLineParser.class); - - //@formatter:off - /* - * Whenever a new command line option is added, perform the following steps: - * 1. Add it as a constant option below. - * 2. Add the constant option into the Options "CLI_OPTS" in the static initializer. - * 3. Add a handler method for it and add the respective map entry in initializeGlobalOptionHandlers - * or initializeInputOptionHandlers with a method reference to the handler. - */ - - // "special", i.e. non-configuration options - private static final Option OPT_HELP = Option.builder("h").longOpt("help").hasArg(false).desc("shows this help").build(); - - // input-specific options - private static final Option OPT_INPUT = Option.builder("i").longOpt("input").hasArg(true).argName("file").type(FileInputStream.class) - .desc("read ASP program from this file").build(); - private static final Option OPT_NUM_ANSWER_SETS = Option.builder("n").longOpt("numAS").hasArg(true).argName("number").type(Integer.class) - .desc("the number of answer sets to compute (default: compute all)").build(); - private static final Option OPT_FILTER = Option.builder("f").longOpt("filter").hasArg(true).argName("filter").valueSeparator(',') - .desc("predicates to show when printing answer sets").build(); - private static final Option OPT_ASPSTRING = Option.builder("str").longOpt("aspstring").hasArg(true).argName("program").type(String.class) - .desc("provide the asp program as a string").build(); - private static final Option OPT_LITERATE = Option.builder("l").longOpt("literate") - .desc("enable literate programming mode (default: " + InputConfig.DEFAULT_LITERATE + ")").build(); - private static final Option OPT_WRITE_PREPROCESSED = Option.builder("wpp").longOpt("writePreprocessedProgram").hasArg(true).argName("target") - .desc("write the internal program that is passed into the solver after transformations to a file. Writing to STDOUT is possible by setting target to: " + InputConfig.PREPROC_STDOUT_PATH).build(); - private static final Option OPT_WRITE_DEPGRAPH = Option.builder("wdg").longOpt("writeDependencyGraph").hasArg(true).argName("target") - .desc("Write a dot file with the input program's dependency graph").build(); - private static final Option OPT_WRITE_COMPGRAPH = Option.builder("wcg").longOpt("writeComponentGraph").hasArg(true).argName("target") - .desc("Write a dot file with the input program's component graph").build(); - private static final Option OPT_WRITE_XSLX = Option.builder("wx").longOpt("write-xlsx").hasArg(true).argName("path").type(String.class) - .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("dbg").longOpt("DebugEnableInternalChecks") - .desc("run additional (time-consuming) safety checks (default: " + SystemConfig.DEFAULT_DEBUG_INTERNAL_CHECKS + ")").build(); - private static final Option OPT_BRANCHING_HEURISTIC = Option.builder("b").longOpt("branchingHeuristic").hasArg(true).argName("heuristic") - .desc("the branching heuristic to use (default: " + SystemConfig.DEFAULT_BRANCHING_HEURISTIC.name() + ")").build(); - private static final Option OPT_MOMS_STRATEGY = Option.builder("ms").longOpt("momsStrategy").hasArg(true).argName("strategy") - .desc("strategy for mom's heuristic (CountBinaryWatches or BinaryNoGoodPropagation, default: " + SystemConfig.DEFAULT_MOMS_STRATEGY.name() + ")") - .build(); - private static final Option OPT_REPLAY_CHOICES = Option.builder("rc").longOpt("replayChoices").hasArg().argName("choices") - .desc("comma-separated list of choices to be replayed (each choice is represented by a signed integer whose absolute value designates an atom ID and whose sign designates a truth value)") - .build(); - private static final Option OPT_QUIET = Option.builder("q").longOpt("quiet").desc("do not print answer sets (default: " + SystemConfig.DEFAULT_QUIET) - .build(); - private static final Option OPT_STATS = Option.builder("st").longOpt("stats").desc("print statistics (default: " + SystemConfig.DEFAULT_PRINT_STATS + ")") - .build(); - private static final Option OPT_NO_JUSTIFICATION = Option.builder("dj").longOpt("disableJustifications") - .desc("disable the search for justifications on must-be-true assigned atoms in the solver (default: " - + SystemConfig.DEFAULT_DISABLE_JUSTIFICATION_SEARCH + ")") - .build(); - private static final Option OPT_NORMALIZATION_GRID = Option.builder("ng").longOpt("normalizationCountingGrid") - .desc("use counting grid normalization instead of sorting circuit for #count (default: " + SystemConfig.DEFAULT_USE_NORMALIZATION_GRID + ")") - .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 + ")") - .build(); - private static final Option OPT_GROUNDER_TOLERANCE_CONSTRAINTS = Option.builder("gtc").longOpt("grounderToleranceConstraints") - .desc("grounder tolerance for constraints (default: " + SystemConfig.DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS + ")") - .hasArg().argName("tolerance") - .build(); - private static final Option OPT_GROUNDER_TOLERANCE_RULES = Option.builder("gtr").longOpt("grounderToleranceRules") - .desc("grounder tolerance for rules (default: " + SystemConfig.DEFAULT_GROUNDER_TOLERANCE_RULES + ")") - .hasArg().argName("tolerance") - .build(); - private static final Option OPT_GROUNDER_ACCUMULATOR_ENABLED = Option.builder("acc").longOpt("enableAccumulator") - .desc("activates the accumulator grounding strategy by disabling removal of instances from grounder memory in certain cases (default: " - + SystemConfig.DEFAULT_GROUNDER_ACCUMULATOR_ENABLED + ")") - .build(); - private static final Option OPT_OUTPUT_ATOM_SEPARATOR = Option.builder("sep").longOpt("atomSeparator").hasArg(true).argName("separator") - .desc("a character (sequence) to use as separator for atoms in printed answer sets (default: " - + SystemConfig.DEFAULT_ATOM_SEPARATOR + ")") - .build(); - //@formatter:on - - private static final Options CLI_OPTS = new Options(); - - static { - /* - * Below code adds all options defined above to CLI_OPTS - needed for parsing - */ - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_HELP); - - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NUM_ANSWER_SETS); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_FILTER); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_LITERATE); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_INPUT); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_ASPSTRING); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_XSLX); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_PREPROCESSED); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_DEPGRAPH); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_COMPGRAPH); - - 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); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_MOMS_STRATEGY); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_REPLAY_CHOICES); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_QUIET); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_STATS); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NO_JUSTIFICATION); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NORMALIZATION_GRID); - - 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); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER_ACCUMULATOR_ENABLED); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_OUTPUT_ATOM_SEPARATOR); - } - - /* - * Below maps map commandline options to handler methods. If a new option is added, the appropriate put into the map - * must be added in the constructor - */ - private final Map> globalOptionHandlers = new HashMap<>(); - private final Map> inputOptionHandlers = new HashMap<>(); - private Consumer abortAction; - private String cmdSyntax; - - /** - * Creates a new CommandLineParser. The abortAction described below is passed into the constructor - * externally in order to avoid strongly coupling this class to any other part of the application. Especially an - * abortAction - which likely will include some call like System.exit({state}) - should not be specified by utility - * classes themselves, but rather by the application's main class. - * - * @param cmdLineSyntax a string describing the basic call syntax for the application binary, e.g. "java -jar - * somejar.jar" - * @param abortAction a Consumer that is called when option parsing is aborted, as is the case - * when the "help" option is encountered. - * It expects a string parameter, which is a message accompanying the abort - */ - public CommandLineParser(String cmdLineSyntax, Consumer abortAction) { - this.cmdSyntax = cmdLineSyntax; - this.abortAction = abortAction; - this.initializeGlobalOptionHandlers(); - this.initializeInputOptionHandlers(); - } - - private void initializeGlobalOptionHandlers() { - /* - * below put invocations are used to "register" the handler methods for each commandline option - */ - // 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); - this.globalOptionHandlers.put(CommandLineParser.OPT_MOMS_STRATEGY.getOpt(), this::handleMomsStrategy); - this.globalOptionHandlers.put(CommandLineParser.OPT_REPLAY_CHOICES.getOpt(), this::handleReplayChoices); - this.globalOptionHandlers.put(CommandLineParser.OPT_QUIET.getOpt(), this::handleQuiet); - this.globalOptionHandlers.put(CommandLineParser.OPT_STATS.getOpt(), this::handleStats); - this.globalOptionHandlers.put(CommandLineParser.OPT_NO_JUSTIFICATION.getOpt(), this::handleNoJustification); - this.globalOptionHandlers.put(CommandLineParser.OPT_NORMALIZATION_GRID.getOpt(), this::handleNormalizationGrid); - 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); - this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER_ACCUMULATOR_ENABLED.getOpt(), this::handleGrounderNoInstanceRemoval); - this.globalOptionHandlers.put(CommandLineParser.OPT_OUTPUT_ATOM_SEPARATOR.getOpt(), this::handleAtomSeparator); - } - - private void initializeInputOptionHandlers() { - this.inputOptionHandlers.put(CommandLineParser.OPT_NUM_ANSWER_SETS.getOpt(), this::handleNumAnswerSets); - this.inputOptionHandlers.put(CommandLineParser.OPT_INPUT.getOpt(), this::handleInput); - this.inputOptionHandlers.put(CommandLineParser.OPT_FILTER.getOpt(), this::handleFilters); - this.inputOptionHandlers.put(CommandLineParser.OPT_ASPSTRING.getOpt(), this::handleAspString); - this.inputOptionHandlers.put(CommandLineParser.OPT_LITERATE.getOpt(), this::handleLiterate); - this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_XSLX.getOpt(), this::handleWriteXlsx); - this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_PREPROCESSED.getOpt(), this::handleWritePreprocessed); - this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_DEPGRAPH.getOpt(), this::handleWriteDepgraph); - this.inputOptionHandlers.put(CommandLineParser.OPT_WRITE_COMPGRAPH.getOpt(), this::handleWriteCompgraph); - } - - public AlphaConfig parseCommandLine(String[] args) throws ParseException { - CommandLine commandLine = new DefaultParser().parse(CommandLineParser.CLI_OPTS, args); - if (commandLine.getArgs().length > 0) { - throw new ParseException("Positional arguments { " + StringUtils.join(args, ' ') + " } are invalid!"); - } - AlphaConfig retVal = new AlphaConfig(); - SystemConfig sysConf = new SystemConfig(); - InputConfig inputConf = new InputConfig(); - if (commandLine.hasOption(CommandLineParser.OPT_HELP.getOpt())) { - LOGGER.debug("Found help option!"); - this.handleHelp(); - } else { - this.validate(commandLine); - } - for (Option opt : commandLine.getOptions()) { - this.handleOption(opt, sysConf, inputConf); - } - retVal.setSystemConfig(sysConf); - retVal.setInputConfig(inputConf); - return retVal; - } - - private void handleOption(Option opt, SystemConfig sysConf, InputConfig inputConf) throws ParseException { - CliOptionHandler globalOptionHandler; - CliOptionHandler inputOptionHandler; - globalOptionHandler = this.globalOptionHandlers.get(opt.getOpt()); - if (globalOptionHandler != null) { - globalOptionHandler.handleOption(opt, sysConf); - } else { - inputOptionHandler = this.inputOptionHandlers.get(opt.getOpt()); - if (inputOptionHandler != null) { - inputOptionHandler.handleOption(opt, inputConf); - } else { - throw new ParseException("Cannot handle option: " + opt.getOpt()); - } - } - } - - public String getUsageMessage() { - HelpFormatter formatter = new HelpFormatter(); - // Unfortunately, commons-cli does not offer a method of simply rendering a help - // message into a string, therefore the ByteArrayOutputStream.. - ByteArrayOutputStream helpBuffer = new ByteArrayOutputStream(); - PrintWriter pw = new PrintWriter(helpBuffer); - formatter.printHelp(pw, HelpFormatter.DEFAULT_WIDTH, this.cmdSyntax, "", CommandLineParser.CLI_OPTS, HelpFormatter.DEFAULT_LEFT_PAD, - HelpFormatter.DEFAULT_DESC_PAD, ""); - pw.flush(); - return helpBuffer.toString(); - } - - private void validate(CommandLine commandLine) throws ParseException { - if (!commandLine.hasOption(CommandLineParser.OPT_INPUT.getOpt()) && !commandLine.hasOption(CommandLineParser.OPT_ASPSTRING.getOpt())) { - throw new ParseException("Missing input source - need to specifiy either a file (" + CommandLineParser.OPT_INPUT.getOpt() + ") or a string (" - + CommandLineParser.OPT_ASPSTRING.getOpt() + " - or both)!"); - } - } - - private void handleNumAnswerSets(Option opt, InputConfig cfg) { - String optVal = opt.getValue(); - int limit; - if (optVal != null) { - limit = Integer.valueOf(optVal); - cfg.setNumAnswerSets(limit); - } else { - cfg.setNumAnswerSets(InputConfig.DEFAULT_NUM_ANSWER_SETS); - } - } - - private void handleHelp() { - this.abortAction.accept(this.getUsageMessage()); - } - - private void handleInput(Option opt, InputConfig cfg) { - String optVal = opt.getValue().trim(); - 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)); - } - - private void handleNogoodStore(Option opt, SystemConfig cfg) { - cfg.setNogoodStoreName(opt.getValue(SystemConfig.DEFAULT_NOGOOD_STORE_NAME)); - } - - private void handleFilters(Option opt, InputConfig cfg) { - String pred = opt.getValue().trim(); - cfg.getDesiredPredicates().add(pred); - } - - private void handleAspString(Option opt, InputConfig cfg) { - String optVal = opt.getValue().trim(); - cfg.getAspStrings().add(optVal); - } - - private void handleSort(Option opt, SystemConfig cfg) { - cfg.setSortAnswerSets(true); - } - - 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) { - seed = Long.valueOf(optVal); - cfg.setSeed(seed); - } else { - cfg.setSeed(SystemConfig.DEFAULT_SEED); - } - } - - private void handleInternalChecks(Option opt, SystemConfig cfg) { - cfg.setDebugInternalChecks(true); - } - - private void handleBranchingHeuristic(Option opt, SystemConfig cfg) throws ParseException { - String branchingHeuristicName = opt.getValue(SystemConfig.DEFAULT_BRANCHING_HEURISTIC.name()); - try { - cfg.setBranchingHeuristicName(branchingHeuristicName); - } catch (IllegalArgumentException e) { - throw new ParseException( - "Unknown branching heuristic: " + branchingHeuristicName + ". Please try one of the following: " + Heuristic.listAllowedValues()); - } - } - - private void handleMomsStrategy(Option opt, SystemConfig cfg) throws ParseException { - String momsStrategyName = opt.getValue(SystemConfig.DEFAULT_MOMS_STRATEGY.name()); - try { - cfg.setMomsStrategyName(momsStrategyName); - } catch (IllegalArgumentException e) { - throw new ParseException("Unknown mom's strategy: " + momsStrategyName + ". Please try one of the following: " - + BinaryNoGoodPropagationEstimationStrategy.listAllowedValues()); - } - } - - private void handleReplayChoices(Option opt, SystemConfig cfg) throws ParseException { - String replayChoices = opt.getValue(SystemConfig.DEFAULT_REPLAY_CHOICES.toString()); - try { - cfg.setReplayChoices(replayChoices); - } catch (NumberFormatException e) { - throw new ParseException("Cannot parse list of signed integers indicating choices to be replayed: " + replayChoices); - } - } - - private void handleQuiet(Option opt, SystemConfig cfg) { - cfg.setQuiet(true); - } - - private void handleLiterate(Option opt, InputConfig cfg) { - cfg.setLiterate(true); - } - - private void handleWriteXlsx(Option opt, InputConfig cfg) { - cfg.setWriteAnswerSetsAsXlsx(true); - String outputPath = opt.getValue(InputConfig.DEFAULT_XLSX_OUTFILE_PATH); - cfg.setAnswerSetFileOutputPath(outputPath); - } - - private void handleStats(Option opt, SystemConfig cfg) { - cfg.setPrintStats(true); - } - - private void handleNoJustification(Option opt, SystemConfig cfg) { - cfg.setDisableJustificationSearch(true); - } - - private void handleNormalizationGrid(Option opt, SystemConfig cfg) { - cfg.setUseNormalizationGrid(true); - } - - private void handleDisableStratifedEval(Option opt, SystemConfig cfg) { - cfg.setEvaluateStratifiedPart(false); - } - - private void handleWritePreprocessed(Option opt, InputConfig cfg) { - cfg.setWritePreprocessed(true); - String preprocessedPath = opt.getValue(InputConfig.DEFAULT_PREPROC_TARGET_FILE); - cfg.setPreprocessedPath(preprocessedPath); - } - - private void handleWriteDepgraph(Option opt, InputConfig cfg) { - cfg.setWriteDependencyGraph(true); - String depgraphPath = opt.getValue(InputConfig.DEFAULT_DEPGRAPH_TARGET_FILE); - cfg.setDepgraphPath(depgraphPath); - } - - private void handleWriteCompgraph(Option opt, InputConfig cfg) { - cfg.setWriteComponentGraph(true); - String compgraphPath = opt.getValue(InputConfig.DEFAULT_COMPGRAPH_TARGET_FILE); - cfg.setCompgraphPath(compgraphPath); - } - - private void handleNoNoGoodDeletion(Option opt, SystemConfig cfg) { - cfg.setDisableNoGoodDeletion(true); - } - - private void handleGrounderToleranceConstraints(Option opt, SystemConfig cfg) { - String grounderToleranceConstraints = opt.getValue(SystemConfig.DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS); - cfg.setGrounderToleranceConstraints(grounderToleranceConstraints); - } - - private void handleGrounderToleranceRules(Option opt, SystemConfig cfg) { - String grounderToleranceRules = opt.getValue(SystemConfig.DEFAULT_GROUNDER_TOLERANCE_RULES); - cfg.setGrounderToleranceRules(grounderToleranceRules); - } - - private void handleGrounderNoInstanceRemoval(Option opt, SystemConfig cfg) { - cfg.setGrounderAccumulatorEnabled(true); - } - - private void handleAtomSeparator(Option opt, SystemConfig cfg) { - cfg.setAtomSeparator(StringEscapeUtils.unescapeJava(opt.getValue(SystemConfig.DEFAULT_ATOM_SEPARATOR))); - } - -} diff --git a/cli/src/main/resources/logback.xml b/cli/src/main/resources/logback.xml deleted file mode 100644 index 379c1c22e..000000000 --- a/cli/src/main/resources/logback.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - %5relative %.-1level %20.20logger %msg %n - - - - - - - - - - diff --git a/core/build.gradle b/core/build.gradle deleted file mode 100644 index 65fad3019..000000000 --- a/core/build.gradle +++ /dev/null @@ -1,58 +0,0 @@ -plugins { - id 'antlr' - id 'alpha.java-library-conventions' -} - - -def antlrVersion = '4.7' - -/* The following configuration directive is a work-around for a fault in the Gradle - * ANTLR plugin. It would require both antlr4 and antlr4-runtime at compile time and - * at run time, which unnecessarily bloats our JARs. Only antlr4-runtime is needed. - * We therefore remove this extension of antlr dependencies being compile dependencies - * and reintroduce them on our own. - */ -configurations { - implementation { - extendsFrom = extendsFrom.findAll { it != configurations.antlr } - } -} - -dependencies { - api project(':api') - - // We need to give the ANTLR Plugin a hint. - antlr group: 'org.antlr', name: 'antlr4', version: "${antlrVersion}" - - // Re-introduce antlr4-runtime as compile dependency. - implementation group: 'org.antlr', name: 'antlr4-runtime', version: "${antlrVersion}" -} - -tasks.withType(AntlrTask) { - // See https://github.com/antlr/antlr4/blob/master/doc/tool-options.md - arguments += [ - "-visitor", - "-no-listener", - "-long-messages", - "-package", "at.ac.tuwien.kr.alpha.antlr", - "-Werror", - "-Xlog", - "-lib", "src/main/antlr/at/ac/tuwien/kr/alpha/antlr" - ] -} - -jacocoTestReport { - reports { - xml.enabled = true - } - - // NOTE: Contents of the antlr subpackage are autogenerated (see configuration of - // AntlrTasks above). It does not make sense to include them in our coverage - // report. - afterEvaluate { - getClassDirectories().setFrom(files(classDirectories.files.collect { - fileTree(dir: it, exclude: "at/ac/tuwien/kr/alpha/antlr/**") - })) - } -} - diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java deleted file mode 100644 index 2a6ff3bbb..000000000 --- a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2BaseVisitor.java +++ /dev/null @@ -1,350 +0,0 @@ -// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 -package at.ac.tuwien.kr.alpha.antlr; -import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; - -/** - * This class provides an empty implementation of {@link ASPCore2Visitor}, - * which can be extended to create a visitor which only needs to handle a subset - * of the available methods. - * - * @param The return type of the visit operation. Use {@link Void} for - * operations with no return type. - */ -public class ASPCore2BaseVisitor extends AbstractParseTreeVisitor implements ASPCore2Visitor { - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitProgram(ASPCore2Parser.ProgramContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitStatements(ASPCore2Parser.StatementsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitQuery(ASPCore2Parser.QueryContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitStatement_rule(ASPCore2Parser.Statement_ruleContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitStatement_weightConstraint(ASPCore2Parser.Statement_weightConstraintContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitStatement_directive(ASPCore2Parser.Statement_directiveContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitHead(ASPCore2Parser.HeadContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitBody(ASPCore2Parser.BodyContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitChoice(ASPCore2Parser.ChoiceContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitAggregate(ASPCore2Parser.AggregateContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitAggregate_elements(ASPCore2Parser.Aggregate_elementsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitAggregate_function(ASPCore2Parser.Aggregate_functionContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitWeight_at_level(ASPCore2Parser.Weight_at_levelContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitClassical_literal(ASPCore2Parser.Classical_literalContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitBinop(ASPCore2Parser.BinopContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerms(ASPCore2Parser.TermsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_const(ASPCore2Parser.Term_constContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_variable(ASPCore2Parser.Term_variableContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitTerm_parenthesisedTerm(ASPCore2Parser.Term_parenthesisedTermContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitInterval(ASPCore2Parser.IntervalContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitExternal_atom(ASPCore2Parser.External_atomContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitDirective(ASPCore2Parser.DirectiveContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitGround_term(ASPCore2Parser.Ground_termContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

      The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

      - */ - @Override public T visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { return visitChildren(ctx); } -} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java deleted file mode 100644 index f4de95f3f..000000000 --- a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Lexer.java +++ /dev/null @@ -1,218 +0,0 @@ -// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 -package at.ac.tuwien.kr.alpha.antlr; -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class ASPCore2Lexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - T__0=1, ANONYMOUS_VARIABLE=2, DOT=3, COMMA=4, QUERY_MARK=5, COLON=6, SEMICOLON=7, - OR=8, NAF=9, CONS=10, WCONS=11, PLUS=12, MINUS=13, TIMES=14, DIV=15, POWER=16, - MODULO=17, BITXOR=18, AT=19, SHARP=20, AMPERSAND=21, QUOTE=22, PAREN_OPEN=23, - PAREN_CLOSE=24, SQUARE_OPEN=25, SQUARE_CLOSE=26, CURLY_OPEN=27, CURLY_CLOSE=28, - EQUAL=29, UNEQUAL=30, LESS=31, GREATER=32, LESS_OR_EQ=33, GREATER_OR_EQ=34, - AGGREGATE_COUNT=35, AGGREGATE_MAX=36, AGGREGATE_MIN=37, AGGREGATE_SUM=38, - ID=39, VARIABLE=40, NUMBER=41, QUOTED_STRING=42, COMMENT=43, MULTI_LINE_COMMEN=44, - BLANK=45; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE" - }; - - public static final String[] ruleNames = { - "T__0", "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", "SEMICOLON", - "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", "POWER", - "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", - "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", - "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", - "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", - "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", - "BLANK" - }; - - private static final String[] _LITERAL_NAMES = { - null, "'enumeration_predicate_is'", "'_'", "'.'", "','", "'?'", "':'", - "';'", "'|'", "'not'", "':-'", "':~'", "'+'", "'-'", "'*'", "'/'", "'**'", - "'\\'", "'^'", "'@'", "'#'", "'&'", "'\"'", "'('", "')'", "'['", "']'", - "'{'", "'}'", "'='", null, "'<'", "'>'", "'<='", "'>='", "'#count'", "'#max'", - "'#min'", "'#sum'" - }; - private static final String[] _SYMBOLIC_NAMES = { - null, null, "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", - "SEMICOLON", "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", - "POWER", "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", - "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", - "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", - "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", - "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", - "BLANK" - }; - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public ASPCore2Lexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "ASPCore2.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2/\u011a\b\1\4\2\t"+ - "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ - "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ - "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ - "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ - "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ - ",\t,\4-\t-\4.\t.\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3"+ - "\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5"+ - "\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3"+ - "\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\21\3\22\3\22"+ - "\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31"+ - "\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\37\3\37\3\37\3\37"+ - "\5\37\u00b8\n\37\3 \3 \3!\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3$\3$\3$\3"+ - "$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3(\3(\7(\u00dc\n("+ - "\f(\16(\u00df\13(\3)\3)\7)\u00e3\n)\f)\16)\u00e6\13)\3*\3*\3*\7*\u00eb"+ - "\n*\f*\16*\u00ee\13*\5*\u00f0\n*\3+\3+\3+\3+\7+\u00f6\n+\f+\16+\u00f9"+ - "\13+\3+\3+\3,\3,\7,\u00ff\n,\f,\16,\u0102\13,\3,\3,\3-\3-\3-\3-\7-\u010a"+ - "\n-\f-\16-\u010d\13-\3-\3-\3-\3-\3-\3.\6.\u0115\n.\r.\16.\u0116\3.\3."+ - "\4\u00f7\u010b\2/\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31"+ - "\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65"+ - "\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/\3\2\5\6\2\62;C\\a"+ - "ac|\4\2\f\f\17\17\5\2\13\f\16\17\"\"\2\u0123\2\3\3\2\2\2\2\5\3\2\2\2\2"+ - "\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2"+ - "\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2"+ - "\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2"+ - "\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2"+ - "\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2"+ - "\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2"+ - "M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3"+ - "\2\2\2\2[\3\2\2\2\3]\3\2\2\2\5v\3\2\2\2\7x\3\2\2\2\tz\3\2\2\2\13|\3\2"+ - "\2\2\r~\3\2\2\2\17\u0080\3\2\2\2\21\u0082\3\2\2\2\23\u0084\3\2\2\2\25"+ - "\u0088\3\2\2\2\27\u008b\3\2\2\2\31\u008e\3\2\2\2\33\u0090\3\2\2\2\35\u0092"+ - "\3\2\2\2\37\u0094\3\2\2\2!\u0096\3\2\2\2#\u0099\3\2\2\2%\u009b\3\2\2\2"+ - "\'\u009d\3\2\2\2)\u009f\3\2\2\2+\u00a1\3\2\2\2-\u00a3\3\2\2\2/\u00a5\3"+ - "\2\2\2\61\u00a7\3\2\2\2\63\u00a9\3\2\2\2\65\u00ab\3\2\2\2\67\u00ad\3\2"+ - "\2\29\u00af\3\2\2\2;\u00b1\3\2\2\2=\u00b7\3\2\2\2?\u00b9\3\2\2\2A\u00bb"+ - "\3\2\2\2C\u00bd\3\2\2\2E\u00c0\3\2\2\2G\u00c3\3\2\2\2I\u00ca\3\2\2\2K"+ - "\u00cf\3\2\2\2M\u00d4\3\2\2\2O\u00d9\3\2\2\2Q\u00e0\3\2\2\2S\u00ef\3\2"+ - "\2\2U\u00f1\3\2\2\2W\u00fc\3\2\2\2Y\u0105\3\2\2\2[\u0114\3\2\2\2]^\7g"+ - "\2\2^_\7p\2\2_`\7w\2\2`a\7o\2\2ab\7g\2\2bc\7t\2\2cd\7c\2\2de\7v\2\2ef"+ - "\7k\2\2fg\7q\2\2gh\7p\2\2hi\7a\2\2ij\7r\2\2jk\7t\2\2kl\7g\2\2lm\7f\2\2"+ - "mn\7k\2\2no\7e\2\2op\7c\2\2pq\7v\2\2qr\7g\2\2rs\7a\2\2st\7k\2\2tu\7u\2"+ - "\2u\4\3\2\2\2vw\7a\2\2w\6\3\2\2\2xy\7\60\2\2y\b\3\2\2\2z{\7.\2\2{\n\3"+ - "\2\2\2|}\7A\2\2}\f\3\2\2\2~\177\7<\2\2\177\16\3\2\2\2\u0080\u0081\7=\2"+ - "\2\u0081\20\3\2\2\2\u0082\u0083\7~\2\2\u0083\22\3\2\2\2\u0084\u0085\7"+ - "p\2\2\u0085\u0086\7q\2\2\u0086\u0087\7v\2\2\u0087\24\3\2\2\2\u0088\u0089"+ - "\7<\2\2\u0089\u008a\7/\2\2\u008a\26\3\2\2\2\u008b\u008c\7<\2\2\u008c\u008d"+ - "\7\u0080\2\2\u008d\30\3\2\2\2\u008e\u008f\7-\2\2\u008f\32\3\2\2\2\u0090"+ - "\u0091\7/\2\2\u0091\34\3\2\2\2\u0092\u0093\7,\2\2\u0093\36\3\2\2\2\u0094"+ - "\u0095\7\61\2\2\u0095 \3\2\2\2\u0096\u0097\7,\2\2\u0097\u0098\7,\2\2\u0098"+ - "\"\3\2\2\2\u0099\u009a\7^\2\2\u009a$\3\2\2\2\u009b\u009c\7`\2\2\u009c"+ - "&\3\2\2\2\u009d\u009e\7B\2\2\u009e(\3\2\2\2\u009f\u00a0\7%\2\2\u00a0*"+ - "\3\2\2\2\u00a1\u00a2\7(\2\2\u00a2,\3\2\2\2\u00a3\u00a4\7$\2\2\u00a4.\3"+ - "\2\2\2\u00a5\u00a6\7*\2\2\u00a6\60\3\2\2\2\u00a7\u00a8\7+\2\2\u00a8\62"+ - "\3\2\2\2\u00a9\u00aa\7]\2\2\u00aa\64\3\2\2\2\u00ab\u00ac\7_\2\2\u00ac"+ - "\66\3\2\2\2\u00ad\u00ae\7}\2\2\u00ae8\3\2\2\2\u00af\u00b0\7\177\2\2\u00b0"+ - ":\3\2\2\2\u00b1\u00b2\7?\2\2\u00b2<\3\2\2\2\u00b3\u00b4\7>\2\2\u00b4\u00b8"+ - "\7@\2\2\u00b5\u00b6\7#\2\2\u00b6\u00b8\7?\2\2\u00b7\u00b3\3\2\2\2\u00b7"+ - "\u00b5\3\2\2\2\u00b8>\3\2\2\2\u00b9\u00ba\7>\2\2\u00ba@\3\2\2\2\u00bb"+ - "\u00bc\7@\2\2\u00bcB\3\2\2\2\u00bd\u00be\7>\2\2\u00be\u00bf\7?\2\2\u00bf"+ - "D\3\2\2\2\u00c0\u00c1\7@\2\2\u00c1\u00c2\7?\2\2\u00c2F\3\2\2\2\u00c3\u00c4"+ - "\7%\2\2\u00c4\u00c5\7e\2\2\u00c5\u00c6\7q\2\2\u00c6\u00c7\7w\2\2\u00c7"+ - "\u00c8\7p\2\2\u00c8\u00c9\7v\2\2\u00c9H\3\2\2\2\u00ca\u00cb\7%\2\2\u00cb"+ - "\u00cc\7o\2\2\u00cc\u00cd\7c\2\2\u00cd\u00ce\7z\2\2\u00ceJ\3\2\2\2\u00cf"+ - "\u00d0\7%\2\2\u00d0\u00d1\7o\2\2\u00d1\u00d2\7k\2\2\u00d2\u00d3\7p\2\2"+ - "\u00d3L\3\2\2\2\u00d4\u00d5\7%\2\2\u00d5\u00d6\7u\2\2\u00d6\u00d7\7w\2"+ - "\2\u00d7\u00d8\7o\2\2\u00d8N\3\2\2\2\u00d9\u00dd\4c|\2\u00da\u00dc\t\2"+ - "\2\2\u00db\u00da\3\2\2\2\u00dc\u00df\3\2\2\2\u00dd\u00db\3\2\2\2\u00dd"+ - "\u00de\3\2\2\2\u00deP\3\2\2\2\u00df\u00dd\3\2\2\2\u00e0\u00e4\4C\\\2\u00e1"+ - "\u00e3\t\2\2\2\u00e2\u00e1\3\2\2\2\u00e3\u00e6\3\2\2\2\u00e4\u00e2\3\2"+ - "\2\2\u00e4\u00e5\3\2\2\2\u00e5R\3\2\2\2\u00e6\u00e4\3\2\2\2\u00e7\u00f0"+ - "\7\62\2\2\u00e8\u00ec\4\63;\2\u00e9\u00eb\4\62;\2\u00ea\u00e9\3\2\2\2"+ - "\u00eb\u00ee\3\2\2\2\u00ec\u00ea\3\2\2\2\u00ec\u00ed\3\2\2\2\u00ed\u00f0"+ - "\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ef\u00e7\3\2\2\2\u00ef\u00e8\3\2\2\2\u00f0"+ - "T\3\2\2\2\u00f1\u00f7\5-\27\2\u00f2\u00f3\7^\2\2\u00f3\u00f6\7$\2\2\u00f4"+ - "\u00f6\13\2\2\2\u00f5\u00f2\3\2\2\2\u00f5\u00f4\3\2\2\2\u00f6\u00f9\3"+ - "\2\2\2\u00f7\u00f8\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f8\u00fa\3\2\2\2\u00f9"+ - "\u00f7\3\2\2\2\u00fa\u00fb\5-\27\2\u00fbV\3\2\2\2\u00fc\u0100\7\'\2\2"+ - "\u00fd\u00ff\n\3\2\2\u00fe\u00fd\3\2\2\2\u00ff\u0102\3\2\2\2\u0100\u00fe"+ - "\3\2\2\2\u0100\u0101\3\2\2\2\u0101\u0103\3\2\2\2\u0102\u0100\3\2\2\2\u0103"+ - "\u0104\b,\2\2\u0104X\3\2\2\2\u0105\u0106\7\'\2\2\u0106\u0107\7,\2\2\u0107"+ - "\u010b\3\2\2\2\u0108\u010a\13\2\2\2\u0109\u0108\3\2\2\2\u010a\u010d\3"+ - "\2\2\2\u010b\u010c\3\2\2\2\u010b\u0109\3\2\2\2\u010c\u010e\3\2\2\2\u010d"+ - "\u010b\3\2\2\2\u010e\u010f\7,\2\2\u010f\u0110\7\'\2\2\u0110\u0111\3\2"+ - "\2\2\u0111\u0112\b-\2\2\u0112Z\3\2\2\2\u0113\u0115\t\4\2\2\u0114\u0113"+ - "\3\2\2\2\u0115\u0116\3\2\2\2\u0116\u0114\3\2\2\2\u0116\u0117\3\2\2\2\u0117"+ - "\u0118\3\2\2\2\u0118\u0119\b.\2\2\u0119\\\3\2\2\2\r\2\u00b7\u00dd\u00e4"+ - "\u00ec\u00ef\u00f5\u00f7\u0100\u010b\u0116\3\2\3\2"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java deleted file mode 100644 index 491bd12ca..000000000 --- a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Parser.java +++ /dev/null @@ -1,2632 +0,0 @@ -// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 -package at.ac.tuwien.kr.alpha.antlr; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.misc.*; -import org.antlr.v4.runtime.tree.*; -import java.util.List; -import java.util.Iterator; -import java.util.ArrayList; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class ASPCore2Parser extends Parser { - static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - T__0=1, ANONYMOUS_VARIABLE=2, DOT=3, COMMA=4, QUERY_MARK=5, COLON=6, SEMICOLON=7, - OR=8, NAF=9, CONS=10, WCONS=11, PLUS=12, MINUS=13, TIMES=14, DIV=15, POWER=16, - MODULO=17, BITXOR=18, AT=19, SHARP=20, AMPERSAND=21, QUOTE=22, PAREN_OPEN=23, - PAREN_CLOSE=24, SQUARE_OPEN=25, SQUARE_CLOSE=26, CURLY_OPEN=27, CURLY_CLOSE=28, - EQUAL=29, UNEQUAL=30, LESS=31, GREATER=32, LESS_OR_EQ=33, GREATER_OR_EQ=34, - AGGREGATE_COUNT=35, AGGREGATE_MAX=36, AGGREGATE_MIN=37, AGGREGATE_SUM=38, - ID=39, VARIABLE=40, NUMBER=41, QUOTED_STRING=42, COMMENT=43, MULTI_LINE_COMMEN=44, - BLANK=45; - public static final int - RULE_program = 0, RULE_statements = 1, RULE_query = 2, RULE_statement = 3, - RULE_head = 4, RULE_body = 5, RULE_disjunction = 6, RULE_choice = 7, RULE_choice_elements = 8, - RULE_choice_element = 9, RULE_aggregate = 10, RULE_aggregate_elements = 11, - RULE_aggregate_element = 12, RULE_aggregate_function = 13, RULE_weight_at_level = 14, - RULE_naf_literals = 15, RULE_naf_literal = 16, RULE_classical_literal = 17, - RULE_builtin_atom = 18, RULE_binop = 19, RULE_terms = 20, RULE_term = 21, - RULE_interval = 22, RULE_external_atom = 23, RULE_directive = 24, RULE_directive_enumeration = 25, - RULE_basic_terms = 26, RULE_basic_term = 27, RULE_ground_term = 28, RULE_variable_term = 29, - RULE_answer_set = 30, RULE_answer_sets = 31; - public static final String[] ruleNames = { - "program", "statements", "query", "statement", "head", "body", "disjunction", - "choice", "choice_elements", "choice_element", "aggregate", "aggregate_elements", - "aggregate_element", "aggregate_function", "weight_at_level", "naf_literals", - "naf_literal", "classical_literal", "builtin_atom", "binop", "terms", - "term", "interval", "external_atom", "directive", "directive_enumeration", - "basic_terms", "basic_term", "ground_term", "variable_term", "answer_set", - "answer_sets" - }; - - private static final String[] _LITERAL_NAMES = { - null, "'enumeration_predicate_is'", "'_'", "'.'", "','", "'?'", "':'", - "';'", "'|'", "'not'", "':-'", "':~'", "'+'", "'-'", "'*'", "'/'", "'**'", - "'\\'", "'^'", "'@'", "'#'", "'&'", "'\"'", "'('", "')'", "'['", "']'", - "'{'", "'}'", "'='", null, "'<'", "'>'", "'<='", "'>='", "'#count'", "'#max'", - "'#min'", "'#sum'" - }; - private static final String[] _SYMBOLIC_NAMES = { - null, null, "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", - "SEMICOLON", "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", - "POWER", "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", - "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", - "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", - "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", - "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", - "BLANK" - }; - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - @Override - public String getGrammarFileName() { return "ASPCore2.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public ATN getATN() { return _ATN; } - - public ASPCore2Parser(TokenStream input) { - super(input); - _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - public static class ProgramContext extends ParserRuleContext { - public TerminalNode EOF() { return getToken(ASPCore2Parser.EOF, 0); } - public StatementsContext statements() { - return getRuleContext(StatementsContext.class,0); - } - public QueryContext query() { - return getRuleContext(QueryContext.class,0); - } - public ProgramContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_program; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitProgram(this); - else return visitor.visitChildren(this); - } - } - - public final ProgramContext program() throws RecognitionException { - ProgramContext _localctx = new ProgramContext(_ctx, getState()); - enterRule(_localctx, 0, RULE_program); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(65); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) { - case 1: - { - setState(64); - statements(); - } - break; - } - setState(68); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==MINUS || _la==ID) { - { - setState(67); - query(); - } - } - - setState(70); - match(EOF); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class StatementsContext extends ParserRuleContext { - public List statement() { - return getRuleContexts(StatementContext.class); - } - public StatementContext statement(int i) { - return getRuleContext(StatementContext.class,i); - } - public StatementsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_statements; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatements(this); - else return visitor.visitChildren(this); - } - } - - public final StatementsContext statements() throws RecognitionException { - StatementsContext _localctx = new StatementsContext(_ctx, getState()); - enterRule(_localctx, 2, RULE_statements); - try { - int _alt; - enterOuterAlt(_localctx, 1); - { - setState(73); - _errHandler.sync(this); - _alt = 1; - do { - switch (_alt) { - case 1: - { - { - setState(72); - statement(); - } - } - break; - default: - throw new NoViableAltException(this); - } - setState(75); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,2,_ctx); - } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class QueryContext extends ParserRuleContext { - public Classical_literalContext classical_literal() { - return getRuleContext(Classical_literalContext.class,0); - } - public TerminalNode QUERY_MARK() { return getToken(ASPCore2Parser.QUERY_MARK, 0); } - public QueryContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_query; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitQuery(this); - else return visitor.visitChildren(this); - } - } - - public final QueryContext query() throws RecognitionException { - QueryContext _localctx = new QueryContext(_ctx, getState()); - enterRule(_localctx, 4, RULE_query); - try { - enterOuterAlt(_localctx, 1); - { - setState(77); - classical_literal(); - setState(78); - match(QUERY_MARK); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class StatementContext extends ParserRuleContext { - public StatementContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_statement; } - - public StatementContext() { } - public void copyFrom(StatementContext ctx) { - super.copyFrom(ctx); - } - } - public static class Statement_factContext extends StatementContext { - public HeadContext head() { - return getRuleContext(HeadContext.class,0); - } - public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } - public Statement_factContext(StatementContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_fact(this); - else return visitor.visitChildren(this); - } - } - public static class Statement_ruleContext extends StatementContext { - public HeadContext head() { - return getRuleContext(HeadContext.class,0); - } - public TerminalNode CONS() { return getToken(ASPCore2Parser.CONS, 0); } - public BodyContext body() { - return getRuleContext(BodyContext.class,0); - } - public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } - public Statement_ruleContext(StatementContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_rule(this); - else return visitor.visitChildren(this); - } - } - public static class Statement_weightConstraintContext extends StatementContext { - public TerminalNode WCONS() { return getToken(ASPCore2Parser.WCONS, 0); } - public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } - public TerminalNode SQUARE_OPEN() { return getToken(ASPCore2Parser.SQUARE_OPEN, 0); } - public Weight_at_levelContext weight_at_level() { - return getRuleContext(Weight_at_levelContext.class,0); - } - public TerminalNode SQUARE_CLOSE() { return getToken(ASPCore2Parser.SQUARE_CLOSE, 0); } - public BodyContext body() { - return getRuleContext(BodyContext.class,0); - } - public Statement_weightConstraintContext(StatementContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_weightConstraint(this); - else return visitor.visitChildren(this); - } - } - public static class Statement_constraintContext extends StatementContext { - public TerminalNode CONS() { return getToken(ASPCore2Parser.CONS, 0); } - public BodyContext body() { - return getRuleContext(BodyContext.class,0); - } - public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } - public Statement_constraintContext(StatementContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_constraint(this); - else return visitor.visitChildren(this); - } - } - public static class Statement_directiveContext extends StatementContext { - public DirectiveContext directive() { - return getRuleContext(DirectiveContext.class,0); - } - public Statement_directiveContext(StatementContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitStatement_directive(this); - else return visitor.visitChildren(this); - } - } - - public final StatementContext statement() throws RecognitionException { - StatementContext _localctx = new StatementContext(_ctx, getState()); - enterRule(_localctx, 6, RULE_statement); - int _la; - try { - setState(102); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { - case 1: - _localctx = new Statement_factContext(_localctx); - enterOuterAlt(_localctx, 1); - { - setState(80); - head(); - setState(81); - match(DOT); - } - break; - case 2: - _localctx = new Statement_constraintContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(83); - match(CONS); - setState(84); - body(); - setState(85); - match(DOT); - } - break; - case 3: - _localctx = new Statement_ruleContext(_localctx); - enterOuterAlt(_localctx, 3); - { - setState(87); - head(); - setState(88); - match(CONS); - setState(89); - body(); - setState(90); - match(DOT); - } - break; - case 4: - _localctx = new Statement_weightConstraintContext(_localctx); - enterOuterAlt(_localctx, 4); - { - setState(92); - match(WCONS); - setState(94); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << NAF) | (1L << MINUS) | (1L << AMPERSAND) | (1L << PAREN_OPEN) | (1L << AGGREGATE_COUNT) | (1L << AGGREGATE_MAX) | (1L << AGGREGATE_MIN) | (1L << AGGREGATE_SUM) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { - { - setState(93); - body(); - } - } - - setState(96); - match(DOT); - setState(97); - match(SQUARE_OPEN); - setState(98); - weight_at_level(); - setState(99); - match(SQUARE_CLOSE); - } - break; - case 5: - _localctx = new Statement_directiveContext(_localctx); - enterOuterAlt(_localctx, 5); - { - setState(101); - directive(); - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class HeadContext extends ParserRuleContext { - public DisjunctionContext disjunction() { - return getRuleContext(DisjunctionContext.class,0); - } - public ChoiceContext choice() { - return getRuleContext(ChoiceContext.class,0); - } - public HeadContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_head; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitHead(this); - else return visitor.visitChildren(this); - } - } - - public final HeadContext head() throws RecognitionException { - HeadContext _localctx = new HeadContext(_ctx, getState()); - enterRule(_localctx, 8, RULE_head); - try { - setState(106); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { - case 1: - enterOuterAlt(_localctx, 1); - { - setState(104); - disjunction(); - } - break; - case 2: - enterOuterAlt(_localctx, 2); - { - setState(105); - choice(); - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class BodyContext extends ParserRuleContext { - public Naf_literalContext naf_literal() { - return getRuleContext(Naf_literalContext.class,0); - } - public AggregateContext aggregate() { - return getRuleContext(AggregateContext.class,0); - } - public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } - public BodyContext body() { - return getRuleContext(BodyContext.class,0); - } - public BodyContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_body; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBody(this); - else return visitor.visitChildren(this); - } - } - - public final BodyContext body() throws RecognitionException { - BodyContext _localctx = new BodyContext(_ctx, getState()); - enterRule(_localctx, 10, RULE_body); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(110); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { - case 1: - { - setState(108); - naf_literal(); - } - break; - case 2: - { - setState(109); - aggregate(); - } - break; - } - setState(114); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==COMMA) { - { - setState(112); - match(COMMA); - setState(113); - body(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class DisjunctionContext extends ParserRuleContext { - public Classical_literalContext classical_literal() { - return getRuleContext(Classical_literalContext.class,0); - } - public TerminalNode OR() { return getToken(ASPCore2Parser.OR, 0); } - public DisjunctionContext disjunction() { - return getRuleContext(DisjunctionContext.class,0); - } - public DisjunctionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_disjunction; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitDisjunction(this); - else return visitor.visitChildren(this); - } - } - - public final DisjunctionContext disjunction() throws RecognitionException { - DisjunctionContext _localctx = new DisjunctionContext(_ctx, getState()); - enterRule(_localctx, 12, RULE_disjunction); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(116); - classical_literal(); - setState(119); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==OR) { - { - setState(117); - match(OR); - setState(118); - disjunction(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class ChoiceContext extends ParserRuleContext { - public TermContext lt; - public BinopContext lop; - public BinopContext uop; - public TermContext ut; - public TerminalNode CURLY_OPEN() { return getToken(ASPCore2Parser.CURLY_OPEN, 0); } - public TerminalNode CURLY_CLOSE() { return getToken(ASPCore2Parser.CURLY_CLOSE, 0); } - public Choice_elementsContext choice_elements() { - return getRuleContext(Choice_elementsContext.class,0); - } - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public List binop() { - return getRuleContexts(BinopContext.class); - } - public BinopContext binop(int i) { - return getRuleContext(BinopContext.class,i); - } - public ChoiceContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_choice; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitChoice(this); - else return visitor.visitChildren(this); - } - } - - public final ChoiceContext choice() throws RecognitionException { - ChoiceContext _localctx = new ChoiceContext(_ctx, getState()); - enterRule(_localctx, 14, RULE_choice); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(124); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { - { - setState(121); - ((ChoiceContext)_localctx).lt = term(0); - setState(122); - ((ChoiceContext)_localctx).lop = binop(); - } - } - - setState(126); - match(CURLY_OPEN); - setState(128); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==MINUS || _la==ID) { - { - setState(127); - choice_elements(); - } - } - - setState(130); - match(CURLY_CLOSE); - setState(134); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQUAL) | (1L << UNEQUAL) | (1L << LESS) | (1L << GREATER) | (1L << LESS_OR_EQ) | (1L << GREATER_OR_EQ))) != 0)) { - { - setState(131); - ((ChoiceContext)_localctx).uop = binop(); - setState(132); - ((ChoiceContext)_localctx).ut = term(0); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Choice_elementsContext extends ParserRuleContext { - public Choice_elementContext choice_element() { - return getRuleContext(Choice_elementContext.class,0); - } - public TerminalNode SEMICOLON() { return getToken(ASPCore2Parser.SEMICOLON, 0); } - public Choice_elementsContext choice_elements() { - return getRuleContext(Choice_elementsContext.class,0); - } - public Choice_elementsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_choice_elements; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitChoice_elements(this); - else return visitor.visitChildren(this); - } - } - - public final Choice_elementsContext choice_elements() throws RecognitionException { - Choice_elementsContext _localctx = new Choice_elementsContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_choice_elements); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(136); - choice_element(); - setState(139); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==SEMICOLON) { - { - setState(137); - match(SEMICOLON); - setState(138); - choice_elements(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Choice_elementContext extends ParserRuleContext { - public Classical_literalContext classical_literal() { - return getRuleContext(Classical_literalContext.class,0); - } - public TerminalNode COLON() { return getToken(ASPCore2Parser.COLON, 0); } - public Naf_literalsContext naf_literals() { - return getRuleContext(Naf_literalsContext.class,0); - } - public Choice_elementContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_choice_element; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitChoice_element(this); - else return visitor.visitChildren(this); - } - } - - public final Choice_elementContext choice_element() throws RecognitionException { - Choice_elementContext _localctx = new Choice_elementContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_choice_element); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(141); - classical_literal(); - setState(146); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==COLON) { - { - setState(142); - match(COLON); - setState(144); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << NAF) | (1L << MINUS) | (1L << AMPERSAND) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { - { - setState(143); - naf_literals(); - } - } - - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class AggregateContext extends ParserRuleContext { - public TermContext lt; - public BinopContext lop; - public BinopContext uop; - public TermContext ut; - public Aggregate_functionContext aggregate_function() { - return getRuleContext(Aggregate_functionContext.class,0); - } - public TerminalNode CURLY_OPEN() { return getToken(ASPCore2Parser.CURLY_OPEN, 0); } - public Aggregate_elementsContext aggregate_elements() { - return getRuleContext(Aggregate_elementsContext.class,0); - } - public TerminalNode CURLY_CLOSE() { return getToken(ASPCore2Parser.CURLY_CLOSE, 0); } - public TerminalNode NAF() { return getToken(ASPCore2Parser.NAF, 0); } - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public List binop() { - return getRuleContexts(BinopContext.class); - } - public BinopContext binop(int i) { - return getRuleContext(BinopContext.class,i); - } - public AggregateContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_aggregate; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate(this); - else return visitor.visitChildren(this); - } - } - - public final AggregateContext aggregate() throws RecognitionException { - AggregateContext _localctx = new AggregateContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_aggregate); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(149); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==NAF) { - { - setState(148); - match(NAF); - } - } - - setState(154); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { - { - setState(151); - ((AggregateContext)_localctx).lt = term(0); - setState(152); - ((AggregateContext)_localctx).lop = binop(); - } - } - - setState(156); - aggregate_function(); - setState(157); - match(CURLY_OPEN); - setState(158); - aggregate_elements(); - setState(159); - match(CURLY_CLOSE); - setState(163); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQUAL) | (1L << UNEQUAL) | (1L << LESS) | (1L << GREATER) | (1L << LESS_OR_EQ) | (1L << GREATER_OR_EQ))) != 0)) { - { - setState(160); - ((AggregateContext)_localctx).uop = binop(); - setState(161); - ((AggregateContext)_localctx).ut = term(0); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Aggregate_elementsContext extends ParserRuleContext { - public Aggregate_elementContext aggregate_element() { - return getRuleContext(Aggregate_elementContext.class,0); - } - public TerminalNode SEMICOLON() { return getToken(ASPCore2Parser.SEMICOLON, 0); } - public Aggregate_elementsContext aggregate_elements() { - return getRuleContext(Aggregate_elementsContext.class,0); - } - public Aggregate_elementsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_aggregate_elements; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate_elements(this); - else return visitor.visitChildren(this); - } - } - - public final Aggregate_elementsContext aggregate_elements() throws RecognitionException { - Aggregate_elementsContext _localctx = new Aggregate_elementsContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_aggregate_elements); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(165); - aggregate_element(); - setState(168); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==SEMICOLON) { - { - setState(166); - match(SEMICOLON); - setState(167); - aggregate_elements(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Aggregate_elementContext extends ParserRuleContext { - public Basic_termsContext basic_terms() { - return getRuleContext(Basic_termsContext.class,0); - } - public TerminalNode COLON() { return getToken(ASPCore2Parser.COLON, 0); } - public Naf_literalsContext naf_literals() { - return getRuleContext(Naf_literalsContext.class,0); - } - public Aggregate_elementContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_aggregate_element; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate_element(this); - else return visitor.visitChildren(this); - } - } - - public final Aggregate_elementContext aggregate_element() throws RecognitionException { - Aggregate_elementContext _localctx = new Aggregate_elementContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_aggregate_element); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(171); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { - { - setState(170); - basic_terms(); - } - } - - setState(177); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==COLON) { - { - setState(173); - match(COLON); - setState(175); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << NAF) | (1L << MINUS) | (1L << AMPERSAND) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { - { - setState(174); - naf_literals(); - } - } - - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Aggregate_functionContext extends ParserRuleContext { - public TerminalNode AGGREGATE_COUNT() { return getToken(ASPCore2Parser.AGGREGATE_COUNT, 0); } - public TerminalNode AGGREGATE_MAX() { return getToken(ASPCore2Parser.AGGREGATE_MAX, 0); } - public TerminalNode AGGREGATE_MIN() { return getToken(ASPCore2Parser.AGGREGATE_MIN, 0); } - public TerminalNode AGGREGATE_SUM() { return getToken(ASPCore2Parser.AGGREGATE_SUM, 0); } - public Aggregate_functionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_aggregate_function; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAggregate_function(this); - else return visitor.visitChildren(this); - } - } - - public final Aggregate_functionContext aggregate_function() throws RecognitionException { - Aggregate_functionContext _localctx = new Aggregate_functionContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_aggregate_function); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(179); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << AGGREGATE_COUNT) | (1L << AGGREGATE_MAX) | (1L << AGGREGATE_MIN) | (1L << AGGREGATE_SUM))) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Weight_at_levelContext extends ParserRuleContext { - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public TerminalNode AT() { return getToken(ASPCore2Parser.AT, 0); } - public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } - public TermsContext terms() { - return getRuleContext(TermsContext.class,0); - } - public Weight_at_levelContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_weight_at_level; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitWeight_at_level(this); - else return visitor.visitChildren(this); - } - } - - public final Weight_at_levelContext weight_at_level() throws RecognitionException { - Weight_at_levelContext _localctx = new Weight_at_levelContext(_ctx, getState()); - enterRule(_localctx, 28, RULE_weight_at_level); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(181); - term(0); - setState(184); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==AT) { - { - setState(182); - match(AT); - setState(183); - term(0); - } - } - - setState(188); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==COMMA) { - { - setState(186); - match(COMMA); - setState(187); - terms(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Naf_literalsContext extends ParserRuleContext { - public Naf_literalContext naf_literal() { - return getRuleContext(Naf_literalContext.class,0); - } - public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } - public Naf_literalsContext naf_literals() { - return getRuleContext(Naf_literalsContext.class,0); - } - public Naf_literalsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_naf_literals; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitNaf_literals(this); - else return visitor.visitChildren(this); - } - } - - public final Naf_literalsContext naf_literals() throws RecognitionException { - Naf_literalsContext _localctx = new Naf_literalsContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_naf_literals); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(190); - naf_literal(); - setState(193); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==COMMA) { - { - setState(191); - match(COMMA); - setState(192); - naf_literals(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Naf_literalContext extends ParserRuleContext { - public External_atomContext external_atom() { - return getRuleContext(External_atomContext.class,0); - } - public Classical_literalContext classical_literal() { - return getRuleContext(Classical_literalContext.class,0); - } - public Builtin_atomContext builtin_atom() { - return getRuleContext(Builtin_atomContext.class,0); - } - public TerminalNode NAF() { return getToken(ASPCore2Parser.NAF, 0); } - public Naf_literalContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_naf_literal; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitNaf_literal(this); - else return visitor.visitChildren(this); - } - } - - public final Naf_literalContext naf_literal() throws RecognitionException { - Naf_literalContext _localctx = new Naf_literalContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_naf_literal); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(196); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==NAF) { - { - setState(195); - match(NAF); - } - } - - setState(201); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { - case 1: - { - setState(198); - external_atom(); - } - break; - case 2: - { - setState(199); - classical_literal(); - } - break; - case 3: - { - setState(200); - builtin_atom(); - } - break; - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Classical_literalContext extends ParserRuleContext { - public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } - public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } - public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } - public TermsContext terms() { - return getRuleContext(TermsContext.class,0); - } - public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } - public Classical_literalContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_classical_literal; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitClassical_literal(this); - else return visitor.visitChildren(this); - } - } - - public final Classical_literalContext classical_literal() throws RecognitionException { - Classical_literalContext _localctx = new Classical_literalContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_classical_literal); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(204); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==MINUS) { - { - setState(203); - match(MINUS); - } - } - - setState(206); - match(ID); - setState(211); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==PAREN_OPEN) { - { - setState(207); - match(PAREN_OPEN); - setState(208); - terms(); - setState(209); - match(PAREN_CLOSE); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Builtin_atomContext extends ParserRuleContext { - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public BinopContext binop() { - return getRuleContext(BinopContext.class,0); - } - public Builtin_atomContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_builtin_atom; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBuiltin_atom(this); - else return visitor.visitChildren(this); - } - } - - public final Builtin_atomContext builtin_atom() throws RecognitionException { - Builtin_atomContext _localctx = new Builtin_atomContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_builtin_atom); - try { - enterOuterAlt(_localctx, 1); - { - setState(213); - term(0); - setState(214); - binop(); - setState(215); - term(0); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class BinopContext extends ParserRuleContext { - public TerminalNode EQUAL() { return getToken(ASPCore2Parser.EQUAL, 0); } - public TerminalNode UNEQUAL() { return getToken(ASPCore2Parser.UNEQUAL, 0); } - public TerminalNode LESS() { return getToken(ASPCore2Parser.LESS, 0); } - public TerminalNode GREATER() { return getToken(ASPCore2Parser.GREATER, 0); } - public TerminalNode LESS_OR_EQ() { return getToken(ASPCore2Parser.LESS_OR_EQ, 0); } - public TerminalNode GREATER_OR_EQ() { return getToken(ASPCore2Parser.GREATER_OR_EQ, 0); } - public BinopContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_binop; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBinop(this); - else return visitor.visitChildren(this); - } - } - - public final BinopContext binop() throws RecognitionException { - BinopContext _localctx = new BinopContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_binop); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(217); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQUAL) | (1L << UNEQUAL) | (1L << LESS) | (1L << GREATER) | (1L << LESS_OR_EQ) | (1L << GREATER_OR_EQ))) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class TermsContext extends ParserRuleContext { - public TermContext term() { - return getRuleContext(TermContext.class,0); - } - public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } - public TermsContext terms() { - return getRuleContext(TermsContext.class,0); - } - public TermsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_terms; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerms(this); - else return visitor.visitChildren(this); - } - } - - public final TermsContext terms() throws RecognitionException { - TermsContext _localctx = new TermsContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_terms); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(219); - term(0); - setState(222); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==COMMA) { - { - setState(220); - match(COMMA); - setState(221); - terms(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class TermContext extends ParserRuleContext { - public TermContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_term; } - - public TermContext() { } - public void copyFrom(TermContext ctx) { - super.copyFrom(ctx); - } - } - public static class Term_numberContext extends TermContext { - public TerminalNode NUMBER() { return getToken(ASPCore2Parser.NUMBER, 0); } - public Term_numberContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_number(this); - else return visitor.visitChildren(this); - } - } - public static class Term_anonymousVariableContext extends TermContext { - public TerminalNode ANONYMOUS_VARIABLE() { return getToken(ASPCore2Parser.ANONYMOUS_VARIABLE, 0); } - public Term_anonymousVariableContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_anonymousVariable(this); - else return visitor.visitChildren(this); - } - } - public static class Term_constContext extends TermContext { - public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } - public Term_constContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_const(this); - else return visitor.visitChildren(this); - } - } - public static class Term_minusArithTermContext extends TermContext { - public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } - public TermContext term() { - return getRuleContext(TermContext.class,0); - } - public Term_minusArithTermContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_minusArithTerm(this); - else return visitor.visitChildren(this); - } - } - public static class Term_bitxorArithTermContext extends TermContext { - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public TerminalNode BITXOR() { return getToken(ASPCore2Parser.BITXOR, 0); } - public Term_bitxorArithTermContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_bitxorArithTerm(this); - else return visitor.visitChildren(this); - } - } - public static class Term_intervalContext extends TermContext { - public IntervalContext interval() { - return getRuleContext(IntervalContext.class,0); - } - public Term_intervalContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_interval(this); - else return visitor.visitChildren(this); - } - } - public static class Term_variableContext extends TermContext { - public TerminalNode VARIABLE() { return getToken(ASPCore2Parser.VARIABLE, 0); } - public Term_variableContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_variable(this); - else return visitor.visitChildren(this); - } - } - public static class Term_timesdivmodArithTermContext extends TermContext { - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public TerminalNode TIMES() { return getToken(ASPCore2Parser.TIMES, 0); } - public TerminalNode DIV() { return getToken(ASPCore2Parser.DIV, 0); } - public TerminalNode MODULO() { return getToken(ASPCore2Parser.MODULO, 0); } - public Term_timesdivmodArithTermContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_timesdivmodArithTerm(this); - else return visitor.visitChildren(this); - } - } - public static class Term_plusminusArithTermContext extends TermContext { - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public TerminalNode PLUS() { return getToken(ASPCore2Parser.PLUS, 0); } - public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } - public Term_plusminusArithTermContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_plusminusArithTerm(this); - else return visitor.visitChildren(this); - } - } - public static class Term_powerArithTermContext extends TermContext { - public List term() { - return getRuleContexts(TermContext.class); - } - public TermContext term(int i) { - return getRuleContext(TermContext.class,i); - } - public TerminalNode POWER() { return getToken(ASPCore2Parser.POWER, 0); } - public Term_powerArithTermContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_powerArithTerm(this); - else return visitor.visitChildren(this); - } - } - public static class Term_funcContext extends TermContext { - public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } - public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } - public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } - public TermsContext terms() { - return getRuleContext(TermsContext.class,0); - } - public Term_funcContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_func(this); - else return visitor.visitChildren(this); - } - } - public static class Term_stringContext extends TermContext { - public TerminalNode QUOTED_STRING() { return getToken(ASPCore2Parser.QUOTED_STRING, 0); } - public Term_stringContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_string(this); - else return visitor.visitChildren(this); - } - } - public static class Term_parenthesisedTermContext extends TermContext { - public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } - public TermContext term() { - return getRuleContext(TermContext.class,0); - } - public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } - public Term_parenthesisedTermContext(TermContext ctx) { copyFrom(ctx); } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitTerm_parenthesisedTerm(this); - else return visitor.visitChildren(this); - } - } - - public final TermContext term() throws RecognitionException { - return term(0); - } - - private TermContext term(int _p) throws RecognitionException { - ParserRuleContext _parentctx = _ctx; - int _parentState = getState(); - TermContext _localctx = new TermContext(_ctx, _parentState); - TermContext _prevctx = _localctx; - int _startState = 42; - enterRecursionRule(_localctx, 42, RULE_term, _p); - int _la; - try { - int _alt; - enterOuterAlt(_localctx, 1); - { - setState(243); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { - case 1: - { - _localctx = new Term_constContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - - setState(225); - match(ID); - } - break; - case 2: - { - _localctx = new Term_funcContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(226); - match(ID); - { - setState(227); - match(PAREN_OPEN); - setState(229); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANONYMOUS_VARIABLE) | (1L << MINUS) | (1L << PAREN_OPEN) | (1L << ID) | (1L << VARIABLE) | (1L << NUMBER) | (1L << QUOTED_STRING))) != 0)) { - { - setState(228); - terms(); - } - } - - setState(231); - match(PAREN_CLOSE); - } - } - break; - case 3: - { - _localctx = new Term_numberContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(232); - match(NUMBER); - } - break; - case 4: - { - _localctx = new Term_stringContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(233); - match(QUOTED_STRING); - } - break; - case 5: - { - _localctx = new Term_variableContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(234); - match(VARIABLE); - } - break; - case 6: - { - _localctx = new Term_anonymousVariableContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(235); - match(ANONYMOUS_VARIABLE); - } - break; - case 7: - { - _localctx = new Term_parenthesisedTermContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(236); - match(PAREN_OPEN); - setState(237); - term(0); - setState(238); - match(PAREN_CLOSE); - } - break; - case 8: - { - _localctx = new Term_intervalContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(240); - interval(); - } - break; - case 9: - { - _localctx = new Term_minusArithTermContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(241); - match(MINUS); - setState(242); - term(5); - } - break; - } - _ctx.stop = _input.LT(-1); - setState(259); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,33,_ctx); - while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { - if ( _alt==1 ) { - if ( _parseListeners!=null ) triggerExitRuleEvent(); - _prevctx = _localctx; - { - setState(257); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,32,_ctx) ) { - case 1: - { - _localctx = new Term_powerArithTermContext(new TermContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_term); - setState(245); - if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); - setState(246); - match(POWER); - setState(247); - term(4); - } - break; - case 2: - { - _localctx = new Term_timesdivmodArithTermContext(new TermContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_term); - setState(248); - if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); - setState(249); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TIMES) | (1L << DIV) | (1L << MODULO))) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(250); - term(4); - } - break; - case 3: - { - _localctx = new Term_plusminusArithTermContext(new TermContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_term); - setState(251); - if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(252); - _la = _input.LA(1); - if ( !(_la==PLUS || _la==MINUS) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(253); - term(3); - } - break; - case 4: - { - _localctx = new Term_bitxorArithTermContext(new TermContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_term); - setState(254); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(255); - match(BITXOR); - setState(256); - term(2); - } - break; - } - } - } - setState(261); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,33,_ctx); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - unrollRecursionContexts(_parentctx); - } - return _localctx; - } - - public static class IntervalContext extends ParserRuleContext { - public Token lower; - public Token upper; - public List DOT() { return getTokens(ASPCore2Parser.DOT); } - public TerminalNode DOT(int i) { - return getToken(ASPCore2Parser.DOT, i); - } - public List NUMBER() { return getTokens(ASPCore2Parser.NUMBER); } - public TerminalNode NUMBER(int i) { - return getToken(ASPCore2Parser.NUMBER, i); - } - public List VARIABLE() { return getTokens(ASPCore2Parser.VARIABLE); } - public TerminalNode VARIABLE(int i) { - return getToken(ASPCore2Parser.VARIABLE, i); - } - public IntervalContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_interval; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitInterval(this); - else return visitor.visitChildren(this); - } - } - - public final IntervalContext interval() throws RecognitionException { - IntervalContext _localctx = new IntervalContext(_ctx, getState()); - enterRule(_localctx, 44, RULE_interval); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(262); - ((IntervalContext)_localctx).lower = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==VARIABLE || _la==NUMBER) ) { - ((IntervalContext)_localctx).lower = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(263); - match(DOT); - setState(264); - match(DOT); - setState(265); - ((IntervalContext)_localctx).upper = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==VARIABLE || _la==NUMBER) ) { - ((IntervalContext)_localctx).upper = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class External_atomContext extends ParserRuleContext { - public TermsContext input; - public TermsContext output; - public TerminalNode AMPERSAND() { return getToken(ASPCore2Parser.AMPERSAND, 0); } - public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } - public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } - public TerminalNode SQUARE_OPEN() { return getToken(ASPCore2Parser.SQUARE_OPEN, 0); } - public TerminalNode SQUARE_CLOSE() { return getToken(ASPCore2Parser.SQUARE_CLOSE, 0); } - public TerminalNode PAREN_OPEN() { return getToken(ASPCore2Parser.PAREN_OPEN, 0); } - public TerminalNode PAREN_CLOSE() { return getToken(ASPCore2Parser.PAREN_CLOSE, 0); } - public List terms() { - return getRuleContexts(TermsContext.class); - } - public TermsContext terms(int i) { - return getRuleContext(TermsContext.class,i); - } - public External_atomContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_external_atom; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitExternal_atom(this); - else return visitor.visitChildren(this); - } - } - - public final External_atomContext external_atom() throws RecognitionException { - External_atomContext _localctx = new External_atomContext(_ctx, getState()); - enterRule(_localctx, 46, RULE_external_atom); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(268); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==MINUS) { - { - setState(267); - match(MINUS); - } - } - - setState(270); - match(AMPERSAND); - setState(271); - match(ID); - setState(276); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==SQUARE_OPEN) { - { - setState(272); - match(SQUARE_OPEN); - setState(273); - ((External_atomContext)_localctx).input = terms(); - setState(274); - match(SQUARE_CLOSE); - } - } - - setState(282); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==PAREN_OPEN) { - { - setState(278); - match(PAREN_OPEN); - setState(279); - ((External_atomContext)_localctx).output = terms(); - setState(280); - match(PAREN_CLOSE); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class DirectiveContext extends ParserRuleContext { - public Directive_enumerationContext directive_enumeration() { - return getRuleContext(Directive_enumerationContext.class,0); - } - public DirectiveContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_directive; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitDirective(this); - else return visitor.visitChildren(this); - } - } - - public final DirectiveContext directive() throws RecognitionException { - DirectiveContext _localctx = new DirectiveContext(_ctx, getState()); - enterRule(_localctx, 48, RULE_directive); - try { - enterOuterAlt(_localctx, 1); - { - setState(284); - directive_enumeration(); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Directive_enumerationContext extends ParserRuleContext { - public TerminalNode SHARP() { return getToken(ASPCore2Parser.SHARP, 0); } - public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } - public TerminalNode DOT() { return getToken(ASPCore2Parser.DOT, 0); } - public Directive_enumerationContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_directive_enumeration; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitDirective_enumeration(this); - else return visitor.visitChildren(this); - } - } - - public final Directive_enumerationContext directive_enumeration() throws RecognitionException { - Directive_enumerationContext _localctx = new Directive_enumerationContext(_ctx, getState()); - enterRule(_localctx, 50, RULE_directive_enumeration); - try { - enterOuterAlt(_localctx, 1); - { - setState(286); - match(SHARP); - setState(287); - match(T__0); - setState(288); - match(ID); - setState(289); - match(DOT); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Basic_termsContext extends ParserRuleContext { - public Basic_termContext basic_term() { - return getRuleContext(Basic_termContext.class,0); - } - public TerminalNode COMMA() { return getToken(ASPCore2Parser.COMMA, 0); } - public Basic_termsContext basic_terms() { - return getRuleContext(Basic_termsContext.class,0); - } - public Basic_termsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_basic_terms; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBasic_terms(this); - else return visitor.visitChildren(this); - } - } - - public final Basic_termsContext basic_terms() throws RecognitionException { - Basic_termsContext _localctx = new Basic_termsContext(_ctx, getState()); - enterRule(_localctx, 52, RULE_basic_terms); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(291); - basic_term(); - setState(294); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==COMMA) { - { - setState(292); - match(COMMA); - setState(293); - basic_terms(); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Basic_termContext extends ParserRuleContext { - public Ground_termContext ground_term() { - return getRuleContext(Ground_termContext.class,0); - } - public Variable_termContext variable_term() { - return getRuleContext(Variable_termContext.class,0); - } - public Basic_termContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_basic_term; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitBasic_term(this); - else return visitor.visitChildren(this); - } - } - - public final Basic_termContext basic_term() throws RecognitionException { - Basic_termContext _localctx = new Basic_termContext(_ctx, getState()); - enterRule(_localctx, 54, RULE_basic_term); - try { - setState(298); - _errHandler.sync(this); - switch (_input.LA(1)) { - case MINUS: - case ID: - case NUMBER: - case QUOTED_STRING: - enterOuterAlt(_localctx, 1); - { - setState(296); - ground_term(); - } - break; - case ANONYMOUS_VARIABLE: - case VARIABLE: - enterOuterAlt(_localctx, 2); - { - setState(297); - variable_term(); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Ground_termContext extends ParserRuleContext { - public TerminalNode ID() { return getToken(ASPCore2Parser.ID, 0); } - public TerminalNode QUOTED_STRING() { return getToken(ASPCore2Parser.QUOTED_STRING, 0); } - public TerminalNode NUMBER() { return getToken(ASPCore2Parser.NUMBER, 0); } - public TerminalNode MINUS() { return getToken(ASPCore2Parser.MINUS, 0); } - public Ground_termContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_ground_term; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitGround_term(this); - else return visitor.visitChildren(this); - } - } - - public final Ground_termContext ground_term() throws RecognitionException { - Ground_termContext _localctx = new Ground_termContext(_ctx, getState()); - enterRule(_localctx, 56, RULE_ground_term); - int _la; - try { - setState(306); - _errHandler.sync(this); - switch (_input.LA(1)) { - case ID: - enterOuterAlt(_localctx, 1); - { - setState(300); - match(ID); - } - break; - case QUOTED_STRING: - enterOuterAlt(_localctx, 2); - { - setState(301); - match(QUOTED_STRING); - } - break; - case MINUS: - case NUMBER: - enterOuterAlt(_localctx, 3); - { - setState(303); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==MINUS) { - { - setState(302); - match(MINUS); - } - } - - setState(305); - match(NUMBER); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Variable_termContext extends ParserRuleContext { - public TerminalNode VARIABLE() { return getToken(ASPCore2Parser.VARIABLE, 0); } - public TerminalNode ANONYMOUS_VARIABLE() { return getToken(ASPCore2Parser.ANONYMOUS_VARIABLE, 0); } - public Variable_termContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_variable_term; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitVariable_term(this); - else return visitor.visitChildren(this); - } - } - - public final Variable_termContext variable_term() throws RecognitionException { - Variable_termContext _localctx = new Variable_termContext(_ctx, getState()); - enterRule(_localctx, 58, RULE_variable_term); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(308); - _la = _input.LA(1); - if ( !(_la==ANONYMOUS_VARIABLE || _la==VARIABLE) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Answer_setContext extends ParserRuleContext { - public TerminalNode CURLY_OPEN() { return getToken(ASPCore2Parser.CURLY_OPEN, 0); } - public TerminalNode CURLY_CLOSE() { return getToken(ASPCore2Parser.CURLY_CLOSE, 0); } - public List classical_literal() { - return getRuleContexts(Classical_literalContext.class); - } - public Classical_literalContext classical_literal(int i) { - return getRuleContext(Classical_literalContext.class,i); - } - public List COMMA() { return getTokens(ASPCore2Parser.COMMA); } - public TerminalNode COMMA(int i) { - return getToken(ASPCore2Parser.COMMA, i); - } - public Answer_setContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_answer_set; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAnswer_set(this); - else return visitor.visitChildren(this); - } - } - - public final Answer_setContext answer_set() throws RecognitionException { - Answer_setContext _localctx = new Answer_setContext(_ctx, getState()); - enterRule(_localctx, 60, RULE_answer_set); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(310); - match(CURLY_OPEN); - setState(312); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==MINUS || _la==ID) { - { - setState(311); - classical_literal(); - } - } - - setState(318); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==COMMA) { - { - { - setState(314); - match(COMMA); - setState(315); - classical_literal(); - } - } - setState(320); - _errHandler.sync(this); - _la = _input.LA(1); - } - setState(321); - match(CURLY_CLOSE); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class Answer_setsContext extends ParserRuleContext { - public TerminalNode EOF() { return getToken(ASPCore2Parser.EOF, 0); } - public List answer_set() { - return getRuleContexts(Answer_setContext.class); - } - public Answer_setContext answer_set(int i) { - return getRuleContext(Answer_setContext.class,i); - } - public Answer_setsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_answer_sets; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof ASPCore2Visitor ) return ((ASPCore2Visitor)visitor).visitAnswer_sets(this); - else return visitor.visitChildren(this); - } - } - - public final Answer_setsContext answer_sets() throws RecognitionException { - Answer_setsContext _localctx = new Answer_setsContext(_ctx, getState()); - enterRule(_localctx, 62, RULE_answer_sets); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(326); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==CURLY_OPEN) { - { - { - setState(323); - answer_set(); - } - } - setState(328); - _errHandler.sync(this); - _la = _input.LA(1); - } - setState(329); - match(EOF); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { - switch (ruleIndex) { - case 21: - return term_sempred((TermContext)_localctx, predIndex); - } - return true; - } - private boolean term_sempred(TermContext _localctx, int predIndex) { - switch (predIndex) { - case 0: - return precpred(_ctx, 4); - case 1: - return precpred(_ctx, 3); - case 2: - return precpred(_ctx, 2); - case 3: - return precpred(_ctx, 1); - } - return true; - } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3/\u014e\4\2\t\2\4"+ - "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ - "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ - "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ - "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ - "\t!\3\2\5\2D\n\2\3\2\5\2G\n\2\3\2\3\2\3\3\6\3L\n\3\r\3\16\3M\3\4\3\4\3"+ - "\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5a\n\5\3"+ - "\5\3\5\3\5\3\5\3\5\3\5\5\5i\n\5\3\6\3\6\5\6m\n\6\3\7\3\7\5\7q\n\7\3\7"+ - "\3\7\5\7u\n\7\3\b\3\b\3\b\5\bz\n\b\3\t\3\t\3\t\5\t\177\n\t\3\t\3\t\5\t"+ - "\u0083\n\t\3\t\3\t\3\t\3\t\5\t\u0089\n\t\3\n\3\n\3\n\5\n\u008e\n\n\3\13"+ - "\3\13\3\13\5\13\u0093\n\13\5\13\u0095\n\13\3\f\5\f\u0098\n\f\3\f\3\f\3"+ - "\f\5\f\u009d\n\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00a6\n\f\3\r\3\r\3\r"+ - "\5\r\u00ab\n\r\3\16\5\16\u00ae\n\16\3\16\3\16\5\16\u00b2\n\16\5\16\u00b4"+ - "\n\16\3\17\3\17\3\20\3\20\3\20\5\20\u00bb\n\20\3\20\3\20\5\20\u00bf\n"+ - "\20\3\21\3\21\3\21\5\21\u00c4\n\21\3\22\5\22\u00c7\n\22\3\22\3\22\3\22"+ - "\5\22\u00cc\n\22\3\23\5\23\u00cf\n\23\3\23\3\23\3\23\3\23\3\23\5\23\u00d6"+ - "\n\23\3\24\3\24\3\24\3\24\3\25\3\25\3\26\3\26\3\26\5\26\u00e1\n\26\3\27"+ - "\3\27\3\27\3\27\3\27\5\27\u00e8\n\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+ - "\3\27\3\27\3\27\3\27\3\27\5\27\u00f6\n\27\3\27\3\27\3\27\3\27\3\27\3\27"+ - "\3\27\3\27\3\27\3\27\3\27\3\27\7\27\u0104\n\27\f\27\16\27\u0107\13\27"+ - "\3\30\3\30\3\30\3\30\3\30\3\31\5\31\u010f\n\31\3\31\3\31\3\31\3\31\3\31"+ - "\3\31\5\31\u0117\n\31\3\31\3\31\3\31\3\31\5\31\u011d\n\31\3\32\3\32\3"+ - "\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\5\34\u0129\n\34\3\35\3\35\5\35"+ - "\u012d\n\35\3\36\3\36\3\36\5\36\u0132\n\36\3\36\5\36\u0135\n\36\3\37\3"+ - "\37\3 \3 \5 \u013b\n \3 \3 \7 \u013f\n \f \16 \u0142\13 \3 \3 \3!\7!\u0147"+ - "\n!\f!\16!\u014a\13!\3!\3!\3!\2\3,\"\2\4\6\b\n\f\16\20\22\24\26\30\32"+ - "\34\36 \"$&(*,.\60\62\64\668:<>@\2\b\3\2%(\3\2\37$\4\2\20\21\23\23\3\2"+ - "\16\17\3\2*+\4\2\4\4**\2\u0167\2C\3\2\2\2\4K\3\2\2\2\6O\3\2\2\2\bh\3\2"+ - "\2\2\nl\3\2\2\2\fp\3\2\2\2\16v\3\2\2\2\20~\3\2\2\2\22\u008a\3\2\2\2\24"+ - "\u008f\3\2\2\2\26\u0097\3\2\2\2\30\u00a7\3\2\2\2\32\u00ad\3\2\2\2\34\u00b5"+ - "\3\2\2\2\36\u00b7\3\2\2\2 \u00c0\3\2\2\2\"\u00c6\3\2\2\2$\u00ce\3\2\2"+ - "\2&\u00d7\3\2\2\2(\u00db\3\2\2\2*\u00dd\3\2\2\2,\u00f5\3\2\2\2.\u0108"+ - "\3\2\2\2\60\u010e\3\2\2\2\62\u011e\3\2\2\2\64\u0120\3\2\2\2\66\u0125\3"+ - "\2\2\28\u012c\3\2\2\2:\u0134\3\2\2\2<\u0136\3\2\2\2>\u0138\3\2\2\2@\u0148"+ - "\3\2\2\2BD\5\4\3\2CB\3\2\2\2CD\3\2\2\2DF\3\2\2\2EG\5\6\4\2FE\3\2\2\2F"+ - "G\3\2\2\2GH\3\2\2\2HI\7\2\2\3I\3\3\2\2\2JL\5\b\5\2KJ\3\2\2\2LM\3\2\2\2"+ - "MK\3\2\2\2MN\3\2\2\2N\5\3\2\2\2OP\5$\23\2PQ\7\7\2\2Q\7\3\2\2\2RS\5\n\6"+ - "\2ST\7\5\2\2Ti\3\2\2\2UV\7\f\2\2VW\5\f\7\2WX\7\5\2\2Xi\3\2\2\2YZ\5\n\6"+ - "\2Z[\7\f\2\2[\\\5\f\7\2\\]\7\5\2\2]i\3\2\2\2^`\7\r\2\2_a\5\f\7\2`_\3\2"+ - "\2\2`a\3\2\2\2ab\3\2\2\2bc\7\5\2\2cd\7\33\2\2de\5\36\20\2ef\7\34\2\2f"+ - "i\3\2\2\2gi\5\62\32\2hR\3\2\2\2hU\3\2\2\2hY\3\2\2\2h^\3\2\2\2hg\3\2\2"+ - "\2i\t\3\2\2\2jm\5\16\b\2km\5\20\t\2lj\3\2\2\2lk\3\2\2\2m\13\3\2\2\2nq"+ - "\5\"\22\2oq\5\26\f\2pn\3\2\2\2po\3\2\2\2qt\3\2\2\2rs\7\6\2\2su\5\f\7\2"+ - "tr\3\2\2\2tu\3\2\2\2u\r\3\2\2\2vy\5$\23\2wx\7\n\2\2xz\5\16\b\2yw\3\2\2"+ - "\2yz\3\2\2\2z\17\3\2\2\2{|\5,\27\2|}\5(\25\2}\177\3\2\2\2~{\3\2\2\2~\177"+ - "\3\2\2\2\177\u0080\3\2\2\2\u0080\u0082\7\35\2\2\u0081\u0083\5\22\n\2\u0082"+ - "\u0081\3\2\2\2\u0082\u0083\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0088\7\36"+ - "\2\2\u0085\u0086\5(\25\2\u0086\u0087\5,\27\2\u0087\u0089\3\2\2\2\u0088"+ - "\u0085\3\2\2\2\u0088\u0089\3\2\2\2\u0089\21\3\2\2\2\u008a\u008d\5\24\13"+ - "\2\u008b\u008c\7\t\2\2\u008c\u008e\5\22\n\2\u008d\u008b\3\2\2\2\u008d"+ - "\u008e\3\2\2\2\u008e\23\3\2\2\2\u008f\u0094\5$\23\2\u0090\u0092\7\b\2"+ - "\2\u0091\u0093\5 \21\2\u0092\u0091\3\2\2\2\u0092\u0093\3\2\2\2\u0093\u0095"+ - "\3\2\2\2\u0094\u0090\3\2\2\2\u0094\u0095\3\2\2\2\u0095\25\3\2\2\2\u0096"+ - "\u0098\7\13\2\2\u0097\u0096\3\2\2\2\u0097\u0098\3\2\2\2\u0098\u009c\3"+ - "\2\2\2\u0099\u009a\5,\27\2\u009a\u009b\5(\25\2\u009b\u009d\3\2\2\2\u009c"+ - "\u0099\3\2\2\2\u009c\u009d\3\2\2\2\u009d\u009e\3\2\2\2\u009e\u009f\5\34"+ - "\17\2\u009f\u00a0\7\35\2\2\u00a0\u00a1\5\30\r\2\u00a1\u00a5\7\36\2\2\u00a2"+ - "\u00a3\5(\25\2\u00a3\u00a4\5,\27\2\u00a4\u00a6\3\2\2\2\u00a5\u00a2\3\2"+ - "\2\2\u00a5\u00a6\3\2\2\2\u00a6\27\3\2\2\2\u00a7\u00aa\5\32\16\2\u00a8"+ - "\u00a9\7\t\2\2\u00a9\u00ab\5\30\r\2\u00aa\u00a8\3\2\2\2\u00aa\u00ab\3"+ - "\2\2\2\u00ab\31\3\2\2\2\u00ac\u00ae\5\66\34\2\u00ad\u00ac\3\2\2\2\u00ad"+ - "\u00ae\3\2\2\2\u00ae\u00b3\3\2\2\2\u00af\u00b1\7\b\2\2\u00b0\u00b2\5 "+ - "\21\2\u00b1\u00b0\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\u00b4\3\2\2\2\u00b3"+ - "\u00af\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\33\3\2\2\2\u00b5\u00b6\t\2\2"+ - "\2\u00b6\35\3\2\2\2\u00b7\u00ba\5,\27\2\u00b8\u00b9\7\25\2\2\u00b9\u00bb"+ - "\5,\27\2\u00ba\u00b8\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc"+ - "\u00bd\7\6\2\2\u00bd\u00bf\5*\26\2\u00be\u00bc\3\2\2\2\u00be\u00bf\3\2"+ - "\2\2\u00bf\37\3\2\2\2\u00c0\u00c3\5\"\22\2\u00c1\u00c2\7\6\2\2\u00c2\u00c4"+ - "\5 \21\2\u00c3\u00c1\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4!\3\2\2\2\u00c5"+ - "\u00c7\7\13\2\2\u00c6\u00c5\3\2\2\2\u00c6\u00c7\3\2\2\2\u00c7\u00cb\3"+ - "\2\2\2\u00c8\u00cc\5\60\31\2\u00c9\u00cc\5$\23\2\u00ca\u00cc\5&\24\2\u00cb"+ - "\u00c8\3\2\2\2\u00cb\u00c9\3\2\2\2\u00cb\u00ca\3\2\2\2\u00cc#\3\2\2\2"+ - "\u00cd\u00cf\7\17\2\2\u00ce\u00cd\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cf\u00d0"+ - "\3\2\2\2\u00d0\u00d5\7)\2\2\u00d1\u00d2\7\31\2\2\u00d2\u00d3\5*\26\2\u00d3"+ - "\u00d4\7\32\2\2\u00d4\u00d6\3\2\2\2\u00d5\u00d1\3\2\2\2\u00d5\u00d6\3"+ - "\2\2\2\u00d6%\3\2\2\2\u00d7\u00d8\5,\27\2\u00d8\u00d9\5(\25\2\u00d9\u00da"+ - "\5,\27\2\u00da\'\3\2\2\2\u00db\u00dc\t\3\2\2\u00dc)\3\2\2\2\u00dd\u00e0"+ - "\5,\27\2\u00de\u00df\7\6\2\2\u00df\u00e1\5*\26\2\u00e0\u00de\3\2\2\2\u00e0"+ - "\u00e1\3\2\2\2\u00e1+\3\2\2\2\u00e2\u00e3\b\27\1\2\u00e3\u00f6\7)\2\2"+ - "\u00e4\u00e5\7)\2\2\u00e5\u00e7\7\31\2\2\u00e6\u00e8\5*\26\2\u00e7\u00e6"+ - "\3\2\2\2\u00e7\u00e8\3\2\2\2\u00e8\u00e9\3\2\2\2\u00e9\u00f6\7\32\2\2"+ - "\u00ea\u00f6\7+\2\2\u00eb\u00f6\7,\2\2\u00ec\u00f6\7*\2\2\u00ed\u00f6"+ - "\7\4\2\2\u00ee\u00ef\7\31\2\2\u00ef\u00f0\5,\27\2\u00f0\u00f1\7\32\2\2"+ - "\u00f1\u00f6\3\2\2\2\u00f2\u00f6\5.\30\2\u00f3\u00f4\7\17\2\2\u00f4\u00f6"+ - "\5,\27\7\u00f5\u00e2\3\2\2\2\u00f5\u00e4\3\2\2\2\u00f5\u00ea\3\2\2\2\u00f5"+ - "\u00eb\3\2\2\2\u00f5\u00ec\3\2\2\2\u00f5\u00ed\3\2\2\2\u00f5\u00ee\3\2"+ - "\2\2\u00f5\u00f2\3\2\2\2\u00f5\u00f3\3\2\2\2\u00f6\u0105\3\2\2\2\u00f7"+ - "\u00f8\f\6\2\2\u00f8\u00f9\7\22\2\2\u00f9\u0104\5,\27\6\u00fa\u00fb\f"+ - "\5\2\2\u00fb\u00fc\t\4\2\2\u00fc\u0104\5,\27\6\u00fd\u00fe\f\4\2\2\u00fe"+ - "\u00ff\t\5\2\2\u00ff\u0104\5,\27\5\u0100\u0101\f\3\2\2\u0101\u0102\7\24"+ - "\2\2\u0102\u0104\5,\27\4\u0103\u00f7\3\2\2\2\u0103\u00fa\3\2\2\2\u0103"+ - "\u00fd\3\2\2\2\u0103\u0100\3\2\2\2\u0104\u0107\3\2\2\2\u0105\u0103\3\2"+ - "\2\2\u0105\u0106\3\2\2\2\u0106-\3\2\2\2\u0107\u0105\3\2\2\2\u0108\u0109"+ - "\t\6\2\2\u0109\u010a\7\5\2\2\u010a\u010b\7\5\2\2\u010b\u010c\t\6\2\2\u010c"+ - "/\3\2\2\2\u010d\u010f\7\17\2\2\u010e\u010d\3\2\2\2\u010e\u010f\3\2\2\2"+ - "\u010f\u0110\3\2\2\2\u0110\u0111\7\27\2\2\u0111\u0116\7)\2\2\u0112\u0113"+ - "\7\33\2\2\u0113\u0114\5*\26\2\u0114\u0115\7\34\2\2\u0115\u0117\3\2\2\2"+ - "\u0116\u0112\3\2\2\2\u0116\u0117\3\2\2\2\u0117\u011c\3\2\2\2\u0118\u0119"+ - "\7\31\2\2\u0119\u011a\5*\26\2\u011a\u011b\7\32\2\2\u011b\u011d\3\2\2\2"+ - "\u011c\u0118\3\2\2\2\u011c\u011d\3\2\2\2\u011d\61\3\2\2\2\u011e\u011f"+ - "\5\64\33\2\u011f\63\3\2\2\2\u0120\u0121\7\26\2\2\u0121\u0122\7\3\2\2\u0122"+ - "\u0123\7)\2\2\u0123\u0124\7\5\2\2\u0124\65\3\2\2\2\u0125\u0128\58\35\2"+ - "\u0126\u0127\7\6\2\2\u0127\u0129\5\66\34\2\u0128\u0126\3\2\2\2\u0128\u0129"+ - "\3\2\2\2\u0129\67\3\2\2\2\u012a\u012d\5:\36\2\u012b\u012d\5<\37\2\u012c"+ - "\u012a\3\2\2\2\u012c\u012b\3\2\2\2\u012d9\3\2\2\2\u012e\u0135\7)\2\2\u012f"+ - "\u0135\7,\2\2\u0130\u0132\7\17\2\2\u0131\u0130\3\2\2\2\u0131\u0132\3\2"+ - "\2\2\u0132\u0133\3\2\2\2\u0133\u0135\7+\2\2\u0134\u012e\3\2\2\2\u0134"+ - "\u012f\3\2\2\2\u0134\u0131\3\2\2\2\u0135;\3\2\2\2\u0136\u0137\t\7\2\2"+ - "\u0137=\3\2\2\2\u0138\u013a\7\35\2\2\u0139\u013b\5$\23\2\u013a\u0139\3"+ - "\2\2\2\u013a\u013b\3\2\2\2\u013b\u0140\3\2\2\2\u013c\u013d\7\6\2\2\u013d"+ - "\u013f\5$\23\2\u013e\u013c\3\2\2\2\u013f\u0142\3\2\2\2\u0140\u013e\3\2"+ - "\2\2\u0140\u0141\3\2\2\2\u0141\u0143\3\2\2\2\u0142\u0140\3\2\2\2\u0143"+ - "\u0144\7\36\2\2\u0144?\3\2\2\2\u0145\u0147\5> \2\u0146\u0145\3\2\2\2\u0147"+ - "\u014a\3\2\2\2\u0148\u0146\3\2\2\2\u0148\u0149\3\2\2\2\u0149\u014b\3\2"+ - "\2\2\u014a\u0148\3\2\2\2\u014b\u014c\7\2\2\3\u014cA\3\2\2\2.CFM`hlpty"+ - "~\u0082\u0088\u008d\u0092\u0094\u0097\u009c\u00a5\u00aa\u00ad\u00b1\u00b3"+ - "\u00ba\u00be\u00c3\u00c6\u00cb\u00ce\u00d5\u00e0\u00e7\u00f5\u0103\u0105"+ - "\u010e\u0116\u011c\u0128\u012c\u0131\u0134\u013a\u0140\u0148"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java deleted file mode 100644 index 39b3c55e7..000000000 --- a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPCore2Visitor.java +++ /dev/null @@ -1,319 +0,0 @@ -// Generated from at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 by ANTLR 4.7 -package at.ac.tuwien.kr.alpha.antlr; -import org.antlr.v4.runtime.tree.ParseTreeVisitor; - -/** - * This interface defines a complete generic visitor for a parse tree produced - * by {@link ASPCore2Parser}. - * - * @param The return type of the visit operation. Use {@link Void} for - * operations with no return type. - */ -public interface ASPCore2Visitor extends ParseTreeVisitor { - /** - * Visit a parse tree produced by {@link ASPCore2Parser#program}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitProgram(ASPCore2Parser.ProgramContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#statements}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitStatements(ASPCore2Parser.StatementsContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#query}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitQuery(ASPCore2Parser.QueryContext ctx); - /** - * Visit a parse tree produced by the {@code statement_fact} - * labeled alternative in {@link ASPCore2Parser#statement}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitStatement_fact(ASPCore2Parser.Statement_factContext ctx); - /** - * Visit a parse tree produced by the {@code statement_constraint} - * labeled alternative in {@link ASPCore2Parser#statement}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx); - /** - * Visit a parse tree produced by the {@code statement_rule} - * labeled alternative in {@link ASPCore2Parser#statement}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitStatement_rule(ASPCore2Parser.Statement_ruleContext ctx); - /** - * Visit a parse tree produced by the {@code statement_weightConstraint} - * labeled alternative in {@link ASPCore2Parser#statement}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitStatement_weightConstraint(ASPCore2Parser.Statement_weightConstraintContext ctx); - /** - * Visit a parse tree produced by the {@code statement_directive} - * labeled alternative in {@link ASPCore2Parser#statement}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitStatement_directive(ASPCore2Parser.Statement_directiveContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#head}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitHead(ASPCore2Parser.HeadContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#body}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitBody(ASPCore2Parser.BodyContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#disjunction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitDisjunction(ASPCore2Parser.DisjunctionContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#choice}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitChoice(ASPCore2Parser.ChoiceContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#choice_elements}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#choice_element}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitChoice_element(ASPCore2Parser.Choice_elementContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#aggregate}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitAggregate(ASPCore2Parser.AggregateContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#aggregate_elements}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitAggregate_elements(ASPCore2Parser.Aggregate_elementsContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#aggregate_element}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#aggregate_function}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitAggregate_function(ASPCore2Parser.Aggregate_functionContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#weight_at_level}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitWeight_at_level(ASPCore2Parser.Weight_at_levelContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#naf_literals}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#naf_literal}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#classical_literal}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitClassical_literal(ASPCore2Parser.Classical_literalContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#builtin_atom}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#binop}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitBinop(ASPCore2Parser.BinopContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#terms}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerms(ASPCore2Parser.TermsContext ctx); - /** - * Visit a parse tree produced by the {@code term_number} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_number(ASPCore2Parser.Term_numberContext ctx); - /** - * Visit a parse tree produced by the {@code term_anonymousVariable} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx); - /** - * Visit a parse tree produced by the {@code term_const} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_const(ASPCore2Parser.Term_constContext ctx); - /** - * Visit a parse tree produced by the {@code term_minusArithTerm} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx); - /** - * Visit a parse tree produced by the {@code term_bitxorArithTerm} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx); - /** - * Visit a parse tree produced by the {@code term_interval} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx); - /** - * Visit a parse tree produced by the {@code term_variable} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_variable(ASPCore2Parser.Term_variableContext ctx); - /** - * Visit a parse tree produced by the {@code term_timesdivmodArithTerm} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx); - /** - * Visit a parse tree produced by the {@code term_plusminusArithTerm} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx); - /** - * Visit a parse tree produced by the {@code term_powerArithTerm} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx); - /** - * Visit a parse tree produced by the {@code term_func} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_func(ASPCore2Parser.Term_funcContext ctx); - /** - * Visit a parse tree produced by the {@code term_string} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_string(ASPCore2Parser.Term_stringContext ctx); - /** - * Visit a parse tree produced by the {@code term_parenthesisedTerm} - * labeled alternative in {@link ASPCore2Parser#term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitTerm_parenthesisedTerm(ASPCore2Parser.Term_parenthesisedTermContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#interval}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInterval(ASPCore2Parser.IntervalContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#external_atom}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExternal_atom(ASPCore2Parser.External_atomContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#directive}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitDirective(ASPCore2Parser.DirectiveContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#directive_enumeration}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#basic_terms}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#basic_term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitBasic_term(ASPCore2Parser.Basic_termContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#ground_term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitGround_term(ASPCore2Parser.Ground_termContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#variable_term}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitVariable_term(ASPCore2Parser.Variable_termContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#answer_set}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitAnswer_set(ASPCore2Parser.Answer_setContext ctx); - /** - * Visit a parse tree produced by {@link ASPCore2Parser#answer_sets}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx); -} \ No newline at end of file diff --git a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java b/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java deleted file mode 100644 index 2a3f15b4e..000000000 --- a/core/build/generated-src/antlr/main/at/ac/tuwien/kr/alpha/antlr/ASPLexer.java +++ /dev/null @@ -1,209 +0,0 @@ -// Generated from at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 by ANTLR 4.7 -package at.ac.tuwien.kr.alpha.antlr; -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class ASPLexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - ANONYMOUS_VARIABLE=1, DOT=2, COMMA=3, QUERY_MARK=4, COLON=5, SEMICOLON=6, - OR=7, NAF=8, CONS=9, WCONS=10, PLUS=11, MINUS=12, TIMES=13, DIV=14, POWER=15, - MODULO=16, BITXOR=17, AT=18, SHARP=19, AMPERSAND=20, QUOTE=21, PAREN_OPEN=22, - PAREN_CLOSE=23, SQUARE_OPEN=24, SQUARE_CLOSE=25, CURLY_OPEN=26, CURLY_CLOSE=27, - EQUAL=28, UNEQUAL=29, LESS=30, GREATER=31, LESS_OR_EQ=32, GREATER_OR_EQ=33, - AGGREGATE_COUNT=34, AGGREGATE_MAX=35, AGGREGATE_MIN=36, AGGREGATE_SUM=37, - ID=38, VARIABLE=39, NUMBER=40, QUOTED_STRING=41, COMMENT=42, MULTI_LINE_COMMEN=43, - BLANK=44; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE" - }; - - public static final String[] ruleNames = { - "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", "SEMICOLON", - "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", "POWER", - "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", - "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", - "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", - "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", - "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", - "BLANK" - }; - - private static final String[] _LITERAL_NAMES = { - null, "'_'", "'.'", "','", "'?'", "':'", "';'", "'|'", "'not'", "':-'", - "':~'", "'+'", "'-'", "'*'", "'/'", "'**'", "'\\'", "'^'", "'@'", "'#'", - "'&'", "'\"'", "'('", "')'", "'['", "']'", "'{'", "'}'", "'='", null, - "'<'", "'>'", "'<='", "'>='", "'#count'", "'#max'", "'#min'", "'#sum'" - }; - private static final String[] _SYMBOLIC_NAMES = { - null, "ANONYMOUS_VARIABLE", "DOT", "COMMA", "QUERY_MARK", "COLON", "SEMICOLON", - "OR", "NAF", "CONS", "WCONS", "PLUS", "MINUS", "TIMES", "DIV", "POWER", - "MODULO", "BITXOR", "AT", "SHARP", "AMPERSAND", "QUOTE", "PAREN_OPEN", - "PAREN_CLOSE", "SQUARE_OPEN", "SQUARE_CLOSE", "CURLY_OPEN", "CURLY_CLOSE", - "EQUAL", "UNEQUAL", "LESS", "GREATER", "LESS_OR_EQ", "GREATER_OR_EQ", - "AGGREGATE_COUNT", "AGGREGATE_MAX", "AGGREGATE_MIN", "AGGREGATE_SUM", - "ID", "VARIABLE", "NUMBER", "QUOTED_STRING", "COMMENT", "MULTI_LINE_COMMEN", - "BLANK" - }; - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public ASPLexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "ASPLexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2.\u00ff\b\1\4\2\t"+ - "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ - "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ - "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ - "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ - "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ - ",\t,\4-\t-\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t"+ - "\3\t\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17"+ - "\3\17\3\20\3\20\3\20\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25"+ - "\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34"+ - "\3\35\3\35\3\36\3\36\3\36\3\36\5\36\u009d\n\36\3\37\3\37\3 \3 \3!\3!\3"+ - "!\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3"+ - "&\3&\3&\3&\3\'\3\'\7\'\u00c1\n\'\f\'\16\'\u00c4\13\'\3(\3(\7(\u00c8\n"+ - "(\f(\16(\u00cb\13(\3)\3)\3)\7)\u00d0\n)\f)\16)\u00d3\13)\5)\u00d5\n)\3"+ - "*\3*\3*\3*\7*\u00db\n*\f*\16*\u00de\13*\3*\3*\3+\3+\7+\u00e4\n+\f+\16"+ - "+\u00e7\13+\3+\3+\3,\3,\3,\3,\7,\u00ef\n,\f,\16,\u00f2\13,\3,\3,\3,\3"+ - ",\3,\3-\6-\u00fa\n-\r-\16-\u00fb\3-\3-\4\u00dc\u00f0\2.\3\3\5\4\7\5\t"+ - "\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23"+ - "%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G"+ - "%I&K\'M(O)Q*S+U,W-Y.\3\2\5\6\2\62;C\\aac|\4\2\f\f\17\17\5\2\13\f\16\17"+ - "\"\"\2\u0108\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2"+ - "\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2"+ - "\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2"+ - "\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2"+ - "\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3"+ - "\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2"+ - "\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2"+ - "S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\3[\3\2\2\2\5]\3\2\2\2\7_\3"+ - "\2\2\2\ta\3\2\2\2\13c\3\2\2\2\re\3\2\2\2\17g\3\2\2\2\21i\3\2\2\2\23m\3"+ - "\2\2\2\25p\3\2\2\2\27s\3\2\2\2\31u\3\2\2\2\33w\3\2\2\2\35y\3\2\2\2\37"+ - "{\3\2\2\2!~\3\2\2\2#\u0080\3\2\2\2%\u0082\3\2\2\2\'\u0084\3\2\2\2)\u0086"+ - "\3\2\2\2+\u0088\3\2\2\2-\u008a\3\2\2\2/\u008c\3\2\2\2\61\u008e\3\2\2\2"+ - "\63\u0090\3\2\2\2\65\u0092\3\2\2\2\67\u0094\3\2\2\29\u0096\3\2\2\2;\u009c"+ - "\3\2\2\2=\u009e\3\2\2\2?\u00a0\3\2\2\2A\u00a2\3\2\2\2C\u00a5\3\2\2\2E"+ - "\u00a8\3\2\2\2G\u00af\3\2\2\2I\u00b4\3\2\2\2K\u00b9\3\2\2\2M\u00be\3\2"+ - "\2\2O\u00c5\3\2\2\2Q\u00d4\3\2\2\2S\u00d6\3\2\2\2U\u00e1\3\2\2\2W\u00ea"+ - "\3\2\2\2Y\u00f9\3\2\2\2[\\\7a\2\2\\\4\3\2\2\2]^\7\60\2\2^\6\3\2\2\2_`"+ - "\7.\2\2`\b\3\2\2\2ab\7A\2\2b\n\3\2\2\2cd\7<\2\2d\f\3\2\2\2ef\7=\2\2f\16"+ - "\3\2\2\2gh\7~\2\2h\20\3\2\2\2ij\7p\2\2jk\7q\2\2kl\7v\2\2l\22\3\2\2\2m"+ - "n\7<\2\2no\7/\2\2o\24\3\2\2\2pq\7<\2\2qr\7\u0080\2\2r\26\3\2\2\2st\7-"+ - "\2\2t\30\3\2\2\2uv\7/\2\2v\32\3\2\2\2wx\7,\2\2x\34\3\2\2\2yz\7\61\2\2"+ - "z\36\3\2\2\2{|\7,\2\2|}\7,\2\2} \3\2\2\2~\177\7^\2\2\177\"\3\2\2\2\u0080"+ - "\u0081\7`\2\2\u0081$\3\2\2\2\u0082\u0083\7B\2\2\u0083&\3\2\2\2\u0084\u0085"+ - "\7%\2\2\u0085(\3\2\2\2\u0086\u0087\7(\2\2\u0087*\3\2\2\2\u0088\u0089\7"+ - "$\2\2\u0089,\3\2\2\2\u008a\u008b\7*\2\2\u008b.\3\2\2\2\u008c\u008d\7+"+ - "\2\2\u008d\60\3\2\2\2\u008e\u008f\7]\2\2\u008f\62\3\2\2\2\u0090\u0091"+ - "\7_\2\2\u0091\64\3\2\2\2\u0092\u0093\7}\2\2\u0093\66\3\2\2\2\u0094\u0095"+ - "\7\177\2\2\u00958\3\2\2\2\u0096\u0097\7?\2\2\u0097:\3\2\2\2\u0098\u0099"+ - "\7>\2\2\u0099\u009d\7@\2\2\u009a\u009b\7#\2\2\u009b\u009d\7?\2\2\u009c"+ - "\u0098\3\2\2\2\u009c\u009a\3\2\2\2\u009d<\3\2\2\2\u009e\u009f\7>\2\2\u009f"+ - ">\3\2\2\2\u00a0\u00a1\7@\2\2\u00a1@\3\2\2\2\u00a2\u00a3\7>\2\2\u00a3\u00a4"+ - "\7?\2\2\u00a4B\3\2\2\2\u00a5\u00a6\7@\2\2\u00a6\u00a7\7?\2\2\u00a7D\3"+ - "\2\2\2\u00a8\u00a9\7%\2\2\u00a9\u00aa\7e\2\2\u00aa\u00ab\7q\2\2\u00ab"+ - "\u00ac\7w\2\2\u00ac\u00ad\7p\2\2\u00ad\u00ae\7v\2\2\u00aeF\3\2\2\2\u00af"+ - "\u00b0\7%\2\2\u00b0\u00b1\7o\2\2\u00b1\u00b2\7c\2\2\u00b2\u00b3\7z\2\2"+ - "\u00b3H\3\2\2\2\u00b4\u00b5\7%\2\2\u00b5\u00b6\7o\2\2\u00b6\u00b7\7k\2"+ - "\2\u00b7\u00b8\7p\2\2\u00b8J\3\2\2\2\u00b9\u00ba\7%\2\2\u00ba\u00bb\7"+ - "u\2\2\u00bb\u00bc\7w\2\2\u00bc\u00bd\7o\2\2\u00bdL\3\2\2\2\u00be\u00c2"+ - "\4c|\2\u00bf\u00c1\t\2\2\2\u00c0\u00bf\3\2\2\2\u00c1\u00c4\3\2\2\2\u00c2"+ - "\u00c0\3\2\2\2\u00c2\u00c3\3\2\2\2\u00c3N\3\2\2\2\u00c4\u00c2\3\2\2\2"+ - "\u00c5\u00c9\4C\\\2\u00c6\u00c8\t\2\2\2\u00c7\u00c6\3\2\2\2\u00c8\u00cb"+ - "\3\2\2\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2\2\2\u00caP\3\2\2\2\u00cb"+ - "\u00c9\3\2\2\2\u00cc\u00d5\7\62\2\2\u00cd\u00d1\4\63;\2\u00ce\u00d0\4"+ - "\62;\2\u00cf\u00ce\3\2\2\2\u00d0\u00d3\3\2\2\2\u00d1\u00cf\3\2\2\2\u00d1"+ - "\u00d2\3\2\2\2\u00d2\u00d5\3\2\2\2\u00d3\u00d1\3\2\2\2\u00d4\u00cc\3\2"+ - "\2\2\u00d4\u00cd\3\2\2\2\u00d5R\3\2\2\2\u00d6\u00dc\5+\26\2\u00d7\u00d8"+ - "\7^\2\2\u00d8\u00db\7$\2\2\u00d9\u00db\13\2\2\2\u00da\u00d7\3\2\2\2\u00da"+ - "\u00d9\3\2\2\2\u00db\u00de\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dc\u00da\3\2"+ - "\2\2\u00dd\u00df\3\2\2\2\u00de\u00dc\3\2\2\2\u00df\u00e0\5+\26\2\u00e0"+ - "T\3\2\2\2\u00e1\u00e5\7\'\2\2\u00e2\u00e4\n\3\2\2\u00e3\u00e2\3\2\2\2"+ - "\u00e4\u00e7\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6\u00e8"+ - "\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e8\u00e9\b+\2\2\u00e9V\3\2\2\2\u00ea\u00eb"+ - "\7\'\2\2\u00eb\u00ec\7,\2\2\u00ec\u00f0\3\2\2\2\u00ed\u00ef\13\2\2\2\u00ee"+ - "\u00ed\3\2\2\2\u00ef\u00f2\3\2\2\2\u00f0\u00f1\3\2\2\2\u00f0\u00ee\3\2"+ - "\2\2\u00f1\u00f3\3\2\2\2\u00f2\u00f0\3\2\2\2\u00f3\u00f4\7,\2\2\u00f4"+ - "\u00f5\7\'\2\2\u00f5\u00f6\3\2\2\2\u00f6\u00f7\b,\2\2\u00f7X\3\2\2\2\u00f8"+ - "\u00fa\t\4\2\2\u00f9\u00f8\3\2\2\2\u00fa\u00fb\3\2\2\2\u00fb\u00f9\3\2"+ - "\2\2\u00fb\u00fc\3\2\2\2\u00fc\u00fd\3\2\2\2\u00fd\u00fe\b-\2\2\u00fe"+ - "Z\3\2\2\2\r\2\u009c\u00c2\u00c9\u00d1\u00d4\u00da\u00dc\u00e5\u00f0\u00fb"+ - "\3\2\3\2"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 b/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 deleted file mode 100644 index aeca5cc2d..000000000 --- a/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPCore2.g4 +++ /dev/null @@ -1,90 +0,0 @@ -grammar ASPCore2; - -import ASPLexer; - -/* The ASP-Core-2 grammar in ANTLR v4 based on - * 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). - */ - -program : statements? query? EOF; - -statements : statement+; - -query : classical_literal QUERY_MARK; - -statement : head DOT # statement_fact - | CONS body DOT # statement_constraint - | head CONS body DOT # statement_rule - | WCONS body? DOT SQUARE_OPEN weight_at_level SQUARE_CLOSE # statement_weightConstraint - | directive # statement_directive; // NOT Core2 syntax. - -head : disjunction | choice; - -body : ( naf_literal | aggregate ) (COMMA body)?; - -disjunction : classical_literal (OR disjunction)?; - -choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; - -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_elements : aggregate_element (SEMICOLON aggregate_elements)?; - -aggregate_element : basic_terms? (COLON naf_literals?)?; - -aggregate_function : AGGREGATE_COUNT | AGGREGATE_MAX | AGGREGATE_MIN | AGGREGATE_SUM; - -weight_at_level : term (AT term)? (COMMA terms)?; - -naf_literals : naf_literal (COMMA naf_literals)?; - -naf_literal : NAF? (external_atom | classical_literal | builtin_atom); - -classical_literal : MINUS? ID (PAREN_OPEN terms PAREN_CLOSE)?; - -builtin_atom : term binop term; - -binop : EQUAL | UNEQUAL | LESS | GREATER | LESS_OR_EQ | GREATER_OR_EQ; - -terms : term (COMMA terms)?; - -term : ID # term_const - | ID (PAREN_OPEN terms? PAREN_CLOSE) # term_func - | NUMBER # term_number - | QUOTED_STRING # term_string - | VARIABLE # term_variable - | ANONYMOUS_VARIABLE # term_anonymousVariable - | PAREN_OPEN term PAREN_CLOSE # term_parenthesisedTerm - | interval # term_interval // Syntax extension. - | MINUS term # term_minusArithTerm - | term POWER term # term_powerArithTerm - | term (TIMES | DIV | MODULO) term # term_timesdivmodArithTerm - | term (PLUS | MINUS) term # term_plusminusArithTerm - | term BITXOR term # term_bitxorArithTerm - ; - -interval : lower = (NUMBER | VARIABLE) DOT DOT upper = (NUMBER | VARIABLE); // NOT Core2 syntax, but widespread - -external_atom : MINUS? AMPERSAND ID (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; // NOT Core2 syntax. - -directive : directive_enumeration; // NOT Core2 syntax, allows solver specific directives. Further directives shall be added here. - -directive_enumeration : SHARP 'enumeration_predicate_is' ID DOT; // NOT Core2 syntax, used for aggregate translation. - -basic_terms : basic_term (COMMA basic_terms)? ; - -basic_term : ground_term | variable_term; - -ground_term : /*SYMBOLIC_CONSTANT*/ ID | QUOTED_STRING | MINUS? NUMBER; - -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 diff --git a/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 b/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 deleted file mode 100644 index a900ca342..000000000 --- a/core/src/main/antlr/at/ac/tuwien/kr/alpha/antlr/ASPLexer.g4 +++ /dev/null @@ -1,50 +0,0 @@ -lexer grammar ASPLexer; - -ANONYMOUS_VARIABLE : '_'; -DOT : '.'; -COMMA : ','; -QUERY_MARK : '?'; -COLON : ':'; -SEMICOLON : ';'; -OR : '|'; -NAF : 'not'; -CONS : ':-'; -WCONS : ':~'; -PLUS : '+'; -MINUS : '-'; -TIMES : '*'; -DIV : '/'; -POWER : '**'; -MODULO : '\\'; -BITXOR : '^'; -AT : '@'; -SHARP : '#'; // NOT Core2 syntax but gringo -AMPERSAND : '&'; -QUOTE : '"'; - -PAREN_OPEN : '('; -PAREN_CLOSE : ')'; -SQUARE_OPEN : '['; -SQUARE_CLOSE : ']'; -CURLY_OPEN : '{'; -CURLY_CLOSE : '}'; -EQUAL : '='; -UNEQUAL : '<>' | '!='; -LESS : '<'; -GREATER : '>'; -LESS_OR_EQ : '<='; -GREATER_OR_EQ : '>='; - -AGGREGATE_COUNT : '#count'; -AGGREGATE_MAX : '#max'; -AGGREGATE_MIN : '#min'; -AGGREGATE_SUM : '#sum'; - -ID : ('a'..'z') ( 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' )*; -VARIABLE : ('A'..'Z') ( 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' )*; -NUMBER : '0' | ('1'..'9') ('0'..'9')*; -QUOTED_STRING : QUOTE ( '\\"' | . )*? QUOTE; - -COMMENT : '%' ~[\r\n]* -> channel(HIDDEN); -MULTI_LINE_COMMEN : '%*' .*? '*%' -> channel(HIDDEN); -BLANK : [ \t\r\n\f]+ -> channel(HIDDEN); \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java deleted file mode 100644 index fada6277c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/AlphaImpl.java +++ /dev/null @@ -1,226 +0,0 @@ -/** - * 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. - * - * 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; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.grounder.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation; -import at.ac.tuwien.kr.alpha.solver.Solver; -import at.ac.tuwien.kr.alpha.solver.SolverFactory; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.charset.CodingErrorAction; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class AlphaImpl implements Alpha { - - private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); - - private SystemConfig config = new SystemConfig(); // The config is initialized with default values. - - public AlphaImpl(SystemConfig cfg) { - this.config = cfg; - } - - public AlphaImpl() { - } - - public InputProgram readProgram(InputConfig cfg) throws IOException { - InputProgram.Builder prgBuilder = InputProgram.builder(); - InputProgram tmpProg; - if (!cfg.getFiles().isEmpty()) { - tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); - prgBuilder.accumulate(tmpProg); - } - if (!cfg.getAspStrings().isEmpty()) { - tmpProg = readProgramString(StringUtils.join(cfg.getAspStrings(), System.lineSeparator()), cfg.getPredicateMethods()); - prgBuilder.accumulate(tmpProg); - } - return prgBuilder.build(); - } - - 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[] {})); - } - - public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - ProgramParser parser = new ProgramParser(externals); - InputProgram.Builder prgBuilder = InputProgram.builder(); - InputProgram tmpProg; - for (Path path : paths) { - CharStream stream; - if (!literate) { - stream = CharStreams.fromPath(path); - } else { - stream = CharStreams.fromChannel(Util.streamToChannel(Util.literate(Files.lines(path))), 4096, CodingErrorAction.REPLACE, path.toString()); - } - tmpProg = parser.parse(stream); - prgBuilder.accumulate(tmpProg); - } - return prgBuilder.build(); - } - - public InputProgram readProgramString(String aspString, Map externals) { - ProgramParser parser = new ProgramParser(externals); - return parser.parse(aspString); - } - - public InputProgram readProgramString(String aspString) { - return readProgramString(aspString, null); - } - - public NormalProgram normalizeProgram(InputProgram program) { - return new NormalizeProgramTransformation(config.isUseNormalizationGrid()).apply(program); - } - - public InternalProgram performProgramPreprocessing(InternalProgram program) { - LOGGER.debug("Preprocessing InternalProgram!"); - InternalProgram retVal = program; - if (config.isEvaluateStratifiedPart()) { - AnalyzedProgram analyzed = new AnalyzedProgram(program.getRules(), program.getFacts()); - retVal = new StratifiedEvaluation().apply(analyzed); - } - return retVal; - } - - public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { - LOGGER.debug("Preprocessing AnalyzedProgram!"); - InternalProgram retVal = program; - if (config.isEvaluateStratifiedPart()) { - retVal = new StratifiedEvaluation().apply(program); - } - return retVal; - } - - /** - * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the - * program analysis and normalization aren't of interest. - */ - public Stream solve(InputProgram program) { - return solve(program, InputConfig.DEFAULT_FILTER); - } - - /** - * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where - * details of the program analysis and normalization aren't of interest. - */ - public Stream solve(InputProgram program, java.util.function.Predicate filter) { - NormalProgram normalized = normalizeProgram(program); - return solve(normalized, filter); - } - - /** - * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the - * program analysis aren't of interest. - */ - public Stream solve(NormalProgram program, java.util.function.Predicate filter) { - InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); - return solve(preprocessed, filter); - } - - /** - * Overloaded version of solve({@link InternalProgram}, {@link Predicate}) that uses a default filter (accept - * everything). - * - * @param program the program to solve - * @return a stream of answer sets - */ - public Stream solve(InternalProgram program) { - return solve(program, InputConfig.DEFAULT_FILTER); - } - - /** - * 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 - * @return a Stream of answer sets representing stable models of the given program - */ - public Stream solve(InternalProgram program, java.util.function.Predicate filter) { - Stream retVal = prepareSolverFor(program, filter).stream(); - return config.isSortAnswerSets() ? retVal.sorted() : retVal; - } - - /** - * 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. - * @return a solver (and accompanying grounder) instance pre-loaded with the given program. - */ - public Solver prepareSolverFor(InternalProgram 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 SystemConfig getConfig() { - return config; - } - - public void setConfig(SystemConfig config) { - this.config = config; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java b/core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java deleted file mode 100644 index 29b9adf3f..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/CustomErrorListener.java +++ /dev/null @@ -1,28 +0,0 @@ -package at.ac.tuwien.kr.alpha; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; - -public class CustomErrorListener extends BaseErrorListener { - RecognitionException recognitionException; - - private final String fileName; - - public CustomErrorListener(String fileName) { - this.fileName = fileName; - } - - @Override - public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { - super.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e); - - System.err.println(fileName + ":" + line + ":" + charPositionInLine + ": " + msg); - - this.recognitionException = e; - } - - public RecognitionException getRecognitionException() { - return recognitionException; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/Util.java b/core/src/main/java/at/ac/tuwien/kr/alpha/Util.java deleted file mode 100644 index b8e9efde0..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/Util.java +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Copyright (c) 2016, 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; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.charset.StandardCharsets; -import java.util.AbstractMap; -import java.util.Iterator; -import java.util.Map; -import java.util.SortedSet; -import java.util.StringJoiner; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class Util { - private static final String LITERATE_INDENT = " "; - - public static Map.Entry entry(K key, V value) { - return new AbstractMap.SimpleEntry<>(key, value); - } - - public static Collector, ?, Map> entriesToMap() { - return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue); - } - - public static String join(String prefix, Iterable iterable, String suffix) { - return join(prefix, iterable, ", ", suffix); - } - - public static String join(String prefix, Iterable iterable, String delimiter, String suffix) { - StringJoiner joiner = new StringJoiner(delimiter, prefix, suffix); - for (E element : iterable) { - joiner.add(element.toString()); - } - return joiner.toString(); - } - - public static > int compareSortedSets(SortedSet a, SortedSet b) { - if (a.size() != b.size()) { - return a.size() - b.size(); - } - - if (a.isEmpty() && b.isEmpty()) { - return 0; - } - - final Iterator ita = a.iterator(); - final Iterator itb = b.iterator(); - - do { - final int result = ita.next().compareTo(itb.next()); - - if (result != 0) { - return result; - } - } while (ita.hasNext() && itb.hasNext()); - - return 0; - } - - public static RuntimeException oops(String message, Exception e) { - return new RuntimeException(message + "! Should not happen.", e); - } - - public static RuntimeException oops(String message) { - // We do not call oops(String, Exception) here to not bloat the stack trace. - return new RuntimeException(message + "! Should not happen."); - } - - public static RuntimeException oops() { - return oops("Reached fatal state"); - } - - public static Stream literate(Stream input) { - return input.map(l -> { - if (l.startsWith(LITERATE_INDENT)) { - return l.substring(LITERATE_INDENT.length()); - } - return "% " + l; - }); - } - - public static ReadableByteChannel streamToChannel(Stream lines) throws IOException { - return Channels.newChannel(new ByteArrayInputStream(lines.collect(Collectors.joining(System.lineSeparator())).getBytes(StandardCharsets.UTF_8))); - } - - public static int arrayGrowthSize(int oldSize) { - // Growth factor is 1.5. - return oldSize + (oldSize >> 1); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java deleted file mode 100644 index 0bb017067..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Externals.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.api.externals; - -import at.ac.tuwien.kr.alpha.api.externals.stdlib.AspStandardLibrary; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.*; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import org.reflections.Reflections; -import org.reflections.scanners.MethodAnnotationsScanner; - -import java.lang.reflect.Method; -import java.util.*; - -public final class Externals { - - // Private constructor since this is a utility class. - private Externals() { - - } - - /** - * Returns a map of external definitions making up the "standard library" of - * externals that are always available in programs for Alpha. - * This method scans all predicate-annotated methods in the package holding the - * class {@link AspStandardLibrary}. - */ - public static Map getStandardLibraryExternals() { - return Externals.scan(AspStandardLibrary.class.getPackage()); - } - - public static Map scan(Package basePackage) { - Reflections reflections = new Reflections(basePackage.getName(), new MethodAnnotationsScanner()); - Set methods = reflections.getMethodsAnnotatedWith(Predicate.class); - return Externals.scanMethods(methods); - } - - public static Map scan(Class classWithPredicateMethods) { - Method[] methods = classWithPredicateMethods.getMethods(); - Set predicateMethods = new HashSet<>(); - for (Method method : methods) { - if (method.isAnnotationPresent(Predicate.class)) { - predicateMethods.add(method); - } - } - return Externals.scanMethods(predicateMethods); - } - - private static Map scanMethods(Iterable methods) { - Map retVal = new HashMap<>(); - String name; - for (Method method : methods) { - name = method.getAnnotation(Predicate.class).name(); - if (name.isEmpty()) { - name = method.getName(); - } - retVal.put(name, Externals.processPredicateMethod(method)); - } - return retVal; - } - - public static PredicateInterpretation processPredicateMethod(Method method) { - if (method.getReturnType().equals(boolean.class)) { - return new MethodPredicateInterpretation(method); - } - - if (method.getGenericReturnType().getTypeName().startsWith(PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX)) { - return new BindingMethodPredicateInterpretation(method); - } - - throw new IllegalArgumentException("Passed method has unexpected return type. Should be either boolean or start with " - + PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX + "."); - } - - public static PredicateInterpretation processPredicate(java.util.function.Predicate predicate) { - return new UnaryPredicateInterpretation<>(predicate); - } - - public static PredicateInterpretation processPredicate(java.util.function.IntPredicate predicate) { - return new IntPredicateInterpretation(predicate); - } - - public static PredicateInterpretation processPredicate(java.util.function.LongPredicate predicate) { - return new LongPredicateInterpretation(predicate); - } - - public static PredicateInterpretation processPredicate(java.util.function.BiPredicate predicate) { - return new BinaryPredicateInterpretation<>(predicate); - } - - public static PredicateInterpretation processPredicate(java.util.function.Supplier>>> supplier) { - return new SuppliedPredicateInterpretation(supplier); - } - - /** - * Converts a collection of objects to facts. - * Every item in the collection is wrapped in a {@link ConstantTerm}, which is the argument of a unary predicate whose - * symbol is the class name of the given class (i.e. the declared type of objects inside the collection), modified to - * start with a lower-case letter. - * - * @param the type of the objects to use as facts - * @param classOfExtFacts the {@link Class} object of the value type - * @param extFacts a {@link Collection} of objects of type classOfExtFacts - * @return a list of {@link Atom}s. - */ - public static > List asFacts(Class classOfExtFacts, Collection extFacts) { - // Use Class as parameter here, taking simple name from first element might not give desired result if it is a subtype. - List retVal = new ArrayList<>(); - String javaName = classOfExtFacts.getSimpleName(); - String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. - for (T instance : extFacts) { - // TODO use properly wrapped BasicAtoms here - retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.CorePredicate.getInstance(name, 1), CoreConstantTerm.getInstance(instance))); - } - return retVal; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java b/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java deleted file mode 100644 index 973e738de..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibrary.java +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.api.externals.stdlib; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.api.externals.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Terms; - -/** - * Collection of methods that can be used as external atoms from ASP programs. - * Provides commonly used functionality such as basic string operations, - * datetime handling etc. - * - * All functions exposed by this class are guaranteed to be stateless and - * side-effect free. - * - * Copyright (c) 2020, the Alpha Team. - */ -public final class AspStandardLibrary { - - private AspStandardLibrary() { - throw new AssertionError(this.getClass().getSimpleName() + " is a non-instantiable utility class!"); - } - - /** - * Parses a string representing a datetime without time-zone and returns the - * year, month, day, hours, minutes and seconds as separate symbolic integer - * terms. - * Example: - * - *

      -	 * 		A valid ground instance of the atom &stdlib_datetime_parse[DTSTR, "dd.mm.yyyy hh:MM:ss"](YEAR, MONTH, DAY, HOUR, MIN, SEC)
      -	 * 		would be: &stdlib_datetime_parse["20.05.2020 01:19:13", "dd.mm.yyyy hh:MM:ss"](2020, 5, 20, 1, 19, 13)
      -	 * 
      - * - * Timezones are not supported by this function. Datetime values are parsed - * using {@link LocalDateTime.parse}. - * - * @param datetime a string representing a datetime without time zone - * information - * @param format a format string that is accepted by {@link DateTimeFormatter} - * @return a 6-value integer tuple of format (YEAR, MONTH, DAY, HOUR, MIN, SEC) - */ - @Predicate(name = "stdlib_datetime_parse") - public static Set>> datetimeParse(String dtstr, String format) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); - LocalDateTime datetime = LocalDateTime.parse(dtstr, formatter); - List> terms = Terms.asTermList( - datetime.getYear(), datetime.getMonth().getValue(), datetime.getDayOfMonth(), - datetime.getHour(), datetime.getMinute(), datetime.getSecond()); - return Collections.singleton(terms); - } - - /** - * Compares two datetimes and returns true iff the first datetime (dt1) is - * before the second datetime (dt2). Both datetimes are represented as six - * integers each, referring to years, months, days, hours, minutes and seconds - * respectively. - * - * @param dt1Year the year field for dt1 - * @param dt1Month the month field for dt1 - * @param dt1Day the day field for dt1 - * @param dt1Hour the hour field for dt1 - * @param dt1Minute the minute field for dt1 - * @param dt1Second the second field for dt1 - * @param dt2Year the year field for dt2 - * @param dt2Month the month field for dt2 - * @param dt2Day the day field for dt2 - * @param dt2Hour the hour field for dt2 - * @param dt2Minute the minute field for dt2 - * @param dt2Second the second field for dt2 - * @return true if dt1 is before dt2 in time, false otherwise - */ - @Predicate(name = "stdlib_datetime_is_before") - public static boolean datetimeIsBefore(int dt1Year, int dt1Month, int dt1Day, int dt1Hour, int dt1Minute, int dt1Second, - int dt2Year, int dt2Month, int dt2Day, int dt2Hour, int dt2Minute, int dt2Second) { - LocalDateTime dt1 = LocalDateTime.of(dt1Year, dt1Month, dt1Day, dt1Hour, dt1Minute, dt1Second); - LocalDateTime dt2 = LocalDateTime.of(dt2Year, dt2Month, dt2Day, dt2Hour, dt2Minute, dt2Second); - return dt1.isBefore(dt2); - } - - /** - * Compares two datetimes and returns true iff the first datetime (dt1) is - * equal to the second datetime (dt2). Both datetimes are represented as six - * integers each, referring to years, months, days, hours, minutes and seconds - * respectively. - * - * @param dt1Year the year field for dt1 - * @param dt1Month the month field for dt1 - * @param dt1Day the day field for dt1 - * @param dt1Hour the hour field for dt1 - * @param dt1Minute the minute field for dt1 - * @param dt1Second the second field for dt1 - * @param dt2Year the year field for dt2 - * @param dt2Month the month field for dt2 - * @param dt2Day the day field for dt2 - * @param dt2Hour the hour field for dt2 - * @param dt2Minute the minute field for dt2 - * @param dt2Second the second field for dt2 - * @return true if dt1 is equal to dt2, false otherwise - */ - @Predicate(name = "stdlib_datetime_is_equal") - public static boolean datetimeIsEqual(int dt1Year, int dt1Month, int dt1Day, int dt1Hour, int dt1Minute, int dt1Second, - int dt2Year, int dt2Month, int dt2Day, int dt2Hour, int dt2Minute, int dt2Second) { - LocalDateTime dt1 = LocalDateTime.of(dt1Year, dt1Month, dt1Day, dt1Hour, dt1Minute, dt1Second); - LocalDateTime dt2 = LocalDateTime.of(dt2Year, dt2Month, dt2Day, dt2Hour, dt2Minute, dt2Second); - return dt1.isEqual(dt2); - } - - /** - * Compares two datetimes and returns true iff the first datetime (dt1) is - * before or equal to the second datetime (dt2). Both datetimes are represented - * as six integers each, referring to years, months, days, hours, minutes and seconds - * respectively. - * - * @param dt1Year the year field for dt1 - * @param dt1Month the month field for dt1 - * @param dt1Day the day field for dt1 - * @param dt1Hour the hour field for dt1 - * @param dt1Minute the minute field for dt1 - * @param dt1Second the second field for dt1 - * @param dt2Year the year field for dt2 - * @param dt2Month the month field for dt2 - * @param dt2Day the day field for dt2 - * @param dt2Hour the hour field for dt2 - * @param dt2Minute the minute field for dt2 - * @param dt2Second the second field for dt2 - * @return true if dt1 is before dt2 in time or both dt1 and dt2 denote the same - * point in time, false otherwise - */ - @Predicate(name = "stdlib_datetime_is_before_or_equal") - public static boolean datetimeIsBeforeOrEqual(int dt1Year, int dt1Month, int dt1Day, int dt1Hour, int dt1Minute, int dt1Second, - int dt2Year, int dt2Month, int dt2Day, int dt2Hour, int dt2Minute, int dt2Second) { - LocalDateTime dt1 = LocalDateTime.of(dt1Year, dt1Month, dt1Day, dt1Hour, dt1Minute, dt1Second); - LocalDateTime dt2 = LocalDateTime.of(dt2Year, dt2Month, dt2Day, dt2Hour, dt2Minute, dt2Second); - return dt1.isBefore(dt2) || dt1.isEqual(dt2); - } - - /** - * Formats a datetime value represented using six integers as a string according - * to the given pattern. Valid format trings are those accepted by - * {@link DateTimeFormatter.ofPattern}. - * - * @param year - * @param month - * @param day - * @param hours - * @param minutes - * @param seconds - * @param format - * @return a string representing the given datetime in the format specified by - * the format string - */ - @Predicate(name = "stdlib_datetime_to_string") - public static Set>> datetimeToString(int year, int month, int day, int hours, int minutes, int seconds, String format) { - LocalDateTime datetime = LocalDateTime.of(year, month, day, hours, minutes, seconds); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); - return Collections.singleton(Terms.asTermList(formatter.format(datetime))); - } - - /** - * Checks whether the given string matches the given regex. - */ - @Predicate(name = "stdlib_string_matches_regex") - public static boolean stringMatchesRegex(String str, String regex) { - return str.matches(regex); - } - - /** - * Returns the length of the given string - */ - @Predicate(name = "stdlib_string_length") - public static Set>> stringLength(String str) { - return Collections.singleton(Terms.asTermList(str.length())); - } - - /** - * Concatenates the two given strings - */ - @Predicate(name = "stdlib_string_concat") - public static Set>> stringConcat(String s1, String s2) { - return Collections.singleton(Terms.asTermList(s1 + s2)); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java deleted file mode 100644 index e7c091951..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetBuilder.java +++ /dev/null @@ -1,99 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; - -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static java.util.Collections.singletonList; - -public class AnswerSetBuilder { - private boolean firstInstance = true; - private String predicateSymbol; - private CorePredicate predicate; - private SortedSet predicates = new TreeSet<>(); - private SortedSet instances = new TreeSet<>(); - private Map> predicateInstances = new HashMap<>(); - - public AnswerSetBuilder() { - } - - public AnswerSetBuilder(AnswerSetBuilder copy) { - this.firstInstance = copy.firstInstance; - this.predicateSymbol = copy.predicateSymbol; - this.predicate = copy.predicate; - this.predicates = new TreeSet<>(copy.predicates); - this.instances = new TreeSet<>(copy.instances); - this.predicateInstances = new HashMap<>(copy.predicateInstances); - this.predicateInstances = copy.predicateInstances.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> new TreeSet<>(e.getValue()))); - } - - private void flush() { - if (firstInstance) { - predicate = CorePredicate.getInstance(predicateSymbol, 0); - predicates.add(predicate); - predicateInstances.put(predicate, new TreeSet<>(singletonList(new BasicAtom(predicate)))); - } else { - SortedSet atoms = predicateInstances.get(predicate); - if (atoms == null) { - predicateInstances.put(predicate, new TreeSet<>(instances)); - } else { - atoms.addAll(instances); - } - } - firstInstance = true; - instances.clear(); - predicate = null; - } - - public AnswerSetBuilder predicate(String predicateSymbol) { - if (this.predicateSymbol != null) { - flush(); - } - this.predicateSymbol = predicateSymbol; - return this; - } - - @SafeVarargs - public final > AnswerSetBuilder instance(final T... terms) { - if (firstInstance) { - firstInstance = false; - predicate = CorePredicate.getInstance(predicateSymbol, terms.length); - predicates.add(predicate); - } - - // Note that usage of terms does not pollute the heap, - // since we are only reading, not writing. - List termList = Stream - .of(terms) - .map(CoreConstantTerm::getInstance) - .collect(Collectors.toList()); - - instances.add(new BasicAtom(predicate, termList)); - return this; - } - - public AnswerSetBuilder symbolicInstance(String... terms) { - if (firstInstance) { - firstInstance = false; - predicate = CorePredicate.getInstance(predicateSymbol, terms.length); - predicates.add(predicate); - } - - List termList = Stream.of(terms).map(CoreConstantTerm::getSymbolicInstance).collect(Collectors.toList()); - instances.add(new BasicAtom(predicate, termList)); - return this; - } - - public BasicAnswerSet build() { - flush(); - return new BasicAnswerSet(predicates, predicateInstances); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java deleted file mode 100644 index 8467cc19b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatter.java +++ /dev/null @@ -1,6 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -@FunctionalInterface -public interface AnswerSetFormatter { - T format(AnswerSet answerSet); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java deleted file mode 100644 index d8b4fb7cf..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Assignment.java +++ /dev/null @@ -1,184 +0,0 @@ -/** - * 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 - * 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.common; - -import at.ac.tuwien.kr.alpha.solver.Antecedent; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; - -import java.util.Set; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; - -public interface Assignment { - Entry get(int atom); - - /** - * Returns the truth value assigned to an atom. - * @param atom the id of the atom. - * @return the truth value; null if atomId is not assigned. - */ - default ThriceTruth getTruth(int atom) { - final Entry entry = get(atom); - return entry == null ? null : entry.getTruth(); - } - - /** - * Returns the weak decision level of the atom if it is assigned. - * @param atom the atom. - * @return the weak decision level of the atom if it is assigned; otherwise any value may be returned. - */ - int getWeakDecisionLevel(int atom); - - /** - * Returns the strong decision level of the atom. - * @param atom the atom. - * @return the strong decision level of the atom or -1. - */ - int getStrongDecisionLevel(int atom); - - boolean isAssigned(int atom); - - /** - * Returns the NoGood that implied the atom. - * @param atom the atom. - * @return the implying Antecedent. - */ - Antecedent getImpliedBy(int atom); - - /** - * Determines if the given {@code noGood} is undefined in the current assignment. - * - * @param noGood - * @return {@code true} iff at least one literal in {@code noGood} is unassigned. - */ - default boolean isUndefined(NoGood noGood) { - for (Integer literal : noGood) { - if (!isAssigned(atomOf(literal))) { - return true; - } - } - return false; - } - - /** - * Returns an iterator over all newly assigned atoms. New assignments are only returned once. - * @return an iterator over all atoms newly assigned to TRUE or MBT. - */ - IntIterator getNewPositiveAssignmentsIterator(); - - /** - * Returns the new assignments to process. - * @return a Pollable that yields the atoms that were newly assigned. - */ - Pollable getAssignmentsToProcess(); - - /** - * Returns the weak decision level of the atom considering also out-of-order assignments. - * @param atom the atom. - * @return the weakDecisionLevel of the atom if it is not an out-of-order assignment, otherwise the lowest - * decision level at which it will be re-assigned. - */ - int getRealWeakDecisionLevel(int atom); - - interface Pollable { - int peek(); - int remove(); - boolean isEmpty(); - } - - interface Entry { - ThriceTruth getTruth(); - int getAtom(); - int getDecisionLevel(); - Antecedent getImpliedBy(); - - boolean hasPreviousMBT(); - int getMBTDecisionLevel(); - - } - - int getDecisionLevel(); - - default boolean isViolated(int literal) { - final int atom = atomOf(literal); - final ThriceTruth truth = getTruth(atom); - - // For unassigned atoms, any literal is not violated. - return truth != null && isNegated(literal) != truth.toBoolean(); - - } - - default boolean violates(NoGood noGood) { - // Check each NoGood, if it is violated - for (Integer noGoodLiteral : noGood) { - if (!isAssigned(atomOf(noGoodLiteral)) || !isViolated(noGoodLiteral)) { - return false; - } - } - return true; - } - - /** - * Returns all atomIds that are assigned TRUE in the current assignment. - * @return a list of all true assigned atoms. - */ - Set getTrueAssignments(); - - /** - * Reports how many atoms are assigned to must-be-true currently. If this method returns - * zero, the assignment is guaranteed to be free of must-be-true values (i.e. it only - * contains assignments to either true or false). - * @return the count of must-be-true values in the asignment. - */ - int getMBTCount(); - - void backtrack(); - - /** - * Grows all internal data structures to accommodate for all atoms known. - */ - void growForMaxAtomId(); - - /** - * @return the number of atoms assigned since the last decision - */ - int getNumberOfAtomsAssignedSinceLastDecision(); - - /** - * Obtain a BasicAtom that is currently assigned MBT (but not TRUE). - * @return some BasicAtom that is assigned MBT. - */ - int getBasicAtomAssignedMBT(); - - /** - * Assigns all unassigned atoms to FALSE. - * @return true if any atom was assigned. - */ - boolean closeUnassignedAtoms(); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java deleted file mode 100644 index 2581cb11b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016-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.common; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.solver.AtomCounter; - -import java.util.Iterator; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; - -/** - * Translates atoms between integer (solver) and object (grounder) representation. - */ -public interface AtomStore { - - /** - * Returns true whenever the atom is a valid choice point (i.e., it represents a rule body). - * @param atom - * @return - */ - boolean isAtomChoicePoint(int atom); - - /** - * Returns the highest atomId in use. - * @return the highest atomId in use. - */ - int getMaxAtomId(); - - /** - * Translates an atom represented as int into an Atom object. - * @param atom the atom to translate. - * @return the Atom object represented by the int. - */ - CoreAtom get(int atom); - - /** - * Translates an atom represented as Atom object into an int. - * @param atom the Atom object to translate. - * @return the int representing the Atom object. - */ - int get(CoreAtom atom); - - /** - * If the given ground atom is not already stored, associates it with a new integer (ID) and stores it, else - * returns the current associated atom ID. Hence, multiple calls with the same parameter will return the same - * value. - * @param groundAtom the ground atom to look up in the store. - * @return the integer ID of the ground atom, possibly newly assigned. - */ - int putIfAbsent(CoreAtom groundAtom); - - /** - * Returns whether the given ground atom is known to the AtomStore. - * @param groundAtom the ground atom to test. - * @return true if the ground atom is already associated an integer ID. - */ - boolean contains(CoreAtom groundAtom); - - String atomToString(int atom); - - default String literalToString(int literal) { - return (isNegated(literal) ? "-" : "+") + "(" + atomToString(atomOf(literal)) + ")"; - } - - /** - * Prints the NoGood such that literals are structured atoms instead of integers. - * @param noGood the nogood to translate - * @return the string representation of the NoGood. - */ - default String noGoodToString(T noGood) { - StringBuilder sb = new StringBuilder(); - - if (noGood.hasHead()) { - sb.append("*"); - } - sb.append("{"); - - for (Iterator iterator = noGood.iterator(); iterator.hasNext();) { - sb.append(literalToString(iterator.next())); - - if (iterator.hasNext()) { - sb.append(", "); - } - } - - sb.append("}"); - - return sb.toString(); - } - - AtomCounter getAtomCounter(); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java deleted file mode 100644 index 67994c90a..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/AtomStoreImpl.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * 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 - * 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.common; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.solver.AtomCounter; - -/** - * This class stores ground atoms and provides the translation from an (integer) atomId to a (structured) predicate instance. - */ -public class AtomStoreImpl implements AtomStore { - private final List atomIdsToInternalBasicAtoms = new ArrayList<>(); - private final Map predicateInstancesToAtomIds = new HashMap<>(); - private final IntIdGenerator atomIdGenerator = new IntIdGenerator(1); - private final AtomCounter atomCounter = new AtomCounter(); - - private final List releasedAtomIds = new ArrayList<>(); // contains atomIds ready to be garbage collected if necessary. - - public AtomStoreImpl() { - // Create atomId for falsum (currently not needed, but it gets atomId 0, which cannot represent a negated literal). - atomIdsToInternalBasicAtoms.add(null); - } - - @Override - public int putIfAbsent(CoreAtom groundAtom) { - if (!groundAtom.isGround()) { - throw new IllegalArgumentException("Atom must be ground: " + groundAtom); - } - - Integer id = predicateInstancesToAtomIds.get(groundAtom); - - if (id == null) { - id = atomIdGenerator.getNextId(); - predicateInstancesToAtomIds.put(groundAtom, id); - atomIdsToInternalBasicAtoms.add(id, groundAtom); - atomCounter.add(groundAtom); - } - - return id; - } - - @Override - public boolean contains(CoreAtom groundAtom) { - return predicateInstancesToAtomIds.containsKey(groundAtom); - } - - /** - * Removes the given atom from the AtomStoreImpl. - * @param atomId - */ - public void releaseAtomId(int atomId) { - releasedAtomIds.add(atomId); - // HINT: Additionally removing the terms used in the instance might be beneficial in some cases. - } - - public String printAtomIdTermMapping() { - StringBuilder ret = new StringBuilder(); - for (Map.Entry entry : predicateInstancesToAtomIds.entrySet()) { - ret.append(entry.getValue()).append(" <-> ").append(entry.getKey().toString()).append(System.lineSeparator()); - } - return ret.toString(); - } - - @Override - public String atomToString(int atomId) { - return get(atomId).toString(); - } - - @Override - public boolean isAtomChoicePoint(int atom) { - return get(atom) instanceof RuleAtom; - } - - @Override - public int getMaxAtomId() { - return atomIdsToInternalBasicAtoms.size() - 1; - } - - @Override - public CoreAtom get(int atom) { - try { - return atomIdsToInternalBasicAtoms.get(atom); - } catch (IndexOutOfBoundsException e) { - throw oops("Unknown atom ID encountered: " + atom, e); - } - } - - @Override - public int get(CoreAtom atom) { - return predicateInstancesToAtomIds.get(atom); - } - - @Override - public AtomCounter getAtomCounter() { - return atomCounter; - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java deleted file mode 100644 index 1bd486460..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSet.java +++ /dev/null @@ -1,117 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; - -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; - -import static java.util.Collections.emptyMap; -import static java.util.Collections.emptySortedSet; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -// TODO bring this into public non-core API by using something like an "answer-set-view" -public class BasicAnswerSet implements AnswerSet { - public static final BasicAnswerSet EMPTY = new BasicAnswerSet(emptySortedSet(), emptyMap()); - - private final SortedSet predicates; - private final Map> predicateInstances; - - public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { - this.predicates = predicates; - this.predicateInstances = predicateInstances; - } - - @Override - public SortedSet getPredicates() { - return predicates; - } - - @Override - public SortedSet getPredicateInstances(Predicate predicate) { - return predicateInstances.get(predicate); - } - - @Override - public boolean isEmpty() { - return predicates.isEmpty(); - } - - @Override - public String toString() { - if (predicates.isEmpty()) { - return "{}"; - } - - final StringBuilder sb = new StringBuilder("{ "); - for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { - Predicate predicate = iterator.next(); - Set instances = getPredicateInstances(predicate); - - if (instances == null || instances.isEmpty()) { - sb.append(predicate.getName()); - continue; - } - - for (Iterator instanceIterator = instances.iterator(); instanceIterator.hasNext();) { - sb.append(instanceIterator.next()); - if (instanceIterator.hasNext()) { - sb.append(", "); - } - } - - if (iterator.hasNext()) { - sb.append(", "); - } - } - sb.append(" }"); - return sb.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof BasicAnswerSet)) { - return false; - } - - BasicAnswerSet that = (BasicAnswerSet) o; - - if (!predicates.equals(that.predicates)) { - return false; - } - - return predicateInstances.equals(that.predicateInstances); - } - - @Override - public int hashCode() { - return 31 * predicates.hashCode() + predicateInstances.hashCode(); - } - - @Override - public int compareTo(AnswerSet other) { - final SortedSet predicates = this.getPredicates(); - int result = Util.compareSortedSets(predicates, other.getPredicates()); - - if (result != 0) { - return result; - } - - for (Predicate predicate : predicates) { - result = Util.compareSortedSets(this.getPredicateInstances(predicate), other.getPredicateInstances(predicate)); - - if (result != 0) { - return result; - } - } - - return 0; - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java deleted file mode 100644 index b9a61571a..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/ComparisonOperator.java +++ /dev/null @@ -1,39 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -public enum ComparisonOperator { - EQ("="), - NE("!="), - LT("<"), - GT(">"), - LE("<="), - GE(">="); - - private String asString; - - ComparisonOperator(String asString) { - this.asString = asString; - } - - @Override - public String toString() { - return asString; - } - - public ComparisonOperator getNegation() { - switch (this) { - case EQ: return NE; - case NE: return EQ; - case LT: return GE; - case GT: return LE; - case LE: return GT; - case GE: return LT; - } - throw oops("Unknown binary operator encountered, cannot negate it"); - } - - public CorePredicate predicate() { - return CorePredicate.getInstance(this.asString, 2); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java deleted file mode 100644 index 670241c1c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/CorePredicate.java +++ /dev/null @@ -1,107 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -/** - * A predicate as used by the Alpha solver internally. - * - * Copyright (c) 2016-2020, the Alpha Team. - */ -public class CorePredicate implements Comparable { - - private static final Interner INTERNER = new Interner<>(); - - private final String name; - private final int arity; - private final boolean internal; - private final boolean solverInternal; - - protected CorePredicate(String name, int arity, boolean internal, boolean solverInternal) { - this.name = name; - this.arity = arity; - this.internal = internal; - this.solverInternal = solverInternal; - } - - public static CorePredicate getInstance(String symbol, int arity) { - return getInstance(symbol, arity, false, false); - } - - public static CorePredicate getInstance(String symbol, int arity, boolean internal) { - return getInstance(symbol, arity, internal, false); - } - - public static CorePredicate getInstance(String symbol, int arity, boolean internal, boolean solverInternal) { - return INTERNER.intern(new CorePredicate(symbol, arity, internal, solverInternal)); - } - - @Override - public int hashCode() { - int result = name != null ? name.hashCode() : 0; - result = 31 * result + arity; - result = 31 * result + (internal ? 1 : 0); - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof CorePredicate)) { - return false; - } - - CorePredicate predicate = (CorePredicate) o; - - if (arity != predicate.arity) { - return false; - } - - if (internal != predicate.internal) { - return false; - } - - return name != null ? name.equals(predicate.name) : predicate.name == null; - } - - /** - * Marks internal predicates that should not be shown/printed in answer sets. - * @return true iff this Predicate should be omitted from answer sets. - */ - public boolean isInternal() { - return internal; - } - - /** - * Marks predicates that are used purely for encoding rules by NoGoods in the solver component. Solver internal - * predicates are guaranteed to not occur in any rule bodies and hence are ignored by the grounder. - * @return true iff this Predicate is internal to the solver component. - */ - public boolean isSolverInternal() { - return solverInternal; - } - - @Override - public int compareTo(CorePredicate other) { - int result = getName().compareTo(other.getName()); - - if (result != 0) { - return result; - } - - return Integer.compare(getArity(), other.getArity()); - } - - public String getName() { - return name; - } - - public int getArity() { - return arity; - } - - @Override - public String toString() { - return name + "/" + arity; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java deleted file mode 100644 index 0e7c0790e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/IntIterator.java +++ /dev/null @@ -1,20 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -/** - * An iterator returning raw int integers instead of Integer objects (for efficiency). - * - * Copyright (c) 2020, the Alpha Team. - */ -public interface IntIterator { - - /** - * @return true if the iterator has more elements. - */ - boolean hasNext(); - - /** - * @return the next int in the iteration. - */ - int next(); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java deleted file mode 100644 index debfa2423..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Interner.java +++ /dev/null @@ -1,26 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import java.lang.ref.WeakReference; -import java.util.WeakHashMap; - -public class Interner { - private WeakHashMap> pool = new WeakHashMap<>(); - - public synchronized T intern(T object) { - T res; - // (The loop is needed to deal with race - // conditions where the GC runs while we are - // accessing the 'pool' map or the 'ref' object.) - do { - WeakReference ref = pool.get(object); - if (ref == null) { - ref = new WeakReference<>(object); - pool.put(object, ref); - res = object; - } else { - res = ref.get(); - } - } while (res == null); - return res; - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java deleted file mode 100644 index 8c703a54b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * 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 - * 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.common; - -/** - * Provides methods to convert atoms to literals and vice versa, - * and to obtain and change information on the polarity of a literal. - * A literal is represented by an integer whose least significant bit is - * 1 if the literal is negated and 0 otherwise, and whose other bits - * encode the atom. - */ -public final class Literals { - /** - * Given a literal, returns the corresponding atom. - * @param literal the literal to translate. - * @return the corresponding atom. - */ - public static int atomOf(int literal) { - return literal >> 1; - } - - /** - * A utility to check if a given literal is negated. - * @param literal the literal to check. - * @return {@code true} iff the literal is negated, {@code false} otherwise. - */ - public static boolean isNegated(int literal) { - return (literal & 0x1) == 1; - } - - public static boolean isPositive(int literal) { - return (literal & 0x1) == 0; - } - - public static int negateLiteral(int literal) { - return literal ^ 0x1; - } - - public static int atomToLiteral(int atom, boolean truth) { - return truth ? atomToLiteral(atom) : atomToNegatedLiteral(atom); - } - - public static int atomToLiteral(int atom) { - return atom << 1; - } - - public static int atomToNegatedLiteral(int atom) { - return negateLiteral(atomToLiteral(atom)); - } - - public static int positiveLiteral(int literal) { - return literal & ~0x1; - } - - public static String literalToString(int literal) { - return (isPositive(literal) ? "+" : "-") + atomOf(literal); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java deleted file mode 100644 index 84e70cd0e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2016-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.common; - -import at.ac.tuwien.kr.alpha.solver.Antecedent; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.stream.IntStream; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.*; - -public class NoGood implements NoGoodInterface, Comparable { - public static final int HEAD = 0; - public static final NoGood UNSAT = new NoGood(); - - protected final int[] literals; - private final boolean head; - private final Type type; - - public NoGood(int... literals) { - this(STATIC, literals, false); - } - - public NoGood(Type type, int... literals) { - this(type, literals, false); - } - - private NoGood(Type type, int[] literals, boolean head) { - this.type = type; - this.head = head; - if (head && !isNegated(literals[0])) { - throw oops("Head is not negative"); - } - - // HINT: this might decrease performance if NoGoods are mostly small. - Arrays.sort(literals, head ? 1 : 0, literals.length); - - int shift = 0; - for (int i = 1; i < literals.length; i++) { - if (literals[i - 1] == literals[i]) { // check for duplicate - shift++; - } - literals[i - shift] = literals[i]; // Remove duplicates in place by shifting remaining literals. - } - - // copy-shrink array if needed. - this.literals = shift <= 0 ? literals : Arrays.copyOf(literals, literals.length - shift); - } - - protected NoGood(NoGood noGood) { - this.literals = noGood.literals.clone(); - this.head = noGood.head; - this.type = noGood.type; - } - - public static NoGood learnt(int... literals) { - return new NoGood(LEARNT, literals); - } - - public static NoGood headFirst(int... literals) { - return headFirst(STATIC, literals); - } - - public static NoGood headFirstInternal(int... literals) { - return headFirst(INTERNAL, literals); - } - - public static NoGood headFirst(Type type, int... literals) { - return new NoGood(type, literals, true); - } - - public static NoGood fact(int literal) { - return headFirst(literal); - } - - public static NoGood support(int headLiteral, int bodyRepresentingLiteral) { - return new NoGood(SUPPORT, headLiteral, negateLiteral(bodyRepresentingLiteral)); - } - - public static NoGood fromConstraint(List posLiterals, List negLiterals) { - return new NoGood(addPosNeg(new int[posLiterals.size() + negLiterals.size()], posLiterals, negLiterals, 0)); - } - - public static NoGood fromBody(List posLiterals, List negLiterals, int bodyRepresentingLiteral) { - return fromBody(STATIC, posLiterals, negLiterals, bodyRepresentingLiteral); - } - - public static NoGood fromBodyInternal(List posLiterals, List negLiterals, int bodyRepresentingLiteral) { - return fromBody(INTERNAL, posLiterals, negLiterals, bodyRepresentingLiteral); - } - - public static NoGood fromBody(Type type, List posLiterals, List negLiterals, int bodyRepresentingLiteral) { - int[] bodyLiterals = new int[posLiterals.size() + negLiterals.size() + 1]; - bodyLiterals[0] = negateLiteral(bodyRepresentingLiteral); - return NoGood.headFirst(type, addPosNeg(bodyLiterals, posLiterals, negLiterals, 1)); - } - - private static int[] addPosNeg(int[] literals, List posLiterals, List negLiterals, int offset) { - int i = offset; - for (Integer literal : posLiterals) { - literals[i++] = literal; - } - for (Integer literal : negLiterals) { - literals[i++] = negateLiteral(literal); - } - return literals; - } - - @Override - public int size() { - return literals.length; - } - - @Override - public Antecedent asAntecedent() { - return new Antecedent() { - - @Override - public int[] getReasonLiterals() { - return NoGood.this.literals; // Beware: returned array must not be modified! - } - - @Override - public void bumpActivity() { - } - - @Override - public void decreaseActivity() { - } - }; - } - - public NoGood withoutHead() { - return new NoGood(type, literals.clone()); - } - - /** - * A shorthand for Literals.positiveLiteral(getLiteral(...)) - */ - public int getPositiveLiteral(int index) { - return positiveLiteral(getLiteral(index)); - } - - @Override - public int getLiteral(int index) { - return literals[index]; - } - - @Override - public boolean hasHead() { - return head; - } - - @Override - public int getHead() { - return getLiteral(HEAD); - } - - @Override - public Type getType() { - return type; - } - - @Override - public Iterator iterator() { - return new Iterator() { - private int i; - - @Override - public boolean hasNext() { - return literals.length > i; - } - - @Override - public Integer next() { - return literals[i++]; - } - }; - } - - public IntStream stream() { - return Arrays.stream(literals); - } - - @Override - public int compareTo(NoGood o) { - if (o == null) { - throw new NullPointerException("Cannot compare against null."); - } - - if (o.head && !head) { - return -1; - } - - if (!o.head && head) { - return +1; - } - - if (o.literals.length > literals.length) { - return -1; - } - - if (o.literals.length < literals.length) { - return +1; - } - - for (int i = 0; i < literals.length; i++) { - if (o.literals[i] > literals[i]) { - return -1; - } - if (o.literals[i] < literals[i]) { - return +1; - } - } - - return 0; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - NoGood noGood = (NoGood) o; - - return head == noGood.head && Arrays.equals(literals, noGood.literals); - } - - @Override - public int hashCode() { - return 31 * Arrays.hashCode(literals) * (head ? +1 : -1); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - if (head) { - sb.append("*"); - } - - sb.append("{ "); - - for (int literal : literals) { - sb.append(isPositive(literal) ? "+" : "-"); - sb.append(atomOf(literal)); - sb.append(" "); - } - - sb.append("}"); - - return sb.toString(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java deleted file mode 100644 index 95157630e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java +++ /dev/null @@ -1,95 +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.common; - -import at.ac.tuwien.kr.alpha.solver.Antecedent; - -public interface NoGoodInterface extends Iterable { - - /** - * Returns the literal at the given index. - * @param index the index position within the NoGood. - * @return the literal at the index. - */ - int getLiteral(int index); - - /** - * Returns whether the NoGood has a head. - * @return true if the NoGood has a head. - */ - boolean hasHead(); - - /** - * Returns the head literal of the NoGood, if present. - * @return the head literal if the NoGood has a head, otherwise an arbitrary integer. - */ - int getHead(); - - /** - * Returns the size, i.e., number of literals, in the NoGood. - * @return the size of the NoGood. - */ - int size(); - - default boolean isUnary() { - return size() == 1; - } - - default boolean isBinary() { - return size() == 2; - } - - Antecedent asAntecedent(); - - Type getType(); - - /** - * The possible nogood types - */ - enum Type { - /** - * Unremovable nogood from the input program - */ - STATIC, - - /** - * Removable support nogood from the input program - */ - SUPPORT, - - /** - * Removable nogood learnt from a conflict - */ - LEARNT, - - /** - * Nogood containing solver-internal atoms - */ - INTERNAL, - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java deleted file mode 100644 index f705ca4be..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatter.java +++ /dev/null @@ -1,33 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import java.util.ArrayList; -import java.util.List; -import java.util.SortedSet; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; - -public class SimpleAnswerSetFormatter implements AnswerSetFormatter { - - private final String atomSeparator; - - public SimpleAnswerSetFormatter(String atomSeparator) { - this.atomSeparator = atomSeparator; - } - - @Override - public String format(AnswerSet answerSet) { - List predicateInstanceStrings = new ArrayList<>(); - for (CorePredicate p : answerSet.getPredicates()) { - SortedSet instances; - if ((instances = answerSet.getPredicateInstances(p)) == null || instances.isEmpty()) { - predicateInstanceStrings.add(p.getName()); - } else { - List atomStrings = instances.stream().map((atom) -> atom.toString()).collect(Collectors.toList()); - predicateInstanceStrings.add(String.join(this.atomSeparator, atomStrings)); - } - } - return "{ " + String.join(this.atomSeparator, predicateInstanceStrings) + " }"; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java deleted file mode 100644 index 58283a094..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/Truth.java +++ /dev/null @@ -1,10 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -/** - * Represents truth value that can be converted to a Boolean truth value. - * Copyright (c) 2016, the Alpha Team. - */ -@FunctionalInterface -public interface Truth { - boolean toBoolean(); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java deleted file mode 100644 index f37e0acc8..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateAtom.java +++ /dev/null @@ -1,269 +0,0 @@ -/** - * 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. - * - * 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.common.atoms; - -import static at.ac.tuwien.kr.alpha.Util.join; -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -public class AggregateAtom extends CoreAtom { - - private final ComparisonOperator lowerBoundOperator; - private final CoreTerm lowerBoundTerm; - private final ComparisonOperator upperBoundOperator; - private final CoreTerm upperBoundTerm; - private final AGGREGATEFUNCTION aggregatefunction; - private final List aggregateElements; - - public AggregateAtom(ComparisonOperator lowerBoundOperator, CoreTerm lowerBoundTerm, ComparisonOperator upperBoundOperator, CoreTerm upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { - this.lowerBoundOperator = lowerBoundOperator; - this.lowerBoundTerm = lowerBoundTerm; - this.upperBoundOperator = upperBoundOperator; - this.upperBoundTerm = upperBoundTerm; - this.aggregatefunction = aggregatefunction; - this.aggregateElements = aggregateElements; - if (upperBoundOperator != null || lowerBoundOperator != ComparisonOperator.LE || lowerBoundTerm == null) { - throw new UnsupportedOperationException("Aggregate construct not yet supported: " + this); - } - } - - @Override - public boolean isGround() { - for (AggregateElement aggregateElement : aggregateElements) { - if (!aggregateElement.isGround()) { - return false; - } - } - if (lowerBoundTerm != null && !lowerBoundTerm.isGround() - || upperBoundTerm != null && !upperBoundTerm.isGround()) { - return false; - } - return true; - } - - - @Override - public AggregateLiteral toLiteral(boolean positive) { - return new AggregateLiteral(this, positive); - } - - @Override - public List getTerms() { - throw oops("Aggregate atom cannot report terms."); - } - - @Override - public CoreAtom withTerms(List terms) { - throw new UnsupportedOperationException("Editing term list is not supported for aggregate atoms!"); - } - - @Override - public CorePredicate getPredicate() { - throw oops("Aggregate atom cannot report predicate."); - } - - /** - * Returns all variables occurring inside the aggregate, between { ... }. - * @return each variable occurring in some aggregate element. - */ - public List getAggregateVariables() { - List occurringVariables = new LinkedList<>(); - for (AggregateElement aggregateElement : aggregateElements) { - occurringVariables.addAll(aggregateElement.getOccurringVariables()); - } - return occurringVariables; - } - - @Override - public AggregateAtom substitute(Substitution substitution) { - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AggregateAtom that = (AggregateAtom) o; - - if (lowerBoundOperator != that.lowerBoundOperator) { - return false; - } - if (lowerBoundTerm != null ? !lowerBoundTerm.equals(that.lowerBoundTerm) : that.lowerBoundTerm != null) { - return false; - } - if (upperBoundOperator != that.upperBoundOperator) { - return false; - } - if (upperBoundTerm != null ? !upperBoundTerm.equals(that.upperBoundTerm) : that.upperBoundTerm != null) { - return false; - } - if (aggregateElements != null ? !aggregateElements.equals(that.aggregateElements) : that.aggregateElements != null) { - return false; - } - return aggregatefunction == that.aggregatefunction; - } - - @Override - public String toString() { - String lowerBound = lowerBoundTerm == null ? "" : (lowerBoundTerm.toString() + lowerBoundOperator); - String upperBound = upperBoundTerm == null ? "" : (upperBoundOperator.toString() + upperBoundTerm); - return lowerBound + "#" + aggregatefunction + "{ " + join("", aggregateElements, "; ", "") + " }" + upperBound; - } - - @Override - public int hashCode() { - int result = lowerBoundOperator != null ? lowerBoundOperator.hashCode() : 0; - result = 31 * result + (lowerBoundTerm != null ? lowerBoundTerm.hashCode() : 0); - result = 31 * result + (upperBoundOperator != null ? upperBoundOperator.hashCode() : 0); - result = 31 * result + (upperBoundTerm != null ? upperBoundTerm.hashCode() : 0); - result = 31 * result + (aggregateElements != null ? aggregateElements.hashCode() : 0); - result = 31 * result + (aggregatefunction != null ? aggregatefunction.hashCode() : 0); - return result; - } - - public ComparisonOperator getLowerBoundOperator() { - return lowerBoundOperator; - } - - public CoreTerm getLowerBoundTerm() { - return lowerBoundTerm; - } - - public ComparisonOperator getUpperBoundOperator() { - return upperBoundOperator; - } - - public CoreTerm getUpperBoundTerm() { - return upperBoundTerm; - } - - public AGGREGATEFUNCTION getAggregatefunction() { - return aggregatefunction; - } - - public List getAggregateElements() { - return Collections.unmodifiableList(aggregateElements); - } - - public enum AGGREGATEFUNCTION { - COUNT, - MAX, - MIN, - SUM - } - - public static class AggregateElement { - final List elementTerms; - final List elementLiterals; - - public AggregateElement(List elementTerms, List elementLiterals) { - this.elementTerms = elementTerms; - this.elementLiterals = elementLiterals; - } - - public List getElementTerms() { - return elementTerms; - } - - public List getElementLiterals() { - return elementLiterals; - } - - public boolean isGround() { - for (CoreTerm elementTerm : elementTerms) { - if (!elementTerm.isGround()) { - return false; - } - } - for (CoreLiteral elementLiteral : elementLiterals) { - if (!elementLiteral.isGround()) { - return false; - } - } - return true; - } - - public List getOccurringVariables() { - List occurringVariables = new LinkedList<>(); - for (CoreTerm term : elementTerms) { - if (term instanceof VariableTerm) { - occurringVariables.add((VariableTerm) term); - } - } - for (CoreLiteral literal : elementLiterals) { - occurringVariables.addAll(literal.getBindingVariables()); - occurringVariables.addAll(literal.getNonBindingVariables()); - } - return occurringVariables; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AggregateElement that = (AggregateElement) o; - - if (elementTerms != null ? !elementTerms.equals(that.elementTerms) : that.elementTerms != null) { - return false; - } - return elementLiterals != null ? elementLiterals.equals(that.elementLiterals) : that.elementLiterals == null; - } - - @Override - public int hashCode() { - int result = elementTerms != null ? elementTerms.hashCode() : 0; - result = 31 * result + (elementLiterals != null ? elementLiterals.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return join("", elementTerms, " : ") + join("", elementLiterals, ""); - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java deleted file mode 100644 index a2d6123cc..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/AggregateLiteral.java +++ /dev/null @@ -1,64 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.atoms; - -import java.util.HashSet; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Copyright (c) 2018, the Alpha Team. - */ -public class AggregateLiteral extends CoreLiteral { - public AggregateLiteral(AggregateAtom atom, boolean positive) { - super(atom, positive); - } - - @Override - public AggregateAtom getAtom() { - return (AggregateAtom)atom; - } - - @Override - public AggregateLiteral negate() { - return new AggregateLiteral(getAtom(), !positive); - } - - /** - * @see CoreAtom#substitute(Substitution) - */ - @Override - public AggregateLiteral substitute(Substitution substitution) { - return new AggregateLiteral(getAtom().substitute(substitution), positive); - } - - @Override - public Set getBindingVariables() { - Set bindingVariables = new HashSet<>(); - if (boundBindingVariable(getAtom().getLowerBoundOperator(), getAtom().getLowerBoundTerm(), positive) != null) { - bindingVariables.add((VariableTerm) getAtom().getLowerBoundTerm()); - } - if (boundBindingVariable(getAtom().getUpperBoundOperator(), getAtom().getUpperBoundTerm(), positive) != null) { - bindingVariables.add((VariableTerm) getAtom().getUpperBoundTerm()); - } - return bindingVariables; - } - - @Override - public Set getNonBindingVariables() { - // Note: every local variable that also occurs globally in the rule is a nonBindingVariable, hence an - // aggregate literal alone cannot detect its non-binding (i.e. global) variables. - throw new UnsupportedOperationException(); - } - - private static VariableTerm boundBindingVariable(ComparisonOperator op, CoreTerm bound, boolean positive) { - boolean isNormalizedEquality = op == ComparisonOperator.EQ && positive || op == ComparisonOperator.NE && !positive; - if (isNormalizedEquality && bound instanceof VariableTerm) { - return (VariableTerm) bound; - } - return null; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java deleted file mode 100644 index 746abc051..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicAtom.java +++ /dev/null @@ -1,166 +0,0 @@ -/** - * Copyright (c) 2016-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.common.atoms; - -import static at.ac.tuwien.kr.alpha.Util.join; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Represents ordinary ASP atoms. - */ -public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { - private final CorePredicate predicate; - private final List terms; - private final boolean ground; - - /** - * Creates a positive BasicAtom over predicate and terms. - * - * @param predicate - * @param terms - */ - public BasicAtom(CorePredicate predicate, List terms) { - this.predicate = predicate; - this.terms = terms; - - boolean ground = true; - for (CoreTerm term : terms) { - if (!term.isGround()) { - ground = false; - break; - } - } - - this.ground = ground; - } - - public BasicAtom(CorePredicate predicate, CoreTerm... terms) { - this(predicate, Arrays.asList(terms)); - } - - public BasicAtom(CorePredicate predicate) { - this(predicate, Collections.emptyList()); - } - - @Override - public CorePredicate getPredicate() { - return predicate; - } - - @Override - public List getTerms() { - return terms; - } - - @Override - public boolean isGround() { - return ground; - } - - @Override - public BasicAtom substitute(Substitution substitution) { - return new BasicAtom(predicate, terms.stream() - .map(t -> t.substitute(substitution)) - .collect(Collectors.toList())); - } - - @Override - public BasicAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); - return new BasicAtom(predicate, renamedTerms); - } - - @Override - public CoreLiteral toLiteral(boolean positive) { - return new BasicLiteral(this, positive); - } - - @Override - public String toString() { - final String prefix = predicate.getName(); - if (terms.isEmpty()) { - return prefix; - } - - return join(prefix + "(", terms, ")"); - } - - @Override - public int compareTo(CoreAtom o) { - if (this.terms.size() != o.getTerms().size()) { - return this.terms.size() - o.getTerms().size(); - } - - int result = this.predicate.compareTo(o.getPredicate()); - - if (result != 0) { - return result; - } - - for (int i = 0; i < terms.size(); i++) { - result = terms.get(i).compareTo(o.getTerms().get(i)); - if (result != 0) { - return result; - } - } - - return 0; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - BasicAtom that = (BasicAtom) o; - - return predicate.equals(that.predicate) && terms.equals(that.terms); - } - - @Override - public int hashCode() { - return 31 * predicate.hashCode() + terms.hashCode(); - } - - @Override - public CoreAtom withTerms(List terms) { - return new BasicAtom(predicate, terms); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java deleted file mode 100644 index 173e9befc..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/BasicLiteral.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.atoms; - -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * Contains a potentially negated {@link BasicAtom}. - * - * Copyright (c) 2017-2018, the Alpha Team. - */ -public class BasicLiteral extends CoreLiteral { - - public BasicLiteral(BasicAtom atom, boolean positive) { - super(atom, positive); - } - - @Override - public BasicAtom getAtom() { - return (BasicAtom) atom; - } - - /** - * Returns a new copy of this literal whose {@link Literal#isNegated()} status is inverted - */ - @Override - public BasicLiteral negate() { - return new BasicLiteral(getAtom(), !positive); - } - - /** - * @see CoreAtom#substitute(Substitution) - */ - @Override - public BasicLiteral substitute(Substitution substitution) { - return new BasicLiteral(getAtom().substitute(substitution), positive); - } - - /** - * Set of all variables occurring in the Atom that are potentially binding, i.e., variables in positive atoms. - * - * @return - */ - @Override - public Set getBindingVariables() { - if (!positive) { - // Negative literal has no binding variables. - return Collections.emptySet(); - } - Set bindingVariables = new HashSet<>(); - for (CoreTerm term : atom.getTerms()) { - bindingVariables.addAll(term.getOccurringVariables()); - } - return bindingVariables; - } - - /** - * Set of all variables occurring in the Atom that are never binding, not even in positive atoms, e.g., variables in intervals or built-in atoms. - * - * @return - */ - @Override - public Set getNonBindingVariables() { - if (positive) { - // Positive literal has only binding variables. - return Collections.emptySet(); - } - Set nonbindingVariables = new HashSet<>(); - for (CoreTerm term : atom.getTerms()) { - nonbindingVariables.addAll(term.getOccurringVariables()); - } - return nonbindingVariables; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java deleted file mode 100644 index c94b8e231..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonAtom.java +++ /dev/null @@ -1,128 +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.common.atoms; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Represents a builtin comparison atom according to the standard. - */ -public class ComparisonAtom extends CoreAtom implements VariableNormalizableAtom { - private final CorePredicate predicate; - final ComparisonOperator operator; - private final List terms; - - private ComparisonAtom(List terms, ComparisonOperator operator) { - this.terms = terms; - this.operator = operator; - this.predicate = operator.predicate(); - } - - public ComparisonAtom(CoreTerm term1, CoreTerm term2, ComparisonOperator operator) { - this(Arrays.asList(term1, term2), operator); - } - - @Override - public CorePredicate getPredicate() { - return predicate; - } - - @Override - public List getTerms() { - return terms; - } - - @Override - public boolean isGround() { - return terms.get(0).isGround() && terms.get(1).isGround(); - } - - @Override - public ComparisonAtom substitute(Substitution substitution) { - List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); - return new ComparisonAtom(substitutedTerms, operator); - } - - @Override - public ComparisonLiteral toLiteral(boolean positive) { - return new ComparisonLiteral(this, positive); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(terms.get(0)); - sb.append(" "); - sb.append(operator); - sb.append(" "); - sb.append(terms.get(1)); - return sb.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ComparisonAtom that = (ComparisonAtom) o; - - if (operator != that.operator) { - return false; - } - return terms.equals(that.terms); - } - - @Override - public int hashCode() { - return 31 * (31 * operator.hashCode() + terms.hashCode()); - } - - @Override - public ComparisonAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); - return new ComparisonAtom(renamedTerms.get(0), renamedTerms.get(1), operator); - } - - @Override - public CoreAtom withTerms(List terms) { - return new ComparisonAtom(terms, operator); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java deleted file mode 100644 index 836cd21be..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ComparisonLiteral.java +++ /dev/null @@ -1,218 +0,0 @@ -/** - * 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. - * - * 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.common.atoms; - -import static at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm.evaluateGroundTerm; - -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Contains a potentially negated {@link ComparisonAtom}. - */ -public class ComparisonLiteral extends FixedInterpretationLiteral { - private final boolean isNormalizedEquality; - - public ComparisonLiteral(ComparisonAtom atom, boolean positive) { - super(atom, positive); - final ComparisonOperator operator = getAtom().operator; - isNormalizedEquality = (positive && operator == ComparisonOperator.EQ) - || (!positive && operator == ComparisonOperator.NE); - } - - @Override - public ComparisonAtom getAtom() { - return (ComparisonAtom)atom; - } - - public boolean isNormalizedEquality() { - return isNormalizedEquality; - } - - /** - * Returns a new copy of this literal whose {@link Literal#isNegated()} status is inverted - */ - @Override - public ComparisonLiteral negate() { - return new ComparisonLiteral(getAtom(), !positive); - } - - /** - * @see CoreAtom#substitute(Substitution) - */ - @Override - public ComparisonLiteral substitute(Substitution substitution) { - return new ComparisonLiteral(getAtom().substitute(substitution), positive); - } - - private boolean assignable(CoreTerm term) { - return isNormalizedEquality && term instanceof VariableTerm; - } - - @Override - public Set getBindingVariables() { - final CoreTerm left = getTerms().get(0); - final CoreTerm right = getTerms().get(1); - if (assignable(left) && assignable(right)) { - // In case this is "X = Y" or "not X != Y" then both sides are binding given that the other is. - // In this case non-binding and binding variables cannot be reported accurately, in fact, the double variable could be compiled away. - throw new RuntimeException("Builtin equality with left and right side being variables encountered. Should not happen."); - } - if (assignable(left)) { - return Collections.singleton((VariableTerm) left); - } - if (assignable(right)) { - return Collections.singleton((VariableTerm) right); - } - return Collections.emptySet(); - } - - @Override - public Set getNonBindingVariables() { - final CoreTerm left = getTerms().get(0); - final CoreTerm right = getTerms().get(1); - HashSet occurringVariables = new HashSet<>(); - List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); - List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); - if (assignable(left)) { - leftOccurringVariables.remove(left); - } - if (assignable(right)) { - rightOccurringVariables.remove(right); - } - occurringVariables.addAll(leftOccurringVariables); - occurringVariables.addAll(rightOccurringVariables); - if (assignable(left) || assignable(right)) { - return occurringVariables; - } - // Neither left- nor right-assigning, hence no variable is binding. - return occurringVariables; - } - - @Override - public List getSatisfyingSubstitutions(Substitution partialSubstitution) { - // Treat case where this is just comparison with all variables bound by partialSubstitution. - final CoreTerm left = getAtom().getTerms().get(0).substitute(partialSubstitution); - final CoreTerm right = getAtom().getTerms().get(1).substitute(partialSubstitution); - final boolean leftAssigning = assignable(left); - final boolean rightAssigning = assignable(right); - if (!leftAssigning && !rightAssigning) { - // No assignment (variables are bound by partialSubstitution), thus evaluate comparison only. - CoreTerm leftEvaluatedSubstitute = evaluateTerm(left); - if (leftEvaluatedSubstitute == null) { - return Collections.emptyList(); - } - CoreTerm rightEvaluatedSubstitute = evaluateTerm(right); - if (rightEvaluatedSubstitute == null) { - return Collections.emptyList(); - } - if (compare(leftEvaluatedSubstitute, rightEvaluatedSubstitute)) { - return Collections.singletonList(partialSubstitution); - } else { - return Collections.emptyList(); - } - } - // Treat case that this is X = t or t = X. - VariableTerm variable = null; - CoreTerm expression = null; - if (leftAssigning) { - variable = (VariableTerm) left; - expression = right; - } - if (rightAssigning) { - variable = (VariableTerm) right; - expression = left; - } - CoreTerm groundTerm = expression.substitute(partialSubstitution); - CoreTerm resultTerm = null; - // Check if the groundTerm is an arithmetic expression and evaluate it if so. - if (groundTerm instanceof ArithmeticTerm) { - Integer result = evaluateGroundTerm(groundTerm); - if (result == null) { - return Collections.emptyList(); - } - resultTerm = CoreConstantTerm.getInstance(result); - } else { - // Ground term is another term (constant, or function term). - resultTerm = groundTerm; - } - Substitution extendedSubstitution = new Substitution(partialSubstitution); - extendedSubstitution.put(variable, resultTerm); - return Collections.singletonList(extendedSubstitution); - } - - public boolean isLeftOrRightAssigning() { - final CoreTerm left = getTerms().get(0); - final CoreTerm right = getTerms().get(1); - return isNormalizedEquality && (assignable(left) && right.isGround() || assignable(right) && left.isGround()); - } - - private CoreTerm evaluateTerm(CoreTerm term) { - // Evaluate arithmetics. - if (term instanceof ArithmeticTerm) { - Integer result = ArithmeticTerm.evaluateGroundTerm(term); - if (result == null) { - return null; - } - return CoreConstantTerm.getInstance(result); - } - return term; - } - - private boolean compare(CoreTerm x, CoreTerm y) { - final int comparisonResult = x.compareTo(y); - ComparisonOperator operator = isNegated() ? getAtom().operator.getNegation() : getAtom().operator; - switch (operator) { - case EQ: - return comparisonResult == 0; - case LT: - return comparisonResult < 0; - case GT: - return comparisonResult > 0; - case LE: - return comparisonResult <= 0; - case GE: - return comparisonResult >= 0; - case NE: - return comparisonResult != 0; - default: - throw new UnsupportedOperationException("Unknown comparison operator requested!"); - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java deleted file mode 100644 index d8fe2ee7e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreAtom.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright (c) 2016-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.common.atoms; - -import java.util.List; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.Unifier; - -/** - * An Atom is the common superclass of all representations of ASP atoms used by Alpha. - */ -public abstract class CoreAtom implements Comparable{ - - /** - * Creates a new Atom that represents this Atom, but has the given term list instead. - * - * @param terms the terms to set. - * @return a new Atom with the given terms set. - */ - public abstract CoreAtom withTerms(List terms); - - /** - * Returns the set of all variables occurring in the Atom. - */ - public Set getOccurringVariables() { - return toLiteral().getOccurringVariables(); - } - - /** - * This method applies a substitution to the atom. Note that, depending on the atom and the substitution, the - * resulting atom may still contain variables. - * - * @param substitution the variable substitution to apply. - * @return the atom resulting from the application of the substitution. - */ - public abstract CoreAtom substitute(Substitution substitution); - - public abstract List getTerms(); - - public abstract CorePredicate getPredicate(); - - /** - * Returns whether this atom is ground, i.e., variable-free. - * - * @return true iff the terms of this atom contain no {@link VariableTerm}. - */ - public abstract boolean isGround(); - - /** - * Creates a non-negated literal containing this atom. - */ - public CoreLiteral toLiteral() { - return toLiteral(true); - } - - public abstract CoreLiteral toLiteral(boolean positive); - - public CoreAtom renameVariables(String newVariablePrefix) { - Unifier renamingSubstitution = new Unifier(); - int counter = 0; - for (VariableTerm variable : getOccurringVariables()) { - renamingSubstitution.put(variable, VariableTerm.getInstance(newVariablePrefix + counter++)); - } - return this.substitute(renamingSubstitution); - } - - @Override - public int compareTo(CoreAtom o) { - if (o == null) { - return 1; - } - - final List aTerms = this.getTerms(); - final List bTerms = o.getTerms(); - - if (aTerms.size() != bTerms.size()) { - return Integer.compare(aTerms.size(), bTerms.size()); - } - - int result = this.getPredicate().compareTo(o.getPredicate()); - - if (result != 0) { - return result; - } - - for (int i = 0; i < aTerms.size(); i++) { - result = aTerms.get(i).compareTo(o.getTerms().get(i)); - if (result != 0) { - return result; - } - } - - return 0; - } - - @Override - public abstract boolean equals(Object o); - - @Override - public abstract int hashCode(); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java deleted file mode 100644 index b87bafc64..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/CoreLiteral.java +++ /dev/null @@ -1,122 +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.common.atoms; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import org.apache.commons.collections4.SetUtils; - -import java.util.List; -import java.util.Set; - -/** - * A potentially negated {@link CoreAtom} - * - * Copyright (c) 2017-2018, the Alpha Team. - */ -public abstract class CoreLiteral { - - protected final CoreAtom atom; - protected final boolean positive; - - public CoreLiteral(CoreAtom atom, boolean positive) { - this.atom = atom; - this.positive = positive; - } - - public CoreAtom getAtom() { - return atom; - } - - public boolean isNegated() { - return !positive; - } - - public abstract CoreLiteral negate(); - - public abstract CoreLiteral substitute(Substitution substitution); - - public abstract Set getBindingVariables(); - - public abstract Set getNonBindingVariables(); - - /** - * Union of {@link #getBindingVariables()} and {@link #getNonBindingVariables()} - */ - public Set getOccurringVariables() { - return SetUtils.union(getBindingVariables(), getNonBindingVariables()); - } - - /** - * @see CoreAtom#getPredicate() - */ - public CorePredicate getPredicate() { - return atom.getPredicate(); - } - - /** - * @see CoreAtom#getTerms() - */ - public List getTerms() { - return atom.getTerms(); - } - - /** - * @see CoreAtom#isGround() - */ - public boolean isGround() { - return atom.isGround(); - } - - @Override - public String toString() { - return (positive ? "" : "not ") + atom.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - CoreLiteral that = (CoreLiteral) o; - - return atom.equals(that.atom) && positive == that.positive; - } - - @Override - public int hashCode() { - return 12 * atom.hashCode() + (positive ? 1 : 0); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java deleted file mode 100644 index 50a62cf63..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java +++ /dev/null @@ -1,180 +0,0 @@ -/** - * 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. - *

      - * 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.common.atoms; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import static at.ac.tuwien.kr.alpha.Util.join; - -public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { - - private final List input; - private final List output; - - protected final CorePredicate predicate; - protected final PredicateInterpretation interpretation; - - public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { - if (predicate == null) { - throw new IllegalArgumentException("predicate must not be null!"); - } - if (interpretation == null) { - throw new IllegalArgumentException("interpretation must not be null!"); - } - if (input == null) { - throw new IllegalArgumentException("input must not be null!"); - } - if (output == null) { - throw new IllegalArgumentException("output must not be null!"); - } - this.predicate = predicate; - this.interpretation = interpretation; - this.input = input; - this.output = output; - } - - public boolean hasOutput() { - return !output.isEmpty(); - } - - @Override - public CorePredicate getPredicate() { - return predicate; - } - - public PredicateInterpretation getInterpretation() { - return interpretation; - } - - public List getInput() { - return Collections.unmodifiableList(input); - } - - public List getOutput() { - return Collections.unmodifiableList(output); - } - - @Override - public List getTerms() { - return input; - } - - @Override - public boolean isGround() { - for (CoreTerm t : input) { - if (!t.isGround()) { - return false; - } - } - for (CoreTerm t : output) { - if (!t.isGround()) { - return false; - } - } - return true; - } - - @Override - public ExternalAtom 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 ExternalAtom(predicate, interpretation, substitutedInput, substitutedOutput); - } - - @Override - public ExternalLiteral toLiteral(boolean positive) { - return new ExternalLiteral(this, positive); - } - - @Override - public String toString() { - String result = "&" + predicate.getName(); - if (!input.isEmpty()) { - result += join("[", input, "]"); - } - if (!output.isEmpty()) { - result += join("(", output, ")"); - } - return result; - } - - @Override - public CoreAtom withTerms(List terms) { - throw new UnsupportedOperationException("Editing term list is not supported for external atoms!"); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + this.input.hashCode(); - result = prime * result + this.output.hashCode(); - result = prime * result + this.predicate.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ExternalAtom)) { - return false; - } - ExternalAtom other = (ExternalAtom) obj; - if (!this.input.equals(other.input)) { - return false; - } - if (!this.output.equals(other.output)) { - return false; - } - if (!this.predicate.equals(other.predicate)) { - return false; - } - return true; - } - - @Override - public ExternalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedInput = CoreTerm.renameTerms(this.input, prefix + "_IN_", counterStartingValue); - List renamedOutput = CoreTerm.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); - return new ExternalAtom(this.predicate, this.interpretation, renamedInput, renamedOutput); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java deleted file mode 100644 index 29dfffed6..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalLiteral.java +++ /dev/null @@ -1,209 +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.common.atoms; - -import at.ac.tuwien.kr.alpha.common.terms.*; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.*; - -/** - * Contains a potentially negated {@link ExternalAtom}. - */ -public class ExternalLiteral extends FixedInterpretationLiteral { - - public ExternalLiteral(ExternalAtom atom, boolean positive) { - super(atom, positive); - } - - @Override - public ExternalAtom getAtom() { - return (ExternalAtom) atom; - } - - /** - * Returns a new copy of this literal whose {@link Literal#isNegated()} status - * is inverted - */ - @Override - public ExternalLiteral negate() { - return new ExternalLiteral(getAtom(), !positive); - } - - /** - * @see CoreAtom#substitute(Substitution) - */ - @Override - public ExternalLiteral substitute(Substitution substitution) { - return new ExternalLiteral(getAtom().substitute(substitution), positive); - } - - @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 (!positive) { - return Collections.emptySet(); - } - - List output = getAtom().getOutput(); - - Set binding = new HashSet<>(output.size()); - - for (CoreTerm 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 (CoreTerm term : input) { - nonbindingVariables.addAll(term.getOccurringVariables()); - } - - // If the external atom is negative, then all variables of input and output are - // non-binding. - if (!positive) { - for (CoreTerm out : output) { - if (out instanceof VariableTerm) { - nonbindingVariables.add((VariableTerm) out); - } - } - } - - return nonbindingVariables; - } - - @Override - public List getSatisfyingSubstitutions(Substitution partialSubstitution) { - List input = getAtom().getInput(); - List substitutes = new ArrayList<>(input.size()); - - // In preparation for evaluating the external atom, set the input values according - // to the partial substitution supplied by the grounder. - for (CoreTerm t : input) { - substitutes.add(t.substitute(partialSubstitution)); - } - Set>> results = getAtom().getInterpretation().evaluate(substitutes); - if (results == null) { - throw new NullPointerException("Predicate " + getPredicate().getName() + " returned null. It must return a Set."); - } - - if (this.isNegated()) { - return this.isNegatedLiteralSatisfied(results) ? Collections.singletonList(partialSubstitution) : Collections.emptyList(); - } else { - return this.buildSubstitutionsForOutputs(partialSubstitution, results); - } - } - - /** - * Checks whether this negated external literal is satisfied. - * - * Note that this method must only be called on negated external literals. - * In that case, the literal itself does not bind any output variables, - * i.e. the underlying atom is satisfied iff the output terms obtained by - * evaluating the underlying external atom match the values to which - * the respective output variables are bound. The result of this method assumes - * that the literal is negated, i.e. for the underlying atom AT, it represents - * the truth value !AT. - * Furthermore, this method assumes that the output terms of the underlying atom - * are {@link ConstantTerm}s, i.e. that the grounder's current partial - * substitution has already been applied to them. That assumption is safe since - * in case of a negated external literal, the output variables are always - * non-binding. - * - * @param externalMethodResult The term lists obtained from evaluating the external atom - * (i.e. calling the java method) encapsulated by this literal - * @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) { - List externalAtomOutTerms = this.getAtom().getOutput(); - boolean outputMatches; - for (List> resultTerms : externalMethodResult) { - outputMatches = true; - for (int i = 0; i < externalAtomOutTerms.size(); i++) { - if (!resultTerms.get(i).equals(externalAtomOutTerms.get(i))) { - outputMatches = false; - break; - } - } - if (outputMatches) { - // We found one term list where all terms match the ground output terms of the - // external atom, therefore the atom is true and the (negative) literal false. - return false; - } - } - // We checked all term list and none matches the ground output terms, therefore - // the external atom is false, making the literal true. - return true; - } - - private List buildSubstitutionsForOutputs(Substitution partialSubstitution, Set>> outputs) { - List retVal = new ArrayList<>(); - List externalAtomOutputTerms = this.getAtom().getOutput(); - for (List> bindings : outputs) { - if (bindings.size() < externalAtomOutputTerms.size()) { - throw new RuntimeException( - "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() - + " were expected."); - } - Substitution ith = new Substitution(partialSubstitution); - boolean skip = false; - for (int i = 0; i < externalAtomOutputTerms.size(); i++) { - CoreTerm out = externalAtomOutputTerms.get(i); - - if (out instanceof VariableTerm) { - ith.put((VariableTerm) out, bindings.get(i)); - } else { - if (!bindings.get(i).equals(out)) { - skip = true; - break; - } - } - } - if (!skip) { - retVal.add(ith); - } - } - return retVal; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java deleted file mode 100644 index fc318944e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/FixedInterpretationLiteral.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.atoms; - -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.List; - -/** - * Represents a literal whose ground truth value(s) are independent of the - * current assignment. - * Examples of atoms underlying such literals are builtin atoms and external - * atoms. - * Copyright (c) 2017-2018, the Alpha Team. - */ -public abstract class FixedInterpretationLiteral extends CoreLiteral { - - public FixedInterpretationLiteral(CoreAtom atom, boolean positive) { - super(atom, positive); - } - - /** - * Creates a list of {@link Substitution}s based on the given partial - * substitution, such that - * this {@link FixedInterpretationLiteral} is true in every returned - * substitution. - * In cases where this is not possible (because of conflicting variable - * assignments in the partial substitution), getSatisfyingSubstitutions is - * required to return an empty list - * - * @param partialSubstitution a partial substitution that is required to bind - * all variables that are non-binding in this literal - * @return a list of substitutions, in each of which this literal is true, or an - * empty list if no such substitution exists - */ - public abstract List getSatisfyingSubstitutions(Substitution partialSubstitution); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java deleted file mode 100644 index 7c63cf0b9..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/atoms/VariableNormalizableAtom.java +++ /dev/null @@ -1,20 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.atoms; - -/** - * Interface for atom whose variables can be normalized, i.e., enumerated from - * left to right. - * Copyright (c) 2018 the Alpha Team. - */ -public interface VariableNormalizableAtom { - - /** - * Returns an Atom whose variables are enumerated as Vi, .. Vn. - * - * @param prefix the variable prefix V in front of the counter. - * @param counterStartingValue the initial value i of the counter. - * @return the Atom where all variables are renamed and enumerated - * left-to-right. - */ - CoreAtom normalizeVariables(String prefix, int counterStartingValue); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java deleted file mode 100644 index 34096e4f6..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/ComponentGraph.java +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Copyright (c) 2019, the Alpha Team. - * 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.common.depgraph; - -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import org.apache.commons.lang3.StringUtils; - -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; - -/** - * Representation of an {@link InternalProgram}'s component graph, i.e. the directed acyclic graph resulting from condensing the program's - * {@link DependencyGraph} into its strongly connected components. Needed in order to calculate stratifications from which an evaluation order for the - * {@link at.ac.tuwien.kr.alpha.grounder.transformation.StratifiedEvaluation} transformation can be derived. - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public final class ComponentGraph { - - private final ArrayList components; - private final List entryPoints; - - private ComponentGraph(ArrayList components, List entryPoints) { - this.components = components; - this.entryPoints = entryPoints; - } - - /** - * Creates a new {@link ComponentGraph} based on a dependency graph and an {@link StronglyConnectedComponentsAlgorithm.SccResult} representing the - * result of calculating the dependency graph's strongly connected components (SCCs). - * - * @param dg the dependency graph backing this component graph. - * @param sccResult the SCC calculation result for the dependency graph in question. - * @return a new {@link ComponentGraph} representing the strongly connected components of the given dependency graph. - */ - public static ComponentGraph buildComponentGraph(DependencyGraph dg, StronglyConnectedComponentsAlgorithm.SccResult sccResult) { - return new ComponentGraph.Builder(dg, sccResult).build(); - } - - public List getComponents() { - return Collections.unmodifiableList(components); - } - - public List getEntryPoints() { - return Collections.unmodifiableList(entryPoints); - } - - public static class SCComponent { - - private final int id; - private final List nodes; - private final Map dependencyIds; - private final Set dependentIds; - private final boolean hasNegativeCycle; - - private SCComponent(int id, List nodes, Map dependencyIds, Set dependentIds, boolean hasNegativeCycle) { - this.id = id; - this.nodes = nodes; - this.dependencyIds = dependencyIds; - this.dependentIds = dependentIds; - this.hasNegativeCycle = hasNegativeCycle; - } - - public Map getDependencyIds() { - return Collections.unmodifiableMap(dependencyIds); - } - - public Set getDependentIds() { - return Collections.unmodifiableSet(dependentIds); - } - - @Override - public String toString() { - return "SCComponent{" + StringUtils.join(nodes, ",") + "}"; - } - - public boolean hasNegativeCycle() { - return hasNegativeCycle; - } - - public List getNodes() { - return nodes; - } - - public int getId() { - return id; - } - - private static class Builder { - - private int id; - private List nodes; - private Map dependencyIds = new HashMap<>(); - private Set dependentIds = new HashSet<>(); - private boolean hasNegativeCycle; - - private Builder(int id, List nodes) { - this.nodes = nodes; - this.id = id; - } - - private SCComponent build() { - return new SCComponent(id, nodes, dependencyIds, dependentIds, hasNegativeCycle); - } - - } - - } - - private static class Builder { - - private DependencyGraph depGraph; - private List> componentMap; - private Map nodesByComponentId; - private ArrayList componentBuilders = new ArrayList<>(); - private ArrayList components = new ArrayList<>(); - - private Builder(DependencyGraph dg, StronglyConnectedComponentsAlgorithm.SccResult sccResult) { - this.depGraph = dg; - this.componentMap = sccResult.stronglyConnectedComponents; - this.nodesByComponentId = sccResult.nodesByComponentId; - } - - private ComponentGraph build() { - // Create a ComponentBuilder for each component. - for (int i = 0; i < componentMap.size(); i++) { - componentBuilders.add(new SCComponent.Builder(i, componentMap.get(i))); - } - // Iterate and register each edge of every component. - for (int i = 0; i < componentBuilders.size(); i++) { - SCComponent.Builder builder = componentBuilders.get(i); - for (Node node : builder.nodes) { - for (Edge edge : depGraph.getAdjancencyMap().get(node)) { - registerEdge(i, edge); - } - } - } - // Build each component and identify starting components. - List startingPoints = new ArrayList<>(); - for (SCComponent.Builder builder : componentBuilders) { - SCComponent tmpComponent = builder.build(); - components.add(tmpComponent); - // Component is starting if it has no dependencies. - if (tmpComponent.getDependencyIds().isEmpty()) { - startingPoints.add(tmpComponent); - } - } - return new ComponentGraph(components, startingPoints); - } - - private void registerEdge(int srcComponentId, Edge edge) { - int destComponentId = nodesByComponentId.get(edge.getTarget()); - if (srcComponentId == destComponentId) { - // Record negative self-loop. - if (!edge.getSign()) { - componentBuilders.get(srcComponentId).hasNegativeCycle = true; - } - } else { - SCComponent.Builder srcComponentBld = componentBuilders.get(srcComponentId); - srcComponentBld.dependentIds.add(destComponentId); - SCComponent.Builder destComponentBld = componentBuilders.get(destComponentId); - boolean isPositiveDep = true; - if (destComponentBld.dependencyIds.containsKey(srcComponentId)) { - isPositiveDep = destComponentBld.dependencyIds.get(srcComponentId); - } - // If the dependency to srcComponent already is negative, it stays that way, otherwise it is determined by the edge's sign. - destComponentBld.dependencyIds.put(srcComponentId, isPositiveDep & edge.getSign()); - } - } - - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java deleted file mode 100644 index 395daeb4a..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraph.java +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Copyright (c) 2019, the Alpha Team. - * 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.common.depgraph; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Internal representation of an {@link at.ac.tuwien.kr.alpha.common.program.InternalProgram}'s dependency graph. The dependency graph tracks dependencies - * between rules of a program. Each {@link Node} of the graph represents a {@link CorePredicate} occurring in the program. A node has an incoming {@link Edge} for - * every {@link Literal} in some rule body that depends on it, i.e. the predicate of the literal in question is the same as that of the node. The "sign" flag of - * an {@link Edge} indicates whether the dependency is a positive or negative one, i.e. if the atom in question is preceded by a "not". - * - * Note that constraints are represented by one dummy predicate (named "constr_{num}"). Each constraint node has a negative edge to itself to express the - * notation of a constraint ":- a, b." as "x :- a, b, not x.". - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public final class DependencyGraph { - - private static final Logger LOGGER = LoggerFactory.getLogger(DependencyGraph.class); - - /* - * Maps nodes to outgoing edges of that node. - * Note: using List rather than Map as one node may have positive and negative edges to - * another. - */ - private final Map> adjacencyMap; - - private final Map nodesByPredicate; - - private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { - this.adjacencyMap = adjacencyMap; - this.nodesByPredicate = nodesByPredicate; - } - - public static DependencyGraph buildDependencyGraph(Map nonGroundRules) { - return new DependencyGraph.Builder(nonGroundRules.values()).build(); - } - - public Node getNodeForPredicate(CorePredicate p) { - return nodesByPredicate.get(p); - } - - public Map> getAdjancencyMap() { - return Collections.unmodifiableMap(adjacencyMap); - } - - private static class Builder { - - private static final String CONSTRAINT_PREDICATE_FORMAT = "[constr_%d]"; - - private int constraintNumber; - private Collection rules; - - private Map> adjacentNodesMap = new HashMap<>(); - private Map nodesByPredicate = new HashMap<>(); - - private Builder(Collection rules) { - this.rules = rules; - this.constraintNumber = 0; - } - - private DependencyGraph build() { - for (InternalRule rule : rules) { - LOGGER.debug("Processing rule: {}", rule); - Node headNode = handleRuleHead(rule); - for (CoreLiteral literal : rule.getBody()) { - LOGGER.trace("Processing rule body literal: {}", literal); - if (literal instanceof FixedInterpretationLiteral) { - LOGGER.trace("Ignoring FixedInterpretationLiteral {}", literal); - continue; - } - handleRuleBodyLiteral(headNode, literal); - } - } - return new DependencyGraph(adjacentNodesMap, nodesByPredicate); - } - - private Node handleRuleHead(InternalRule rule) { - LOGGER.trace("Processing head of rule: {}", rule); - Node headNode; - if (rule.isConstraint()) { - CorePredicate pred = generateConstraintDummyPredicate(); - headNode = new Node(pred); - List dependencies = new ArrayList<>(); - dependencies.add(new Edge(headNode, false)); - if (adjacentNodesMap.containsKey(headNode)) { - throw new IllegalStateException("Dependency graph already contains node for constraint " + pred.toString() + "!"); - } - adjacentNodesMap.put(headNode, dependencies); - nodesByPredicate.put(pred, headNode); - } else { - CoreAtom head = rule.getHeadAtom(); - CorePredicate pred = head.getPredicate(); - if (!nodesByPredicate.containsKey(pred)) { - headNode = new Node(pred); - adjacentNodesMap.put(headNode, new ArrayList<>()); - nodesByPredicate.put(pred, headNode); - } else { - headNode = nodesByPredicate.get(pred); - } - } - return headNode; - } - - private void handleRuleBodyLiteral(Node headNode, CoreLiteral lit) { - List dependants; - Node bodyNode; - CorePredicate bodyPred = lit.getPredicate(); - if (!nodesByPredicate.containsKey(bodyPred)) { - LOGGER.trace("Creating new node for bodyPred {}", bodyPred); - dependants = new ArrayList<>(); - bodyNode = new Node(bodyPred); - nodesByPredicate.put(bodyPred, bodyNode); - adjacentNodesMap.put(bodyNode, dependants); - } else { - LOGGER.trace("Node for bodyPred {} already exists", bodyPred); - bodyNode = nodesByPredicate.get(bodyPred); - dependants = adjacentNodesMap.get(bodyNode); - } - Edge tmpEdge = new Edge(headNode, !lit.isNegated()); - if (!dependants.contains(tmpEdge)) { - LOGGER.trace("Adding dependency: {} -> {} ({})", bodyNode.getPredicate(), headNode.getPredicate(), tmpEdge.getSign() ? "+" : "-"); - dependants.add(tmpEdge); - } - nodesByPredicate.put(bodyPred, bodyNode); - } - - private CorePredicate generateConstraintDummyPredicate() { - return CorePredicate.getInstance(String.format(DependencyGraph.Builder.CONSTRAINT_PREDICATE_FORMAT, ++constraintNumber), 0); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java deleted file mode 100644 index 02b0347e1..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/DepthFirstSearchAlgorithm.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 2019, the Alpha Team. - * 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.common.depgraph; - -import java.util.ArrayList; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Performs a depth-first search on a given graph. - * The algorithm follows the approach outlined in "Introduction to Algorithms, 3rd Edition" by Cormen et al. - */ -class DepthFirstSearchAlgorithm { - - private Set discoveredNodes; // The "gray" nodes that have been seen but not fully processed yet. - private Deque finishedNodes; // The "black" nodes that have been processed. - private Map> depthFirstReachable; // Per root node, all others that are reachable from it. - - private DepthFirstSearchAlgorithm() { - discoveredNodes = new HashSet<>(); - finishedNodes = new LinkedList<>(); - depthFirstReachable = new HashMap<>(); - depthFirstReachable.put(null, new ArrayList<>()); - } - - public static DfsResult performDfs(Map> graph) { - return performDfs(graph.keySet().iterator(), graph); - } - - /** - * Performs a depth-first search on the given graph. The algorithm follows the approach outlined in - * "Introduction to Algortihms, 3rd Edition" by Cormen et al. - * Discovered nodes are "gray" and finished nodes "black", respectively, in the terminology used in the book. - * - * @param nodeVisitIt an Iterator over all nodes of the graph, defining in which sequence nodes should be - * visited (i.e., nodeVisitIt yields all initially "white" nodes of the graph). - * @param graph an adjacency map defining the dependency graph of an ASP program. - * @return a {@link DfsResult} holding all nodes in the sequence they were finished and per root node all its - * depth-first reachable nodes. - */ - public static DfsResult performDfs(Iterator nodeVisitIt, Map> graph) { - DepthFirstSearchAlgorithm algorithm = new DepthFirstSearchAlgorithm(); - return algorithm.performDepthFirstSearchAlgorithm(nodeVisitIt, graph); - } - - private DfsResult performDepthFirstSearchAlgorithm(Iterator nodeVisitIt, Map> graph) { - while (nodeVisitIt.hasNext()) { - Node currentNode = nodeVisitIt.next(); - if (!discoveredNodes.contains(currentNode)) { - depthFirstReachable.get(null).add(currentNode); - dfsVisit(currentNode, currentNode, graph); - } - } - DfsResult dfsResult = new DfsResult(); - dfsResult.finishedNodes = finishedNodes; - dfsResult.depthFirstReachable = depthFirstReachable; - return dfsResult; - } - - private void dfsVisit(Node currNode, Node rootNode, Map> graph) { - discoveredNodes.add(currNode); - - // Record root-reachability of current node. - if (!depthFirstReachable.containsKey(rootNode)) { - depthFirstReachable.put(rootNode, new ArrayList<>()); - } - depthFirstReachable.get(rootNode).add(currNode); - - for (Edge edge : graph.get(currNode)) { - // Proceed with adjacent (i.e., deeper) nodes first. - Node tmpNeighbor = edge.getTarget(); - if (!discoveredNodes.contains(tmpNeighbor)) { - dfsVisit(tmpNeighbor, rootNode, graph); - } - } - finishedNodes.add(currNode); - } - - /** - * The result of a depth first search: - * - a deque containing all nodes in their finishing order and - * - per root node all reachable other nodes (including the root itself). - */ - static class DfsResult { - Deque finishedNodes; - Map> depthFirstReachable; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java deleted file mode 100644 index f286020b7..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Edge.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright (c) 2019, the Alpha Team. - * 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.common.depgraph; - -/** - * An edge in a dependency graph to be used in adjacency lists (i.e., only the target of the edge is recorded). Edges - * are labelled with a boolean sign indicating the polarity of the edge. - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public class Edge { - - private final Node target; - private final boolean sign; - - /** - * Creates a new edge for a dependency graph. Read as "target depends on source". The sign indicates whether the - * dependency is positive or negative (target node depends on default negated atom). - * Note: working assumption is that strong negation is treated like a positive dependency. - * - * @param target the target node. - * @param sign the polarity of the edge. - */ - public Edge(Node target, boolean sign) { - this.target = target; - this.sign = sign; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Edge)) { - return false; - } - Edge other = (Edge) o; - return this.target.equals(other.target) && this.sign == other.sign; - } - - @Override - public int hashCode() { - return ("" + target.getPredicate().toString() + sign).hashCode(); - } - - @Override - public String toString() { - return "(" + (sign ? "+" : "-") + ") ---> " + target.toString(); - } - - public Node getTarget() { - return target; - } - - public boolean getSign() { - return sign; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java deleted file mode 100644 index f7f041aba..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/Node.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2019, the Alpha Team. - * 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.common.depgraph; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; - -/** - * A node in a dependency graph. One node references exactly one predicate. This means that all rule heads deriving the - * same predicate will be condensed into the same graph node. In some cases this results in more "conservative" results - * in stratification analysis, where some rules will not be evaluated up-front, although that would be possible. - * - * Copyright (c) 2017-2020, the Alpha Team. - */ -public class Node { - - private final CorePredicate predicate; - - public Node(CorePredicate predicate) { - this.predicate = predicate; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Node)) { - return false; - } - return predicate.equals(((Node) o).predicate); - } - - @Override - public int hashCode() { - return predicate.hashCode(); - } - - @Override - public String toString() { - return "Node{" + predicate.toString() + "}"; - } - - public String getLabel() { - return predicate.toString(); - } - - public CorePredicate getPredicate() { - return predicate; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java deleted file mode 100644 index cab16a8a9..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithm.java +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (c) 2019, the Alpha Team. - * 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.common.depgraph; - -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -/** - * Algorithm for finding a stratification of a given {@link ComponentGraph}. - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public class StratificationAlgorithm { - - private static final Logger LOGGER = LoggerFactory.getLogger(StratificationAlgorithm.class); - - private ComponentGraph componentGraph; - - private final boolean[] visitedComponents; // Marks visited components. - private final boolean[] isUnstratifiableComponent; // Marks those known to be not stratifiable (may be due to parent not being stratifiable). - private final SCComponent[] componentEvaluationSequence; // Store the topological order of all components. - - private int doneComponents; - private int numComponents; - - private StratificationAlgorithm(ComponentGraph cg) { - componentGraph = cg; - doneComponents = 0; - numComponents = cg.getComponents().size(); - visitedComponents = new boolean[numComponents]; - isUnstratifiableComponent = new boolean[numComponents]; - componentEvaluationSequence = new SCComponent[numComponents]; - } - - /** - * Calculates a stratification covering as much as possible (the maximal stratifiable part) of the given - * component graph. It assigns each strongly-connected component its own stratum and returns a sequence of - * all stratifiable components in topological order, i.e., if component A depends on component B then B occurs - * earlier in the returned sequence. - * - * @param cg the graph of strongly-connected-components (that must be acyclic). - * @return a list of all stratifiable components in the order that they can be evaluated. - */ - public static List calculateStratification(ComponentGraph cg) { - return new StratificationAlgorithm(cg).runStratification(); - } - - - private List runStratification() { - LOGGER.debug("Initial call to stratify with entry points!"); - - // Compute topological order and mark unstratifiable components. - for (SCComponent component : componentGraph.getEntryPoints()) { - topoSort(component, false); - } - - // Extract list of stratifiable components. - List stratifiableComponentsSequence = new ArrayList<>(); - for (SCComponent component : componentEvaluationSequence) { - if (!isUnstratifiableComponent[component.getId()]) { - stratifiableComponentsSequence.add(component); - } - } - - return stratifiableComponentsSequence; - } - - private void topoSort(SCComponent component, boolean hasUnstratifiableParent) { - // We compute a topological ordering using a depth-first search where for any node its position in the - // topological ordering is the reverse of its finishing time (i.e., last-finishing node comes first). - - int componentId = component.getId(); - - // If this component is marked unstratifiable, it was processed already, immediately return. - if (isUnstratifiableComponent[componentId]) { - return; - } - - boolean isUnstratifiable = hasUnstratifiableParent || component.hasNegativeCycle(); - isUnstratifiableComponent[componentId] = isUnstratifiable; - - // Note: the input graph is a component graph, hence it is a DAG and has no cycles, thus we do not have - // to mark nodes as visited before descending to deeper nodes. - - for (Integer dependentComponentId : component.getDependentIds()) { - // Descend if the lower node has not been visited yet or we need to propagate unstratifiable. - if (isUnstratifiable || !visitedComponents[dependentComponentId]) { - topoSort(componentGraph.getComponents().get(dependentComponentId), isUnstratifiable); - } - } - - // Add current component in front of all others (if we are visiting for the first time). - if (!visitedComponents[componentId]) { - visitedComponents[componentId] = true; - doneComponents++; - componentEvaluationSequence[numComponents - doneComponents] = component; - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java deleted file mode 100644 index 0854e7f3d..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/depgraph/StronglyConnectedComponentsAlgorithm.java +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Copyright (c) 2019, the Alpha Team. - * 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.common.depgraph; - -import java.util.ArrayList; -import java.util.Deque; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Algorithm to find strongly connected components of a given {@link DependencyGraph}. - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public class StronglyConnectedComponentsAlgorithm { - - private Map nodesByComponentId = new HashMap<>(); - - /** - * Calculates the strongly connected components of the given {@link DependencyGraph} according to the algorithm - * given in "Introduction to algorithms" by Cormen, Leiserson, Rivest, and Stein - * (aka Kosajaru-algorithm). - * - * @param dg the {@link DependencyGraph} for which to compute the strongly-connected components. - * @return an {@link SccResult} containing a list of all strongly-connected components and a mapping of each - * node to the component it belongs to. - */ - public static SccResult findStronglyConnectedComponents(DependencyGraph dg) { - return new StronglyConnectedComponentsAlgorithm().runStronglyConnectedComponentsAlgorithm(dg); - } - - private SccResult runStronglyConnectedComponentsAlgorithm(DependencyGraph dg) { - // Find al SCCs with Kosajaru's algorithm. - DepthFirstSearchAlgorithm.DfsResult intermediateResult = DepthFirstSearchAlgorithm.performDfs(dg.getAdjancencyMap()); - Map> transposedNodes = transposeGraph(dg.getAdjancencyMap()); - Deque finishedNodes = intermediateResult.finishedNodes; - DepthFirstSearchAlgorithm.DfsResult finalResult = DepthFirstSearchAlgorithm.performDfs(finishedNodes.descendingIterator(), transposedNodes); - // Extract components. - List> componentMap = extractComponents(finalResult); - return new SccResult(componentMap, nodesByComponentId); - } - - private List> extractComponents(DepthFirstSearchAlgorithm.DfsResult dfsResult) { - // Each node reachable from "null" in the DfsResult points to a different strongly-connected component. - List> componentMap = new ArrayList<>(); - for (Node componentRoot : dfsResult.depthFirstReachable.get(null)) { - int componentId = componentMap.size(); - // Note: every node inside a component is reachable from its root, even the root itself. - List nodesInComponent = dfsResult.depthFirstReachable.get(componentRoot); - for (Node node : nodesInComponent) { - nodesByComponentId.put(node, componentId); - } - List componentMembers = new ArrayList<>(nodesInComponent); - componentMap.add(componentMembers); - } - return componentMap; - } - - /** - * Transposes the given dependency graph, i.e. reverses the direction of each edge. - */ - private static Map> transposeGraph(Map> graph) { - Map> transposed = new HashMap<>(); - for (Map.Entry> entry : graph.entrySet()) { - Node srcNode = entry.getKey(); - if (!transposed.containsKey(srcNode)) { - transposed.put(srcNode, new ArrayList<>()); - } - for (Edge e : entry.getValue()) { - Node targetNode = e.getTarget(); - if (!transposed.containsKey(e.getTarget())) { - transposed.put(targetNode, new ArrayList<>()); - } - transposed.get(targetNode).add(new Edge(srcNode, e.getSign())); - } - } - return transposed; - } - - /** - * Represents the result of a search for strongly connected components on a {@link DependencyGraph}. - */ - public static class SccResult { - - final List> stronglyConnectedComponents; // List of strongly-connected-components (each component being a list of nodes). - final Map nodesByComponentId; // Reverse association of stronglyConnectedComponents. - - SccResult(List> components, Map nodesByComponentId) { - this.stronglyConnectedComponents = components; - this.nodesByComponentId = nodesByComponentId; - } - - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java deleted file mode 100644 index aabd4f55b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BinaryPredicateInterpretation.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - -import java.util.List; - -public class BinaryPredicateInterpretation extends NonBindingPredicateInterpretation { - private final java.util.function.BiPredicate predicate; - - public BinaryPredicateInterpretation(java.util.function.BiPredicate predicate) { - super(2); - this.predicate = predicate; - } - - @Override - @SuppressWarnings("unchecked") - public boolean test(List> terms) { - return predicate.test( - (T) terms.get(0).getObject(), - (U) terms.get(1).getObject() - ); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java deleted file mode 100644 index 081de663b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/BindingMethodPredicateInterpretation.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import org.apache.commons.lang3.ClassUtils; -import org.apache.commons.lang3.StringUtils; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -public class BindingMethodPredicateInterpretation implements BindingPredicateInterpretation { - private final Method method; - - public BindingMethodPredicateInterpretation(Method method) { - if (!method.getReturnType().equals(Set.class)) { - throw new IllegalArgumentException("method must return Set"); - } - - this.method = method; - } - - @Override - @SuppressWarnings("unchecked") - public Set>> evaluate(List terms) { - if (terms.size() != method.getParameterCount()) { - throw new IllegalArgumentException( - "Parameter count mismatch when calling " + method.getName() + ". " + - "Expected " + method.getParameterCount() + " parameters but got " + terms.size() + "."); - } - - final Class[] parameterTypes = method.getParameterTypes(); - - final Object[] arguments = new Object[terms.size()]; - - for (int i = 0; i < arguments.length; i++) { - if (!(terms.get(i) instanceof ConstantTerm)) { - throw new IllegalArgumentException( - "Expected only constants as input for " + method.getName() + ", but got " + - "something else at position " + i + "."); - } - - arguments[i] = ((ConstantTerm) terms.get(i)).getObject(); - - final Class expected = parameterTypes[i]; - final Class actual = arguments[i].getClass(); - - if (expected.isAssignableFrom(actual)) { - continue; - } - - if (expected.isPrimitive() && ClassUtils.primitiveToWrapper(expected).isAssignableFrom(actual)) { - continue; - } - - throw new IllegalArgumentException( - "Parameter type mismatch when calling " + method.getName() + - " at position " + i + ". Expected " + expected + " but got " + - actual + "."); - } - - try { - 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/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java deleted file mode 100644 index 908f34a35..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/IntPredicateInterpretation.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - -import java.util.List; - -public class IntPredicateInterpretation extends NonBindingPredicateInterpretation { - private final java.util.function.IntPredicate predicate; - - public IntPredicateInterpretation(java.util.function.IntPredicate predicate) { - this.predicate = predicate; - } - - @Override - protected boolean test(List> terms) { - if (!(terms.get(0).getObject() instanceof Integer)) { - throw new IllegalArgumentException("Integer expected"); - } - return predicate.test((Integer) terms.get(0).getObject()); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java deleted file mode 100644 index e572b78db..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/LongPredicateInterpretation.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - -import java.util.List; - -public class LongPredicateInterpretation extends NonBindingPredicateInterpretation { - private final java.util.function.LongPredicate predicate; - - public LongPredicateInterpretation(java.util.function.LongPredicate predicate) { - this.predicate = predicate; - } - - @Override - protected boolean test(List> terms) { - if (!(terms.get(0).getObject() instanceof Long)) { - throw new IllegalArgumentException("Long expected"); - } - return predicate.test((Long) terms.get(0).getObject()); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java deleted file mode 100644 index 622efdaa4..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/MethodPredicateInterpretation.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import org.apache.commons.lang3.ClassUtils; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; - -public class MethodPredicateInterpretation extends NonBindingPredicateInterpretation { - private final Method method; - - public MethodPredicateInterpretation(Method method) { - super(method.getParameterCount()); - - if (!method.getReturnType().equals(boolean.class)) { - throw new IllegalArgumentException("method must return boolean"); - } - - this.method = method; - } - - @Override - protected boolean test(List> terms) { - final Class[] parameterTypes = method.getParameterTypes(); - final Object[] arguments = new Object[terms.size()]; - - for (int i = 0; i < arguments.length; i++) { - arguments[i] = terms.get(i).getObject(); - - final Class expected = parameterTypes[i]; - final Class actual = arguments[i].getClass(); - - if (expected.isAssignableFrom(actual)) { - continue; - } - - if (expected.isPrimitive() && ClassUtils.primitiveToWrapper(expected).isAssignableFrom(actual)) { - continue; - } - - throw new IllegalArgumentException( - "Parameter type mismatch at position " + i + ". Expected " + expected + " but got " + - actual + "." - ); - } - - try { - return (boolean) method.invoke(null, arguments); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java deleted file mode 100644 index 9ff2080a6..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/NonBindingPredicateInterpretation.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * Template for predicate interpretations that do not generate new bindings but only return - * a truth value. - */ -public abstract class NonBindingPredicateInterpretation implements PredicateInterpretation { - private final int arity; - - public NonBindingPredicateInterpretation(int arity) { - this.arity = arity; - } - - public NonBindingPredicateInterpretation() { - this(1); - } - - @Override - public Set>> evaluate(List terms) { - if (terms.size() != arity) { - throw new IllegalArgumentException("Exactly " + arity + " term(s) required."); - } - - final List> constants = new ArrayList<>(terms.size()); - for (int i = 0; i < terms.size(); i++) { - if (!(terms.get(i) instanceof ConstantTerm)) { - throw new IllegalArgumentException( - "Expected only constants as input, but got " + - "something else at position " + i + "." - ); - } - - constants.add((ConstantTerm) terms.get(i)); - } - - try { - return test(constants) ? TRUE : FALSE; - } catch (ClassCastException e) { - throw new IllegalArgumentException("Argument types do not match.", e); - } - } - - protected abstract boolean test(List> terms); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java deleted file mode 100644 index c59499477..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/PredicateInterpretationImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -import java.util.List; -import java.util.Set; - -public interface PredicateInterpretationImpl extends PredicateInterpretation { - @Override - Set>> evaluate(List terms); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java deleted file mode 100644 index d440837b8..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/SuppliedPredicateInterpretation.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -import java.util.List; -import java.util.Set; -import java.util.function.Supplier; - -public class SuppliedPredicateInterpretation implements BindingPredicateInterpretation { - private final Supplier>>> supplier; - - public SuppliedPredicateInterpretation(Supplier>>> supplier) { - this.supplier = supplier; - } - - @Override - public Set>> evaluate(List terms) { - if (!terms.isEmpty()) { - throw new IllegalArgumentException("Can only be used without any arguments."); - } - return supplier.get(); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java deleted file mode 100644 index fca1f5484..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/UnaryPredicateInterpretation.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.common.fixedinterpretations; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - -import java.util.List; - -public class UnaryPredicateInterpretation extends NonBindingPredicateInterpretation { - private final java.util.function.Predicate predicate; - - public UnaryPredicateInterpretation(java.util.function.Predicate predicate) { - this.predicate = predicate; - } - - @Override - @SuppressWarnings("unchecked") - protected boolean test(List> terms) { - return predicate.test((T) terms.get(0).getObject()); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java deleted file mode 100644 index de315f778..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriter.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Copyright (c) 2019-2020, the Alpha Team. - * 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.common.graphio; - -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; -import at.ac.tuwien.kr.alpha.common.depgraph.Node; - -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.List; -import java.util.Map.Entry; - -public class ComponentGraphWriter { - - private static final String GRAPH_HEADING = "digraph componentGraph"; - - private static final String NODE_FMT = "n%d [label = C%d]%n"; - private static final String EDGE_FMT = "n%d -> n%d [xlabel=\"%s\" labeldistance=0.1]%n"; - - public void writeAsDot(ComponentGraph graph, OutputStream out) { - PrintStream ps = new PrintStream(out); - startGraph(ps); - writeComponentsTable(ps, graph); - ps.println(); - writeGraph(ps, graph); - finishGraph(ps); - ps.close(); - } - - private void startGraph(PrintStream ps) { - ps.println(ComponentGraphWriter.GRAPH_HEADING); - ps.println("{"); - ps.println("splines=false;"); - ps.println("ranksep=4.0;"); - } - - private void writeComponentsTable(PrintStream ps, ComponentGraph cg) { - ps.println("label = <"); - ps.println("\t"); - StringBuilder headerBuilder = new StringBuilder(""); - headerBuilder.append(""); - for (int i = 0; i < cg.getComponents().size(); i++) { - headerBuilder.append(""); - } - headerBuilder.append(""); - ps.println("\t\t" + headerBuilder.toString()); - StringBuilder contentBuilder = new StringBuilder(""); - contentBuilder.append(""); - for (int i = 0; i < cg.getComponents().size(); i++) { - contentBuilder.append(""); - } - contentBuilder.append(""); - ps.println("\t\t" + contentBuilder.toString()); - ps.println("\t
      Component Id").append(i).append("
      Predicates"); - for (Node n : cg.getComponents().get(i).getNodes()) { - contentBuilder.append(n.getLabel()).append("
      "); - } - contentBuilder.append("
      "); - ps.println(">"); - } - - private void writeGraph(PrintStream ps, ComponentGraph cg) { - List components = cg.getComponents(); - // Write the node descriptors for the components. - for (int componentId = 0; componentId < components.size(); componentId++) { - ps.printf(NODE_FMT, componentId, componentId); - for (Entry dependency : components.get(componentId).getDependencyIds().entrySet()) { - ps.printf(EDGE_FMT, dependency.getKey(), componentId, dependency.getValue().equals(true) ? "+" : "-"); - } - } - } - - private void finishGraph(PrintStream ps) { - ps.println("}"); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java deleted file mode 100644 index 7d838f8ca..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriter.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (c) 2019-2020, the Alpha Team. - * 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.common.graphio; - -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.Edge; -import at.ac.tuwien.kr.alpha.common.depgraph.Node; - -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.BiFunction; - -public class DependencyGraphWriter { - - private static final String DEFAULT_GRAPH_HEADING = "digraph dependencyGraph"; - - private static final String DEFAULT_NODE_FORMAT = "n%d [label = \"%s\"]%n"; - private static final String DEFAULT_EDGE_FORMAT = "n%d -> n%d [xlabel=\"%s\" labeldistance=0.1]%n"; - - public void writeAsDot(DependencyGraph graph, OutputStream out) { - writeAsDot(graph.getAdjancencyMap(), out); - } - - private void writeAsDot(Map> graph, OutputStream out) { - BiFunction nodeFormatter = this::buildNodeString; - writeAsDot(graph, out, nodeFormatter); - } - - private void writeAsDot(Map> graph, OutputStream out, BiFunction nodeFormatter) { - PrintStream ps = new PrintStream(out); - startGraph(ps); - - Set>> graphDataEntries = graph.entrySet(); - // First, write all nodes. - int nodeCnt = 0; - Map nodesToNumbers = new HashMap<>(); - for (Map.Entry> entry : graphDataEntries) { - ps.print(nodeFormatter.apply(entry.getKey(), nodeCnt)); - nodesToNumbers.put(entry.getKey(), nodeCnt); - nodeCnt++; - } - - // Second, write all edges. - for (Map.Entry> entry : graphDataEntries) { - int fromNodeNum = nodesToNumbers.get(entry.getKey()); - for (Edge edge : entry.getValue()) { - int toNodeNum = nodesToNumbers.get(edge.getTarget()); - ps.printf(DependencyGraphWriter.DEFAULT_EDGE_FORMAT, fromNodeNum, toNodeNum, edge.getSign() ? "+" : "-"); - } - } - - finishGraph(ps); - ps.close(); - } - - private void startGraph(PrintStream ps) { - ps.println(DependencyGraphWriter.DEFAULT_GRAPH_HEADING); - ps.println("{"); - ps.println("splines=false;"); - ps.println("ranksep=4.0;"); - } - - private void finishGraph(PrintStream ps) { - ps.println("}"); - } - - private String buildNodeString(Node n, int nodeNum) { - return String.format(DependencyGraphWriter.DEFAULT_NODE_FORMAT, nodeNum, n.getLabel()); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java deleted file mode 100644 index 0043b5e7b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AbstractProgram.java +++ /dev/null @@ -1,52 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.program; - -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.AbstractRule; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; - -import java.util.Collections; -import java.util.List; - -/** - * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives) - * - * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an implementation permits - * Copyright (c) 2019, the Alpha Team. - */ -public abstract class AbstractProgram> { - - private final List rules; - private final List facts; - private final InlineDirectives inlineDirectives; - - public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { - this.rules = rules; - this.facts = facts; - this.inlineDirectives = inlineDirectives; - } - - public List getRules() { - return Collections.unmodifiableList(rules); - } - - public List getFacts() { - return Collections.unmodifiableList(facts); - } - - public InlineDirectives getInlineDirectives() { - return inlineDirectives; - } - - @Override - public String toString() { - final String ls = System.lineSeparator(); - final String result = facts.isEmpty() ? "" : Util.join("", facts, "." + ls, "." + ls); - if (rules.isEmpty()) { - return result; - } - return Util.join(result, rules, ls, ls); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java deleted file mode 100644 index 6a7437c36..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/AnalyzedProgram.java +++ /dev/null @@ -1,48 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.program; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.StronglyConnectedComponentsAlgorithm; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import java.util.List; - - -/** - * An {@link InternalProgram} with dependency information. - * - * Copyright (c) 2019-2020, the Alpha Team - */ -public class AnalyzedProgram extends InternalProgram { - - private final DependencyGraph dependencyGraph; - private final ComponentGraph componentGraph; - - public AnalyzedProgram(List rules, List facts) { - super(rules, facts); - dependencyGraph = DependencyGraph.buildDependencyGraph(getRulesById()); - componentGraph = buildComponentGraph(dependencyGraph); - } - - public static AnalyzedProgram analyzeNormalProgram(NormalProgram prog) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); - return new AnalyzedProgram(rulesAndFacts.left, rulesAndFacts.right); - } - - private ComponentGraph buildComponentGraph(DependencyGraph depGraph) { - StronglyConnectedComponentsAlgorithm.SccResult sccResult = StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(depGraph); - return ComponentGraph.buildComponentGraph(depGraph, sccResult); - } - - public ComponentGraph getComponentGraph() { - return componentGraph; - } - - public DependencyGraph getDependencyGraph() { - return dependencyGraph; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java deleted file mode 100644 index 3bb1d8190..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InputProgram.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 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.common.program; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. - *

      - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class InputProgram extends AbstractProgram implements Program { - - public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectives()); - - public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { - super(rules, facts, inlineDirectives); - } - - public InputProgram() { - super(new ArrayList<>(), new ArrayList<>(), new InlineDirectives()); - } - - public static Builder builder() { - return new Builder(); - } - - public static Builder builder(InputProgram prog) { - return new Builder(prog); - } - - /** - * Builder for more complex program construction scenarios, ensuring that an {@link InputProgram} is immutable - */ - public static class Builder { - - private List rules = new ArrayList<>(); - private List facts = new ArrayList<>(); - private InlineDirectives inlineDirectives = new InlineDirectives(); - - public Builder(InputProgram prog) { - this.addRules(prog.getRules()); - this.addFacts(prog.getFacts()); - this.addInlineDirectives(prog.getInlineDirectives()); - } - - public Builder() { - - } - - public Builder addRules(List rules) { - this.rules.addAll(rules); - return this; - } - - public Builder addRule(BasicRule r) { - this.rules.add(r); - return this; - } - - public Builder addFacts(List facts) { - this.facts.addAll(facts); - return this; - } - - public Builder addFact(CoreAtom fact) { - this.facts.add(fact); - return this; - } - - public Builder addInlineDirectives(InlineDirectives inlineDirectives) { - this.inlineDirectives.accumulate(inlineDirectives); - return this; - } - - 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); - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java deleted file mode 100644 index dd8f88f53..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/InternalProgram.java +++ /dev/null @@ -1,89 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.program; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.grounder.FactIntervalEvaluator; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import java.util.*; - -/** - * A program in the internal representation needed for grounder and solver, i.e.: rules must have normal heads, all - * aggregates must be rewritten, all intervals must be preprocessed (into interval atoms), and equality predicates must - * be rewritten. - *

      - * Copyright (c) 2017-2020, the Alpha Team. - */ -public class InternalProgram extends AbstractProgram { - - private final Map> predicateDefiningRules = new LinkedHashMap<>(); - private final Map> factsByPredicate = new LinkedHashMap<>(); - private final Map rulesById = new LinkedHashMap<>(); - - public InternalProgram(List rules, List facts) { - super(rules, facts, null); - recordFacts(facts); - recordRules(rules); - } - - static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { - List internalRules = new ArrayList<>(); - List facts = new ArrayList<>(normalProgram.getFacts()); - for (NormalRule r : normalProgram.getRules()) { - if (r.getBody().isEmpty()) { - if (!r.getHead().isGround()) { - throw new IllegalArgumentException("InternalProgram does not support non-ground rules with empty bodies! (Head = " + r.getHead().toString() + ")"); - } - facts.add(r.getHeadAtom()); - } else { - internalRules.add(InternalRule.fromNormalRule(r)); - } - } - return new ImmutablePair<>(internalRules, facts); - } - - public static InternalProgram fromNormalProgram(NormalProgram normalProgram) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); - return new InternalProgram(rulesAndFacts.left, rulesAndFacts.right); - } - - private void recordFacts(List facts) { - for (CoreAtom fact : facts) { - List tmpInstances = FactIntervalEvaluator.constructFactInstances(fact); - CorePredicate tmpPredicate = fact.getPredicate(); - factsByPredicate.putIfAbsent(tmpPredicate, new LinkedHashSet<>()); - factsByPredicate.get(tmpPredicate).addAll(tmpInstances); - } - } - - private void recordRules(List rules) { - for (InternalRule rule : rules) { - rulesById.put(rule.getRuleId(), rule); - if (!rule.isConstraint()) { - recordDefiningRule(rule.getHeadAtom().getPredicate(), rule); - } - } - } - - private void recordDefiningRule(CorePredicate headPredicate, InternalRule rule) { - predicateDefiningRules.putIfAbsent(headPredicate, new LinkedHashSet<>()); - predicateDefiningRules.get(headPredicate).add(rule); - } - - public Map> getPredicateDefiningRules() { - return Collections.unmodifiableMap(predicateDefiningRules); - } - - public Map> getFactsByPredicate() { - return Collections.unmodifiableMap(factsByPredicate); - } - - public Map getRulesById() { - return Collections.unmodifiableMap(rulesById); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java deleted file mode 100644 index d6d1b18e9..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/NormalProgram.java +++ /dev/null @@ -1,31 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.program; - -import java.util.ArrayList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; - -/** - * A program that only contains NormalRules. - * - * Copyright (c) 2019, the Alpha Team. - */ -public class NormalProgram extends AbstractProgram { - - public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { - super(rules, facts, inlineDirectives); - } - - public static NormalProgram fromInputProgram(InputProgram inputProgram) { - List normalRules = new ArrayList<>(); - for (BasicRule r : inputProgram.getRules()) { - normalRules.add(NormalRule.fromBasicRule(r)); - } - return new NormalProgram(normalRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java deleted file mode 100644 index 1353864ef..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/program/Programs.java +++ /dev/null @@ -1,23 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.program; - -import org.antlr.v4.runtime.CharStreams; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -public class Programs { - - private Programs() { - throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); - } - - public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { - ProgramParser parser = new ProgramParser(externals); - return parser.parse(CharStreams.fromStream(is)); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java deleted file mode 100644 index a4c41973e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/AbstractRule.java +++ /dev/null @@ -1,128 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rule; - -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.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; - -/** - * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) - * - * @param the type of head for this rule - * - * Copyright (c) 2017-2019, the Alpha Team. - */ -public abstract class AbstractRule { - - private final H head; - private final Set bodyLiteralsPositive; - private final Set bodyLiteralsNegative; - - public AbstractRule(H head, List body) { - this.head = head; - Set positiveBody = new LinkedHashSet<>(); - Set negativeBody = new LinkedHashSet<>(); - for (CoreLiteral bodyLiteral : body) { - if (bodyLiteral.isNegated()) { - negativeBody.add(bodyLiteral); - } else { - positiveBody.add(bodyLiteral); - } - } - this.bodyLiteralsPositive = Collections.unmodifiableSet(positiveBody); - this.bodyLiteralsNegative = Collections.unmodifiableSet(negativeBody); - - if (!this.isSafe()) { - // TODO: safety check needs to be adapted to solver what the solver actually understands. Will change in the future, - // adapt exception message accordingly. - throw new RuntimeException("Encountered unsafe rule: " + toString() + System.lineSeparator() - + "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."); - } - } - - /** - * Checks whether a rule is safe. The actual safety condition may vary over the next improvements. Currently, a rule is - * safe iff all negated variables and - * all variables occurring in the head also occur in the positive body). - * - * @return true if this rule is safe. - */ - private boolean isSafe() { - // TODO: do the real check. - // Note that - once a proper safety check is implemented - that check should probably be specific for each rule - // implementation, therefore this method should be "protected abstract" here and implemented in each subclass. - return true; - /* - * Set positiveVariables = new HashSet<>(); Set builtinVariables = new HashSet<>(); - * - * // Check that all negative variables occur in the positive body. for (Literal literal : body) { // FIXME: The - * following five lines depend on concrete - * // implementations of the Atom interface. Not nice. if (literal instanceof BasicAtom) { - * positiveVariables.addAll(literal.getOccurringVariables()); } - * else if (literal instanceof BuiltinAtom) { builtinVariables.addAll(literal.getOccurringVariables()); } } - * - * for (Atom negAtom : bodyAtomsNegative) { for (VariableTerm term : negAtom.getOccurringVariables()) { if - * (!positiveVariables.contains(term)) { return - * false; } } } for (VariableTerm builtinVariable : builtinVariables) { if - * (!positiveVariables.contains(builtinVariable)) { return false; } } - * - * // Constraint are safe at this point if (isConstraint()) { return true; } - * - * // Check that all variables of the head occur in the positive body. List headVariables = - * head.getOccurringVariables(); - * headVariables.removeAll(positiveVariables); return headVariables.isEmpty(); - */ - } - - public boolean isConstraint() { - return head == null; - } - - @Override - public String toString() { - return Util.join((isConstraint() ? "" : head.toString() + " ") + ":- ", getBody(), "."); - } - - public H getHead() { - return head; - } - - public Set getBody() { - return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); - } - - public Set getPositiveBody() { - return this.bodyLiteralsPositive; - } - - public Set getNegativeBody() { - return this.bodyLiteralsNegative; - } - - @Override - public int hashCode() { - return Objects.hash(bodyLiteralsNegative, bodyLiteralsPositive, head); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof AbstractRule)) { - 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); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java deleted file mode 100644 index db05e1164..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/BasicRule.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 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.common.rule; - -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.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 NormalRule}. - */ -public class BasicRule extends AbstractRule { - - public BasicRule(Head head, List body) { - super(head, body); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java deleted file mode 100644 index ace3930f3..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/InternalRule.java +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Copyright (c) 2016-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.common.rule; - -import java.util.ArrayList; -import java.util.List; - -import com.google.common.annotations.VisibleForTesting; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrders; -import at.ac.tuwien.kr.alpha.grounder.Unifier; - -/** - * 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 NormalRule { - - private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); - - private final int ruleId; - - private final List occurringPredicates; - - private final RuleGroundingOrders groundingOrders; - - public InternalRule(NormalHead head, List body) { - super(head, 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.occurringPredicates = new ArrayList<>(); - if (!isConstraint()) { - this.occurringPredicates.add(this.getHeadAtom().getPredicate()); - } - - for (CoreLiteral literal : body) { - if (literal instanceof AggregateLiteral) { - throw new IllegalArgumentException("AggregateLiterals aren't supported in InternalRules! (lit: " + literal.toString() + ")"); - } - 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 RuleGroundingOrders(this); - this.groundingOrders.computeGroundingOrders(); - } - - @VisibleForTesting - public static void resetIdGenerator() { - InternalRule.ID_GENERATOR.resetGenerator(); - } - - public static InternalRule fromNormalRule(NormalRule rule) { - return new InternalRule(rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()), 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 - */ - public InternalRule renameVariables(String newVariablePostfix) { - List occurringVariables = new ArrayList<>(); - CoreAtom headAtom = this.getHeadAtom(); - occurringVariables.addAll(headAtom.getOccurringVariables()); - for (CoreLiteral literal : this.getBody()) { - occurringVariables.addAll(literal.getOccurringVariables()); - } - Unifier variableReplacement = new Unifier(); - for (VariableTerm occurringVariable : occurringVariables) { - final String newVariableName = occurringVariable.toString() + newVariablePostfix; - variableReplacement.put(occurringVariable, VariableTerm.getInstance(newVariableName)); - } - CoreAtom renamedHeadAtom = headAtom.substitute(variableReplacement); - ArrayList renamedBody = new ArrayList<>(this.getBody().size()); - for (CoreLiteral literal : this.getBody()) { - renamedBody.add(literal.substitute(variableReplacement)); - } - return new InternalRule(new NormalHead(renamedHeadAtom), renamedBody); - } - - /** - * Returns the predicates occurring in this rule. - * @return a list of all predicates occurring in the rule (may contain duplicates and builtin atoms). - */ - public List getOccurringPredicates() { - return this.occurringPredicates; - } - - public RuleGroundingOrders getGroundingOrders() { - return this.groundingOrders; - } - - public int getRuleId() { - return this.ruleId; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java deleted file mode 100644 index db9f8ac7e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/NormalRule.java +++ /dev/null @@ -1,50 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rule; - -import java.util.ArrayList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; - -/** - * 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. - * - * Copyright (c) 2019, the Alpha Team. - */ -public class NormalRule extends AbstractRule { - - public NormalRule(NormalHead head, List body) { - super(head, body); - } - - public static NormalRule fromBasicRule(BasicRule rule) { - CoreAtom 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(); - } - return new NormalRule(headAtom != null ? new NormalHead(headAtom) : null, new ArrayList<>(rule.getBody())); - } - - public boolean isGround() { - if (!isConstraint() && !this.getHead().isGround()) { - return false; - } - for (CoreLiteral bodyElement : this.getBody()) { - if (!bodyElement.isGround()) { - return false; - } - } - return true; - } - - public CoreAtom getHeadAtom() { - return this.isConstraint() ? null : this.getHead().getAtom(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java deleted file mode 100644 index 6a43cb24d..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/ChoiceHead.java +++ /dev/null @@ -1,147 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -import java.util.List; - -import static at.ac.tuwien.kr.alpha.Util.join; - -/** - * Represents the head of a choice rule. - * - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class ChoiceHead extends Head { - private final List choiceElements; - - private final Term lowerBound; - private final ComparisonOperator lowerOp; - - private final Term upperBound; - private final ComparisonOperator upperOp; - - public static class ChoiceElement { - public final CoreAtom choiceAtom; - public final List conditionLiterals; - - public ChoiceElement(CoreAtom choiceAtom, List conditionLiterals) { - this.choiceAtom = choiceAtom; - this.conditionLiterals = conditionLiterals; - } - - @Override - public String toString() { - String result = choiceAtom.toString(); - - if (conditionLiterals == null || conditionLiterals.size() == 0) { - return result; - } - - return join(result + " : ", conditionLiterals, ""); - } - } - - public ComparisonOperator getLowerOperator() { - return lowerOp; - } - - public ComparisonOperator getUpperOperator() { - return upperOp; - } - - public List getChoiceElements() { - return choiceElements; - } - - public Term getLowerBound() { - return lowerBound; - } - - public Term getUpperBound() { - return upperBound; - } - - public ChoiceHead(List choiceElements, Term lowerBound, ComparisonOperator lowerOp, Term upperBound, ComparisonOperator upperOp) { - this.choiceElements = choiceElements; - this.lowerBound = lowerBound; - this.lowerOp = lowerOp; - this.upperBound = upperBound; - this.upperOp = upperOp; - } - - @Override - public String toString() { - String result = ""; - - if (lowerBound != null) { - result += lowerBound.toString() + lowerOp; - } - - result += join("{ ", choiceElements, "; ", " }"); - - if (upperBound != null) { - result += upperOp.toString() + upperBound; - } - - return result; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.choiceElements == null) ? 0 : this.choiceElements.hashCode()); - result = prime * result + ((this.lowerBound == null) ? 0 : this.lowerBound.hashCode()); - result = prime * result + ((this.lowerOp == null) ? 0 : this.lowerOp.hashCode()); - result = prime * result + ((this.upperBound == null) ? 0 : this.upperBound.hashCode()); - result = prime * result + ((this.upperOp == null) ? 0 : this.upperOp.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ChoiceHead)) { - return false; - } - ChoiceHead other = (ChoiceHead) obj; - if (this.choiceElements == null) { - if (other.choiceElements != null) { - return false; - } - } else if (!this.choiceElements.equals(other.choiceElements)) { - return false; - } - if (this.lowerBound == null) { - if (other.lowerBound != null) { - return false; - } - } else if (!this.lowerBound.equals(other.lowerBound)) { - return false; - } - if (this.lowerOp != other.lowerOp) { - return false; - } - if (this.upperBound == null) { - if (other.upperBound != null) { - return false; - } - } else if (!this.upperBound.equals(other.upperBound)) { - return false; - } - if (this.upperOp != other.upperOp) { - return false; - } - return true; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java deleted file mode 100644 index 11f0e365d..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/DisjunctiveHead.java +++ /dev/null @@ -1,66 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; - -import java.util.List; - -import static at.ac.tuwien.kr.alpha.Util.join; - -/** - * Copyright (c) 2017, the Alpha Team. - */ -public class DisjunctiveHead extends Head { - public final List disjunctiveAtoms; - - public DisjunctiveHead(List disjunctiveAtoms) { - this.disjunctiveAtoms = disjunctiveAtoms; - if (disjunctiveAtoms != null && disjunctiveAtoms.size() > 1) { - throw new UnsupportedOperationException("Disjunction in rule heads is not yet supported"); - } - } - - @Override - public String toString() { - return join("", disjunctiveAtoms, " | ", ""); - } - - public boolean isGround() { - for (Atom atom : disjunctiveAtoms) { - if (!atom.isGround()) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.disjunctiveAtoms == null) ? 0 : this.disjunctiveAtoms.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof DisjunctiveHead)) { - return false; - } - DisjunctiveHead other = (DisjunctiveHead) obj; - if (this.disjunctiveAtoms == null) { - if (other.disjunctiveAtoms != null) { - return false; - } - } else if (!this.disjunctiveAtoms.equals(other.disjunctiveAtoms)) { - return false; - } - return true; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java deleted file mode 100644 index 535466cb6..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/Head.java +++ /dev/null @@ -1,19 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; - -/** - * Represents the head of a rule, i.e., either a choice or a disjunction of atoms, but not both. For normal rules the disjunction contains only one atom. - * - * Copyright (c) 2017-2019, the Alpha Team. - */ -public abstract class Head { - - @Override - public abstract String toString(); - - @Override - public abstract boolean equals(Object o); - - @Override - public abstract int hashCode(); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java deleted file mode 100644 index 650eadbc2..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/rule/head/NormalHead.java +++ /dev/null @@ -1,61 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.rule.head; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; - -/** - * Represents a normal head, i.e., a head that is an Atom. - * Copyright (c) 2019, the Alpha Team. - */ -public class NormalHead extends Head { - - private final CoreAtom atom; - - public NormalHead(CoreAtom atom) { - this.atom = atom; - } - - // Note that at some point in the future it might make sense to have this method directly in Head - public boolean isGround() { - return atom.isGround(); - } - - public CoreAtom getAtom() { - return atom; - } - - @Override - public String toString() { - return atom.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((atom == null) ? 0 : atom.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof NormalHead)) { - return false; - } - NormalHead other = (NormalHead) obj; - if (this.atom == null) { - if (other.atom != null) { - return false; - } - } else if (!this.atom.equals(other.atom)) { - return false; - } - return true; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java deleted file mode 100644 index 3c6d525c0..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/ArithmeticTerm.java +++ /dev/null @@ -1,268 +0,0 @@ -/** - * 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. - * - * 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.common.terms; - -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import com.google.common.math.IntMath; - -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; - -/** - * This class represents an arithmetic expression occurring as a term. - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class ArithmeticTerm extends CoreTerm { - private static final Interner INTERNER = new Interner<>(); - protected final CoreTerm left; - private final ArithmeticOperator arithmeticOperator; - private final CoreTerm right; - - private ArithmeticTerm(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { - this.left = left; - this.arithmeticOperator = arithmeticOperator; - this.right = right; - } - - public static CoreTerm getInstance(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { - // Evaluate ground arithmetic terms immediately and return result. - if (left.isGround() && right.isGround()) { - Integer result = new ArithmeticTerm(left, arithmeticOperator, right).evaluateExpression(); - return CoreConstantTerm.getInstance(result); - } - return INTERNER.intern(new ArithmeticTerm(left, arithmeticOperator, right)); - } - - - @Override - public boolean isGround() { - return left.isGround() && right.isGround(); - } - - @Override - public List getOccurringVariables() { - LinkedHashSet occurringVariables = new LinkedHashSet<>(left.getOccurringVariables()); - occurringVariables.addAll(right.getOccurringVariables()); - return new ArrayList<>(occurringVariables); - } - - @Override - public CoreTerm substitute(Substitution substitution) { - return getInstance(left.substitute(substitution), arithmeticOperator, right.substitute(substitution)); - } - - @Override - public CoreTerm renameVariables(String renamePrefix) { - return getInstance(left.renameVariables(renamePrefix), arithmeticOperator, right.renameVariables(renamePrefix)); - } - - @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); - CoreTerm normalizedRight = right.normalizeVariables(renamePrefix, counter); - return ArithmeticTerm.getInstance(normalizedLeft, arithmeticOperator, normalizedRight); - - } - - public static Integer evaluateGroundTerm(CoreTerm term) { - if (!term.isGround()) { - throw new RuntimeException("Cannot evaluate arithmetic term since it is not ground: " + term); - } - return evaluateGroundTermHelper(term); - } - - private static Integer evaluateGroundTermHelper(CoreTerm term) { - if (term instanceof CoreConstantTerm - && ((CoreConstantTerm) term).getObject() instanceof Integer) { - // Extract integer from the constant. - return (Integer) ((CoreConstantTerm) term).getObject(); - } else if (term instanceof ArithmeticTerm) { - return ((ArithmeticTerm) term).evaluateExpression(); - } else { - // ASP Core 2 standard allows non-integer terms in arithmetic expressions, result is to simply ignore the ground instance. - return null; - } - } - - Integer evaluateExpression() { - Integer leftInt = evaluateGroundTermHelper(left); - Integer rightInt = evaluateGroundTermHelper(right); - if (leftInt == null || rightInt == null) { - return null; - } - return arithmeticOperator.eval(leftInt, rightInt); - } - - @Override - public String toString() { - return left + " " + arithmeticOperator + " " + right; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ArithmeticTerm that = (ArithmeticTerm) o; - - if (left != that.left) { - return false; - } - if (arithmeticOperator != that.arithmeticOperator) { - return false; - } - return right == that.right; - } - - @Override - public int hashCode() { - return 31 * (31 * left.hashCode() + arithmeticOperator.hashCode()) + right.hashCode(); - } - - public enum ArithmeticOperator { - PLUS("+"), - MINUS("-"), - TIMES("*"), - DIV("/"), - POWER("**"), - MODULO("\\"), - BITXOR("^"); - - - private String asString; - - ArithmeticOperator(String asString) { - this.asString = asString; - } - - @Override - public String toString() { - return asString; - } - - public Integer eval(Integer left, Integer right) { - switch (this) { - case PLUS: - return left + right; - case MINUS: - return left - right; - case TIMES: - return left * right; - case DIV: - return left / right; - case POWER: - return IntMath.checkedPow(left, right); - case MODULO: - return left % right; - case BITXOR: - return left ^ right; - default: - throw new RuntimeException("Unknown arithmetic operator encountered."); - - } - } - } - - public static class MinusTerm extends ArithmeticTerm { - - private MinusTerm(CoreTerm term) { - super(term, null, null); - } - - - public static CoreTerm getInstance(CoreTerm term) { - // Evaluate ground arithmetic terms immediately and return result. - if (term.isGround()) { - Integer result = evaluateGroundTermHelper(term) * -1; - return CoreConstantTerm.getInstance(result); - } - return INTERNER.intern(new MinusTerm(term)); - } - - @Override - Integer evaluateExpression() { - return evaluateGroundTermHelper(left) * -1; - } - - @Override - public boolean isGround() { - return left.isGround(); - } - - @Override - public List getOccurringVariables() { - return left.getOccurringVariables(); - } - - @Override - public CoreTerm substitute(Substitution substitution) { - return getInstance(left.substitute(substitution)); - } - - @Override - public CoreTerm renameVariables(String renamePrefix) { - return getInstance(left.renameVariables(renamePrefix)); - } - - @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); - return MinusTerm.getInstance(normalizedLeft); - } - - @Override - public String toString() { - return "-" + left; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - MinusTerm that = (MinusTerm) o; - - return left == that.left; - } - - @Override - public int hashCode() { - return 31 * left.hashCode(); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java deleted file mode 100644 index dd64324dc..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreConstantTerm.java +++ /dev/null @@ -1,154 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.Collections; -import java.util.List; - -/** - * Copyright (c) 2016-2020, the Alpha Team. - */ -public class CoreConstantTerm> extends CoreTerm { - private static final Interner> INTERNER = new Interner<>(); - - private final T object; - private final boolean symbolic; - - private CoreConstantTerm(T object, boolean symbolic) { - this.object = object; - this.symbolic = symbolic; - } - - @SuppressWarnings("unchecked") - public static > CoreConstantTerm getInstance(T symbol) { - return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, false)); - } - - @SuppressWarnings("unchecked") - public static > CoreConstantTerm getSymbolicInstance(String symbol) { - return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, true)); - } - - @Override - public boolean isGround() { - return true; - } - - @Override - public List getOccurringVariables() { - return Collections.emptyList(); - } - - @Override - public CoreTerm substitute(Substitution substitution) { - return this; - } - - @Override - public String toString() { - if (object instanceof String) { - if (symbolic) { - return (String) object; - } else { - return "\"" + object + "\""; - } - } - return object.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - CoreConstantTerm that = (CoreConstantTerm) o; - if (this.symbolic != that.symbolic) { - return false; - } - - return object.equals(that.object); - } - - @Override - public int hashCode() { - int result = object.hashCode(); - result = 31 * result + (symbolic ? 1 : 0); - return result; - } - - /** - * Establishes "priority" for ordering of constant terms depending on the type - * of the corresponding object according to ASP-Core-2.03c. - */ - private static final int priority(final Class clazz, CoreConstantTerm term) { - if (clazz.equals(Integer.class)) { - return 1; - } else if (clazz.equals(String.class)) { - return term.symbolic ? 2 : 3; - } - return 0; - } - - @Override - @SuppressWarnings("unchecked") - public int compareTo(CoreTerm o) { - if (this == o) { - return 0; - } - - if (!(o instanceof CoreConstantTerm)) { - return super.compareTo(o); - } - - CoreConstantTerm other = (CoreConstantTerm) o; - - // We will perform an unchecked cast. - // Because of type erasure, we cannot know the exact type - // of other.object. - // However, may assume that other.object actually is of - // type T. - // We know that this.object if of type T and implements - // Comparable. We ensure that the class of other.object - // equals the class of this.object, which in turn is T. - // That assumption should be quite safe. It can only be - // wrong if we have some bug that generates strange - // ConstantTerms at runtime, bypassing the check for T - // at compile-time. - if (other.object.getClass() == this.object.getClass() && other.symbolic == this.symbolic) { - return this.object.compareTo((T) other.object); - } - - Class thisType = this.object.getClass(); - Class otherType = other.object.getClass(); - - int thisPrio = priority(thisType, this); - int otherPrio = priority(otherType, other); - - if (thisPrio == 0 || otherPrio == 0) { - return thisType.getName().compareTo(otherType.getName()); - } - - return Integer.compare(thisPrio, otherPrio); - } - - @Override - public CoreTerm renameVariables(String renamePrefix) { - // Constant contains no variables, hence stays the same. - return this; - } - - @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - return this; - } - - public T getObject() { - return object; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java deleted file mode 100644 index 7f740aa37..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/CoreTerm.java +++ /dev/null @@ -1,100 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -//@formatter:off -/** - * Common representation of Terms. Terms are constructed such that each term is represented by a unique object, hence - * term equality can be checked by object reference comparison. Each concrete subclass of a Term must implement a - * factory-like method to obtain instances. - * - * We use {@link Comparable} to establish the following ordering among terms: - *

        - *
      1. Constant terms according to their corresponding object and its type - *
          - *
        1. {@link ConstantTerm} ordered by value of the integers
        2. - *
        3. {@link ConstantTerm} and symbolic, lexicographically ordered on the symbol
        4. - *
        5. {@link ConstantTerm} lexicographically - *
        6. {@link ConstantTerm} for all other types, where {@link Comparable#compareTo(Object)} is used as ordering whenever - * possible (i.e. two terms' objects have the same type). For two terms with objects of different type, - * the result is the lexicographic ordering of the type names.
        7. - *
        - *
      2. - *
      3. Function terms (ordered by arity, functor name, and then on their argument terms).
      4. - *
      5. Variable terms (lexicographically ordered on their variable names)
      6. - *
      - * - * Copyright (c) 2016-2020, the Alpha Team. - */ -//@formatter:on -public abstract class CoreTerm implements Comparable { - - public abstract List getOccurringVariables(); - - /** - * Applies a substitution, result may be nonground. - * - * @param substitution the variable substitution to apply. - * @return the non-substitute term where all variable substitutions have been applied. - */ - public abstract CoreTerm substitute(Substitution substitution); - - private static int priority(CoreTerm term) { - final Class clazz = term.getClass(); - if (clazz.equals(ConstantTerm.class)) { - return 1; - } else if (clazz.equals(FunctionTerm.class)) { - return 2; - } else if (clazz.equals(VariableTerm.class)) { - return 3; - } - throw new UnsupportedOperationException("Can only compare constant term, function terms and variable terms among each other."); - } - - @Override - public int compareTo(CoreTerm o) { - return o == null ? 1 : Integer.compare(priority(this), priority(o)); - } - - public abstract boolean isGround(); - - /** - * Rename all variables occurring in this Term by prefixing their name. - * - * @param renamePrefix the name to prefix all occurring variables. - * @return the term with all variables renamed. - */ - public abstract CoreTerm renameVariables(String renamePrefix); - - public abstract CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter); - - public static class RenameCounter { - int counter; - final HashMap renamedVariables; - - public RenameCounter(int startingValue) { - counter = startingValue; - renamedVariables = new HashMap<>(); - } - } - - public static List renameTerms(List terms, String prefix, int counterStartingValue) { - List renamedTerms = new ArrayList<>(terms.size()); - CoreTerm.RenameCounter renameCounter = new CoreTerm.RenameCounter(counterStartingValue); - for (CoreTerm term : terms) { - renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); - } - return renamedTerms; - } - - @Override - public abstract boolean equals(Object o); - - @Override - public abstract int hashCode(); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java deleted file mode 100644 index e2529258a..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/FunctionTerm.java +++ /dev/null @@ -1,157 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.Util.join; - -/** - * Copyright (c) 2016-2017, the Alpha Team. - */ -public class FunctionTerm extends CoreTerm { - private static final Interner INTERNER = new Interner<>(); - - private final String symbol; - private final List terms; - private final boolean ground; - - private FunctionTerm(String symbol, List terms) { - if (symbol == null) { - throw new IllegalArgumentException(); - } - - this.symbol = symbol; - this.terms = Collections.unmodifiableList(terms); - - boolean ground = true; - for (CoreTerm term : terms) { - if (!term.isGround()) { - ground = false; - break; - } - } - this.ground = ground; - } - - public static FunctionTerm getInstance(String functionSymbol, List termList) { - return INTERNER.intern(new FunctionTerm(functionSymbol, termList)); - } - - public static FunctionTerm getInstance(String functionSymbol, CoreTerm... terms) { - return getInstance(functionSymbol, Arrays.asList(terms)); - } - - public List getTerms() { - return terms; - } - - public String getSymbol() { - return symbol; - } - - @Override - public boolean isGround() { - return ground; - } - - @Override - public List getOccurringVariables() { - LinkedList vars = new LinkedList<>(); - for (CoreTerm term : terms) { - vars.addAll(term.getOccurringVariables()); - } - return vars; - } - - @Override - public FunctionTerm substitute(Substitution substitution) { - List groundTermList = new ArrayList<>(terms.size()); - for (CoreTerm term : terms) { - groundTermList.add(term.substitute(substitution)); - } - return FunctionTerm.getInstance(symbol, groundTermList); - } - - @Override - public String toString() { - if (terms.isEmpty()) { - return symbol; - } - - return join(symbol + "(", terms, ")"); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - FunctionTerm that = (FunctionTerm) o; - - if (!symbol.equals(that.symbol)) { - return false; - } - return terms.equals(that.terms); - } - - @Override - public int hashCode() { - return 31 * symbol.hashCode() + terms.hashCode(); - } - - @Override - public int compareTo(CoreTerm o) { - if (this == o) { - return 0; - } - - if (!(o instanceof FunctionTerm)) { - return super.compareTo(o); - } - - FunctionTerm other = (FunctionTerm)o; - - if (terms.size() != other.terms.size()) { - return terms.size() - other.terms.size(); - } - - int result = symbol.compareTo(other.symbol); - - if (result != 0) { - return result; - } - - for (int i = 0; i < terms.size(); i++) { - result = terms.get(i).compareTo(other.terms.get(i)); - if (result != 0) { - return result; - } - } - - return 0; - } - - @Override - public CoreTerm renameVariables(String renamePrefix) { - List renamedTerms = new ArrayList<>(terms.size()); - for (CoreTerm term : terms) { - renamedTerms.add(term.renameVariables(renamePrefix)); - } - return FunctionTerm.getInstance(symbol, renamedTerms); - } - - @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - List normalizedTerms = new ArrayList<>(terms.size()); - for (CoreTerm term : terms) { - normalizedTerms.add(term.normalizeVariables(renamePrefix, counter)); - } - return FunctionTerm.getInstance(symbol, normalizedTerms); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java deleted file mode 100644 index 3a801e7a8..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/IntervalTerm.java +++ /dev/null @@ -1,160 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.LinkedList; -import java.util.List; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -/** - * An IntervalTerm represents the shorthand notation for a set of rules where all elements in this interval occur once, e.g., fact(2..5). - * An IntervalTerm is a meta-term and the grounder must replace it with its corresponding set of facts or rules. - * Copyright (c) 2017, the Alpha Team. - */ -public class IntervalTerm extends CoreTerm { - private static final Interner INTERNER = new Interner<>(); - private final CoreTerm lowerBoundTerm; - private final CoreTerm upperBoundTerm; - - private final int lowerBound; - private final int upperBound; - - private final boolean ground; - - private IntervalTerm(CoreTerm lowerBound, CoreTerm upperBound) { - if (lowerBound == null || upperBound == null) { - throw new IllegalArgumentException(); - } - - this.ground = !((lowerBound instanceof VariableTerm) || (upperBound instanceof VariableTerm)); - - this.lowerBoundTerm = lowerBound; - this.upperBoundTerm = upperBound; - - if (this.ground) { - this.upperBound = Integer.parseInt(upperBoundTerm.toString()); - this.lowerBound = Integer.parseInt(lowerBoundTerm.toString()); - } else { - this.upperBound = -1; - this.lowerBound = -1; - } - } - - public static IntervalTerm getInstance(CoreTerm lowerBound, CoreTerm upperBound) { - return INTERNER.intern(new IntervalTerm(lowerBound, upperBound)); - } - - @Override - public boolean isGround() { - return this.ground; - } - - public int getLowerBound() { - if (!isGround()) { - throw oops("Cannot get the lower bound of non-ground interval"); - } - return this.lowerBound; - } - - public int getUpperBound() { - if (!isGround()) { - throw oops("Cannot get the upper bound of non-ground interval"); - } - return this.upperBound; - } - - @Override - public List getOccurringVariables() { - LinkedList variables = new LinkedList<>(); - if (lowerBoundTerm instanceof VariableTerm) { - variables.add((VariableTerm) lowerBoundTerm); - } - if (upperBoundTerm instanceof VariableTerm) { - variables.add((VariableTerm) upperBoundTerm); - } - return variables; - } - - @Override - public IntervalTerm substitute(Substitution substitution) { - if (isGround()) { - return this; - } - return new IntervalTerm(lowerBoundTerm.substitute(substitution), upperBoundTerm.substitute(substitution)); - } - - @Override - public String toString() { - return lowerBoundTerm + ".." + upperBoundTerm; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - IntervalTerm that = (IntervalTerm) o; - - if (!lowerBoundTerm.equals(that.lowerBoundTerm)) { - return false; - } - return upperBoundTerm.equals(that.upperBoundTerm); - - } - - @Override - public int hashCode() { - return 31 * lowerBoundTerm.hashCode() + upperBoundTerm.hashCode(); - } - - @Override - public int compareTo(CoreTerm o) { - throw new UnsupportedOperationException("Intervals cannot be compared."); - } - - @Override - public CoreTerm renameVariables(String renamePrefix) { - return new IntervalTerm(lowerBoundTerm.renameVariables(renamePrefix), upperBoundTerm.renameVariables(renamePrefix)); - } - - @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - return IntervalTerm.getInstance( - lowerBoundTerm.normalizeVariables(renamePrefix, counter), - upperBoundTerm.normalizeVariables(renamePrefix, counter)); - } - - /** - * Returns true if the term contains (or is) some IntervalTerm. - * @param term the term to test - * @return true iff an IntervalTerm occurs in term. - */ - public static boolean termContainsIntervalTerm(CoreTerm term) { - if (term instanceof IntervalTerm) { - return true; - } else if (term instanceof FunctionTerm) { - return functionTermContainsIntervals((FunctionTerm) term); - } else { - return false; - } - } - - public static boolean functionTermContainsIntervals(FunctionTerm functionTerm) { - // Test whether a function term contains an interval term (recursively). - for (CoreTerm term : functionTerm.getTerms()) { - if (term instanceof IntervalTerm) { - return true; - } - if (term instanceof FunctionTerm && functionTermContainsIntervals((FunctionTerm) term)) { - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java deleted file mode 100644 index 7ba67d17a..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/Terms.java +++ /dev/null @@ -1,33 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import java.util.ArrayList; -import java.util.List; - -/** - * Convenience methods for {@link CoreTerm}s. The methods provided here are an - * attempt to avoid repeating commonly used code snippets, like wrapping sets of - * values in {@link CoreTerm}s and creating lists of those terms, etc. - * - * Copyright (c) 2020, the Alpha Team. - */ -public final class Terms { - - /** - * Since this is purely a utility class, it may not be instantiated. - * - * @throws AssertionError if called - */ - private Terms() { - throw new AssertionError(Terms.class.getSimpleName() + " is a non-instantiable utility class!"); - } - - @SafeVarargs - public static > List> asTermList(T... values) { - List> retVal = new ArrayList<>(); - for (T value : values) { - retVal.add(CoreConstantTerm.getInstance(value)); - } - return retVal; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java b/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java deleted file mode 100644 index 0fd29c5e8..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/common/terms/VariableTerm.java +++ /dev/null @@ -1,108 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import at.ac.tuwien.kr.alpha.common.Interner; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.Collections; -import java.util.List; - -/** - * Copyright (c) 2016-2017, the Alpha Team. - */ -public class VariableTerm extends CoreTerm { - private static final Interner INTERNER = new Interner<>(); - - private static final String ANONYMOUS_VARIABLE_PREFIX = "_"; - private static final IntIdGenerator ANONYMOUS_VARIABLE_COUNTER = new IntIdGenerator(); - - private final String variableName; - - private VariableTerm(String variableName) { - this.variableName = variableName; - } - - public static VariableTerm getInstance(String variableName) { - return INTERNER.intern(new VariableTerm(variableName)); - } - - public static VariableTerm getAnonymousInstance() { - return getInstance(ANONYMOUS_VARIABLE_PREFIX + ANONYMOUS_VARIABLE_COUNTER.getNextId()); - } - - @Override - public boolean isGround() { - return false; - } - - @Override - public List getOccurringVariables() { - return Collections.singletonList(this); - } - - @Override - public CoreTerm substitute(Substitution substitution) { - CoreTerm groundTerm = substitution.eval(this); - if (groundTerm == null) { - // If variable is not substituted, keep term as is. - return this; - } - return groundTerm; - } - - @Override - public String toString() { - return variableName; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - VariableTerm that = (VariableTerm) o; - - return variableName.equals(that.variableName); - } - - @Override - public int hashCode() { - return variableName.hashCode(); - } - - @Override - public int compareTo(CoreTerm o) { - if (this == o) { - return 0; - } - - if (!(o instanceof VariableTerm)) { - return super.compareTo(o); - } - - VariableTerm other = (VariableTerm)o; - return variableName.compareTo(other.variableName); - } - - @Override - public CoreTerm renameVariables(String renamePrefix) { - return VariableTerm.getInstance(renamePrefix + variableName); - } - - @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - VariableTerm renamedThis = counter.renamedVariables.get(this); - if (renamedThis != null) { - return renamedThis; - } else { - VariableTerm renamedVariable = VariableTerm.getInstance(renamePrefix + counter.counter++); - counter.renamedVariables.put(this, renamedVariable); - return renamedVariable; - } - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java deleted file mode 100644 index f37739534..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/AbstractGrounder.java +++ /dev/null @@ -1,18 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public abstract class AbstractGrounder implements Grounder { - protected final java.util.function.Predicate filter; - - protected AbstractGrounder(java.util.function.Predicate filter) { - this.filter = filter; - } - - protected AbstractGrounder() { - this(p -> true); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java deleted file mode 100644 index 98b18eb5b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/BridgedGrounder.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import java.util.HashSet; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; - -public abstract class BridgedGrounder extends AbstractGrounder { - protected final Bridge[] bridges; - - protected BridgedGrounder(java.util.function.Predicate filter, Bridge... bridges) { - super(filter); - this.bridges = bridges; - } - - protected BridgedGrounder(Bridge... bridges) { - super(); - this.bridges = bridges; - } - - protected Set collectExternalRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator) { - Set collectedRules = new HashSet<>(); - - for (Bridge bridge : bridges) { - collectedRules.addAll(bridge.getRules(assignment, atomStore, intIdGenerator)); - } - - return collectedRules; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java deleted file mode 100644 index c807e0bae..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ChoiceRecorder.java +++ /dev/null @@ -1,128 +0,0 @@ -/** - * 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. - * - * 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.grounder; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom.off; -import static at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom.on; -import static java.util.Collections.emptyList; - -public class ChoiceRecorder { - private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); - - private final AtomStore atomStore; - private Pair, Map> newChoiceAtoms = new ImmutablePair<>(new LinkedHashMap<>(), new LinkedHashMap<>()); - private Map> newHeadsToBodies = new LinkedHashMap<>(); - - public ChoiceRecorder(AtomStore atomStore) { - this.atomStore = atomStore; - } - - /** - * @return new choice points and their enablers and disablers. - */ - public Pair, Map> getAndResetChoices() { - Pair, Map> currentChoiceAtoms = newChoiceAtoms; - newChoiceAtoms = new ImmutablePair<>(new LinkedHashMap<>(), new LinkedHashMap<>()); - return currentChoiceAtoms; - } - - /** - * @return a set of new mappings from head atoms to {@link RuleAtom}s deriving it. - */ - public Map> getAndResetHeadsToBodies() { - Map> currentHeadsToBodies = newHeadsToBodies; - newHeadsToBodies = new LinkedHashMap<>(); - return currentHeadsToBodies; - } - - - public List generateChoiceNoGoods(final List posLiterals, final List negLiterals, final int bodyRepresentingLiteral) { - // Obtain an ID for this new choice. - final int choiceId = ID_GENERATOR.getNextId(); - final int bodyRepresentingAtom = atomOf(bodyRepresentingLiteral); - // Create ChoiceOn and ChoiceOff atoms. - final int choiceOnAtom = atomStore.putIfAbsent(on(choiceId)); - newChoiceAtoms.getLeft().put(bodyRepresentingAtom, choiceOnAtom); - final int choiceOffAtom = atomStore.putIfAbsent(off(choiceId)); - newChoiceAtoms.getRight().put(bodyRepresentingAtom, choiceOffAtom); - - final List noGoods = generateNeg(choiceOffAtom, negLiterals); - noGoods.add(generatePos(choiceOnAtom, posLiterals)); - - return noGoods; - } - - private NoGood generatePos(final int atomOn, List posLiterals) { - final int literalOn = atomToLiteral(atomOn); - - return NoGood.fromBodyInternal(posLiterals, emptyList(), literalOn); - } - - private List generateNeg(final int atomOff, List negLiterals) { - final int negLiteralOff = negateLiteral(atomToLiteral(atomOff)); - - final List noGoods = new ArrayList<>(negLiterals.size() + 1); - for (Integer negLiteral : negLiterals) { - // Choice is off if any of the negative atoms is assigned true, - // hence we add one nogood for each such atom. - noGoods.add(NoGood.headFirstInternal(negLiteralOff, negLiteral)); - } - return noGoods; - } - - public void addHeadToBody(int headId, int bodyId) { - Set existingBodies = newHeadsToBodies.get(headId); - if (existingBodies == null) { - existingBodies = new HashSet<>(); - newHeadsToBodies.put(headId, existingBodies); - } - existingBodies.add(bodyId); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("[enablers: "); - for (Map.Entry enablers : newChoiceAtoms.getLeft().entrySet()) { - sb.append(enablers.getKey()).append("/").append(enablers.getValue()).append(", "); - } - sb.append(" disablers: "); - for (Map.Entry disablers : newChoiceAtoms.getRight().entrySet()) { - sb.append(disablers.getKey()).append("/").append(disablers.getValue()); - } - return sb.append("]").toString(); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java deleted file mode 100644 index 7f762c773..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FactIntervalEvaluator.java +++ /dev/null @@ -1,67 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.terms.*; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Helper functions to evaluate facts potentially containing intervals. - * Copyright (c) 2017, the Alpha Team. - */ -public class FactIntervalEvaluator { - - /** - * Helper to construct Instances from a fact that may contain intervals. - * - * @param fact the fact potentially containing intervals. - * @return all instances stemming from unfolding the intervals. - */ - public static List constructFactInstances(CoreAtom fact) { - // Construct instance(s) from the fact. - int arity = fact.getPredicate().getArity(); - CoreTerm[] currentTerms = new CoreTerm[arity]; - boolean containsIntervals = false; - // Check if instance contains intervals at all. - for (int i = 0; i < arity; i++) { - CoreTerm term = fact.getTerms().get(i); - currentTerms[i] = term; - if (term instanceof IntervalTerm) { - containsIntervals = true; - } else if (term instanceof FunctionTerm && IntervalTerm.functionTermContainsIntervals((FunctionTerm) term)) { - containsIntervals = true; - throw new UnsupportedOperationException("Intervals inside function terms in facts are not supported yet. Try turning the fact into a rule."); - } - } - // If fact contains no intervals, simply return the single instance. - if (!containsIntervals) { - return Collections.singletonList(new Instance(currentTerms)); - } - // Fact contains intervals, unroll them all. - return unrollInstances(currentTerms, 0); - } - - private static List unrollInstances(CoreTerm[] currentTerms, int currentPosition) { - if (currentPosition == currentTerms.length) { - return Collections.singletonList(new Instance(currentTerms)); - } - CoreTerm currentTerm = currentTerms[currentPosition]; - if (!(currentTerm instanceof IntervalTerm)) { - return unrollInstances(currentTerms, currentPosition + 1); - } - - List instances = new ArrayList<>(); - - int lower = ((IntervalTerm) currentTerm).getLowerBound(); - int upper = ((IntervalTerm) currentTerm).getUpperBound(); - - for (int i = lower; i <= upper; i++) { - CoreTerm[] clonedTerms = currentTerms.clone(); - clonedTerms[currentPosition] = CoreConstantTerm.getInstance(i); - instances.addAll(unrollInstances(clonedTerms, currentPosition + 1)); - } - return instances; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java deleted file mode 100644 index 03aac3274..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/FilteringGrounder.java +++ /dev/null @@ -1,18 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public abstract class FilteringGrounder implements Grounder { - protected final java.util.function.Predicate filter; - - protected FilteringGrounder(java.util.function.Predicate filter) { - this.filter = filter; - } - - protected FilteringGrounder() { - this(p -> true); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java deleted file mode 100644 index 41849fa53..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Grounder.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * 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 - * 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.grounder; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.Map; -import java.util.Set; - -public interface Grounder { - /** - * Translates an answer-set represented by true atom IDs into its logical representation. - * @param trueAtoms - * @return - */ - AnswerSet assignmentToAnswerSet(Iterable trueAtoms); - - /** - * Applies lazy grounding and returns all newly derived (fully ground) NoGoods. - * @return a mapping of nogood IDs to NoGoods. - */ - Map getNoGoods(Assignment assignment); - - /** - * Return choice points and their enablers and disablers. - * Must be preceeded by a call to getNoGoods(). - * @return a pair (choiceOn, choiceOff) of two maps from atomIds to atomIds, - * choiceOn maps atoms (choice points) to their enabling atoms - * and choiceOff maps atoms (choice points) to their disabling atoms. - */ - Pair, Map> getChoiceAtoms(); - - /** - * Updates the grounder with atoms assigned a positive truth value. - * @param it an iterator over all newly assigned positive atoms. - */ - void updateAssignment(IntIterator it); - - /** - * Returns a set of new mappings from head atoms to {@link RuleAtom}s deriving it. - */ - Map> getHeadsToBodies(); - - void forgetAssignment(int[] atomIds); - - /** - * Registers the given NoGood and returns the identifier of it. - * @param noGood - * @return - */ - int register(NoGood noGood); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java deleted file mode 100644 index a24c9c8a8..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/GrounderFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2016-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.grounder; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; - -public final class GrounderFactory { - public static Grounder getInstance(String name, InternalProgram 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."); - } - - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, - GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); - } - - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, new GrounderHeuristicsConfiguration(), debugInternalChecks); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java deleted file mode 100644 index 578596886..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorage.java +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.grounder; - -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 at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; - -/** - * A storage for instances with a certain arity, where each position of the instance can be indexed. - * This aids in matching and joining instances. An index can be added or removed at any time for a desired position of - * all instances. - * Copyright (c) 2016-2020, the Alpha Team. - */ -public class IndexedInstanceStorage { - private final CorePredicate predicate; - private final boolean positive; - - /** - * A collection of all instances currently stored in this storage. - */ - private final LinkedHashSet instances = new LinkedHashSet<>(); - - /** - * For each position, a mapping of termIds to list of instances with this termId at the corresponding position - */ - private final ArrayList>> indices = new ArrayList<>(); - - private final ArrayList recentlyAddedInstances = new ArrayList<>(); - - public IndexedInstanceStorage(CorePredicate predicate, boolean positive) { - this.predicate = predicate; - this.positive = positive; - - // Create list of mappings, initialize to null. - while (indices.size() < predicate.getArity()) { - indices.add(null); - } - } - - public CorePredicate getPredicate() { - return predicate; - } - - public void markRecentlyAddedInstancesDone() { - recentlyAddedInstances.clear(); - } - - public void addIndexPosition(int position) { - if (position < 0 || position > predicate.getArity() - 1) { - throw new RuntimeException("Requested to create indices for attribute out of range." + - "IndexedInstanceStorage: " + this + " requested indices position: " + position); - } - // Add index - indices.set(position, new LinkedHashMap<>()); - - // Initialize index with all instances currently used. - for (Instance instance : instances) { - indices.get(position).putIfAbsent(instance.terms.get(position), new ArrayList<>()); - ArrayList instancesAtPosition = indices.get(position).get(instance.terms.get(position)); - instancesAtPosition.add(instance); - } - } - - public void removeIndexPosition(int position) { - if (position < 0 || position > predicate.getArity() - 1) { - throw new RuntimeException("Requested to create indices for attribute out of range." + - "IndexedInstanceStorage: " + this + " requested indices position: " + position); - } - indices.set(position, null); - } - - /** - * Returns whether an instance is already contained in the storage. - * - * @param instance the instance to check for containment. - * @return true if the instance is already contained in the storage. - */ - public boolean containsInstance(Instance instance) { - return instances.contains(instance); - } - - public void addInstance(Instance instance) { - if (instance.terms.size() != predicate.getArity()) { - throw new RuntimeException("Instance length does not match arity of IndexedInstanceStorage: " + - "instance size: " + instance.terms.size() - + "IndexedInstanceStorage: " + this); - } - instances.add(instance); - recentlyAddedInstances.add(instance); - // Add instance to all indices. - for (int i = 0; i < indices.size(); i++) { - HashMap> posIndex = indices.get(i); - if (posIndex == null) { - continue; - } - posIndex.putIfAbsent(instance.terms.get(i), new ArrayList<>()); - ArrayList matchingInstancesAtPos = posIndex.get(instance.terms.get(i)); - matchingInstancesAtPos.add(instance); // Add instance - } - } - - public void removeInstance(Instance instance) { - if (recentlyAddedInstances.size() != 0) { - // Hint: exception may be replaced by removing the instance also from the list of recentlyAddedInstances. - throw new RuntimeException("Instance is removed while there are unprocessed new instances; Result dubious."); - } - // Remove from all indices - for (int i = 0; i < indices.size(); i++) { - HashMap> posIndex = indices.get(i); - if (posIndex == null) { - continue; - } - ArrayList matchingInstancesAtPos = posIndex.get(instance.terms.get(i)); - matchingInstancesAtPos.remove(instance); // Remove instance - - // If there are no more instances having the term at the current position, - // remove the entry from the hash. - if (matchingInstancesAtPos.size() == 0) { - posIndex.remove(instance.terms.get(i)); - } - } - instances.remove(instance); - } - - public List getRecentlyAddedInstances() { - return recentlyAddedInstances; - } - - /** - * Returns a list of all instances having the given term at the given position. Returns null if no such - * instances exist. - * - * @param term - * @param position - * @return - */ - public List getInstancesMatchingAtPosition(CoreTerm term, int position) { - Map> indexForPosition = indices.get(position); - if (indexForPosition == null) { - throw new RuntimeException("IndexedInstanceStorage queried for position " + position + " which is not indexed."); - } - ArrayList matchingInstances = indexForPosition.get(term); - return matchingInstances == null ? Collections.emptyList() : matchingInstances; - } - - private int getMostSelectiveGroundTermPosition(CoreAtom atom) { - int smallestNumberOfInstances = Integer.MAX_VALUE; - int mostSelectiveTermPosition = -1; - for (int i = 0; i < atom.getTerms().size(); i++) { - CoreTerm testTerm = atom.getTerms().get(i); - if (testTerm.isGround()) { - ArrayList instancesMatchingTest = indices.get(i).get(testTerm); - if (instancesMatchingTest == null) { - // Ground term at i matches zero instances, it is most selective. - return i; - } - int numInstancesTestTerm = instancesMatchingTest.size(); - if (numInstancesTestTerm < smallestNumberOfInstances) { - smallestNumberOfInstances = numInstancesTestTerm; - mostSelectiveTermPosition = i; - } - } - } - return mostSelectiveTermPosition; - } - - public List getInstancesFromPartiallyGroundAtom(CoreAtom substitute) { - // For selection of the instances, find ground term on which to select. - int firstGroundTermPosition = getMostSelectiveGroundTermPosition(substitute); - // Select matching instances, select all if no ground term was found. - if (firstGroundTermPosition != -1) { - CoreTerm firstGroundTerm = substitute.getTerms().get(firstGroundTermPosition); - return getInstancesMatchingAtPosition(firstGroundTerm, firstGroundTermPosition); - } else { - return new ArrayList<>(getAllInstances()); - } - } - - public Set getAllInstances() { - return instances; - } - - @Override - public String toString() { - return (positive ? "+" : "-") + predicate; - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java deleted file mode 100644 index 9897b5a03..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Instance.java +++ /dev/null @@ -1,57 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import static at.ac.tuwien.kr.alpha.Util.join; - -import java.util.Arrays; -import java.util.List; - -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; - -/** - * An instance is a positional association of terms, e.g., representing a variable substitution, or a ground instance of - * a predicate. - * Copyright (c) 2016, the Alpha Team. - */ -public class Instance { - public final List terms; - - public Instance(CoreTerm... terms) { - this(Arrays.asList(terms)); - } - - public Instance(List terms) { - this.terms = terms; - } - - public static Instance fromAtom(CoreAtom atom) { - if (!atom.isGround()) { - throw Util.oops("Cannot create instance from non-ground atom " + atom.toString()); - } - return new Instance(atom.getTerms()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - return terms.equals(((Instance) o).terms); - } - - @Override - public int hashCode() { - return terms.hashCode(); - } - - @Override - public String toString() { - return join("(", terms, ")"); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java deleted file mode 100644 index 7e5aade1d..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/IntIdGenerator.java +++ /dev/null @@ -1,33 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -/** - * Generates unique, sequential integers starting at 0, i.e., it maintains a counter that is incremented for each getNextId(). - * Copyright (c) 2016, the Alpha Team. - */ -public class IntIdGenerator { - private int highestId; - - public IntIdGenerator() { - this(0); - } - - public IntIdGenerator(int initial) { - this.highestId = initial; - } - - public int getNextId() { - if (highestId == Integer.MAX_VALUE) { - throw oops("Ran out of IDs (integer overflow)"); - } - return highestId++; - } - - /** - * Resets the internal counter. Useful for resetting before each test. - */ - public void resetGenerator() { - highestId = 0; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java deleted file mode 100644 index cb19e5cb3..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java +++ /dev/null @@ -1,639 +0,0 @@ -/** - * 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 - * 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.grounder; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -import java.util.ArrayList; -import java.util.Collection; -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.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.grounder.bridges.Bridge; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; -import at.ac.tuwien.kr.alpha.grounder.instantiation.BindingResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.DefaultLazyGroundingInstantiationStrategy; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; -import at.ac.tuwien.kr.alpha.grounder.structure.AnalyzeUnjustified; - -/** - * A semi-naive grounder. - * - * Copyright (c) 2016-2020, the Alpha Team. - */ -public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGrounder { - private static final Logger LOGGER = LoggerFactory.getLogger(NaiveGrounder.class); - - private final WorkingMemory workingMemory = new WorkingMemory(); - private final AtomStore atomStore; - private final NogoodRegistry registry = new NogoodRegistry(); - final NoGoodGenerator noGoodGenerator; - private final ChoiceRecorder choiceRecorder; - private final InternalProgram program; - private final AnalyzeUnjustified analyzeUnjustified; - - private final Map> factsFromProgram; - private final Map> rulesUsingPredicateWorkingMemory = new HashMap<>(); - private final Map knownNonGroundRules; - - private ArrayList fixedRules = new ArrayList<>(); - private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); - private final boolean debugInternalChecks; - - private final GrounderHeuristicsConfiguration heuristicsConfiguration; - - // Handles instantiation of literals, i.e. supplies ground substitutions for literals of non-ground rules - // according to the rules set by the LiteralInstantiationStrategy used by this grounder. - private final LiteralInstantiator ruleInstantiator; - private final DefaultLazyGroundingInstantiationStrategy instantiationStrategy; - - public NaiveGrounder(InternalProgram program, AtomStore atomStore, boolean debugInternalChecks, Bridge... bridges) { - this(program, atomStore, new GrounderHeuristicsConfiguration(), debugInternalChecks, bridges); - } - - private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { - this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, bridges); - } - - NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { - super(filter, bridges); - this.atomStore = atomStore; - this.heuristicsConfiguration = heuristicsConfiguration; - LOGGER.debug("Grounder configuration: {}", heuristicsConfiguration); - - this.program = program; - - this.factsFromProgram = program.getFactsByPredicate(); - this.knownNonGroundRules = program.getRulesById(); - - this.analyzeUnjustified = new AnalyzeUnjustified(this.program, this.atomStore, this.factsFromProgram); - - this.initializeFactsAndRules(); - - final Set uniqueGroundRulePerGroundHead = getRulesWithUniqueHead(); - choiceRecorder = new ChoiceRecorder(atomStore); - noGoodGenerator = new NoGoodGenerator(atomStore, choiceRecorder, factsFromProgram, this.program, uniqueGroundRulePerGroundHead); - - this.debugInternalChecks = debugInternalChecks; - - // Initialize RuleInstantiator and instantiation strategy. Note that the instantiation strategy also - // needs the current assignment, which is set with every call of getGroundInstantiations. - this.instantiationStrategy = new DefaultLazyGroundingInstantiationStrategy(this.workingMemory, this.atomStore, this.factsFromProgram); - this.instantiationStrategy.setStaleWorkingMemoryEntries(this.removeAfterObtainingNewNoGoods); - this.ruleInstantiator = new LiteralInstantiator(this.instantiationStrategy); - } - - private void initializeFactsAndRules() { - // Initialize all facts. - for (CoreAtom fact : program.getFacts()) { - final CorePredicate predicate = fact.getPredicate(); - - // Record predicate - workingMemory.initialize(predicate); - } - - // Register internal atoms. - workingMemory.initialize(RuleAtom.PREDICATE); - workingMemory.initialize(ChoiceAtom.OFF); - workingMemory.initialize(ChoiceAtom.ON); - - // Initialize rules and constraints in working memory. - for (InternalRule nonGroundRule : program.getRulesById().values()) { - // Create working memories for all predicates occurring in the rule. - for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { - // FIXME: this also contains interval/builtin predicates that are not needed. - workingMemory.initialize(predicate); - } - - // If the rule has fixed ground instantiations, it is not registered but grounded once like facts. - if (nonGroundRule.getGroundingOrders().fixedInstantiation()) { - fixedRules.add(nonGroundRule); - continue; - } - - // Register each starting literal at the corresponding working memory. - for (CoreLiteral literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { - registerLiteralAtWorkingMemory(literal, nonGroundRule); - } - } - } - - private Set getRulesWithUniqueHead() { - // FIXME: below optimisation (adding support nogoods if there is only one rule instantiation per unique atom over the interpretation) could be done as a transformation (adding a non-ground constraint corresponding to the nogood that is generated by the grounder). - // Record all unique rule heads. - final Set uniqueGroundRulePerGroundHead = new HashSet<>(); - - for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { - if (headDefiningRules.getValue().size() != 1) { - continue; - } - - InternalRule nonGroundRule = headDefiningRules.getValue().iterator().next(); - // Check that all variables of the body also occur in the head (otherwise grounding is not unique). - CoreAtom headAtom = nonGroundRule.getHeadAtom(); - - // Rule is not guaranteed unique if there are facts for it. - HashSet potentialFacts = factsFromProgram.get(headAtom.getPredicate()); - if (potentialFacts != null && !potentialFacts.isEmpty()) { - continue; - } - - // Collect head and body variables. - HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); - HashSet occurringVariablesBody = new HashSet<>(); - for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { - occurringVariablesBody.addAll(lit.getBindingVariables()); - } - occurringVariablesBody.removeAll(occurringVariablesHead); - - // Check if ever body variables occurs in the head. - if (occurringVariablesBody.isEmpty()) { - uniqueGroundRulePerGroundHead.add(nonGroundRule); - } - } - return uniqueGroundRulePerGroundHead; - } - - /** - * Registers a starting literal of a NonGroundRule at its corresponding working memory. - * @param nonGroundRule the rule in which the literal occurs. - */ - private void registerLiteralAtWorkingMemory(CoreLiteral literal, InternalRule nonGroundRule) { - if (literal.isNegated()) { - throw new RuntimeException("Literal to register is negated. Should not happen."); - } - IndexedInstanceStorage workingMemory = this.workingMemory.get(literal.getPredicate(), true); - rulesUsingPredicateWorkingMemory.putIfAbsent(workingMemory, new ArrayList<>()); - rulesUsingPredicateWorkingMemory.get(workingMemory).add(new FirstBindingAtom(nonGroundRule, literal)); - } - - @Override - public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { - Map> predicateInstances = new LinkedHashMap<>(); - SortedSet knownPredicates = new TreeSet<>(); - - // Iterate over all true atomIds, computeNextAnswerSet instances from atomStore and add them if not filtered. - for (int trueAtom : trueAtoms) { - final CoreAtom atom = atomStore.get(trueAtom); - CorePredicate predicate = atom.getPredicate(); - - // Skip atoms over internal predicates. - if (predicate.isInternal()) { - continue; - } - - // Skip filtered predicates. - if (!filter.test(predicate)) { - continue; - } - - knownPredicates.add(predicate); - predicateInstances.putIfAbsent(predicate, new TreeSet<>()); - Set instances = predicateInstances.get(predicate); - instances.add(atom); - } - - // Add true atoms from facts. - for (Map.Entry> facts : factsFromProgram.entrySet()) { - CorePredicate factPredicate = facts.getKey(); - // Skip atoms over internal predicates. - if (factPredicate.isInternal()) { - continue; - } - // Skip filtered predicates. - if (!filter.test(factPredicate)) { - continue; - } - // Skip predicates without any instances. - if (facts.getValue().isEmpty()) { - continue; - } - knownPredicates.add(factPredicate); - predicateInstances.putIfAbsent(factPredicate, new TreeSet<>()); - for (Instance factInstance : facts.getValue()) { - SortedSet instances = predicateInstances.get(factPredicate); - instances.add(new BasicAtom(factPredicate, factInstance.terms)); - } - } - - if (knownPredicates.isEmpty()) { - return BasicAnswerSet.EMPTY; - } - - return new BasicAnswerSet(knownPredicates, predicateInstances); - } - - /** - * Prepares facts of the input program for joining and derives all NoGoods representing ground rules. May only be called once. - * @return - */ - protected HashMap bootstrap() { - final HashMap groundNogoods = new LinkedHashMap<>(); - - for (CorePredicate predicate : factsFromProgram.keySet()) { - // Instead of generating NoGoods, add instance to working memories directly. - workingMemory.addInstances(predicate, true, factsFromProgram.get(predicate)); - } - - for (InternalRule nonGroundRule : fixedRules) { - // Generate NoGoods for all rules that have a fixed grounding. - RuleGroundingOrder groundingOrder = nonGroundRule.getGroundingOrders().getFixedGroundingOrder(); - BindingResult bindingResult = getGroundInstantiations(nonGroundRule, groundingOrder, new Substitution(), null); - groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), groundNogoods); - } - - fixedRules = null; - - return groundNogoods; - } - - @Override - public Map getNoGoods(Assignment currentAssignment) { - // In first call, prepare facts and ground rules. - final Map newNoGoods = fixedRules != null ? bootstrap() : new LinkedHashMap<>(); - - // Compute new ground rule (evaluate joins with newly changed atoms) - for (IndexedInstanceStorage modifiedWorkingMemory : workingMemory.modified()) { - // Skip predicates solely used in the solver which do not occur in rules. - CorePredicate workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); - if (workingMemoryPredicate.isSolverInternal()) { - continue; - } - - // Iterate over all rules whose body contains the interpretation corresponding to the current workingMemory. - final ArrayList firstBindingAtoms = rulesUsingPredicateWorkingMemory.get(modifiedWorkingMemory); - - // Skip working memories that are not used by any rule. - if (firstBindingAtoms == null) { - continue; - } - - for (FirstBindingAtom firstBindingAtom : firstBindingAtoms) { - // Use the recently added instances from the modified working memory to construct an initial substitution - InternalRule nonGroundRule = firstBindingAtom.rule; - - // Generate substitutions from each recent instance. - for (Instance instance : modifiedWorkingMemory.getRecentlyAddedInstances()) { - // Check instance if it matches with the atom. - - final Substitution unifier = Substitution.specializeSubstitution(firstBindingAtom.startingLiteral, instance, Substitution.EMPTY_SUBSTITUTION); - - if (unifier == null) { - continue; - } - - final BindingResult bindingResult = getGroundInstantiations( - nonGroundRule, - nonGroundRule.getGroundingOrders().orderStartingFrom(firstBindingAtom.startingLiteral), - unifier, - currentAssignment - ); - - groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), newNoGoods); - } - } - - // Mark instances added by updateAssignment as done - modifiedWorkingMemory.markRecentlyAddedInstancesDone(); - } - - workingMemory.reset(); - for (CoreAtom removeAtom : removeAfterObtainingNewNoGoods) { - final IndexedInstanceStorage storage = workingMemory.get(removeAtom, true); - Instance instance = new Instance(removeAtom.getTerms()); - if (storage.containsInstance(instance)) { - // permissive grounder heuristics may attempt to remove instances that are not yet in the working memory - storage.removeInstance(instance); - } - } - - // Re-Initialize the stale working memory entries set and pass to instantiation strategy. - removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); - instantiationStrategy.setStaleWorkingMemoryEntries(removeAfterObtainingNewNoGoods); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Grounded NoGoods are:"); - for (Map.Entry noGoodEntry : newNoGoods.entrySet()) { - LOGGER.debug("{} == {}", noGoodEntry.getValue(), atomStore.noGoodToString(noGoodEntry.getValue())); - } - LOGGER.debug("{}", choiceRecorder); - } - - if (debugInternalChecks) { - checkTypesOfNoGoods(newNoGoods.values()); - } - - return newNoGoods; - } - - /** - * Grounds the given {@code nonGroundRule} by applying the given {@code substitutions} and registers the nogoods generated during that process. - * - * @param nonGroundRule the rule to be grounded. - * @param substitutions the substitutions to be applied. - * @param newNoGoods a set of nogoods to which newly generated nogoods will be added. - */ - private void groundAndRegister(final InternalRule nonGroundRule, final List substitutions, final Map newNoGoods) { - for (Substitution substitution : substitutions) { - List generatedNoGoods = noGoodGenerator.generateNoGoodsFromGroundSubstitution(nonGroundRule, substitution); - registry.register(generatedNoGoods, newNoGoods); - } - } - - @Override - public int register(NoGood noGood) { - return registry.register(noGood); - } - - // Ideally, this method should be private. It's only visible because NaiveGrounderTest needs to access it. - BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder groundingOrder, Substitution partialSubstitution, - Assignment currentAssignment) { - int tolerance = heuristicsConfiguration.getTolerance(rule.isConstraint()); - if (tolerance < 0) { - tolerance = Integer.MAX_VALUE; - } - - // Update instantiationStrategy with current assignment. - // Note: Actually the assignment could be an instance variable of the grounder (shared with solver), - // but this would have a larger impact on grounder/solver communication design as a whole. - instantiationStrategy.setCurrentAssignment(currentAssignment); - BindingResult bindingResult = bindNextAtomInRule(groundingOrder, 0, tolerance, tolerance, partialSubstitution); - if (LOGGER.isDebugEnabled()) { - for (int i = 0; i < bindingResult.size(); i++) { - Integer numberOfUnassignedPositiveBodyAtoms = bindingResult.getNumbersOfUnassignedPositiveBodyAtoms().get(i); - if (numberOfUnassignedPositiveBodyAtoms > 0) { - LOGGER.debug("Grounded rule in which {} positive atoms are still unassigned: {} (substitution: {})", numberOfUnassignedPositiveBodyAtoms, rule, bindingResult.getGeneratedSubstitutions().get(i)); - } - } - } - return bindingResult; - } - - /** - * Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrder, int, int, int, Substitution)}. - * - * Takes an ImmutablePair of a {@link Substitution} and an accompanying {@link AssignmentStatus} and calls - * bindNextAtomInRule for the next literal in the grounding order. - * If the assignment status for the last bound literal was {@link AssignmentStatus#UNASSIGNED}, the remainingTolerance - * parameter is decreased by 1. If the remaining tolerance drops below zero, this method returns an empty {@link BindingResult}. - * - * @param groundingOrder - * @param orderPosition - * @param originalTolerance - * @param remainingTolerance - * @param lastLiteralBindingResult - * @return the result of calling bindNextAtomInRule on the next literal in the grounding order, or an empty binding result if remaining - * tolerance is less than zero. - */ - private BindingResult continueBinding(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - ImmutablePair lastLiteralBindingResult) { - Substitution substitution = lastLiteralBindingResult.left; - AssignmentStatus lastBoundLiteralAssignmentStatus = lastLiteralBindingResult.right; - switch (lastBoundLiteralAssignmentStatus) { - case TRUE: - return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, substitution); - case UNASSIGNED: - // The last literal bound to obtain the current substitution has not been assigned a truth value by the solver yet. - // If we still have enough tolerance, we can continue grounding nevertheless. - int toleranceForNextRun = remainingTolerance - 1; - if (toleranceForNextRun >= 0) { - return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, toleranceForNextRun, substitution); - } else { - return BindingResult.empty(); - } - case FALSE: - throw Util.oops("Got an assignmentStatus FALSE for literal " + groundingOrder.getLiteralAtOrderPosition(orderPosition) + " and substitution " - + substitution + " - should not happen!"); - default: - throw Util.oops("Got unsupported assignmentStatus " + lastBoundLiteralAssignmentStatus); - } - } - - private BindingResult advanceAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { - groundingOrder.considerUntilCurrentEnd(); - return bindNextAtomInRule(groundingOrder, orderPosition + 1, originalTolerance, remainingTolerance, partialSubstitution); - } - - private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { - RuleGroundingOrder modifiedGroundingOrder = groundingOrder.pushBack(orderPosition); - if (modifiedGroundingOrder == null) { - return BindingResult.empty(); - } - return bindNextAtomInRule(modifiedGroundingOrder, orderPosition + 1, originalTolerance, remainingTolerance, partialSubstitution); - } - - //@formatter:off - - /** - * Computes ground substitutions for a literal based on a {@link RuleGroundingOrder} and a {@link Substitution}. - * - * Computes ground substitutions for the literal at position orderPosition of groundingOrder - * Actual substitutions are computed by this grounder's {@link LiteralInstantiator}. - * - * @param groundingOrder a {@link RuleGroundingOrder} representing the body literals of a rule in the - * sequence in which the should be bound during grounding. - * @param orderPosition the current position within groundingOrder, indicates which literal should be bound - * @param originalTolerance the original tolerance of the used grounding heuristic - * @param remainingTolerance the remaining tolerance, determining if binding continues in the presence of substitutions based on unassigned atoms - * @param partialSubstitution a substitution - * @return a {@link BindingResult} representing applicable ground substitutions for all literals after orderPosition in groundingOrder - */ - //@formatter:on - private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { - CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); - if (currentLiteral == null) { - LOGGER.trace("No more literals found in grounding order, therefore stopping binding!"); - return BindingResult.singleton(partialSubstitution, originalTolerance - remainingTolerance); - } - LOGGER.trace("Binding current literal {} with remaining tolerance {} and partial substitution {}.", currentLiteral, - remainingTolerance, partialSubstitution); - LiteralInstantiationResult instantiationResult = ruleInstantiator.instantiateLiteral(currentLiteral, partialSubstitution); - switch (instantiationResult.getType()) { - case CONTINUE: - /* - * Recursively call bindNextAtomInRule for each generated substitution - * and the next literal in the grounding order (i.e. advance), thereby reducing remaining - * tolerance by 1 iff a substitution uses an unassigned ground atom. - * If remainingTolerance falls below zero, an empty {@link BindingResult} is returned. - */ - List> substitutionInfos = instantiationResult.getSubstitutions(); - LOGGER.trace("Literal instantiator yielded {} substitutions for literal {}.", substitutionInfos.size(), currentLiteral); - BindingResult retVal = new BindingResult(); - for (ImmutablePair substitutionInfo : substitutionInfos) { - retVal.add(this.continueBinding(groundingOrder, orderPosition, originalTolerance, remainingTolerance, - substitutionInfo)); - } - return retVal; - case PUSH_BACK: - /* - * Delegate to pushBackAndBindNextAtomInRule(RuleGroundingOrder, int, int, int, Substitution, Assignment). - * Pushes the current literal to the end of the grounding order and calls bindNextAtomInRule with the modified grounding oder. - */ - LOGGER.trace("Pushing back literal {} in grounding order.", currentLiteral); - return pushBackAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, partialSubstitution); - case MAYBE_PUSH_BACK: - /* - * Indicates that the rule instantiator could not find any substitutions for the current literal. If a permissive grounder heuristic is in - * use, push the current literal to the end of the grounding order and proceed with the next one, otherwise return an empty BindingResult. - */ - if (originalTolerance > 0) { - LOGGER.trace("No substitutions yielded by literal instantiator for literal {}, but using permissive heuristic, therefore pushing the literal back.", currentLiteral); - // This occurs when the grounder heuristic in use is a "permissive" one, - // i.e. it is deemed acceptable to have ground rules where a number of body atoms are not yet assigned a truth value by the solver. - return pushBackAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, partialSubstitution); - } else { - LOGGER.trace("No substitutions found for literal {}", currentLiteral); - return BindingResult.empty(); - } - case STOP_BINDING: - LOGGER.trace("No substitutions found for literal {}", currentLiteral); - return BindingResult.empty(); - default: - throw Util.oops("Unhandled literal instantiation result type: " + instantiationResult.getType()); - } - } - - @Override - public Pair, Map> getChoiceAtoms() { - return choiceRecorder.getAndResetChoices(); - } - - @Override - public Map> getHeadsToBodies() { - return choiceRecorder.getAndResetHeadsToBodies(); - } - - @Override - public void updateAssignment(IntIterator it) { - while (it.hasNext()) { - workingMemory.addInstance(atomStore.get(it.next()), true); - } - } - - @Override - public void forgetAssignment(int[] atomIds) { - throw new UnsupportedOperationException("Forgetting assignments is not implemented"); - } - - @Override - public InternalRule getNonGroundRule(Integer ruleId) { - return knownNonGroundRules.get(ruleId); - } - - @Override - public boolean isFact(CoreAtom atom) { - LinkedHashSet instances = factsFromProgram.get(atom.getPredicate()); - if (instances == null) { - return false; - } - return instances.contains(new Instance(atom.getTerms())); - } - - @Override - public Set justifyAtom(int atomToJustify, Assignment currentAssignment) { - Set literals = analyzeUnjustified.analyze(atomToJustify, currentAssignment); - // Remove facts from justification before handing it over to the solver. - for (Iterator iterator = literals.iterator(); iterator.hasNext(); ) { - CoreLiteral literal = iterator.next(); - if (literal.isNegated()) { - continue; - } - LinkedHashSet factsOverPredicate = factsFromProgram.get(literal.getPredicate()); - if (factsOverPredicate != null && factsOverPredicate.contains(new Instance(literal.getAtom().getTerms()))) { - iterator.remove(); - } - } - return literals; - } - - /** - * Checks that every nogood not marked as {@link NoGoodInterface.Type#INTERNAL} contains only - * atoms which are not {@link CorePredicate#isSolverInternal()} (except {@link RuleAtom}s, which are allowed). - * - * @param newNoGoods - */ - private void checkTypesOfNoGoods(Collection newNoGoods) { - for (NoGood noGood : newNoGoods) { - if (noGood.getType() != NoGoodInterface.Type.INTERNAL) { - for (int literal : noGood) { - CoreAtom atom = atomStore.get(atomOf(literal)); - if (atom.getPredicate().isSolverInternal() && !(atom instanceof RuleAtom)) { - throw oops("NoGood containing atom of internal predicate " + atom + " is " + noGood.getType() + " instead of INTERNAL"); - } - } - } - } - } - - private static class FirstBindingAtom { - final InternalRule rule; - final CoreLiteral startingLiteral; - - FirstBindingAtom(InternalRule rule, CoreLiteral startingLiteral) { - this.rule = rule; - this.startingLiteral = startingLiteral; - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java deleted file mode 100644 index 69996e2e6..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGenerator.java +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.grounder; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.negateLiteral; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; - -/** - * Class to generate ground NoGoods out of non-ground rules and grounding substitutions. - * Copyright (c) 2017-2018, the Alpha Team. - */ -public class NoGoodGenerator { - private final AtomStore atomStore; - private final ChoiceRecorder choiceRecorder; - private final Map> factsFromProgram; - private final InternalProgram programAnalysis; - private final Set uniqueGroundRulePerGroundHead; - - NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { - this.atomStore = atomStore; - this.choiceRecorder = recorder; - this.factsFromProgram = factsFromProgram; - this.programAnalysis = programAnalysis; - this.uniqueGroundRulePerGroundHead = uniqueGroundRulePerGroundHead; - } - - /** - * Generates all NoGoods resulting from a non-ground rule and a variable substitution. - * - * @param nonGroundRule - * the non-ground rule. - * @param substitution - * the grounding substitution, i.e., applying substitution to nonGroundRule results in a ground rule. - * Assumption: atoms with fixed interpretation evaluate to true under the substitution. - * @return a list of the NoGoods corresponding to the ground rule. - */ - List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundRule, final Substitution substitution) { - final List posLiterals = collectPosLiterals(nonGroundRule, substitution); - final List negLiterals = collectNegLiterals(nonGroundRule, substitution); - - if (posLiterals == null || negLiterals == null) { - return emptyList(); - } - - // A constraint is represented by exactly one nogood. - if (nonGroundRule.isConstraint()) { - return singletonList(NoGood.fromConstraint(posLiterals, negLiterals)); - } - - final List result = new ArrayList<>(); - - final CoreAtom groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); - final int headId = atomStore.putIfAbsent(groundHeadAtom); - - // Prepare atom representing the rule body. - final RuleAtom bodyAtom = new RuleAtom(nonGroundRule, substitution); - - // Check uniqueness of ground rule by testing whether the - // body representing atom already has an id. - if (atomStore.contains(bodyAtom)) { - // The current ground instance already exists, - // therefore all nogoods have already been created. - return emptyList(); - } - - final int bodyRepresentingLiteral = atomToLiteral(atomStore.putIfAbsent(bodyAtom)); - final int headLiteral = atomToLiteral(atomStore.putIfAbsent(nonGroundRule.getHeadAtom().substitute(substitution))); - - choiceRecorder.addHeadToBody(headId, atomOf(bodyRepresentingLiteral)); - - // Create a nogood for the head. - result.add(NoGood.headFirst(negateLiteral(headLiteral), bodyRepresentingLiteral)); - - final NoGood ruleBody = NoGood.fromBody(posLiterals, negLiterals, bodyRepresentingLiteral); - result.add(ruleBody); - - // Nogoods such that the atom representing the body is true iff the body is true. - for (int j = 1; j < ruleBody.size(); j++) { - result.add(new NoGood(bodyRepresentingLiteral, negateLiteral(ruleBody.getLiteral(j)))); - } - - // If the rule head is unique, add support. - if (uniqueGroundRulePerGroundHead.contains(nonGroundRule)) { - result.add(NoGood.support(headLiteral, bodyRepresentingLiteral)); - } - - // If the body of the rule contains negation, add choices. - if (!negLiterals.isEmpty()) { - result.addAll(choiceRecorder.generateChoiceNoGoods(posLiterals, negLiterals, bodyRepresentingLiteral)); - } - - return result; - } - - List collectNegLiterals(final InternalRule nonGroundRule, final Substitution substitution) { - final List bodyLiteralsNegative = new ArrayList<>(); - for (CoreLiteral lit : nonGroundRule.getNegativeBody()) { - CoreAtom groundAtom = lit.getAtom().substitute(substitution); - - final Set factInstances = factsFromProgram.get(groundAtom.getPredicate()); - - if (factInstances != null && factInstances.contains(new Instance(groundAtom.getTerms()))) { - // Negative atom that is always true encountered, skip whole rule as it will never fire. - return null; - } - - if (!existsRuleWithPredicateInHead(groundAtom.getPredicate())) { - // Negative atom is no fact and no rule defines it, it is always false, skip it. - continue; - } - - bodyLiteralsNegative.add(atomToLiteral(atomStore.putIfAbsent(groundAtom))); - } - return bodyLiteralsNegative; - } - - private List collectPosLiterals(final InternalRule nonGroundRule, final Substitution substitution) { - final List bodyLiteralsPositive = new ArrayList<>(); - for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { - if (lit instanceof FixedInterpretationLiteral) { - // TODO: conversion of atom to literal is ugly. NonGroundRule could manage atoms instead of literals, cf. FIXME there - // Atom has fixed interpretation, hence was checked earlier that it - // evaluates to true under the given substitution. - // FixedInterpretationAtoms need not be shown to the solver, skip it. - continue; - } - final CoreAtom atom = lit.getAtom(); - // Skip the special enumeration atom. - if (atom instanceof EnumerationAtom) { - continue; - } - - final CoreAtom groundAtom = atom.substitute(substitution); - - // Consider facts to eliminate ground atoms from the generated nogoods that are always true - // and eliminate nogoods that are always satisfied due to facts. - Set factInstances = factsFromProgram.get(groundAtom.getPredicate()); - if (factInstances != null && factInstances.contains(new Instance(groundAtom.getTerms()))) { - // Skip positive atoms that are always true. - continue; - } - - if (!existsRuleWithPredicateInHead(groundAtom.getPredicate())) { - // Atom is no fact and no rule defines it, it cannot be derived (i.e., is always false), skip whole rule as it will never fire. - return null; - } - - bodyLiteralsPositive.add(atomToLiteral(atomStore.putIfAbsent(groundAtom))); - } - return bodyLiteralsPositive; - } - - private boolean existsRuleWithPredicateInHead(final CorePredicate predicate) { - final HashSet definingRules = programAnalysis.getPredicateDefiningRules().get(predicate); - return definingRules != null && !definingRules.isEmpty(); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java deleted file mode 100644 index 43fdd9fce..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/NogoodRegistry.java +++ /dev/null @@ -1,44 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import at.ac.tuwien.kr.alpha.common.NoGood; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class NogoodRegistry { - private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); - - private Map registeredIdentifiers = new LinkedHashMap<>(); - - /** - * Helper methods to analyze average nogood length. - * @return - */ - public float computeAverageNoGoodLength() { - int totalSizes = 0; - for (Map.Entry noGoodEntry : registeredIdentifiers.entrySet()) { - totalSizes += noGoodEntry.getKey().size(); - } - return ((float) totalSizes) / registeredIdentifiers.size(); - } - - void register(Iterable noGoods, Map difference) { - for (NoGood noGood : noGoods) { - // Check if noGood was already derived earlier, add if it is new - if (!registeredIdentifiers.containsKey(noGood)) { - int noGoodId = ID_GENERATOR.getNextId(); - registeredIdentifiers.put(noGood, noGoodId); - difference.put(noGoodId, noGood); - } - } - } - - int register(NoGood noGood) { - if (!registeredIdentifiers.containsKey(noGood)) { - int noGoodId = ID_GENERATOR.getNextId(); - registeredIdentifiers.put(noGood, noGoodId); - return noGoodId; - } - return registeredIdentifiers.get(noGood); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java deleted file mode 100644 index ec99f727d..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/ProgramAnalyzingGrounder.java +++ /dev/null @@ -1,36 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; - -/** - * Copyright (c) 2017, the Alpha Team. - */ -public interface ProgramAnalyzingGrounder extends Grounder { - - /** - * Justifies the absence of an atom, i.e., returns reasons why the atom is not TRUE given the assignment. - * @param atomToJustify the atom to justify. - * @param currentAssignment the current assignment. - * @return a set of literals who jointly imply the atomToJustify not being TRUE. - */ - Set justifyAtom(int atomToJustify, Assignment currentAssignment); - - /** - * Returns true iff the given atom is known to the grounder as a fact (hence not occurring in any assignment). - * @param atom the atom. - * @return true iff atom is a fact. - */ - boolean isFact(CoreAtom atom); - - /** - * Returns the NonGroundRule identified by the given id. - * @param ruleId the id of the rule. - * @return the corresponding NonGroundRule. - */ - InternalRule getNonGroundRule(Integer ruleId); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java deleted file mode 100644 index a3a7c16d7..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrder.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright (c) 2019 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.grounder; - -import java.util.ArrayList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; - -/** - * A grounding order computed by {@link RuleGroundingOrders} for a specific {@link InternalRule} and a specific starting literal. - */ -public class RuleGroundingOrder { - - private CoreLiteral startingLiteral; - private List otherLiterals; - private int positionLastVarBound; - private int stopBindingAtOrderPosition; - private final boolean ground; - - RuleGroundingOrder(CoreLiteral startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { - super(); - this.startingLiteral = startingLiteral; - this.otherLiterals = otherLiterals; - this.positionLastVarBound = positionLastVarBound; - this.stopBindingAtOrderPosition = otherLiterals.size(); - this.ground = isGround; - } - - private RuleGroundingOrder(RuleGroundingOrder otherRuleGroundingOrder) { - this(otherRuleGroundingOrder.startingLiteral, new ArrayList<>(otherRuleGroundingOrder.otherLiterals), otherRuleGroundingOrder.positionLastVarBound, otherRuleGroundingOrder.ground); - this.stopBindingAtOrderPosition = otherRuleGroundingOrder.stopBindingAtOrderPosition; - } - - /** - * Returns the literal at the given position in the grounding order, - * except it is already known that this literal is not able to yield new bindings. - * - * A literal cannot yield new bindings if it has been copied to the end of the grounding order - * when no bindings could be found, and no bindings for other literals could be found in the meantime. - * - * @param orderPosition zero-based index into list of literals except the starting literal - * @return the literal at the given position, or {@code null} if it is already known that this literal is not able to yield new bindings - */ - public CoreLiteral getLiteralAtOrderPosition(int orderPosition) { - if (orderPosition >= stopBindingAtOrderPosition) { - return null; - } - return otherLiterals.get(orderPosition); - } - - /** - * @return the zero-based position from which on all variables are bound in list of literals except the starting literal - */ - public int getPositionFromWhichAllVarsAreBound() { - return positionLastVarBound + 1; - } - - public boolean isGround() { - return ground; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(startingLiteral); - sb.append(" : "); - for (int i = 0; i < otherLiterals.size(); i++) { - if (i == positionLastVarBound + 1) { - sb.append("| "); - } - sb.append(otherLiterals.get(i)); - if (i < otherLiterals.size() - 1) { - sb.append(", "); - } - } - - return sb.toString(); - } - - /** - * "Pushes a literal back" in a grounding order because the literal cannot be used to generate substitutions now but - * maybe later. Pushing back means adding the literal again at the end of the grounding order. Since the literal will - * occur twice in the new grounding order returned by this method, we assume that the grounding order is processed - * from left to right and the literal at {@code orderPosition} will not be considered again. - * - * @param orderPosition the position in the grounding order of the literal to be pushed back. - * @return a new grounding order in which the atom is pushed back, - * or {@code null} if the position of the grounding order after which no new bindings can be found has been reached. - */ - public RuleGroundingOrder pushBack(int orderPosition) { - if (orderPosition >= stopBindingAtOrderPosition - 1) { - return null; - } - RuleGroundingOrder reorderedGroundingOrder = new RuleGroundingOrder(this); - reorderedGroundingOrder.otherLiterals.add(otherLiterals.get(orderPosition)); - return reorderedGroundingOrder; - } - - public void considerUntilCurrentEnd() { - this.stopBindingAtOrderPosition = this.otherLiterals.size(); - } - - public CoreLiteral getStartingLiteral() { - return this.startingLiteral; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java deleted file mode 100644 index a3e022aa3..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrders.java +++ /dev/null @@ -1,229 +0,0 @@ -/** - * 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 - * 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.grounder; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; - -/** - * Provides the grounder with information on the order to ground the literals in the body of a rule. - * Grounding starts with some starting literal (i.e., one that does not require any variables to be bound already) and - * then may join this with any other literal that requires no other variables to be bound other than those already bound - * by the first literal. This class is prepared to take join-selectivities into account for finding a good grounding - * order. - * - * Since the grounder must yield all ground instantiations of rules whose positive body is true in the current assignment, - * a starting literals is a positive BasicAtom and the grounder can wait until after some instance in the working memory - * of the corresponding predicate arrives and only then start grounding. - * - * There is also the case that a rule has no ordinary positive literals (i.e., no positive BasicAtom) but is still safe. - * Such a rule has no starting literal but those rules have a fixed number of ground instantiations and they can be - * computed similar to facts at the beginning of the computation. - * - * Note that rules with self-joins (rules with p(X,Y), p(A,B) in their body) make it necessary that every positive - * literal (whose interpretation is not fixed) is a starting literal, at least for the current grounding procedure. - */ -public class RuleGroundingOrders { - private final InternalRule internalRule; - HashMap groundingOrders; - private HashMap literalSelectivity; - private List startingLiterals; - - private final boolean fixedGroundingInstantiation; - private RuleGroundingOrder fixedGroundingOrder; - - public RuleGroundingOrders(InternalRule internalRule) { - this.internalRule = internalRule; - this.literalSelectivity = new HashMap<>(); - resetLiteralSelectivity(); - this.groundingOrders = new HashMap<>(); - this.fixedGroundingInstantiation = computeStartingLiterals(); - } - - private void resetLiteralSelectivity() { - // Set selectivity of all literals to 1.0f. - for (CoreLiteral literal : internalRule.getBody()) { - literalSelectivity.put(literal, 1.0f); - } - } - - /** - * Computes starting literals and indicates whether there is a fixed ground instantiation for this rule. - * @return true iff the rule has a fixed ground instantiation. - */ - private boolean computeStartingLiterals() { - LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); - LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); - - // If the rule is ground, every body literal is a starting literal and the ground instantiation is fixed. - if (internalRule.isGround()) { - startingLiterals = new LinkedList<>(internalRule.getBody()); - return true; - } - - // Check each literal in the rule body whether it is eligible. - for (CoreLiteral literal : internalRule.getBody()) { - // Only literals that need no variables already bound can start grounding. - if (literal.getNonBindingVariables().size() != 0) { - continue; - } - - if (literal.getAtom() instanceof BasicAtom && !literal.isNegated()) { - // Positive BasicAtom is the main/ordinary case. - ordinaryStartingLiterals.add(literal); - } else { - // If literal is no positive BasicAtom but requires no bound variables, - // it can be the starting literal for some (fixed) instantiation. - fixedStartingLiterals.add(literal); - } - } - // If there are no positive BasicAtoms, the rule only contains fixed ground - // instantiation literals and those are starting for the one-time grounding. - if (!ordinaryStartingLiterals.isEmpty()) { - startingLiterals = new LinkedList<>(ordinaryStartingLiterals); - return false; - } else if (!fixedStartingLiterals.isEmpty()) { - startingLiterals = new LinkedList<>(fixedStartingLiterals); - return true; - } else { - throw new RuntimeException("Unsafe rule encountered: " + internalRule); - } - } - - public List getStartingLiterals() { - return Collections.unmodifiableList(startingLiterals); - } - - public void updateLiteralSelectivity(CoreLiteral literal, int numGivenTuples, int numObtainedTuples) { - // TODO: add old selectivity (with a decay factor) and new selectivity. - } - - public RuleGroundingOrder orderStartingFrom(CoreLiteral startingLiteral) { - return groundingOrders.get(startingLiteral); - } - - - public RuleGroundingOrder getFixedGroundingOrder() { - return fixedGroundingOrder; - } - - /** - * States whether the rule is without positive ordinary atoms, as for example in: p(Y) :- X = 1..3, not q(X), Y = X + 2, &ext[X,Y](). - * @return true if the rule has a (limited number of) fixed grounding instantiation(s). - */ - public boolean fixedInstantiation() { - return fixedGroundingInstantiation; - } - - public void computeGroundingOrders() { - if (fixedGroundingInstantiation) { - // Fixed grounding is only evaluated once and not depending on a starting variable, just use the first. - computeGroundingOrder(startingLiterals.get(0)); - return; - } - // Compute grounding orders for all positive BasicAtoms. - for (CoreLiteral literal : startingLiterals) { - computeGroundingOrder(literal); - } - } - - private void computeGroundingOrder(CoreLiteral startingLiteral) { - Set bodyLiterals = internalRule.getBody(); - HashSet boundVariables = new HashSet<>(); - boundVariables.addAll(startingLiteral.getBindingVariables()); - LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); - remainingLiterals.remove(startingLiteral); - ArrayList literalsOrder; - if (fixedGroundingInstantiation) { - literalsOrder = new ArrayList<>(bodyLiterals.size()); - literalsOrder.add(startingLiteral); - } else { - literalsOrder = new ArrayList<>(bodyLiterals.size() - 1); - } - - int position = 0; - int positionLastVarBound = -1; - while (!remainingLiterals.isEmpty()) { - CoreLiteral nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); - if (nextGroundingLiteral == null) { - throw new RuntimeException("Could not find a grounding order for rule " + internalRule + " with starting literal: " + startingLiteral + ". Rule is not safe."); - } - remainingLiterals.remove(nextGroundingLiteral); - boolean boundNewVars = boundVariables.addAll(nextGroundingLiteral.getBindingVariables()); - if (boundNewVars) { - positionLastVarBound = position; - } - literalsOrder.add(nextGroundingLiteral); - position++; - } - if (fixedGroundingInstantiation) { - fixedGroundingOrder = new RuleGroundingOrder(null, literalsOrder, positionLastVarBound, internalRule.isGround()); - } - groundingOrders.put(startingLiteral, new RuleGroundingOrder(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); - } - - private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { - Float bestSelectivity = Float.MAX_VALUE; - CoreLiteral bestLiteral = null; - boolean bestLiteralSharesVariables = false; - // Find the best literal whose nonbinding variables are already bound and whose selectivity is highest. - // To avoid cross products, select those first that have some of their variables already bound. - for (CoreLiteral literal : remainingLiterals) { - if (!boundVariables.containsAll(literal.getNonBindingVariables())) { - // Only consider literals whose nonbinding variables are already bound. - continue; - } - Float selectivity = literalSelectivity.get(literal); - boolean sharesVariables = sharesVariables(boundVariables, literal.getBindingVariables(), literal.getNonBindingVariables()); - if (bestLiteral == null - || sharesVariables && selectivity < bestSelectivity - || sharesVariables && !bestLiteralSharesVariables) { - bestLiteral = literal; - bestSelectivity = selectivity; - bestLiteralSharesVariables = sharesVariables; - } - } - return bestLiteral; - } - - private boolean sharesVariables(Collection set1, Collection set2part1, Collection set2part2) { - return !Collections.disjoint(set1, set2part1) || !Collections.disjoint(set1, set2part2); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java deleted file mode 100644 index 7cc35a992..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Substitution.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2016-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.grounder; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.TreeMap; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; - -public class Substitution { - - private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); - public static final Substitution EMPTY_SUBSTITUTION = new Substitution() { - @Override - public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { - throw oops("Should not be called on EMPTY_SUBSTITUTION"); - } - }; - - protected TreeMap substitution; - - private Substitution(TreeMap substitution) { - if (substitution == null) { - throw oops("Substitution is null."); - } - this.substitution = substitution; - } - - public Substitution() { - this(new TreeMap<>()); - } - - public Substitution(Substitution clone) { - this(new TreeMap<>(clone.substitution)); - } - - public static Substitution specializeSubstitution(CoreLiteral literal, Instance instance, Substitution substitution) { - return specializeSubstitution(literal.getAtom(), instance, substitution); - } - - /** - * Helper class to lazily clone the input substitution of Substitution.specializeSubstitution only when needed. - */ - private static class SpecializationHelper { - Substitution updatedSubstitution; // Is null for as long as the given partial substitution is not extended, afterwards holds the updated/extended/specialized substitution. - - Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { - for (int i = 0; i < termList.size(); i++) { - if (!unifyTerms(termList.get(i), instance.terms.get(i), partialSubstitution)) { - return null; - } - } - if (updatedSubstitution == null) { - // All terms unify but there was no need to assign a new variable, return the input substitution. - return partialSubstitution; - } - return updatedSubstitution; - } - - boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution partialSubstitution) { - if (termNonGround == termGround) { - // Both terms are either the same constant or the same variable term - return true; - } else if (termNonGround instanceof ConstantTerm) { - // Since right term is ground, both terms differ - return false; - } else if (termNonGround instanceof VariableTerm) { - VariableTerm variableTerm = (VariableTerm) termNonGround; - // Left term is variable, bind it to the right term. Use original substitution if it has - // not been cloned yet. - CoreTerm bound = (updatedSubstitution == null ? partialSubstitution : updatedSubstitution).eval(variableTerm); // Get variable binding, either from input substitution if it has not been updated yet, or from the cloned/updated substitution. - if (bound != null) { - // Variable is already bound, return true if binding is the same as the current ground term. - return termGround == bound; - } - // Record new variable binding. - if (updatedSubstitution == null) { - // Clone substitution if it was not yet updated. - updatedSubstitution = new Substitution(partialSubstitution); - } - updatedSubstitution.put(variableTerm, termGround); - return true; - } else if (termNonGround instanceof FunctionTerm && termGround instanceof FunctionTerm) { - // Both terms are function terms - FunctionTerm ftNonGround = (FunctionTerm) termNonGround; - FunctionTerm ftGround = (FunctionTerm) termGround; - - if (!(ftNonGround.getSymbol().equals(ftGround.getSymbol()))) { - return false; - } - if (ftNonGround.getTerms().size() != ftGround.getTerms().size()) { - return false; - } - - // Iterate over all subterms of both function terms - for (int i = 0; i < ftNonGround.getTerms().size(); i++) { - if (!unifyTerms(ftNonGround.getTerms().get(i), ftGround.getTerms().get(i), partialSubstitution)) { - return false; - } - } - - return true; - } - return false; - } - } - - /** - * Specializes a given substitution such that applying the specialized substitution on the given atom yields the - * given instance (if such a specialized substitution exists). Computes the unifier of the (nonground) atom and - * the given ground instance such that the unifier is an extension of the given partial substitution. If - * specialization succeeds the unifying substitution is returned, if no such unifier exists null is returned. In - * any case the partial substitution is left unchanged. - * - * @param atom the (potentially nonground) atom to unify. - * @param instance the ground instance to unify the atom with. - * @param substitution the (partial) substitution for the atom. This is left unchanged in all cases. - * @return null if the unification/specialization fails, otherwise it is a unifying substitution. If the - * parameter substitution already is a unifier, it is returned. If the unifying substitution is an - * extension of the input substitution, a new substitution will be returned. - */ - public static Substitution specializeSubstitution(CoreAtom atom, Instance instance, Substitution substitution) { - return new SpecializationHelper().unify(atom.getTerms(), instance, substitution); - } - - /** - * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTerm} under this substitution. - * - * @param variableTerm the variable term to substitute, if possible - * @return a constant term if the substitution contains the given variable, {@code null} otherwise. - */ - public CoreTerm eval(VariableTerm variableTerm) { - return this.substitution.get(variableTerm); - } - - public > CoreTerm put(VariableTerm variableTerm, CoreTerm groundTerm) { - if (!groundTerm.isGround()) { - throw oops("Right-hand term is not ground."); - } - CoreTerm alreadyAssigned = substitution.get(variableTerm); - if (alreadyAssigned != null && alreadyAssigned != groundTerm) { - throw oops("Variable is already assigned to another term."); - } - // Note: We're destroying type information here. - return substitution.put(variableTerm, groundTerm); - } - - public boolean isEmpty() { - return substitution.isEmpty(); - } - - public boolean isVariableSet(VariableTerm variable) { - return substitution.get(variable) != null; - } - - public Set getMappedVariables() { - return substitution.keySet(); - } - - /** - * Prints the variable substitution in a uniform way (sorted by variable names). - * - * @return - */ - @Override - public String toString() { - final StringBuilder ret = new StringBuilder("{"); - boolean isFirst = true; - for (Map.Entry e : substitution.entrySet()) { - if (isFirst) { - isFirst = false; - } else { - ret.append(","); - } - ret.append(e.getKey()).append("->").append(e.getValue()); - } - ret.append("}"); - return ret.toString(); - } - - public static Substitution fromString(String substitution) { - String bare = substitution.substring(1, substitution.length() - 1); - String[] assignments = bare.split(","); - Substitution ret = new Substitution(); - for (String assignment : assignments) { - String[] keyVal = assignment.split("->"); - VariableTerm variable = VariableTerm.getInstance(keyVal[0]); - CoreTerm assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); - ret.put(variable, assignedTerm); - } - return ret; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Substitution that = (Substitution) o; - - return Objects.equals(substitution, that.substitution); - } - - @Override - public int hashCode() { - return substitution != null ? substitution.hashCode() : 0; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java deleted file mode 100644 index a188d7adf..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unification.java +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.grounder; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; - -import java.util.Set; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -/** - * Copyright (c) 2017, the Alpha Team. - */ -public class Unification { - - public static Unifier unifyAtoms(CoreAtom left, CoreAtom right) { - return unifyAtoms(left, right, false); - } - - /** - * Instantiates the general Atom to match the specific one and returns the corresponding substitution. - * @param general the general Atom to instantiate. - * @param specific the specific Atom. - * @return a Unifier sigma such that specific == general.substitute(sigma), returns null if no such sigma exists. - */ - public static Unifier instantiate(CoreAtom general, CoreAtom specific) { - return unifyAtoms(specific, general, true); - } - - private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLeftAsIs) { - Set leftOccurringVariables = left.getOccurringVariables(); - Set rightOccurringVaribles = right.getOccurringVariables(); - boolean leftSmaller = leftOccurringVariables.size() < rightOccurringVaribles.size(); - Set smallerSet = leftSmaller ? leftOccurringVariables : rightOccurringVaribles; - Set largerSet = leftSmaller ? rightOccurringVaribles : leftOccurringVariables; - for (VariableTerm variableTerm : smallerSet) { - if (largerSet.contains(variableTerm)) { - throw oops("Left and right atom share variables."); - } - } - Unifier mgu = new Unifier(); - if (!left.getPredicate().equals(right.getPredicate())) { - return null; - } - for (int i = 0; i < left.getPredicate().getArity(); i++) { - final CoreTerm leftTerm = left.getTerms().get(i); - final CoreTerm rightTerm = right.getTerms().get(i); - if (!unifyTerms(leftTerm, rightTerm, mgu, keepLeftAsIs)) { - return null; - } - } - return mgu; - } - - private static boolean unifyTerms(CoreTerm left, CoreTerm right, Unifier currentSubstitution, boolean keepLeftAsIs) { - final CoreTerm leftSubs = left.substitute(currentSubstitution); - final CoreTerm rightSubs = right.substitute(currentSubstitution); - if (leftSubs == rightSubs) { - return true; - } - if (!keepLeftAsIs && leftSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) leftSubs)) { - currentSubstitution.put((VariableTerm) leftSubs, rightSubs); - return true; - } - if (rightSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) rightSubs)) { - currentSubstitution.put((VariableTerm) rightSubs, leftSubs); - return true; - } - if (leftSubs instanceof FunctionTerm && rightSubs instanceof FunctionTerm) { - final FunctionTerm leftFunction = (FunctionTerm) leftSubs; - final FunctionTerm rightFunction = (FunctionTerm) rightSubs; - if (!leftFunction.getSymbol().equals(rightFunction.getSymbol()) - || leftFunction.getTerms().size() != rightFunction.getTerms().size()) { - return false; - } - for (int i = 0; i < leftFunction.getTerms().size(); i++) { - final CoreTerm leftTerm = leftFunction.getTerms().get(i); - final CoreTerm rightTerm = rightFunction.getTerms().get(i); - if (!unifyTerms(leftTerm, rightTerm, currentSubstitution, keepLeftAsIs)) { - return false; - } - } - return true; - } - return false; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java deleted file mode 100644 index 92a3df759..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/Unifier.java +++ /dev/null @@ -1,134 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; - -/** - * A variable substitution allowing variables to occur on the right-hand side. Chains of variable substitutions are - * resolved automatically, i.e., adding the substitutions (X -> A) and (A -> d) results in (X -> d), (A -> d). - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class Unifier extends Substitution { - - private final TreeMap> rightHandVariableOccurrences; - - private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { - if (substitution == null) { - throw oops("Substitution is null."); - } - this.substitution = substitution; - this.rightHandVariableOccurrences = rightHandVariableOccurrences; - } - - public Unifier() { - this(new TreeMap<>(), new TreeMap<>()); - } - - public Unifier(Unifier clone) { - this(new TreeMap<>(clone.substitution), new TreeMap<>(clone.rightHandVariableOccurrences)); - } - - public Unifier(Substitution clone) { - this(new TreeMap<>(clone.substitution), new TreeMap<>()); - } - - - public Unifier extendWith(Substitution extension) { - for (Map.Entry extensionVariable : extension.substitution.entrySet()) { - this.put(extensionVariable.getKey(), extensionVariable.getValue()); - } - return this; - } - - /** - * Returns a list of all variables occurring in that unifier, i.e., variables that are mapped and those that occur (nested) in the right-hand side of the unifier. - * @return the list of variables occurring somewhere in the unifier. - */ - @Override - public Set getMappedVariables() { - Set ret = new HashSet<>(); - for (Map.Entry substitution : substitution.entrySet()) { - ret.add(substitution.getKey()); - ret.addAll(substitution.getValue().getOccurringVariables()); - } - return ret; - } - - - @Override - public > CoreTerm put(VariableTerm variableTerm, CoreTerm term) { - // If term is not ground, store it for right-hand side reverse-lookup. - if (!term.isGround()) { - for (VariableTerm rightHandVariable : term.getOccurringVariables()) { - rightHandVariableOccurrences.putIfAbsent(rightHandVariable, new ArrayList<>()); - rightHandVariableOccurrences.get(rightHandVariable).add(variableTerm); - } - } - // Note: We're destroying type information here. - CoreTerm ret = substitution.put(variableTerm, term); - - // Check if the just-assigned variable occurs somewhere in the right-hand side already. - List rightHandOccurrences = rightHandVariableOccurrences.get(variableTerm); - if (rightHandOccurrences != null) { - // Replace all occurrences on the right-hand side with the just-assigned term. - for (VariableTerm rightHandOccurrence : rightHandOccurrences) { - // Substitute the right hand where this assigned variable occurs with the new value and store it. - CoreTerm previousRightHand = substitution.get(rightHandOccurrence); - if (previousRightHand == null) { - // Variable does not occur on the lef-hand side, skip. - continue; - } - substitution.put(rightHandOccurrence, previousRightHand.substitute(this)); - } - } - - return ret; - } - - /** - * Merge substitution right into left as used in the AnalyzeUnjustified. - * Left mappings are seen as equalities, i.e., - * if left has A -> B and right has A -> t then the result will have A -> t and B -> t. - * If both substitutions are inconsistent, i.e., A -> t1 in left and A -> t2 in right, then null is returned. - * @param left - * @param right - * @return - */ - public static Unifier mergeIntoLeft(Unifier left, Unifier right) { - // Note: we assume both substitutions are free of chains, i.e., no A->B, B->C but A->C, B->C. - Unifier ret = new Unifier(left); - for (Map.Entry mapping : right.substitution.entrySet()) { - VariableTerm variable = mapping.getKey(); - CoreTerm term = mapping.getValue(); - // If variable is unset, simply add. - if (!ret.isVariableSet(variable)) { - ret.put(variable, term); - continue; - } - // Variable is already set. - CoreTerm setTerm = ret.eval(variable); - if (setTerm instanceof VariableTerm) { - // Variable maps to another variable in left. - // Add a new mapping of the setTerm variable into our right-assigned term. - ret.put((VariableTerm) setTerm, term); - // Note: Unifier.put takes care of resolving the chain variable->setTerm->term. - continue; - } - // Check for inconsistency. - if (setTerm != term) { - return null; - } - // Now setTerm equals term, no action needed. - } - return ret; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java deleted file mode 100644 index b5ba106f2..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/WorkingMemory.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.grounder; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.apache.commons.lang3.tuple.ImmutablePair; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; - -public class WorkingMemory { - protected HashMap> workingMemory = new HashMap<>(); - private HashSet modifiedWorkingMemories = new LinkedHashSet<>(); - - public boolean contains(CorePredicate predicate) { - return workingMemory.containsKey(predicate); - } - - public void initialize(CorePredicate predicate) { - if (workingMemory.containsKey(predicate)) { - return; - } - - IndexedInstanceStorage pos = new IndexedInstanceStorage(predicate, true); - IndexedInstanceStorage neg = new IndexedInstanceStorage(predicate, false); - // Index all positions of the storage (may impair efficiency) - for (int i = 0; i < predicate.getArity(); i++) { - pos.addIndexPosition(i); - neg.addIndexPosition(i); - } - - workingMemory.put(predicate, new ImmutablePair<>(pos, neg)); - } - - public IndexedInstanceStorage get(CoreLiteral literal) { - return get(literal.getAtom(), !literal.isNegated()); - } - - public IndexedInstanceStorage get(CoreAtom atom, boolean value) { - return get(atom.getPredicate(), value); - } - - public IndexedInstanceStorage get(CorePredicate predicate, boolean value) { - ImmutablePair pair = workingMemory.get(predicate); - if (value) { - return pair.getLeft(); - } else { - return pair.getRight(); - } - } - - public void addInstance(CoreAtom atom, boolean value) { - addInstance(atom.getPredicate(), value, new Instance(atom.getTerms())); - } - - public void addInstance(CorePredicate predicate, boolean value, Instance instance) { - IndexedInstanceStorage storage = get(predicate, value); - - if (!storage.containsInstance(instance)) { - storage.addInstance(instance); - modifiedWorkingMemories.add(storage); - } - } - - public void addInstances(CorePredicate predicate, boolean value, Iterable instances) { - IndexedInstanceStorage storage = get(predicate, value); - - for (Instance instance : instances) { - if (!storage.containsInstance(instance)) { - storage.addInstance(instance); - modifiedWorkingMemories.add(storage); - } - } - } - - public void reset() { - modifiedWorkingMemories = new LinkedHashSet<>(); - } - - public Set modified() { - return modifiedWorkingMemories; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java deleted file mode 100644 index 3ce4e494e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/ChoiceAtom.java +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.grounder.atoms; - -import static at.ac.tuwien.kr.alpha.Util.join; - -import java.util.Collections; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -public class ChoiceAtom extends CoreAtom { - - public static final CorePredicate ON = CorePredicate.getInstance("ChoiceOn", 1, true, true); - public static final CorePredicate OFF = CorePredicate.getInstance("ChoiceOff", 1, true, true); - - private final CorePredicate predicate; - private final List terms; - - private ChoiceAtom(CorePredicate predicate, CoreTerm term) { - this.predicate = predicate; - this.terms = Collections.singletonList(term); - } - - private ChoiceAtom(CorePredicate predicate, int id) { - this(predicate, CoreConstantTerm.getInstance(Integer.toString(id))); - } - - public static ChoiceAtom on(int id) { - return new ChoiceAtom(ON, id); - } - - public static ChoiceAtom off(int id) { - return new ChoiceAtom(OFF, id); - } - - @Override - public CorePredicate getPredicate() { - return predicate; - } - - @Override - public List getTerms() { - return terms; - } - - @Override - public boolean isGround() { - // NOTE: Term is a ConstantTerm, which is ground by definition. - return true; - } - - @Override - public CoreLiteral toLiteral(boolean negated) { - throw new UnsupportedOperationException("ChoiceAtom cannot be literalized"); - } - - @Override - public CoreAtom substitute(Substitution substitution) { - return this; - } - - @Override - public String toString() { - return join(predicate.getName() + "(", terms, ")"); - } - - @Override - public CoreAtom withTerms(List terms) { - throw new UnsupportedOperationException("Changing terms is not supported for ChoiceAtoms!"); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.predicate == null) ? 0 : this.predicate.hashCode()); - result = prime * result + ((this.terms == null) ? 0 : this.terms.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ChoiceAtom)) { - return false; - } - ChoiceAtom other = (ChoiceAtom) obj; - if (this.predicate == null) { - if (other.predicate != null) { - return false; - } - } else if (!this.predicate.equals(other.predicate)) { - return false; - } - if (this.terms == null) { - if (other.terms != null) { - return false; - } - } else if (!this.terms.equals(other.terms)) { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java deleted file mode 100644 index 80d310fad..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationAtom.java +++ /dev/null @@ -1,95 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.atoms; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.HashMap; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Represents a ground-instance enumeration atom of form: - * enum(enumId, groundTerm, sequenceNo). - * - * The semantics of this is: - * if enum(A,T1, N1) and enum(A,T2,N2) are both true and T1 != T2, then N1 != N2. - * Furthermore, If enum(A,T1,N1) is true with N1 > 0 then enum(A,T2,N1 - 1) is true for some T1 != T2 and - * both, T1 and T2, are ground instances the grounder encountered during the search so far. - * - * Copyright (c) 2017, the Alpha Team. - */ -public class EnumerationAtom extends BasicAtom { - public static final CorePredicate ENUMERATION_PREDICATE = CorePredicate.getInstance("_Enumeration", 3); - private static final HashMap> ENUMERATIONS = new HashMap<>(); - - public EnumerationAtom(List terms) { - super(ENUMERATION_PREDICATE, terms); - if (terms.size() != 3) { - throw new RuntimeException("EnumerationAtom must have arity three. Given terms are of wrong size: " + terms); - } - if (!(getTerms().get(2) instanceof VariableTerm)) { - throw new RuntimeException("Third parameter of EnumerationAtom must be a variable: " + terms); - } - } - - public static void resetEnumerations() { - ENUMERATIONS.clear(); - } - - private Integer getEnumerationIndex(CoreTerm identifier, CoreTerm enumerationTerm) { - ENUMERATIONS.putIfAbsent(identifier, new HashMap<>()); - HashMap enumeratedTerms = ENUMERATIONS.get(identifier); - Integer assignedInteger = enumeratedTerms.get(enumerationTerm); - if (assignedInteger == null) { - int enumerationIndex = enumeratedTerms.size() + 1; - enumeratedTerms.put(enumerationTerm, enumerationIndex); - return enumerationIndex; - } else { - return assignedInteger; - } - - } - - /** - * Based on a given substitution, substitutes the first two terms of this {@link EnumerationAtom} with the values from the substitution, - * and returns a new substitution with all mappings from the input substitution plus a binding for the third term of the enum atom to the - * integer index that is mapped to the first two terms in the internal ENUMERATIONS map. - * - * @param substitution an input substitution which must provide ground terms for the first two terms of the enumeration atom. - * @return a new substitution where the third term of the enumeration atom is bound to an integer. - */ - public Substitution addEnumerationIndexToSubstitution(Substitution substitution) { - CoreTerm idTerm = this.getTerms().get(0).substitute(substitution); - CoreTerm enumerationTerm = this.getTerms().get(1).substitute(substitution); - if (!enumerationTerm.isGround()) { - throw new RuntimeException("Enumeration term is not ground after substitution. Should not happen."); - } - Integer enumerationIndex = getEnumerationIndex(idTerm, enumerationTerm); - Substitution retVal = new Substitution(substitution); - retVal.put((VariableTerm) getTerms().get(2), CoreConstantTerm.getInstance(enumerationIndex)); - return retVal; - } - - @Override - public EnumerationAtom substitute(Substitution substitution) { - return new EnumerationAtom(super.substitute(substitution).getTerms()); - } - - @Override - public EnumerationLiteral toLiteral(boolean positive) { - if (!positive) { - throw oops("IntervalLiteral cannot be negated"); - } - return new EnumerationLiteral(this); - } - - @Override - public EnumerationLiteral toLiteral() { - return toLiteral(true); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java deleted file mode 100644 index 99c1735fd..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/EnumerationLiteral.java +++ /dev/null @@ -1,59 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.atoms; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Copyright (c) 2018, the Alpha Team. - */ -public class EnumerationLiteral extends BasicLiteral { - - public EnumerationLiteral(EnumerationAtom atom) { - super(atom, true); - } - - @Override - public EnumerationAtom getAtom() { - return (EnumerationAtom) super.getAtom(); - } - - @Override - public EnumerationLiteral negate() { - throw new UnsupportedOperationException("EnumerationLiteral cannot be negated"); - } - - @Override - public EnumerationLiteral substitute(Substitution substitution) { - return new EnumerationLiteral(getAtom().substitute(substitution)); - } - - @Override - public Set getBindingVariables() { - return Collections.singleton((VariableTerm)getTerms().get(2)); - } - - @Override - public Set getNonBindingVariables() { - Set ret = new HashSet<>(2); - CoreTerm idTerm = getTerms().get(0); - CoreTerm enumTerm = getTerms().get(1); - if (idTerm instanceof VariableTerm) { - ret.add((VariableTerm) idTerm); - } - if (enumTerm instanceof VariableTerm) { - ret.add((VariableTerm) enumTerm); - } - return ret; - - } - - public Substitution addEnumerationIndexToSubstitution(Substitution partialSubstitution) { - return this.getAtom().addEnumerationIndexToSubstitution(partialSubstitution); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java deleted file mode 100644 index 5d1b96580..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalAtom.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.grounder.atoms; - -import static at.ac.tuwien.kr.alpha.Util.join; -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.Arrays; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Helper for treating IntervalTerms in rules. - * - * Each IntervalTerm is replaced by a variable and this special IntervalAtom is added to the rule body for generating - * all bindings of the variable. - * - * The first term of this atom is an IntervalTerm while the second term is any Term (if it is a VariableTerm, this will - * bind to all elements of the interval, otherwise it is a simple check whether the Term is a ConstantTerm with - * the Integer being inside the interval. - * - * Copyright (c) 2017, the Alpha Team. - */ -public class IntervalAtom extends CoreAtom implements VariableNormalizableAtom { - private static final CorePredicate PREDICATE = CorePredicate.getInstance("_interval", 2, true); - - private final List terms; - - public IntervalAtom(IntervalTerm intervalTerm, CoreTerm intervalRepresentingVariable) { - this.terms = Arrays.asList(intervalTerm, intervalRepresentingVariable); - } - - @Override - public CorePredicate getPredicate() { - return PREDICATE; - } - - @Override - public List getTerms() { - return terms; - } - - @Override - public boolean isGround() { - for (CoreTerm t : this.terms) { - if (!t.isGround()) { - return false; - } - } - return true; - } - - @Override - public IntervalLiteral toLiteral(boolean positive) { - if (!positive) { - throw oops("IntervalLiteral cannot be negated"); - } - return new IntervalLiteral(this); - } - - @Override - public IntervalLiteral toLiteral() { - return toLiteral(true); - } - - @Override - public String toString() { - return join(PREDICATE.getName() + "(", terms, ")"); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - IntervalAtom that = (IntervalAtom) o; - - return terms.equals(that.terms); - } - - @Override - public int hashCode() { - return terms.hashCode(); - } - - @Override - public IntervalAtom substitute(Substitution substitution) { - return new IntervalAtom((IntervalTerm) terms.get(0).substitute(substitution), terms.get(1).substitute(substitution)); - } - - @Override - public IntervalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); - return new IntervalAtom((IntervalTerm) renamedTerms.get(0), renamedTerms.get(1)); - } - - @Override - public CoreAtom withTerms(List terms) { - throw new UnsupportedOperationException("IntervalAtoms do not support setting of terms!"); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java deleted file mode 100644 index 5b6505c5f..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/IntervalLiteral.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.grounder.atoms; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import com.google.common.collect.Sets; - -import at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * @see IntervalAtom - */ -public class IntervalLiteral extends FixedInterpretationLiteral { - - public IntervalLiteral(IntervalAtom atom) { - super(atom, true); - } - - @Override - public IntervalAtom getAtom() { - return (IntervalAtom) atom; - } - - @Override - public IntervalLiteral negate() { - throw new UnsupportedOperationException("IntervalLiteral cannot be negated"); - } - - private List getIntervalSubstitutions(Substitution partialSubstitution) { - List substitutions = new ArrayList<>(); - List terms = getTerms(); - CoreTerm intervalRepresentingVariable = terms.get(1); - IntervalTerm intervalTerm = (IntervalTerm) terms.get(0); - // Check whether intervalRepresentingVariable is bound already. - if (intervalRepresentingVariable instanceof VariableTerm) { - // Still a variable, generate all elements in the interval. - for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) { - Substitution ith = new Substitution(partialSubstitution); - ith.put((VariableTerm) intervalRepresentingVariable, CoreConstantTerm.getInstance(i)); - substitutions.add(ith); - } - return substitutions; - } else { - // The intervalRepresentingVariable is bound already, check if it is in the interval. - if (!(intervalRepresentingVariable instanceof ConstantTerm) - || !(((CoreConstantTerm) intervalRepresentingVariable).getObject() instanceof Integer)) { - // Term is not bound to an integer constant, not in the interval. - return Collections.emptyList(); - } - Integer integer = (Integer) ((CoreConstantTerm) intervalRepresentingVariable).getObject(); - if (intervalTerm.getLowerBound() <= integer && integer <= intervalTerm.getUpperBound()) { - return Collections.singletonList(partialSubstitution); - } - return Collections.emptyList(); - } - } - - @Override - public Set getBindingVariables() { - CoreTerm term = getTerms().get(1); - if (term instanceof VariableTerm) { - return Collections.singleton((VariableTerm) term); - } - return Collections.emptySet(); - } - - @Override - public Set getNonBindingVariables() { - return Sets.newHashSet(getTerms().get(0).getOccurringVariables()); - } - - @Override - public List getSatisfyingSubstitutions(Substitution partialSubstitution) { - // Substitute variables occurring in the interval itself. - IntervalLiteral groundInterval = substitute(partialSubstitution); - // Generate all substitutions for the interval representing variable. - return groundInterval.getIntervalSubstitutions(partialSubstitution); - } - - @Override - public IntervalLiteral substitute(Substitution substitution) { - return new IntervalLiteral(getAtom().substitute(substitution)); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java deleted file mode 100644 index cbe2f5a66..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/atoms/RuleAtom.java +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.grounder.atoms; - -import static at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm.getInstance; - -import java.util.Arrays; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Atoms corresponding to rule bodies use this predicate, first term is rule number, - * second is a term containing variable substitutions. - */ -public class RuleAtom extends CoreAtom { - public static final CorePredicate PREDICATE = CorePredicate.getInstance("_R_", 2, true, true); - - private final List> terms; - - private RuleAtom(List> terms) { - if (terms.size() != 2) { - throw new IllegalArgumentException(); - } - - this.terms = terms; - } - - public RuleAtom(InternalRule nonGroundRule, Substitution substitution) { - this(Arrays.asList( - getInstance(Integer.toString(nonGroundRule.getRuleId())), - getInstance(substitution.toString()) - ) - ); - } - - @Override - public CorePredicate getPredicate() { - return PREDICATE; - } - - @Override - public List getTerms() { - return Arrays.asList(terms.get(0), terms.get(1)); - } - - @Override - public boolean isGround() { - // NOTE: Both terms are ConstantTerms, which are ground by definition. - return true; - } - - @Override - public CoreLiteral toLiteral(boolean positive) { - throw new UnsupportedOperationException("RuleAtom cannot be literalized"); - } - - @Override - public CoreAtom substitute(Substitution substitution) { - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - RuleAtom that = (RuleAtom) o; - - return terms.equals(that.terms); - } - - @Override - public int hashCode() { - return 31 * PREDICATE.hashCode() + terms.hashCode(); - } - - @Override - public String toString() { - return PREDICATE.getName() + "(" + terms.get(0) + "," + terms.get(1) + ')'; - } - - @Override - public CoreAtom withTerms(List terms) { - throw new UnsupportedOperationException("RuleAtoms do not support setting of terms!"); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java deleted file mode 100644 index 15e30600b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/bridges/Bridge.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.bridges; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.IntIdGenerator; - -import java.util.Collection; - -public interface Bridge { - Collection getRules(Assignment assignment, AtomStore atomStore, IntIdGenerator intIdGenerator); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java deleted file mode 100644 index 79026fdcc..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import java.util.ArrayList; -import java.util.List; - -/** - * Abstract base implementation of {@link LiteralInstantiationStrategy} that outlines a basic workflow for - * {@link LiteralInstantiationStrategy#getTruthForGroundLiteral(Literal)} and - * {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)} while leaving details of when an atom is true and - * which {@link AssignmentStatus}es to consider valid for getAcceptedSubstitutions to implementations. - * - * Copyright (c) 2020, the Alpha Team. - */ -public abstract class AbstractLiteralInstantiationStrategy implements LiteralInstantiationStrategy { - - /** - * See {@link LiteralInstantiationStrategy#getTruthForGroundLiteral(Literal). - * - * In general - since this code is used in a grounding context where negative literals in rule bodies can be handled in different ways - the - * logic for determining the {@link AssignmentStatus} of a negated literal is delegated to the abstract method - * {@link AbstractLiteralInstantiationStrategy#getAssignmentStatusForNegatedGroundLiteral(Literal)}. The assignment status for positive - * literals is determined using the abstract method {@link AbstractLiteralInstantiationStrategy#getAssignmentStatusForAtom(Atom)}. - */ - @Override - public final AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral) { - if (groundLiteral.isNegated()) { - return this.getAssignmentStatusForNegatedGroundLiteral(groundLiteral); - } - return this.getAssignmentStatusForAtom(groundLiteral.getAtom()); - } - - /** - * See {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)}. - * - * A very general implementation of the basic steps needed to obtain ground substitutions for a positive literal. - * Potentially valid ground instances are obtained using {@link AbstractLiteralInstantiationStrategy#computeCandidateInstances(Atom)}, then - * checked, such that each candidate instance unifies with the given partial substitution and has a "valid" {@link AssignmentStatus}, - * where "validity" of an {@link AssignmentStatus} is determined using the abstract method - * {@link AbstractLiteralInstantiationStrategy#assignmentStatusAccepted(AssignmentStatus)}. - */ - @Override - public final List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution) { - CoreAtom atom = lit.getAtom(); - Iterable groundInstances = this.computeCandidateInstances(atom); - return this.buildSubstitutionsFromInstances(atom, groundInstances, partialSubstitution); - } - - /** - * Computes instances that are potentially valid ground instances of the given partially-ground atom. - * - * A candidate instance is a ground instance of the same predicate where all terms that are ground in partiallyGroundAtom have - * the same values in the candidate. - * - * @param partiallyGroundAtom a partially ground atom for which to find fitting ground instances - * @return a list of candidate instances - */ - protected abstract Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom); - - /** - * Based on a list of candidate instances (see {@link AbstractLiteralInstantiationStrategy#computeCandidateInstances(Atom)}), create a list - * of substitutions and assignment statuses such that each substitution represents a valid (according to the implementation-specific - * definition of this instantiation strategy) ground instance of atomToSubstitute. - * - * @param atomToSubstitute - * @param candidateInstances - * @param partialSubstitution - * @return - */ - protected final List> buildSubstitutionsFromInstances(CoreAtom atomToSubstitute, - Iterable candidateInstances, Substitution partialSubstitution) { - List> retVal = new ArrayList<>(); - // Filter for only instances unifying with partialSubsitution, i.e. "where all joins work out". - Substitution currentInstanceSubstitution; - CoreAtom atomForCurrentInstance; - for (Instance instance : candidateInstances) { - currentInstanceSubstitution = Substitution.specializeSubstitution(atomToSubstitute, instance, partialSubstitution); - if (currentInstanceSubstitution == null) { - // Instance does not unify with partialSubstitution, move on to the next instance. - continue; - } - // At this point, we know that the substitution works out. - // Now check whether the resulting Atom has an acceptable AssignmentStatus. - atomForCurrentInstance = new BasicAtom(atomToSubstitute.getPredicate(), atomToSubstitute.getTerms()) - .substitute(currentInstanceSubstitution); - AssignmentStatus assignmentStatus = this.getAssignmentStatusForAtom(atomForCurrentInstance); - if (!this.assignmentStatusAccepted(assignmentStatus)) { - // Atom has an assignment status deemed unacceptable by this instantiation strategy. - continue; - } - retVal.add(new ImmutablePair<>(currentInstanceSubstitution, assignmentStatus)); - } - return retVal; - } - - protected abstract AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom); - - protected abstract AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral); - - protected abstract boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java deleted file mode 100644 index 8555e91c6..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/AssignmentStatus.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; - -/** - * Helper type to represent truth values as understood by a {@link Grounder} and {@link LiteralInstantiator}. - * - * Note that this enum is not related in any way to {@link ThriceTruth} and mainly serves to have a clear mechanism to indicate that the - * truth value of an atom is not known at a given point in time (UNASSIGNED) - * - * Copyright (c) 2020, the Alpha Team. - */ -public enum AssignmentStatus { - - /** - * True - */ - TRUE, - - /** - * False - */ - FALSE, - - /** - * Unassigned - indicates that at a given point in time, a {@link LiteralInstantiationStrategy} can not determine whether a literal is true - * or false. This is needed because some grounding strategies consider UNASSIGNED atoms to be valid ground instances in order to be able to - * ground larger parts of a program earlier on in the ground/solve cycle - */ - UNASSIGNED; -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java deleted file mode 100644 index 34ff021bf..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/BindingResult.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -import java.util.ArrayList; -import java.util.List; - -/** - * Contains substitutions produced for generating ground substitutions of a rule, - * and for every substitution the number of positive body atoms still unassigned in the respective ground rule. - */ -public class BindingResult { - - private final List generatedSubstitutions = new ArrayList<>(); - private final List numbersOfUnassignedPositiveBodyAtoms = new ArrayList<>(); - - public void add(Substitution generatedSubstitution, int numberOfUnassignedPositiveBodyAtoms) { - generatedSubstitutions.add(generatedSubstitution); - numbersOfUnassignedPositiveBodyAtoms.add(numberOfUnassignedPositiveBodyAtoms); - } - - public void add(BindingResult otherBindingResult) { - generatedSubstitutions.addAll(otherBindingResult.generatedSubstitutions); - numbersOfUnassignedPositiveBodyAtoms.addAll(otherBindingResult.numbersOfUnassignedPositiveBodyAtoms); - } - - public int size() { - return generatedSubstitutions.size(); - } - - public static BindingResult empty() { - return new BindingResult(); - } - - public static BindingResult singleton(Substitution generatedSubstitution, int numberOfUnassignedPositiveBodyAtoms) { - BindingResult bindingResult = new BindingResult(); - bindingResult.add(generatedSubstitution, numberOfUnassignedPositiveBodyAtoms); - return bindingResult; - } - - public List getGeneratedSubstitutions() { - return generatedSubstitutions; - } - - public List getNumbersOfUnassignedPositiveBodyAtoms() { - return numbersOfUnassignedPositiveBodyAtoms; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java deleted file mode 100644 index 21f30e40b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import java.util.LinkedHashSet; -import java.util.Map; - -import at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.solver.Solver; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; - -/** - * Implementation of {@link AbstractLiteralInstantiationStrategy} designed for use in {@link NaiveGrounder}. - * - * The instantiation strategy shares a {@link WorkingMemory}, an {@link AtomStore}, an {@link Assignment}, a {@link Map} of atoms that were - * facts of the currently grounded program, as well as a list of {@link CoreAtom}s that should be lazily deleted from the working memory, - * with - * the grounder. - * - * The working memory and the facts map are maintained by the grounder and are being read by - * {@link DefaultLazyGroundingInstantiationStrategy} in order to determine {@link AssignmentStatus}es for atoms. The {@link AtomStore} is - * maintained by {@link DefaultLazyGroundingInstantiationStrategy} in the sense that atoms created from newly encountered ground instances - * are added by the instantiation strategy. The {@link Assignment} reflects the {@link Solver}s "current view of the world". It is used by - * {@link DefaultLazyGroundingInstantiationStrategy} to determine {@link AssignmentStatus}es for atoms. - * - * A specialty of this implementation is that - since deletion of obsolete {@link CoreAtom}s from {@link NaiveGrounder}s - * {@link WorkingMemory} - * happens lazily (i.e. at the end of each run of {@link NaiveGrounder#getNoGoods(Assignment)}) - it maintains a set of "stale" atoms that - * is shared with the grounder. Specifically, whenever {@link DefaultLazyGroundingInstantiationStrategy#getAssignmentStatusForAtom(Atom)} - * determines that an {@link CoreAtom} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link CoreAtom} is - * added to - * the stale atom set, which in turn is processed by the grounder, which then deletes the respective atoms from the working memory. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class DefaultLazyGroundingInstantiationStrategy extends AbstractLiteralInstantiationStrategy { - - private WorkingMemory workingMemory; - private AtomStore atomStore; - private Assignment currentAssignment; - private LinkedHashSet staleWorkingMemoryEntries; - private Map> facts; - - public DefaultLazyGroundingInstantiationStrategy(WorkingMemory workingMemory, AtomStore atomStore, - Map> facts) { - this.workingMemory = workingMemory; - this.atomStore = atomStore; - this.facts = facts; - } - - @Override - protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { - IndexedInstanceStorage instanceStorage = this.workingMemory.get(partiallyGroundAtom, true); - return instanceStorage.getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); - } - - //@formatter:off - /** - * Computes the {@link AssignmentStatus} for a given {@link CoreAtom} a. - * - * The atom a is {@link AssignmentStatus#TRUE} iff - *

        - *
      • The instantiation strategy's
        currentAssignment
        is null (i.e. the call originated from {@link NaiveGrounder#bootstrap}).
      • - *
      • a is a fact.
      • - *
      • a is assigned {@link ThriceTruth#TRUE} or {@link ThriceTruth#MBT} in the current assignment by the {@link Solver}. - *
      - * - * An atom is {@link AssignmentStatus#UNASSIGNED} iff it has no {@link ThriceTruth} assigned to it in the current assignment. - * An atom is {@link AssignmentStatus#FALSE} iff it is assigned {@link ThriceTruth#FALSE} in the current assignment by the {@link Solver}. - * - * Whenever an {@link CoreAtom} is found to be UNASSIGNED or FALSE, - * that {@link CoreAtom} is added to the stale atom set for later deletion from working memory by the grounder. - */ - //@formatter:on - @Override - protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { - if (this.currentAssignment == null || this.isFact(atom)) { - // currentAssignment == null is a legitimate case, grounder may be in bootstrap - // and will call bindNextAtom with null assignment in that case. - // Assumption: since the atom came from working memory and we must be in - // bootstrap here, we can assume for the atom to be true (or atom is a fact - // anyway, in which case it's also true). - return AssignmentStatus.TRUE; - } - AssignmentStatus retVal; - // First, make sure that the Atom in question exists in the AtomStore. - if (atomStore.contains(atom)) { - int atomId = this.atomStore.get(atom); - this.currentAssignment.growForMaxAtomId(); - if (currentAssignment.isAssigned(atomId)) { - retVal = currentAssignment.getTruth(atomId).toBoolean() ? AssignmentStatus.TRUE : AssignmentStatus.FALSE; - } else { - retVal = AssignmentStatus.UNASSIGNED; - } - } else { - retVal = AssignmentStatus.UNASSIGNED; - } - if (retVal == AssignmentStatus.FALSE || retVal == AssignmentStatus.UNASSIGNED) { - this.staleWorkingMemoryEntries.add(atom); - } - return retVal; - } - - private boolean isFact(CoreAtom atom) { - if (this.facts.get(atom.getPredicate()) == null) { - return false; - } else { - return this.facts.get(atom.getPredicate()).contains(Instance.fromAtom(atom)); - } - } - - @Override - protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { - return AssignmentStatus.TRUE; - } - - /** - * Checks whether a given {@link AssignmentStatus} is "acceptable" in the sense - * that an atom with that assignment status represents a valid ground - * substitution for a non-ground atom. This instantiation strategy accepts - * {@link AssignmentStatus#TRUE} and {@link AssignmentStatus#UNASSIGNED}. - */ - @Override - protected boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus) { - switch (assignmentStatus) { - case TRUE: - case UNASSIGNED: - return true; - case FALSE: - return false; - default: - throw Util.oops("Unsupported AssignmentStatus: " + assignmentStatus); - } - } - - public void setCurrentAssignment(Assignment currentAssignment) { - this.currentAssignment = currentAssignment; - } - - public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { - this.staleWorkingMemoryEntries = staleWorkingMemoryEntries; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java deleted file mode 100644 index 42d7be9f1..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationResult.java +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * Representation of the result of instantiating, i.e. finding ground instances for a literal, as performed by - * {@link LiteralInstantiator#instantiateLiteral(Literal, Substitution)}. - * - * 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}. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class LiteralInstantiationResult { - - /** - * Indicates how a {@link Grounder} should treat this result. - */ - private final Type type; - - /** - * Ground substitutions together with the {@link AssignmentStatus} of the last literal bound to obtain the substitution. Empty for result - * types STOP_BINDING, PUSH_BACK and MAYBE_PUSH_BACK. - */ - private final List> substitutions; - - private LiteralInstantiationResult(Type type, List> substitutions) { - if (type == Type.CONTINUE && substitutions == null) { - throw new UnsupportedOperationException("A LiteralInstantiationResult of type CONTINUE must have substitutions!"); - } - this.type = type; - this.substitutions = substitutions; - } - - public static LiteralInstantiationResult continueBinding(List> substitutions) { - return new LiteralInstantiationResult(Type.CONTINUE, substitutions); - } - - //@formatter:off - public static LiteralInstantiationResult continueBindingWithTrueSubstitutions(List substitutions) { - List> substitutionsWithAssignment = substitutions.stream() - .map((substitution) -> new ImmutablePair<>(substitution, AssignmentStatus.TRUE)) - .collect(Collectors.toList()); - return new LiteralInstantiationResult(Type.CONTINUE, substitutionsWithAssignment); - } - //@formatter:on - - public static LiteralInstantiationResult continueBinding(Substitution substitution, AssignmentStatus assignmentStatus) { - return new LiteralInstantiationResult(Type.CONTINUE, Collections.singletonList(new ImmutablePair<>(substitution, assignmentStatus))); - } - - public static LiteralInstantiationResult stopBinding() { - return new LiteralInstantiationResult(Type.STOP_BINDING, null); - } - - public static LiteralInstantiationResult pushBack() { - return new LiteralInstantiationResult(Type.PUSH_BACK, null); - } - - public static LiteralInstantiationResult maybePushBack() { - return new LiteralInstantiationResult(Type.MAYBE_PUSH_BACK, null); - } - - public Type getType() { - return this.type; - } - - public List> getSubstitutions() { - if (this.type != Type.CONTINUE) { - throw new UnsupportedOperationException("A LiteralInstantiationResult of type " + this.type + " does not have substitutions!"); - } - return this.substitutions; - } - - /** - * Result type. Used by {@link Grounder}s to determine how to proceed grounding a rule after instantiating the literal that yielded the - * respective instantiation result. - * - * Copyright (c) 2020, the Alpha Team. - */ - public static enum Type { - - /** - * Grounder should stop working on the rule, no valid substitutions exist. - */ - STOP_BINDING, - - /** - * Grounder should continue with the next literal. - */ - CONTINUE, - - /** - * Literal instantiation yielded no ground instances, but depending on the specific workflow of the grounder, proceeding with another - * literal might yet make sense. Grounder should decide whether to stop binding or push the literal back in the overall grounding order. - */ - MAYBE_PUSH_BACK, - - /** - * Currently no ground instances, but proceeding with another literal might make sense, push the literal back in the overall grounding - * order. This is used for {@link at.ac.tuwien.kr.alpha.common.atoms.FixedInterpretationLiteral}s that do not produce bindings, like a - * comparision "X < Y" when one variable is not yet bound. - */ - PUSH_BACK; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java deleted file mode 100644 index 5a8489f77..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategy.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -/** - * A {@link LiteralInstantiationStrategy} finds and validates {@link Substitution}s for {@link Literal}s based on a specific definition of - * when a {@link Substitution} is valid, i.e. what makes a literal "true", "false" or "unassigned". - * - * Copyright (c) 2020, the Alpha Team. - */ -public interface LiteralInstantiationStrategy { - - /** - * Computes the {@link AssignmentStatus} for the given {@link Literal} according to the rules of this {@link LiteralInstantiationStrategy}. - * - * @param groundLiteral a ground {@link Literal} for which to compute an {@link AssignmentStatus} - * @return the current {@link AssignmentStatus} for the given literal according to the rules of this {@link LiteralInstantiationStrategy} - */ - AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral); - - /** - * Computes {@link Substitution}s that yield ground instances for a given literal and starting substitution along with the - * {@link AssignmentStatus} of respective ground instances. Note that in all implementations it must hold that an {@link AssignmentStatus} - * AS for a {@link Substitution} S as yielded by this method for a {@link Literal} lit is the same as the result of calling - * getTruthForGroundLiteral(lit.substitute(S)), i.e. both methods must yield the same assignment status for the same ground - * literal. - * - * @param lit a non-ground {@link Literal} for which to compute substitutions. - * @param partialSubstitution a (possibly empty) substitution to use as a starting point - * @return a list of substitutions along with the assignment status of the respective ground atoms - */ - List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java deleted file mode 100644 index 607f3ac63..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiator.java +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationLiteral; -import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalLiteral; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -/** - * Provides ground instantiations for literals. - * - * This class is intended to be used for grounding and other use cases where ground instantiations of literals need to be computed and - * serves as an abstraction layer to decouple the knowledge of how to ground literals from the overall (rule-)grounding workflow. The task of - * actually finding fitting ground substitutions is mostly delegated to a {@link LiteralInstantiationStrategy}. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class LiteralInstantiator { - - private static final Logger LOGGER = LoggerFactory.getLogger(LiteralInstantiator.class); - - private final LiteralInstantiationStrategy instantiationStrategy; - - /** - * Creates a new {@link LiteralInstantiator} with the given {@link LiteralInstantiationStrategy}. - * - * @param instantiationStrategy the instantiation strategy to use for this instantiator - */ - public LiteralInstantiator(LiteralInstantiationStrategy instantiationStrategy) { - this.instantiationStrategy = instantiationStrategy; - } - - /** - * Instantiates a literal using an existing {@link Substitution} as starting point. - * - * This method is intended to be called as part of a larger rule instantiation (i.e. grounding) workflow in order to find ground - * instantiations of literals, i.e. extensions of the given partial substitution that yield useable ground instances for the given literal. - * These substitutions (if any exist) are wrapped together with some additional status information in a {@link LiteralInstantiationResult}. - * - * @param lit the literal for which to find substitutions that yield ground instances - * @param partialSubstitution a substitution that serves as a starting point. May be empty. - * @return a {@link LiteralInstantiationResult} containing ground substitutions - if any exist - along with some metadata for the grounder - */ - public LiteralInstantiationResult instantiateLiteral(CoreLiteral lit, Substitution partialSubstitution) { - LOGGER.trace("Instantiating literal: {}", lit); - if (lit instanceof FixedInterpretationLiteral) { - return this.instantiateFixedInterpretationLiteral((FixedInterpretationLiteral) lit, partialSubstitution); - } else if (lit instanceof EnumerationLiteral) { - return this.instantiateEnumerationLiteral((EnumerationLiteral) lit, partialSubstitution); - } else { - // Note: At this point we just assume lit to be a basic literal, actual type - // check is not performed since the assumption is that any literal that is no - // FixedInterpretationLiteral or EnumerationLiteral follows the semantics of a - // BasicLiteral even if it has another (currently not existing) type. - return this.instantiateBasicLiteral(lit, partialSubstitution); - } - } - - /** - * Calculates satisfying substitutions for a given {@link FixedInterpretationLiteral} based on a partial substitution. This method assumes - * that the partial substitution has not been applied to the passed literal. - * - * @param lit the (fixed interpretation) literal for which to calculate substitutions - * @param partialSubstitution - * @return a LiteralInstantiationResult representing the result of the search for substitutions - */ - private LiteralInstantiationResult instantiateFixedInterpretationLiteral(FixedInterpretationLiteral lit, Substitution partialSubstitution) { - LOGGER.trace("Instantiating FixedInterpretationLiteral: {}", lit); - List substitutions; - FixedInterpretationLiteral substitutedLiteral = (FixedInterpretationLiteral) lit.substitute(partialSubstitution); - if (this.shouldPushBackFixedInterpretationLiteral(substitutedLiteral)) { - return LiteralInstantiationResult.pushBack(); - } else { - substitutions = substitutedLiteral.getSatisfyingSubstitutions(partialSubstitution); - return substitutions.isEmpty() ? LiteralInstantiationResult.stopBinding() - : LiteralInstantiationResult.continueBindingWithTrueSubstitutions(substitutions); - } - } - - /** - * 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. - * - * @param lit an enumeration literal - * @param partialSubstitution - */ - private LiteralInstantiationResult instantiateEnumerationLiteral(EnumerationLiteral lit, Substitution partialSubstitution) { - LOGGER.trace("Instantiating EnumerationLiteral: {}", lit); - return LiteralInstantiationResult.continueBinding(lit.addEnumerationIndexToSubstitution(partialSubstitution), AssignmentStatus.TRUE); - } - - /** - * Calculates substitutions for a given literal that is not a {@link FixedInterpretationLiteral} or {@link EnumerationLiteral}. - * If applying the given partial substitution to the literal already grounds the literal, the resulting ground literal is verified based on - * this instantiators {@link LiteralInstantiationStrategy}. If the literal is only partially ground after applying the partial substitution, - * ground substitutions are looked up using the instantiators {@link LiteralInstantiationStrategy}. This method assumes that the partial - * substitution has not been applied to the passed literal. - * - * @param lit - * @param partialSubstitution - */ - private LiteralInstantiationResult instantiateBasicLiteral(CoreLiteral lit, Substitution partialSubstitution) { - LOGGER.trace("Instantiating basic literal: {}", lit); - List> substitutions; - CoreLiteral substitutedLiteral = lit.substitute(partialSubstitution); - LOGGER.trace("Substituted literal is {}", substitutedLiteral); - if (substitutedLiteral.isGround()) { - LOGGER.trace("Literal {} is already ground, checking truth", substitutedLiteral); - // Lit seems to be a basic literal, so its satisfiability w.r.t. - // partialSubstitution is decided based on knownInstances by the - // instantiationStrategy. - AssignmentStatus truthForLiteral = this.instantiationStrategy.getTruthForGroundLiteral(substitutedLiteral); - if (truthForLiteral == AssignmentStatus.FALSE) { - return LiteralInstantiationResult.stopBinding(); - } else { - return LiteralInstantiationResult.continueBinding(partialSubstitution, truthForLiteral); - } - } else { - LOGGER.trace("Handling non-ground literal {}", substitutedLiteral); - if (substitutedLiteral.isNegated()) { - return LiteralInstantiationResult.maybePushBack(); - } - // Query instantiationStrategy for acceptable substitutions. - // Note: getAcceptedSubstitutions will only give substitutions where the - // resulting ground atom is true or unassigned, false atoms are internally - // discarded. - substitutions = this.instantiationStrategy.getAcceptedSubstitutions(substitutedLiteral, partialSubstitution); - LOGGER.trace("Got {} substitutions from instantiation strategy for {}", substitutions.size(), substitutedLiteral); - return substitutions.isEmpty() ? LiteralInstantiationResult.maybePushBack() : LiteralInstantiationResult.continueBinding(substitutions); - } - } - - /** - * Helper method for instantiateLiteral to determine whether a {@link FixedInterpretationLiteral} may have substitutions later - * on and should therefore be pushed back in the grounding order. - * - * Any {@link FixedInterpretationLiteral} that does not fulfil any of the following conditions is "pushed back" in the - * grounding order because it cannot be used to generate substitutions now but maybe later: - *

        - *
      • the literal is ground
      • - *
      • the literal is a {@link ComparisonLiteral} that is left-assigning or right-assigning
      • - *
      • the literal is an {@link IntervalLiteral} representing a ground interval term
      • - *
      • the literal is an {@link ExternalLiteral}.
      • - *
      - * - * @param lit a {@link FixedInterpretationLiteral} that is substituted with the partial substitution passed into - * instantiateLiteral - */ - private boolean shouldPushBackFixedInterpretationLiteral(FixedInterpretationLiteral lit) { - return !(lit.isGround() || - (lit instanceof ComparisonLiteral && ((ComparisonLiteral) lit).isLeftOrRightAssigning()) || - (lit instanceof IntervalLiteral && lit.getTerms().get(0).isGround()) || - (lit instanceof ExternalLiteral)); - - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java deleted file mode 100644 index 3f98f3695..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2020, the Alpha Team. - * 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.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; - -/** - * A very basic implementation of {@link AbstractLiteralInstantiationStrategy} that determines truth of an atom solely based on the atom's - * presence in a working memory. Atoms that have a corresponding positive instance in the working memory have {@link AssignmentStatus#TRUE}, - * all other atoms have {@link AssignmentStatus#FALSE}. A negated literal lit is true iff - * getAssignmentStatusForAtom(lit.getAtom()) == AssignmentStatus.FALSE, false otherwise. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class WorkingMemoryBasedInstantiationStrategy extends AbstractLiteralInstantiationStrategy { - - private final WorkingMemory workingMemory; - - public WorkingMemoryBasedInstantiationStrategy(WorkingMemory workingMemory) { - this.workingMemory = workingMemory; - } - - @Override - protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { - return this.workingMemory.get(partiallyGroundAtom, true).getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); - } - - @Override - protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { - return this.workingMemory.get(atom, true).containsInstance(Instance.fromAtom(atom)) ? AssignmentStatus.TRUE : AssignmentStatus.FALSE; - } - - @Override - protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { - return this.getAssignmentStatusForAtom(negatedGroundLiteral.getAtom()) == AssignmentStatus.TRUE ? AssignmentStatus.FALSE : AssignmentStatus.TRUE; - } - - @Override - protected boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus) { - return assignmentStatus == AssignmentStatus.TRUE; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java deleted file mode 100644 index f6fc42ffb..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/InlineDirectives.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.parser; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Stores directives appearing in the ASP program. Each directive starts with # and ends with . - * Copyright (c) 2017, the Alpha Team. - */ -public class InlineDirectives { - - public enum DIRECTIVE { - enum_predicate_is - } - - private final LinkedHashMap directives = new LinkedHashMap<>(); - - public String getDirectiveValue(DIRECTIVE directive) { - return directives.get(directive); - } - - public void addDirective(DIRECTIVE directive, String value) { - if (directives.get(directive) != null) { - throw new RuntimeException("Inline directive multiply defined."); - } - directives.put(directive, value); - } - - public void accumulate(InlineDirectives other) { - for (Map.Entry directiveEntry : other.directives.entrySet()) { - addDirective(directiveEntry.getKey(), directiveEntry.getValue()); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java deleted file mode 100644 index 3571d961b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ParseTreeVisitor.java +++ /dev/null @@ -1,583 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.grounder.parser; - -import at.ac.tuwien.kr.alpha.antlr.ASPCore2BaseVisitor; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.*; -import org.antlr.v4.runtime.RuleContext; -import org.antlr.v4.runtime.tree.TerminalNode; - -import java.util.*; - -import static java.util.Collections.emptyList; - -/** - * Copyright (c) 2016-2018, the Alpha Team. - */ -public class ParseTreeVisitor extends ASPCore2BaseVisitor { - private final Map externals; - private final boolean acceptVariables; - - private InputProgram.Builder programBuilder; - private InlineDirectives inlineDirectives; - - public ParseTreeVisitor(Map externals) { - this(externals, true); - } - - public ParseTreeVisitor(Map externals, boolean acceptVariables) { - this.externals = externals; - this.acceptVariables = acceptVariables; - } - - private UnsupportedOperationException notSupported(RuleContext ctx) { - return new UnsupportedOperationException("Unsupported syntax encountered: " + ctx.getText()); - } - - /** - * Translates a program context (referring to a node in an ATN specific to ANTLR) to the internal representation of Alpha. - */ - public InputProgram translate(ASPCore2Parser.ProgramContext input) { - return visitProgram(input); - } - - /** - * Translates a context for answer sets (referring to a node in an ATN specific to ANTLR) to the representation that Alpha uses. - */ - public Set translate(ASPCore2Parser.Answer_setsContext input) { - return visitAnswer_sets(input); - } - - @Override - public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { - Set result = new TreeSet<>(); - - for (ASPCore2Parser.Answer_setContext answerSetContext : ctx.answer_set()) { - result.add(visitAnswer_set(answerSetContext)); - } - - return result; - } - - @Override - public AnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { - SortedSet predicates = new TreeSet<>(); - Map> predicateInstances = new TreeMap<>(); - - for (ASPCore2Parser.Classical_literalContext classicalLiteralContext : ctx.classical_literal()) { - CoreAtom atom = visitClassical_literal(classicalLiteralContext); - - predicates.add(atom.getPredicate()); - predicateInstances.compute(atom.getPredicate(), (k, v) -> { - if (v == null) { - v = new TreeSet<>(); - } - v.add(atom); - return v; - }); - - } - - return new BasicAnswerSet(predicates, predicateInstances); - } - - @Override - public String visitTerminal(TerminalNode node) { - return node.getText(); - } - - @Override - public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { - // program : statements? query?; - if (ctx.query() != null) { - throw notSupported(ctx.query()); - } - - if (ctx.statements() == null) { - return InputProgram.EMPTY; - } - inlineDirectives = new InlineDirectives(); - programBuilder = InputProgram.builder(); - visitStatements(ctx.statements()); - programBuilder.addInlineDirectives(inlineDirectives); - return programBuilder.build(); - } - - @Override - public Object visitStatements(ASPCore2Parser.StatementsContext ctx) { - // statements : statement+; - for (ASPCore2Parser.StatementContext statementContext : ctx.statement()) { - visit(statementContext); - } - return null; - } - - @Override - public Object visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { - // head DOT - Head head = visitHead(ctx.head()); - if (head instanceof NormalHead) { - programBuilder.addFact(((NormalHead) head).getAtom()); - } else { - // Treat facts with choice or disjunction in the head like a rule. - programBuilder.addRule(new BasicRule(head, emptyList())); - } - return null; - } - - @Override - public Object visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx) { - // CONS body DOT - programBuilder.addRule(new BasicRule(null, 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()))); - return null; - } - - @Override - public Object visitStatement_weightConstraint(ASPCore2Parser.Statement_weightConstraintContext ctx) { - // WCONS body? DOT SQUARE_OPEN weight_at_level SQUARE_CLOSE - throw notSupported(ctx); - } - - @Override - public Object visitStatement_directive(ASPCore2Parser.Statement_directiveContext ctx) { - // directive - visitDirective(ctx.directive()); - // Parsed directives are globally stored, nothing to return here. - return null; - } - - @Override - public Head visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { - // disjunction : classical_literal (OR disjunction)?; - if (ctx.disjunction() != null) { - throw notSupported(ctx); - } - return new NormalHead(visitClassical_literal(ctx.classical_literal())); - } - - @Override - public Head visitHead(ASPCore2Parser.HeadContext ctx) { - // head : disjunction | choice; - if (ctx.choice() != null) { - return visitChoice(ctx.choice()); - } - return visitDisjunction(ctx.disjunction()); - } - - @Override - public Head visitChoice(ASPCore2Parser.ChoiceContext ctx) { - // choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; - Term lt = null; - ComparisonOperator lop = null; - Term ut = null; - ComparisonOperator uop = null; - if (ctx.lt != null) { - lt = (Term) visit(ctx.lt); - lop = visitBinop(ctx.lop); - } - if (ctx.ut != null) { - ut = (Term) visit(ctx.ut); - uop = visitBinop(ctx.uop); - } - return new ChoiceHead(visitChoice_elements(ctx.choice_elements()), lt, lop, ut, uop); - } - - @Override - public List visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { - // choice_elements : choice_element (SEMICOLON choice_elements)?; - List choiceElements; - if (ctx.choice_elements() != null) { - choiceElements = visitChoice_elements(ctx.choice_elements()); - } else { - choiceElements = new LinkedList<>(); - } - choiceElements.add(0, visitChoice_element(ctx.choice_element())); - return choiceElements; - } - - @Override - public ChoiceHead.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { - // choice_element : classical_literal (COLON naf_literals?)?; - BasicAtom atom = (BasicAtom) visitClassical_literal(ctx.classical_literal()); - if (ctx.naf_literals() != null) { - return new ChoiceHead.ChoiceElement(atom, visitNaf_literals(ctx.naf_literals())); - } else { - return new ChoiceHead.ChoiceElement(atom, Collections.emptyList()); - } - } - - @Override - public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { - // naf_literals : naf_literal (COMMA naf_literals)?; - List literals; - if (ctx.naf_literals() != null) { - literals = visitNaf_literals(ctx.naf_literals()); - } else { - literals = new LinkedList<>(); - } - literals.add(0, visitNaf_literal(ctx.naf_literal())); - return literals; - } - - @Override - public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx) { - // directive_enumeration : SHARP 'enum_predicate_is' ID DOT; - inlineDirectives.addDirective(InlineDirectives.DIRECTIVE.enum_predicate_is, ctx.ID().getText()); - return null; - } - - @Override - public List visitBody(ASPCore2Parser.BodyContext ctx) { - // body : ( naf_literal | aggregate ) (COMMA body)?; - if (ctx == null) { - return emptyList(); - } - - final List literals = new ArrayList<>(); - do { - if (ctx.naf_literal() != null) { - literals.add(visitNaf_literal(ctx.naf_literal())); - } else { - literals.add(visitAggregate(ctx.aggregate())); - } - } while ((ctx = ctx.body()) != null); - - return literals; - } - - @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)?; - boolean isPositive = ctx.NAF() == null; - CoreTerm lt = null; - ComparisonOperator lop = null; - Term ut = null; - ComparisonOperator uop = null; - if (ctx.lt != null) { - lt = (CoreTerm) visit(ctx.lt); - lop = visitBinop(ctx.lop); - } - if (ctx.ut != null) { - ut = (Term) visit(ctx.ut); - uop = visitBinop(ctx.uop); - } - AggregateAtom.AGGREGATEFUNCTION aggregateFunction = visitAggregate_function(ctx.aggregate_function()); - List aggregateElements = visitAggregate_elements(ctx.aggregate_elements()); - return new AggregateAtom(lop, lt, uop, ut, aggregateFunction, aggregateElements).toLiteral(isPositive); - } - - @Override - public List visitAggregate_elements(ASPCore2Parser.Aggregate_elementsContext ctx) { - // aggregate_elements : aggregate_element (SEMICOLON aggregate_elements)?; - final List aggregateElements = new ArrayList<>(); - do { - aggregateElements.add(visitAggregate_element(ctx.aggregate_element())); - } while ((ctx = ctx.aggregate_elements()) != null); - - return aggregateElements; - } - - @Override - public AggregateAtom.AggregateElement visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx) { - // aggregate_element : basic_terms? (COLON naf_literals?)?; - List basicTerms = ctx.basic_terms() != null ? visitBasic_terms(ctx.basic_terms()) : null; - if (ctx.naf_literals() != null) { - return new AggregateAtom.AggregateElement(basicTerms, visitNaf_literals(ctx.naf_literals())); - } - return new AggregateAtom.AggregateElement(basicTerms, Collections.emptyList()); - } - - @Override - public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { - // basic_terms : basic_term (COMMA basic_terms)? ; - List termList = new ArrayList<>(); - do { - termList.add(visitBasic_term(ctx.basic_term())); - } while ((ctx = ctx.basic_terms()) != null); - return termList; - } - - @Override - public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { - // basic_term : ground_term | variable_term; - if (ctx.ground_term() != null) { - return visitGround_term(ctx.ground_term()); - } else { - return visitVariable_term(ctx.variable_term()); - } - } - - @Override - public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { - // ground_term : ID | QUOTED_STRING | MINUS? NUMBER; - if (ctx.ID() != null) { - return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); - } else if (ctx.QUOTED_STRING() != null) { - String quotedString = ctx.QUOTED_STRING().getText(); - return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); - } else { - int multiplier = 1; - if (ctx.MINUS() != null) { - multiplier = -1; - } - return CoreConstantTerm.getInstance(multiplier * Integer.parseInt(ctx.NUMBER().getText())); - } - } - - @Override - public Term visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { - // variable_term : VARIABLE | ANONYMOUS_VARIABLE; - if (ctx.VARIABLE() != null) { - return VariableTerm.getInstance(ctx.VARIABLE().getText()); - } else { - return VariableTerm.getAnonymousInstance(); - } - } - - @Override - public AggregateAtom.AGGREGATEFUNCTION visitAggregate_function(ASPCore2Parser.Aggregate_functionContext ctx) { - // aggregate_function : AGGREGATE_COUNT | AGGREGATE_MAX | AGGREGATE_MIN | AGGREGATE_SUM; - if (ctx.AGGREGATE_COUNT() != null) { - return AggregateAtom.AGGREGATEFUNCTION.COUNT; - } else if (ctx.AGGREGATE_MAX() != null) { - return AggregateAtom.AGGREGATEFUNCTION.MAX; - } else if (ctx.AGGREGATE_MIN() != null) { - return AggregateAtom.AGGREGATEFUNCTION.MIN; - } else if (ctx.AGGREGATE_SUM() != null) { - return AggregateAtom.AGGREGATEFUNCTION.SUM; - } else { - throw notSupported(ctx); - } - } - - @Override - public ComparisonOperator visitBinop(ASPCore2Parser.BinopContext ctx) { - // binop : EQUAL | UNEQUAL | LESS | GREATER | LESS_OR_EQ | GREATER_OR_EQ; - if (ctx.EQUAL() != null) { - return ComparisonOperator.EQ; - } else if (ctx.UNEQUAL() != null) { - return ComparisonOperator.NE; - } else if (ctx.LESS() != null) { - return ComparisonOperator.LT; - } else if (ctx.LESS_OR_EQ() != null) { - return ComparisonOperator.LE; - } else if (ctx.GREATER() != null) { - return ComparisonOperator.GT; - } else if (ctx.GREATER_OR_EQ() != null) { - return ComparisonOperator.GE; - } else { - throw notSupported(ctx); - } - } - - @Override - public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { - // builtin_atom : term binop term; - return new ComparisonAtom( - (CoreTerm) visit(ctx.term(0)), - (CoreTerm) visit(ctx.term(1)), - visitBinop(ctx.binop()) - ); - } - - @Override - public CoreLiteral visitNaf_literal(ASPCore2Parser.Naf_literalContext ctx) { - // naf_literal : NAF? (external_atom | classical_literal | builtin_atom); - boolean isCurrentLiteralNegated = ctx.NAF() != null; - if (ctx.builtin_atom() != null) { - return new ComparisonLiteral(visitBuiltin_atom(ctx.builtin_atom()), !isCurrentLiteralNegated); - } else if (ctx.classical_literal() != null) { - return new BasicLiteral(visitClassical_literal(ctx.classical_literal()), !isCurrentLiteralNegated); - } else if (ctx.external_atom() != null) { - return new ExternalLiteral(visitExternal_atom(ctx.external_atom()), !isCurrentLiteralNegated); - } - throw notSupported(ctx); - } - - @Override - public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext ctx) { - // classical_literal : MINUS? ID (PAREN_OPEN terms PAREN_CLOSE)?; - if (ctx.MINUS() != null) { - throw notSupported(ctx); - } - - final List terms = visitTerms(ctx.terms()); - return new BasicAtom(CorePredicate.getInstance(ctx.ID().getText(), terms.size()), terms); - } - - @Override - public List visitTerms(ASPCore2Parser.TermsContext ctx) { - // terms : term (COMMA terms)?; - if (ctx == null) { - return emptyList(); - } - - final List terms = new ArrayList<>(); - do { - ASPCore2Parser.TermContext term = ctx.term(); - terms.add((CoreTerm) visit(term)); - } while ((ctx = ctx.terms()) != null); - - return terms; - } - - @Override - public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { - return CoreConstantTerm.getInstance(Integer.parseInt(ctx.NUMBER().getText())); - } - - @Override - public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { - return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); - } - - @Override - public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { - String quotedString = ctx.QUOTED_STRING().getText().replace("\\\"", "\""); - return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); - } - - @Override - public FunctionTerm visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { - return FunctionTerm.getInstance(ctx.ID().getText(), visitTerms(ctx.terms())); - } - - @Override - public VariableTerm visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx) { - if (!acceptVariables) { - throw notSupported(ctx); - } - - return VariableTerm.getAnonymousInstance(); - } - - @Override - public VariableTerm visitTerm_variable(ASPCore2Parser.Term_variableContext ctx) { - if (!acceptVariables) { - throw notSupported(ctx); - } - - return VariableTerm.getInstance(ctx.VARIABLE().getText()); - } - - @Override - public Term visitTerm_parenthesisedTerm(ASPCore2Parser.Term_parenthesisedTermContext ctx) { - return (Term) visit(ctx.term()); - } - - @Override - public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) { - // external_atom : AMPERSAND ID (SQUARE_OPEN input = terms SQUARE_CLOSE)? (PAREN_OPEN output = terms PAREN_CLOSE)?; - - if (ctx.MINUS() != null) { - throw notSupported(ctx); - } - - final String predicateName = ctx.ID().getText(); - final PredicateInterpretation interpretation = externals.get(predicateName); - - if (interpretation == null) { - throw new IllegalArgumentException("Unknown interpretation name encountered: " + predicateName); - } - - List outputTerms = visitTerms(ctx.output); - - return new ExternalAtom( - CorePredicate.getInstance(predicateName, outputTerms.size()), - interpretation, - visitTerms(ctx.input), - outputTerms - ); - } - - @Override - public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) { - // interval : lower = (NUMBER | VARIABLE) DOT DOT upper = (NUMBER | VARIABLE); - ASPCore2Parser.IntervalContext ictx = ctx.interval(); - String lowerText = ictx.lower.getText(); - String upperText = ictx.upper.getText(); - CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) : VariableTerm.getInstance(lowerText); - CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) : VariableTerm.getInstance(upperText); - return IntervalTerm.getInstance(lower, upper); - } - - @Override - public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { - // | MINUS term - return ArithmeticTerm.MinusTerm.getInstance((CoreTerm) visit(ctx.term())); - } - - @Override - public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { - // | term (TIMES | DIV | MODULO) term - ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES - : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); - } - - @Override - public Object visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { - // | term (PLUS | MINUS) term - ArithmeticTerm.ArithmeticOperator op = ctx.PLUS() != null ? ArithmeticTerm.ArithmeticOperator.PLUS : ArithmeticTerm.ArithmeticOperator.MINUS; - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); - } - - @Override - public Object visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { - // | term POWER term - ArithmeticTerm.ArithmeticOperator op = ArithmeticTerm.ArithmeticOperator.POWER; - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); - } - - @Override - public Object visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { - // | term BITXOR term - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (CoreTerm) visit(ctx.term(1))); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java deleted file mode 100644 index 7bea8f5a2..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramParser.java +++ /dev/null @@ -1,111 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.parser; - -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.DefaultErrorStrategy; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; - -import java.io.IOException; -import java.util.Collections; -import java.util.Map; - -import at.ac.tuwien.kr.alpha.CustomErrorListener; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; - -public class ProgramParser { - private final Map externals; - - public ProgramParser(Map externals) { - this.externals = externals; - } - - public ProgramParser() { - this(Collections.emptyMap()); - } - - public InputProgram parse(String s) { - try { - return parse(CharStreams.fromString(s)); - } catch (IOException e) { - // In this case we assume that something went fundamentally - // wrong when using a String as input. The caller probably - // assumes that I/O on a String should always be fine. - throw new RuntimeException("Encountered I/O-related exception while parsing a String.", e); - } 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 input program.", e); - } - } - - public InputProgram parse(CharStream stream) throws IOException { - //@formatter:off - /* - * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. - * ASPCore2Lexer lexer = new ASPCore2Lexer(new UnbufferedCharStream(is)); - * lexer.setTokenFactory(new CommonTokenFactory(true)); - * final ASPCore2Parser parser = new ASPCore2Parser(new UnbufferedTokenStream<>(lexer)); - * parser.setBuildParseTree(false); - */ - //@formatter:on - CommonTokenStream tokens = new CommonTokenStream(new ASPCore2Lexer(stream)); - final ASPCore2Parser parser = new ASPCore2Parser(tokens); - - // Try SLL parsing mode (faster but may terminate incorrectly). - parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - parser.removeErrorListeners(); - parser.setErrorHandler(new BailErrorStrategy()); - - final CustomErrorListener errorListener = new CustomErrorListener(stream.getSourceName()); - - ASPCore2Parser.ProgramContext programContext; - try { - // Parse program - programContext = parser.program(); - } catch (ParseCancellationException e) { - // Recognition exception may be caused simply by SLL parsing failing, - // retry with LL parser and DefaultErrorStrategy printing errors to console. - if (e.getCause() instanceof RecognitionException) { - tokens.seek(0); - parser.addErrorListener(errorListener); - parser.setErrorHandler(new DefaultErrorStrategy()); - parser.getInterpreter().setPredictionMode(PredictionMode.LL); - // Re-run parse. - programContext = parser.program(); - } else { - throw e; - } - } - - // If the our SwallowingErrorListener has handled some exception during parsing - // just re-throw that exception. - // At this time, error messages will be already printed out to standard error - // because ANTLR by default adds an org.antlr.v4.runtime.ConsoleErrorListener - // to every parser. - // That ConsoleErrorListener will print useful messages, but not report back to - // our code. - // org.antlr.v4.runtime.BailErrorStrategy cannot be used here, because it would - // abruptly stop parsing as soon as the first error is reached (i.e. no recovery - // is attempted) and the user will only see the first error encountered. - if (errorListener.getRecognitionException() != null) { - throw errorListener.getRecognitionException(); - } - - // Abort parsing if there were some (recoverable) syntax errors. - if (parser.getNumberOfSyntaxErrors() != 0) { - throw new ParseCancellationException(); - } - - // Construct internal program representation. - ParseTreeVisitor visitor = new ParseTreeVisitor(externals); - return visitor.translate(programContext); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java deleted file mode 100644 index a7cc0f152..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/parser/ProgramPartParser.java +++ /dev/null @@ -1,80 +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.grounder.parser; - -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.misc.ParseCancellationException; - -import java.util.Collections; - -/** - * A parser that, in contrast to {@link ProgramParser}, 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); - - public CoreTerm parseTerm(String s) { - final ASPCore2Parser parser = getASPCore2Parser(s); - return (CoreTerm)parse(parser.term()); - } - - public BasicAtom parseBasicAtom(String s) { - final ASPCore2Parser parser = getASPCore2Parser(s); - return (BasicAtom)parse(parser.classical_literal()); - } - - public Literal parseLiteral(String s) { - final ASPCore2Parser parser = getASPCore2Parser(s); - return (Literal)parse(parser.naf_literal()); - } - - private ASPCore2Parser getASPCore2Parser(String s) { - return new ASPCore2Parser(new CommonTokenStream(new ASPCore2Lexer(CharStreams.fromString(s)))); - } - - private Object parse(ParserRuleContext context) { - try { - return visitor.visit(context); - } 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 term.", e); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java deleted file mode 100644 index 983f771ed..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleIndex.java +++ /dev/null @@ -1,7 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.rete; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public class TupleIndex { -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java deleted file mode 100644 index 798ad4db0..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/rete/TupleStore.java +++ /dev/null @@ -1,10 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.rete; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public class TupleStore { - - int arity; - TupleIndex[] tupleIndex; -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java deleted file mode 100644 index 52be979bb..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustified.java +++ /dev/null @@ -1,409 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.structure; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.Unification; -import at.ac.tuwien.kr.alpha.grounder.Unifier; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -/** - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class AnalyzeUnjustified { - private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeUnjustified.class); - private final InternalProgram programAnalysis; - private final AtomStore atomStore; - private final Map> factsFromProgram; - private int renamingCounter; - private int padDepth; - - public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { - this.programAnalysis = programAnalysis; - this.atomStore = atomStore; - this.factsFromProgram = factsFromProgram; - padDepth = 0; - } - - private Map> assignedAtoms; - - public Set analyze(int atomToJustify, Assignment currentAssignment) { - padDepth = 0; - CoreAtom atom = atomStore.get(atomToJustify); - if (!(atom instanceof BasicAtom)) { - throw oops("Starting atom must be a BasicAtom, but received: " + atom + " of type: " + atom.getClass()); - } - //@formatter:off - // Calling code must make sure it is a BasicAtom and take precautions. - // Potential solutions: - // If atom instanceof RuleAtom and atom is MBT, then the corresponding rule body has a BasicAtom that is MBT. - // If atom instanceof ChoiceAtom and atom is MBT, then the corresponding rule body has a BasicAtom that is MBT. - // If atom instanceof RuleAtom and atom is FALSE, then this comes from a violated constraint in the end and the corresponding rule body can be taken as the single rule deriving the RuleAtom. - //@formatter:on - assignedAtoms = new LinkedHashMap<>(); - for (int i = 1; i <= atomStore.getMaxAtomId(); i++) { - ThriceTruth truth = currentAssignment.getTruth(i); - if (truth == null) { - continue; - } - CoreAtom assignedAtom = atomStore.get(i); - assignedAtoms.putIfAbsent(assignedAtom.getPredicate(), new ArrayList<>()); - assignedAtoms.get(assignedAtom.getPredicate()).add(assignedAtom); - } - return analyze((BasicAtom) atom, currentAssignment); - } - - private Set analyze(BasicAtom atom, Assignment currentAssignment) { - log(pad("Starting analyze, current assignment is: {}"), currentAssignment); - LinkedHashSet vL = new LinkedHashSet<>(); - LinkedHashSet vToDo = new LinkedHashSet<>(Collections.singleton(new LitSet(atom, new LinkedHashSet<>()))); - LinkedHashSet vDone = new LinkedHashSet<>(); - while (!vToDo.isEmpty()) { - Iterator it = vToDo.iterator(); - LitSet x = it.next(); - it.remove(); - log(""); - log("Treating now: {}", x); - vDone.add(x); - ReturnExplainUnjust unjustRet = explainUnjust(x, currentAssignment); - log("Additional ToDo: {}", unjustRet.vToDo); - // Check each new LitSet if it does not already occur as done. - for (LitSet todoLitSet : unjustRet.vToDo) { - if (!vDone.contains(todoLitSet)) { - vToDo.add(todoLitSet); - } - } - vL.addAll(unjustRet.vL); - } - return vL; - } - - private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment) { - padDepth += 2; - log("Begin explainUnjust(): {}", x); - CoreAtom p = x.getAtom(); - - ReturnExplainUnjust ret = new ReturnExplainUnjust(); - - // Construct set of all 'rules' such that head unifies with p. - List rulesUnifyingWithP = rulesHeadUnifyingWith(p); - log("Rules unifying with {} are {}", p, rulesUnifyingWithP); - rulesLoop: - for (RuleAndUnifier ruleUnifier : rulesUnifyingWithP) { - Unifier sigma = ruleUnifier.unifier; - Set bodyR = ruleUnifier.ruleBody; - CoreAtom sigmaHr = ruleUnifier.originalHead.substitute(sigma); - log("Considering now: {}", ruleUnifier); - Set vN = new LinkedHashSet<>(x.getComplementSubstitutions()); - for (Unifier sigmaN : vN) { - if (Unification.instantiate(p.substitute(sigmaN), sigmaHr) != null) { - log("Unifier is excluded by: {}", sigmaN); - continue rulesLoop; - } - } - Set vNp = new LinkedHashSet<>(); - for (Unifier substitution : vN) { - Unifier merged = Unifier.mergeIntoLeft(substitution, sigma); - // Ignore inconsistent merges. - if (merged == null) { - continue; - } - vNp.add(merged); - } - log("Adapting N to N'. Original N is {}", vN); - log("Adapted N' is {}", vNp); - log("Searching for falsified negated literals in the body: {}", bodyR); - for (CoreLiteral lit : bodyR) { - if (!lit.isNegated()) { - continue; - } - CoreAtom lb = lit.getAtom().substitute(sigma); - log("Found: {}, searching falsifying ground instances of {} (with unifier from the head) now.", lit, lb); - AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(lb.getPredicate()); - while (assignedAtomsOverPredicate.hasNext()) { - CoreAtom lg = assignedAtomsOverPredicate.next(); - log("Considering: {}", lg); - if (atomStore.contains(lg)) { - int atomId = atomStore.get(lg); - if (!currentAssignment.getTruth(atomId).toBoolean()) { - log("{} is not assigned TRUE or MBT. Skipping.", lg); - continue; - } - } // Note: in case the atom is not in the atomStore, it came from a fact and hence is true. - log("{} is TRUE or MBT.", lg); - Unifier sigmagb = Unification.unifyAtoms(lg, lb); - if (sigmagb == null) { - log("{} does not unify with {}", lg, lb); - continue; - } - log("Checking if {} is already covered.", lb); - boolean isCovered = false; - for (Unifier sigmaN : vN) { - if (Unification.instantiate(p.substitute(sigmaN), sigmaHr.substitute(sigmagb)) != null) { - log("{} is already covered by {}", lb, sigmaN); - isCovered = true; - break; - } - } - if (!isCovered) { - Unifier sigmacirc = new Unifier(sigma).extendWith(sigmagb); - vNp.add(sigmacirc); - log("Literal {} is not excluded and falsifies body literal {}", lg, lit); - ret.vL.add(lg.toLiteral()); - log("Reasons extended by: {}", lg); - } - } - - } - List bodyPos = new ArrayList<>(); - for (CoreLiteral literal : bodyR) { - if (!literal.isNegated()) { - bodyPos.add(literal); - } - } - log("Calling UnjustCover() for positive body."); - ret.vToDo.addAll(unjustCover(bodyPos, Collections.singleton(sigma), vNp, currentAssignment)); - } - log("End explainUnjust()."); - padDepth -= 2; - return ret; - } - - private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { - padDepth += 2; - log("Begin UnjustCoverFixed()"); - log("Finding unjustified body literals in: {} / {} excluded {}", vB, vY, vN); - Set ret = new LinkedHashSet<>(); - if (vB.isEmpty() || vY.isEmpty()) { - log("End unjustCover()."); - padDepth -= 2; - return Collections.emptySet(); - } - int chosenLiteralPos = 0; - // Find a body literal that is not a ComparisonLiteral, because these do not generate/have atoms assigned. - for (int i = 0; i < vB.size(); i++) { - if (!(vB.get(i) instanceof ComparisonLiteral)) { - chosenLiteralPos = i; - break; - } - } - CoreAtom b = vB.get(chosenLiteralPos).getAtom(); - log("Picked literal from body is: {}", b); - for (Unifier sigmaY : vY) { - CoreAtom bSigmaY = b.substitute(sigmaY); - log("Treating substitution for: {}", bSigmaY); - Set vYp = new LinkedHashSet<>(); - - log("Checking atoms over predicate: {}", b.getPredicate()); - AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(b.getPredicate()); - atomLoop: - while (assignedAtomsOverPredicate.hasNext()) { - CoreAtom atom = assignedAtomsOverPredicate.next(); - // Check that atom is justified/true. - log("Checking atom: {}", atom); - if (atomStore.contains(atom)) { - int atomId = atomStore.get(atom); - if (currentAssignment.getTruth(atomId) != ThriceTruth.TRUE) { - log("Atom is not TRUE. Skipping."); - continue; - } - } // Note: in case the atom is not in the atomStore, it came from a fact and hence is true. - Unifier sigma = Unification.instantiate(b, atom); - if (sigma == null) { - log("Atom does not unify with picked body literal."); - continue; - } - - CoreAtom bSigma = b.substitute(sigma); - if (!bSigma.isGround()) { - throw oops("Resulting atom is not ground."); - } - Set variablesOccurringInSigma = sigma.getMappedVariables(); - if (Unification.instantiate(bSigmaY, bSigma) != null) { - for (Unifier sigmaN : vN) { - ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); - occurringVariables.addAll(sigmaN.getMappedVariables()); - BasicAtom genericAtom = new BasicAtom(CorePredicate.getInstance("_", occurringVariables.size(), true), occurringVariables); - CoreAtom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); - if (Unification.instantiate(genericSubstituted, genericAtom.substitute(sigma)) != null) { - log("Atom {} is excluded by: {} via {}", genericSubstituted, sigmaN, sigma); - continue atomLoop; - } - } - log("Adding corresponding substitution to Y': {}", sigma); - vYp.add(sigma); - } - } - - log("Unjustified body literals: {}", vYp); - - Set vYpUN = new LinkedHashSet<>(); - vYpUN.addAll(vYp); - vYpUN.addAll(vN); - LitSet toJustify = new LitSet(bSigmaY, vYpUN); - if (!toJustify.coversNothing()) { - log("New litset to do: {}", toJustify); - ret.add(toJustify); - } else { - log("Generated LitSet covers nothing. Ignoring: {}", toJustify); - } - ArrayList newB = new ArrayList<>(vB); - newB.remove(chosenLiteralPos); - ret.addAll(unjustCover(newB, vYp, vN, currentAssignment)); - log("Literal set(s) to treat: {}", ret); - } - log("End unjustCover()."); - padDepth -= 2; - return ret; - } - - private String pad(String string) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < padDepth; i++) { - sb.append(" "); - } - sb.append(string); - return sb.toString(); - } - - private AssignedAtomsIterator getAssignedAtomsOverPredicate(CorePredicate predicate) { - // Find more substitutions, consider currentAssignment. - List assignedAtoms = this.assignedAtoms.get(predicate); - // Consider instances from facts. - LinkedHashSet factsOverPredicate = factsFromProgram.get(predicate); - return new AssignedAtomsIterator(predicate, assignedAtoms, factsOverPredicate); - } - - private static class AssignedAtomsIterator implements Iterator { - private final CorePredicate predicate; - private final Iterator assignedAtomsIterator; - private final Iterator factsIterator; - - public AssignedAtomsIterator(CorePredicate predicate, List assignedAtoms, Set facts) { - this.predicate = predicate; - this.assignedAtomsIterator = assignedAtoms == null ? Collections.emptyIterator() : assignedAtoms.iterator(); - this.factsIterator = facts == null ? Collections.emptyIterator() : facts.iterator(); - } - - @Override - public boolean hasNext() { - return assignedAtomsIterator.hasNext() || factsIterator.hasNext(); - } - - @Override - public CoreAtom next() { - if (assignedAtomsIterator.hasNext()) { - return assignedAtomsIterator.next(); - } - if (factsIterator.hasNext()) { - return new BasicAtom(predicate, factsIterator.next().terms); - } - throw new NoSuchElementException(); - } - } - - private List rulesHeadUnifyingWith(CoreAtom p) { - - List rulesWithUnifier = new ArrayList<>(); - CorePredicate predicate = p.getPredicate(); - - ArrayList definingRulesAndFacts = new ArrayList<>(); - // Get facts over the same predicate. - LinkedHashSet factInstances = factsFromProgram.get(predicate); - if (factInstances != null) { - for (Instance factInstance : factInstances) { - definingRulesAndFacts.add(new FactOrNonGroundRule(factInstance)); - } - } - - HashSet rulesDefiningPredicate = programAnalysis.getPredicateDefiningRules().get(predicate); - if (rulesDefiningPredicate != null) { - for (InternalRule nonGroundRule : rulesDefiningPredicate) { - definingRulesAndFacts.add(new FactOrNonGroundRule(nonGroundRule)); - } - } - for (FactOrNonGroundRule factOrNonGroundRule : definingRulesAndFacts) { - boolean isNonGroundRule = factOrNonGroundRule.nonGroundRule != null; - Set renamedBody; - CoreAtom headAtom; - if (isNonGroundRule) { - // First rename all variables in the rule. - InternalRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++); - renamedBody = rule.getBody(); - headAtom = rule.getHeadAtom(); - } else { - // Create atom and empty rule body out of instance. - headAtom = new BasicAtom(p.getPredicate(), factOrNonGroundRule.factInstance.terms); - renamedBody = Collections.emptySet(); - } - // Unify rule head with literal to justify. - Unifier unifier = Unification.unifyAtoms(p, headAtom); - // Note: maybe it is faster to first check unification and only rename the whole rule afterwards? - // Skip if unification failed. - if (unifier == null) { - continue; - } - rulesWithUnifier.add(new RuleAndUnifier(renamedBody, unifier, headAtom)); - } - return rulesWithUnifier; - } - - private void log(String msg, Object... refs) { - LOGGER.trace(pad(msg), refs); - } - - private static class ReturnExplainUnjust { - Set vL; - Set vToDo; - - ReturnExplainUnjust() { - vL = new LinkedHashSet<>(); - vToDo = new LinkedHashSet<>(); - } - } - - private static class RuleAndUnifier { - final Set ruleBody; - final Unifier unifier; - final CoreAtom originalHead; - - private RuleAndUnifier(Set ruleBody, Unifier unifier, CoreAtom originalHead) { - this.ruleBody = ruleBody; - this.unifier = unifier; - this.originalHead = originalHead; - } - - @Override - public String toString() { - return unifier + "@" + originalHead + " :- " + ruleBody; - } - } - - private static class FactOrNonGroundRule { - final Instance factInstance; - final InternalRule nonGroundRule; - - private FactOrNonGroundRule(Instance factInstance) { - this.factInstance = factInstance; - this.nonGroundRule = null; - } - - private FactOrNonGroundRule(InternalRule nonGroundRule) { - this.nonGroundRule = nonGroundRule; - this.factInstance = null; - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java deleted file mode 100644 index e599f42b8..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/structure/LitSet.java +++ /dev/null @@ -1,143 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.structure; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.VariableNormalizableAtom; -import at.ac.tuwien.kr.alpha.grounder.Unification; -import at.ac.tuwien.kr.alpha.grounder.Unifier; - -/** - * Copyright (c) 2018, the Alpha Team. - */ -public class LitSet { - private final CoreAtom atom; - private final Set complementSubstitutions; - private final int hashCode; - private final CoreAtom normalizedLiteral; - private final Set normalizedSubstitutions; - private static int litSetCounter = 1; - - LitSet(CoreAtom atom, Set complementSubstitutions) { - this.atom = atom.renameVariables("_AS" + litSetCounter++); - this.complementSubstitutions = new HashSet<>(); - for (Unifier complementSubstitution : complementSubstitutions) { - if (complementSubstitution == null) { - throw oops("Unifier is null."); - } - Unifier unifyRightAtom = normalizeSubstitution(atom, complementSubstitution, this.atom); - if (unifyRightAtom == null) { - throw oops("Unification result is null."); - } - this.complementSubstitutions.add(unifyRightAtom); - } - this.normalizedLiteral = computeNormalized(this.atom, "_N"); - this.normalizedSubstitutions = computeNormalizedSubstitutions(); - this.hashCode = computeHashCode(); - } - - /** - * Normalizes a substitution over the originalAtom into a substitution over the normalizedAtom. - * @param originalAtom - * @param substitution - * @param normalizedAtom - * @return - */ - private Unifier normalizeSubstitution(CoreAtom originalAtom, Unifier substitution, CoreAtom normalizedAtom) { - CoreAtom substitutedLiteral = originalAtom.substitute(substitution); - return Unification.instantiate(normalizedAtom, substitutedLiteral); - } - - /** - * Checks if the complementSubstitutions exclude everything. - * @return true if this LitSet represents the empty set (i.e., everything excluded). - */ - public boolean coversNothing() { - for (Unifier substitution : complementSubstitutions) { - if (Unification.instantiate(atom.substitute(substitution), atom) != null) { - return true; - } - } - return false; - } - - public CoreAtom getAtom() { - return atom; - } - - Set getComplementSubstitutions() { - return Collections.unmodifiableSet(complementSubstitutions); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("(" + atom + ",{"); - for (Unifier complementSubstitution : complementSubstitutions) { - sb.append(atom.substitute(complementSubstitution)); - sb.append(", "); - } - sb.append("})"); - return sb.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - LitSet litSet = (LitSet) o; - - if (hashCode() != o.hashCode()) { - return false; - } - - if (!normalizedLiteral.equals(litSet.normalizedLiteral)) { - return false; - } - - return normalizedSubstitutions.equals(litSet.normalizedSubstitutions); - } - - @Override - public int hashCode() { - return hashCode; - } - - private int computeHashCode() { - int result = normalizedLiteral.hashCode(); - result = 31 * result + normalizedSubstitutions.hashCode(); - return result; - } - - private CoreAtom computeNormalized(CoreAtom atom, String prefix) { - if (atom instanceof VariableNormalizableAtom) { - return ((VariableNormalizableAtom) atom).normalizeVariables(prefix, 0); - } else { - throw oops("Atom to normalize is of unknown type: " + atom); - } - } - - private Set computeNormalizedSubstitutions() { - Set ret = new LinkedHashSet<>(); - for (Unifier substitution : complementSubstitutions) { - Unifier preNormalizedSubstitution = normalizeSubstitution(atom, substitution, normalizedLiteral); - // Unifier may still contain variables in the right-hand side, those have to be normalized, too. - CoreAtom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); - // Apply substitution and normalize all remaining variables, i.e., those appearing at the right-hand side of the substitution. - CoreAtom normalized = computeNormalized(appliedSub, "_X"); - // Compute final substitution from normalized atom to the one where also variables are normalized. - Unifier normalizedSubstitution = new Unifier(Unification.instantiate(normalizedLiteral, normalized)); - ret.add(normalizedSubstitution); - } - return ret; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java deleted file mode 100644 index 5ff468496..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/CardinalityNormalization.java +++ /dev/null @@ -1,259 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.Unifier; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Copyright (c) 2017-2020, the Alpha Team. - */ -public class CardinalityNormalization extends ProgramTransformation { - - private int aggregateCount; - private ProgramParser parser = new ProgramParser(); - private final boolean useSortingCircuitEncoding; - - public CardinalityNormalization() { - this(true); - } - - public CardinalityNormalization(boolean useSortingCircuitEncoding) { - this.useSortingCircuitEncoding = useSortingCircuitEncoding; - } - - private InputProgram parse(String program) { - return parser.parse(program); - } - - @Override - public InputProgram apply(InputProgram inputProgram) { - if (!this.rewritingNecessary(inputProgram)) { - return inputProgram; - } - InputProgram.Builder programBuilder = InputProgram.builder(); - programBuilder.addFacts(inputProgram.getFacts()); - programBuilder.addInlineDirectives(inputProgram.getInlineDirectives()); - //@formatter:off - String cardinalityCountingGrid = - "span(R,1..I1) :- I1 = I-1, sorting_network_input_number(R,I).\n" + - "sum(R,0,0) :- sorting_network_input_number(R,_).\n" + - "sum(R,I,S) :- sum(R,I1,S), I1 = I-1, span(R,I).\n" + - "sum(R,I,S1) :- sum(R,I1,S),S1 = S+1, I1 = I-1, sorting_network_input_number(R,I),\n" + - " sorting_network_bound(R,K), S < K.\n" + - "sorting_network_output(R,K) :- sorting_network_bound(R,K), K <= S, sum(R,_,S).\n"; - - // Transforms all cardinality-aggregates into normal logic rules employing a lazy-grounded sorting circuit. - String phi = "N = (I - 1) / S - ((I - 1) / S / B) * B, S = 2 ** (P - L), B = 2 ** L"; - String cardinalitySortingCircuit = - "sorting_network_span(R,I) :- sorting_network_input_number(R,I).\n" + - "sorting_network_span(R,Im1) :- sorting_network_span(R,I), 1 rewrittenRules = rewriteAggregates(inputProgram.getRules()); - - String usedCardinalityEncoding = useSortingCircuitEncoding ? cardinalitySortingCircuit : cardinalityCountingGrid; - InputProgram cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParser().parse(usedCardinalityEncoding)); - programBuilder.addRules(rewrittenRules); - - // Add enumeration rule that uses the special EnumerationAtom. - // The enumeration rule is: "sorting_network_input_number(A, I) :- sorting_network_input(A, X), - // sorting_network_index(A, X, I)." - BasicRule tmpEnumRule = PredicateInternalizer.makePredicatesInternal(parse( - "sorting_network_input_number(A, I) :- sorting_network_input(A, X).")).getRules().get(0); - EnumerationAtom enumerationAtom = new EnumerationAtom(parse("sorting_network_index(A, X, I).").getFacts().get(0).getTerms()); - List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); - enumerationRuleBody.add(enumerationAtom.toLiteral()); - BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); - programBuilder.addRule(enumerationRule); - - // Add cardinality encoding to program. - programBuilder.accumulate(cardinalityEncoding); - return programBuilder.build(); - } - - /** - * Checks if rewriting of count aggregates is necessary for the given program, i.e. if such aggregates exist. - * - * @param program the program. - * @return true if count aggregates occur, false otherwise. - */ - private boolean rewritingNecessary(InputProgram program) { - for (BasicRule rule : program.getRules()) { - for (CoreLiteral lit : rule.getBody()) { - if (lit instanceof AggregateLiteral) { - AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); - if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.COUNT) { - return true; - } - } - } - } - return false; - } - - private List rewriteAggregates(List srcRules) { - List retVal = new ArrayList<>(); - for (BasicRule rule : srcRules) { - retVal.addAll(rewriteAggregatesInRule(rule)); - } - return retVal; - } - - private List rewriteAggregatesInRule(BasicRule rule) { - // Example rewriting/connection: - // num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K). - // is rewritten into: - // num(K) :- sorting_network_output(aggregate_arguments(-731776545), K), dom(K). - // sorting_network_input(aggregate_arguments(-731776545), element_tuple(X, Y, Z)) :- p(X, Y, Z). - // sorting_network_bound(aggregate_arguments(-731776545), K) :- dom(K). - - // Create interface atoms to the aggregate encoding. - final BasicAtom aggregateOutputAtom = (BasicAtom) PredicateInternalizer - .makePredicatesInternal(parse("sorting_network_output(aggregate_arguments(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - final BasicAtom aggregateInputAtom = (BasicAtom) PredicateInternalizer - .makePredicatesInternal(parse("sorting_network_input(aggregate_arguments(AGGREGATE_ID), ELEMENT_TUPLE).")).getFacts().get(0); - final BasicAtom lowerBoundAtom = (BasicAtom) PredicateInternalizer - .makePredicatesInternal(parse("sorting_network_bound(aggregate_arguments(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - - ArrayList aggregateOutputAtoms = new ArrayList<>(); - int aggregatesInRule = 0; // Only needed for limited rewriting. - ArrayList additionalRules = new ArrayList<>(); - - List rewrittenBody = new ArrayList<>(rule.getBody()); - - for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { - CoreLiteral bodyElement = iterator.next(); - // Skip non-aggregates. - if (!(bodyElement instanceof AggregateLiteral)) { - continue; - } - AggregateLiteral aggregateLiteral = (AggregateLiteral) bodyElement; - AggregateAtom aggregateAtom = aggregateLiteral.getAtom(); - - // Check that aggregate is limited to what we currently can deal with. - if (aggregateLiteral.isNegated() || aggregateAtom.getUpperBoundOperator() != null - || (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.COUNT - && aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.SUM) - || aggregatesInRule++ > 0) { - throw new UnsupportedOperationException( - "Only limited #count/#sum aggregates without upper bound are currently supported." + "No rule may have more than one aggregate."); - } - - // Only treat count aggregates. - if (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.COUNT) { - continue; - } - // Remove aggregate from rule body. - iterator.remove(); - - // Prepare aggregate parameters. - aggregateCount++; - Substitution aggregateSubstitution = new Unifier(); - Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); - if (globalVariables.isEmpty()) { - aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); - } else { - // In case some variables are not local to the aggregate, add them to the aggregate identifier - ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); - globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); - aggregateSubstitution.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); - } - aggregateSubstitution.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); - - // Create new output atom for addition to rule body instead of the aggregate. - aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateSubstitution).toLiteral()); - - // Create input to sorting network from aggregate elements. - for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { - // Prepare element substitution. - List elementTerms = aggregateElement.getElementTerms(); - FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); - Substitution elementSubstitution = new Unifier(aggregateSubstitution); - elementSubstitution.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); - - // Create new rule for input. - BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementSubstitution); - List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); - - // If there are global variables used inside the aggregate, add original rule body - // (minus the aggregate itself) to input rule. - if (!globalVariables.isEmpty()) { - elementLiterals.addAll(rewrittenBody); - } - BasicRule inputRule = new BasicRule(new NormalHead(inputHeadAtom), elementLiterals); - additionalRules.add(inputRule); - } - - // Create lower bound for the aggregate. - BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateSubstitution); - List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. - additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); - - } - rewrittenBody.addAll(aggregateOutputAtoms); - BasicRule rewrittenSrcRule = new BasicRule(rule.getHead(), rewrittenBody); - additionalRules.add(rewrittenSrcRule); - return additionalRules; - } - - static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { - // Hacky way to get all global variables: take all variables inside the aggregate that occur also in the - // rest of the rule. - HashSet occurringVariables = new LinkedHashSet<>(); - for (CoreLiteral element : ruleBody) { - if (element instanceof AggregateLiteral) { - continue; - } - occurringVariables.addAll(element.getBindingVariables()); - occurringVariables.addAll(element.getNonBindingVariables()); - } - LinkedHashSet globalVariables = new LinkedHashSet<>(); - for (CoreTerm aggVariable : aggregateAtom.getAggregateVariables()) { - if (occurringVariables.contains(aggVariable)) { - globalVariables.add(aggVariable); - } - } - return globalVariables; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java deleted file mode 100644 index 8dfe872e0..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ChoiceHeadToNormal.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.grounder.transformation; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.*; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.*; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Copyright (c) 2017-2020, the Alpha Team. - */ -public class ChoiceHeadToNormal extends ProgramTransformation { - private final static String PREDICATE_NEGATION_PREFIX = "_n"; - - @Override - public InputProgram apply(InputProgram inputProgram) { - InputProgram.Builder programBuilder = InputProgram.builder(); - List additionalRules = new ArrayList<>(); - - List srcRules = new ArrayList<>(inputProgram.getRules()); - Iterator ruleIterator = srcRules.iterator(); - while (ruleIterator.hasNext()) { - BasicRule rule = ruleIterator.next(); - - Head ruleHead = rule.getHead(); - if (!(ruleHead instanceof ChoiceHead)) { - // Rule is constraint or without choice in the head. Leave as is. - continue; - } - - // Remove this rule, as it will be transformed. - ruleIterator.remove(); - - ChoiceHead choiceHead = (ChoiceHead) ruleHead; - // Choice rules with boundaries are not yet supported. - if (choiceHead.getLowerBound() != null || choiceHead.getUpperBound() != null) { - throw new UnsupportedOperationException("Found choice rule with bounds, which are not yet supported. Rule is: " + rule); - } - - // Only rewrite rules with a choice in their head. - for (ChoiceHead.ChoiceElement choiceElement : choiceHead.getChoiceElements()) { - // Create two guessing rules for each choiceElement. - - // Construct common body to both rules. - CoreAtom head = choiceElement.choiceAtom; - List ruleBody = new ArrayList<>(rule.getBody()); - ruleBody.addAll(choiceElement.conditionLiterals); - - if (containsIntervalTerms(head)) { - throw new RuntimeException("Program contains a choice rule with interval terms in its head. This is not supported (yet)."); - } - - // Construct head atom for the choice. - CorePredicate headPredicate = head.getPredicate(); - - CorePredicate negPredicate = CorePredicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); - List headTerms = new ArrayList<>(head.getTerms()); - headTerms.add(0, CoreConstantTerm.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for - // classical negative atoms. - CoreAtom negHead = new BasicAtom(negPredicate, headTerms); - - // Construct two guessing rules. - List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); - guessingRuleBodyWithNegHead.add(new BasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); - additionalRules.add(new BasicRule(new NormalHead(negHead), guessingRuleBodyWithNegHead)); - - List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); - guessingRuleBodyWithHead.add(new BasicAtom(negPredicate, headTerms).toLiteral(false)); - additionalRules.add(new BasicRule(new NormalHead(head), guessingRuleBodyWithHead)); - - // TODO: when cardinality constraints are possible, process the boundaries by adding a constraint with a cardinality check. - } - } - return programBuilder.addRules(srcRules).addRules(additionalRules).addFacts(inputProgram.getFacts()) - .addInlineDirectives(inputProgram.getInlineDirectives()).build(); - } - - private static boolean containsIntervalTerms(CoreAtom atom) { - for (CoreTerm term : atom.getTerms()) { - if (IntervalTerm.termContainsIntervalTerm(term)) { - return true; - } - } - return false; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java deleted file mode 100644 index 54b78535c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/EnumerationRewriting.java +++ /dev/null @@ -1,86 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; - -/** - * Rewrites the ordinary atom whose name is given in the input program by the enumeration directive #enum_atom_is into - * the special EnumerationAtom. - * - * Copyright (c) 2017-2020, the Alpha Team. - */ -public class EnumerationRewriting extends ProgramTransformation { - - @Override - public InputProgram apply(InputProgram inputProgram) { - // Read enumeration predicate from directive. - String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectives.DIRECTIVE.enum_predicate_is); - if (enumDirective == null) { - // Directive not set, nothing to rewrite. - return inputProgram; - } - CorePredicate enumPredicate = CorePredicate.getInstance(enumDirective, 3); - - InputProgram.Builder programBuilder = InputProgram.builder().addInlineDirectives(inputProgram.getInlineDirectives()); - - checkFactsAreEnumerationFree(inputProgram.getFacts(), enumPredicate); - programBuilder.addFacts(inputProgram.getFacts()); - - List srcRules = new ArrayList<>(inputProgram.getRules()); - programBuilder.addRules(rewriteRules(srcRules, enumPredicate)); - return programBuilder.build(); - } - - private void checkFactsAreEnumerationFree(List srcFacts, CorePredicate enumPredicate) { - for (CoreAtom fact : srcFacts) { - if (fact.getPredicate().equals(enumPredicate)) { - throw oops("Atom declared as enumeration atom by directive occurs in a fact: " + fact); - } - } - } - - private List rewriteRules(List srcRules, CorePredicate enumPredicate) { - List rewrittenRules = new ArrayList<>(); - for (BasicRule rule : srcRules) { - if (rule.getHead() != null && !(rule.getHead() instanceof NormalHead)) { - throw oops("Encountered rule whose head is not normal: " + rule); - } - 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()); - Iterator rit = modifiedBodyLiterals.iterator(); - LinkedList rewrittenLiterals = new LinkedList<>(); - while (rit.hasNext()) { - CoreLiteral literal = rit.next(); - if (!(literal instanceof BasicLiteral)) { - continue; - } - BasicLiteral basicLiteral = (BasicLiteral) literal; - if (!basicLiteral.getPredicate().equals(enumPredicate)) { - continue; - } - rit.remove(); - rewrittenLiterals.add(new EnumerationAtom(basicLiteral.getAtom().getTerms()).toLiteral()); - } - modifiedBodyLiterals.addAll(rewrittenLiterals); - rewrittenRules.add(new BasicRule(rule.getHead(), modifiedBodyLiterals)); - } - return rewrittenRules; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java deleted file mode 100644 index 0307133cf..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/IntervalTermToIntervalAtom.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.grounder.transformation; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.atoms.IntervalAtom; - -/** - * Rewrites all interval terms in a rule into a new variable and an IntervalAtom. - * - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class IntervalTermToIntervalAtom extends ProgramTransformation { - private static final String INTERVAL_VARIABLE_PREFIX = "_Interval"; - - /** - * Rewrites intervals into a new variable and special IntervalAtom. - * - * @return true if some interval occurs in the rule. - */ - private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { - // Collect all intervals and replace them with variables. - Map intervalReplacements = new LinkedHashMap<>(); - - List rewrittenBody = new ArrayList<>(); - - for (CoreLiteral literal : rule.getBody()) { - rewrittenBody.add(rewriteLiteral(literal, intervalReplacements)); - } - NormalHead rewrittenHead = rule.isConstraint() ? null : - new NormalHead(rewriteLiteral(rule.getHeadAtom().toLiteral(), intervalReplacements).getAtom()); - - // If intervalReplacements is empty, no IntervalTerms have been found, keep rule as is. - if (intervalReplacements.isEmpty()) { - return rule; - } - - // Add new IntervalAtoms representing the interval specifications. - for (Map.Entry interval : intervalReplacements.entrySet()) { - rewrittenBody.add(new IntervalAtom(interval.getValue(), interval.getKey()).toLiteral()); - } - return new NormalRule(rewrittenHead, rewrittenBody); - } - - /** - * Replaces every IntervalTerm by a new variable and returns a mapping of the replaced VariableTerm -> IntervalTerm. - */ - private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { - CoreAtom atom = lit.getAtom(); - List termList = new ArrayList<>(atom.getTerms()); - boolean didChange = false; - for (int i = 0; i < termList.size(); i++) { - CoreTerm term = termList.get(i); - if (term instanceof IntervalTerm) { - VariableTerm replacementVariable = VariableTerm.getInstance(INTERVAL_VARIABLE_PREFIX + intervalReplacement.size()); - intervalReplacement.put(replacementVariable, (IntervalTerm) term); - termList.set(i, replacementVariable); - didChange = true; - } - if (term instanceof FunctionTerm) { - // Rewrite function terms recursively. - FunctionTerm rewrittenFunctionTerm = rewriteFunctionTerm((FunctionTerm) term, intervalReplacement); - termList.set(i, rewrittenFunctionTerm); - didChange = true; - } - } - if (didChange) { - CoreAtom rewrittenAtom = atom.withTerms(termList); - return lit.isNegated() ? rewrittenAtom.toLiteral().negate() : rewrittenAtom.toLiteral(); - } - return lit; - } - - private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map intervalReplacement) { - List termList = new ArrayList<>(functionTerm.getTerms()); - boolean didChange = false; - for (int i = 0; i < termList.size(); i++) { - CoreTerm term = termList.get(i); - if (term instanceof IntervalTerm) { - VariableTerm replacementVariable = VariableTerm.getInstance("_Interval" + intervalReplacement.size()); - intervalReplacement.put(replacementVariable, (IntervalTerm) term); - termList.set(i, replacementVariable); - didChange = true; - } - if (term instanceof FunctionTerm) { - // Recursively rewrite function terms. - FunctionTerm rewrittenFunctionTerm = rewriteFunctionTerm((FunctionTerm) term, intervalReplacement); - if (rewrittenFunctionTerm != term) { - termList.set(i, rewrittenFunctionTerm); - didChange = true; - } - } - } - if (didChange) { - return FunctionTerm.getInstance(functionTerm.getSymbol(), termList); - } - return functionTerm; - } - - @Override - public NormalProgram apply(NormalProgram inputProgram) { - boolean didChange = false; - List rewrittenRules = new ArrayList<>(); - for (NormalRule rule : inputProgram.getRules()) { - NormalRule rewrittenRule = rewriteIntervalSpecifications(rule); - rewrittenRules.add(rewrittenRule); - - // If no rewriting occurred, the output rule is the same as the input to the rewriting. - if (rewrittenRule != rule) { - didChange = true; - } - } - // Return original program if no rule was actually rewritten. - if (!didChange) { - return inputProgram; - } - return new NormalProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java deleted file mode 100644 index 3d68d7e06..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/NormalizeProgramTransformation.java +++ /dev/null @@ -1,42 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; - -/** - * Encapsulates all transformations necessary to transform a given program into a @{link NormalProgram} that is understood by Alpha internally - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public class NormalizeProgramTransformation extends ProgramTransformation { - - private boolean useNormalizationGrid; - - public NormalizeProgramTransformation(boolean useNormalizationGrid) { - this.useNormalizationGrid = useNormalizationGrid; - } - - @Override - public NormalProgram apply(InputProgram inputProgram) { - InputProgram tmpPrg; - // Transform choice rules. - tmpPrg = new ChoiceHeadToNormal().apply(inputProgram); - // Transform cardinality aggregates. - tmpPrg = new CardinalityNormalization(!this.useNormalizationGrid).apply(tmpPrg); - // Transform sum aggregates. - tmpPrg = new SumNormalization().apply(tmpPrg); - // Transform enumeration atoms. - tmpPrg = new EnumerationRewriting().apply(tmpPrg); - EnumerationAtom.resetEnumerations(); - - // Construct the normal program. - NormalProgram retVal = NormalProgram.fromInputProgram(tmpPrg); - // Transform intervals - CAUTION - this MUST come before VariableEqualityRemoval! - retVal = new IntervalTermToIntervalAtom().apply(retVal); - // Remove variable equalities. - retVal = new VariableEqualityRemoval().apply(retVal); - return retVal; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java deleted file mode 100644 index 956296bdd..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/PredicateInternalizer.java +++ /dev/null @@ -1,61 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import java.util.ArrayList; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.Head; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; - -/** - * - * Rewrites all predicates of a given Program such that they are internal and hence hidden from answer sets. - * - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class PredicateInternalizer { - - static InputProgram makePredicatesInternal(InputProgram program) { - InputProgram.Builder prgBuilder = InputProgram.builder(); - for (CoreAtom atom : program.getFacts()) { - prgBuilder.addFact(PredicateInternalizer.makePredicateInternal(atom)); - } - for (BasicRule rule : program.getRules()) { - prgBuilder.addRule(PredicateInternalizer.makePredicateInternal(rule)); - } - prgBuilder.addInlineDirectives(program.getInlineDirectives()); - return prgBuilder.build(); - } - - private static BasicRule makePredicateInternal(BasicRule rule) { - Head newHead = null; - if (rule.getHead() != null) { - if (!(rule.getHead() instanceof NormalHead)) { - throw new UnsupportedOperationException("Cannot make predicates in rules internal whose head is not normal."); - } - newHead = new NormalHead(makePredicateInternal(((NormalHead) rule.getHead()).getAtom())); - } - List newBody = new ArrayList<>(); - for (CoreLiteral bodyElement : rule.getBody()) { - // Only rewrite BasicAtoms. - if (bodyElement instanceof BasicLiteral) { - newBody.add(makePredicateInternal(bodyElement.getAtom()).toLiteral()); - } else { - // Keep other body element as is. - newBody.add(bodyElement); - } - } - return new BasicRule(newHead, newBody); - } - - private static CoreAtom makePredicateInternal(CoreAtom atom) { - CorePredicate newInternalPredicate = CorePredicate.getInstance(atom.getPredicate().getName(), atom.getPredicate().getArity(), true); - return new BasicAtom(newInternalPredicate, atom.getTerms()); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java deleted file mode 100644 index 6aa85027c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/ProgramTransformation.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import at.ac.tuwien.kr.alpha.common.program.AbstractProgram; - -/** - * Copyright (c) 2017-2019, the Alpha Team. - */ -public abstract class ProgramTransformation, O extends AbstractProgram> { - - public abstract O apply(I inputProgram); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java deleted file mode 100644 index 4c7b470ef..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluation.java +++ /dev/null @@ -1,369 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Stack; - -import org.apache.commons.collections4.SetUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.common.CorePredicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; -import at.ac.tuwien.kr.alpha.common.depgraph.Node; -import at.ac.tuwien.kr.alpha.common.depgraph.StratificationAlgorithm; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.IndexedInstanceStorage; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrder; -import at.ac.tuwien.kr.alpha.grounder.RuleGroundingOrders; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.grounder.instantiation.AssignmentStatus; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiationResult; -import at.ac.tuwien.kr.alpha.grounder.instantiation.LiteralInstantiator; -import at.ac.tuwien.kr.alpha.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy; - -/** - * Evaluates the stratifiable part of a given (analyzed) ASP program. - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public class StratifiedEvaluation extends ProgramTransformation { - - private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluation.class); - - private WorkingMemory workingMemory = new WorkingMemory(); - private Map> predicateDefiningRules; - - private Map> modifiedInLastEvaluationRun = new HashMap<>(); - - private List additionalFacts = new ArrayList<>(); // 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; - - @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) { - // Calculate a stratification and initialize the working memory. - ComponentGraph componentGraph = inputProgram.getComponentGraph(); - List strata = StratificationAlgorithm.calculateStratification(componentGraph); - predicateDefiningRules = inputProgram.getPredicateDefiningRules(); - - // Set up list of atoms which are known to be true - these will be expand by the evaluation. - Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); - for (Map.Entry> entry : knownFacts.entrySet()) { - workingMemory.initialize(entry.getKey()); - workingMemory.addInstances(entry.getKey(), true, entry.getValue()); - } - - // Create working memories for all predicates occurring in each rule. - for (InternalRule nonGroundRule : inputProgram.getRulesById().values()) { - for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { - workingMemory.initialize(predicate); - } - } - - workingMemory.reset(); - - // Set up literal instantiator. - literalInstantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); - - // Evaluate the program part covered by the calculated stratification. - for (SCComponent currComponent : strata) { - evaluateComponent(currComponent); - } - - // 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); - } - - private void evaluateComponent(SCComponent comp) { - LOGGER.debug("Evaluating component {}", comp); - ComponentEvaluationInfo evaluationInfo = getRulesToEvaluate(comp); - if (evaluationInfo.isEmpty()) { - LOGGER.debug("No rules to evaluate for component {}", comp); - return; - } - - // Rules outside of dependency cycles only need to be evaluated once. - if (!evaluationInfo.nonRecursiveRules.isEmpty()) { - prepareInitialEvaluation(evaluationInfo.nonRecursiveRules); - 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(new BasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } - instanceStorage.markRecentlyAddedInstancesDone(); - } - } - boolean isInitialRun = true; - if (!evaluationInfo.recursiveRules.isEmpty()) { - do { - // Now do the rules that cyclically depend on each other, - // evaluate these until nothing new can be derived any more. - if (isInitialRun) { - prepareInitialEvaluation(evaluationInfo.recursiveRules); - } - evaluateRules(evaluationInfo.recursiveRules, isInitialRun); - isInitialRun = false; - modifiedInLastEvaluationRun = new HashMap<>(); - // 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(new BasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } - modifiedInLastEvaluationRun.putIfAbsent(instanceStorage.getPredicate(), new LinkedHashSet<>()); - modifiedInLastEvaluationRun.get(instanceStorage.getPredicate()).addAll(instanceStorage.getRecentlyAddedInstances()); - instanceStorage.markRecentlyAddedInstancesDone(); - } - // If the evaluation of rules did not modify the working memory we have a fixed-point. - } while (!workingMemory.modified().isEmpty()); - } - LOGGER.debug("Evaluation done - reached a fixed point on component {}", comp); - SetUtils.union(evaluationInfo.nonRecursiveRules, evaluationInfo.recursiveRules) - .forEach((rule) -> solvedRuleIds.add(rule.getRuleId())); - } - - private void evaluateRules(Set rules, boolean isInitialRun) { - workingMemory.reset(); - LOGGER.debug("Starting component evaluation run..."); - for (InternalRule r : rules) { - evaluateRule(r, !isInitialRun); - } - } - - /** - * To be called at the start of evaluateComponent. Adds all known instances of the predicates occurring in the given set - * of rules to the "modifiedInLastEvaluationRun" map in order to "bootstrap" incremental grounding, i.e. making sure - * that those instances are taken into account for ground substitutions by evaluateRule. - */ - private void prepareInitialEvaluation(Set rulesToEvaluate) { - modifiedInLastEvaluationRun = new HashMap<>(); - for (InternalRule rule : rulesToEvaluate) { - // Register rule head instances. - CorePredicate headPredicate = rule.getHeadAtom().getPredicate(); - IndexedInstanceStorage headInstances = workingMemory.get(headPredicate, true); - modifiedInLastEvaluationRun.putIfAbsent(headPredicate, new LinkedHashSet<>()); - if (headInstances != null) { - modifiedInLastEvaluationRun.get(headPredicate).addAll(headInstances.getAllInstances()); - } - // Register positive body literal instances. - for (CoreLiteral lit : rule.getPositiveBody()) { - CorePredicate bodyPredicate = lit.getPredicate(); - IndexedInstanceStorage bodyInstances = workingMemory.get(bodyPredicate, true); - modifiedInLastEvaluationRun.putIfAbsent(bodyPredicate, new LinkedHashSet<>()); - if (bodyInstances != null) { - modifiedInLastEvaluationRun.get(bodyPredicate).addAll(bodyInstances.getAllInstances()); - } - } - } - } - - private void evaluateRule(InternalRule rule, boolean checkAllStartingLiterals) { - LOGGER.debug("Evaluating rule {}", rule); - List satisfyingSubstitutions = calculateSatisfyingSubstitutionsForRule(rule, checkAllStartingLiterals); - for (Substitution subst : satisfyingSubstitutions) { - fireRule(rule, subst); - } - } - - private List calculateSatisfyingSubstitutionsForRule(InternalRule rule, boolean checkAllStartingLiterals) { - LOGGER.debug("Grounding rule {}", rule); - RuleGroundingOrders groundingOrders = rule.getGroundingOrders(); - - // Treat rules with fixed instantiation first. - LOGGER.debug("Is fixed rule? {}", rule.getGroundingOrders().fixedInstantiation()); - if (groundingOrders.fixedInstantiation()) { - RuleGroundingOrder fixedGroundingOrder = groundingOrders.getFixedGroundingOrder(); - return calcSubstitutionsWithGroundingOrder(fixedGroundingOrder, Collections.singletonList(new Substitution())); - } - - List startingLiterals = groundingOrders.getStartingLiterals(); - // Check only one starting literal if indicated by the parameter. - if (!checkAllStartingLiterals) { - // If this is the first evaluation run, it suffices to start from the first starting literal only. - CoreLiteral lit = startingLiterals.get(0); - return calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), substituteFromRecentlyAddedInstances(lit)); - } - - // Ground from all starting literals. - List groundSubstitutions = new ArrayList<>(); // Collection of full ground substitutions for the given rule. - for (CoreLiteral lit : startingLiterals) { - List substitutionsForStartingLiteral = calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), - substituteFromRecentlyAddedInstances(lit)); - groundSubstitutions.addAll(substitutionsForStartingLiteral); - } - return groundSubstitutions; - } - - /** - * 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). - */ - private List substituteFromRecentlyAddedInstances(CoreLiteral lit) { - List retVal = new ArrayList<>(); - Set instances = modifiedInLastEvaluationRun.get(lit.getPredicate()); - if (instances == null) { - return Collections.emptyList(); - } - for (Instance instance : instances) { - Substitution unifyingSubstitution = Substitution.specializeSubstitution(lit, instance, Substitution.EMPTY_SUBSTITUTION); - if (unifyingSubstitution != null) { - retVal.add(unifyingSubstitution); - } - } - return retVal; - } - - private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrder groundingOrder, List startingSubstitutions) { - // Iterate through the grounding order and whenever instantiation of a Literal with a given substitution - // causes a result with a type other than CONTINUE, discard that substitution. - - // Note that this function uses a stack of partial substitutions to simulate a recursive function. - Stack> substitutionStack = new Stack<>(); // For speed, we really want ArrayLists on the stack. - if (startingSubstitutions instanceof ArrayList) { - substitutionStack.push((ArrayList) startingSubstitutions); - } else { - substitutionStack.push(new ArrayList<>(startingSubstitutions)); // Copy startingSubstitutions into ArrayList. Note: mostly happens for empty or - // singleton lists. - } - int currentOrderPosition = 0; - List fullSubstitutions = new ArrayList<>(); - while (!substitutionStack.isEmpty()) { - List currentSubstitutions = substitutionStack.peek(); - // If no more substitutions remain at current position, all have been processed, continue on next lower level. - if (currentSubstitutions.isEmpty()) { - substitutionStack.pop(); - currentOrderPosition--; - continue; - } - // In case the full grounding order has been worked on, all current substitutions are full substitutions, add them to - // result. - CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(currentOrderPosition); - if (currentLiteral == null) { - fullSubstitutions.addAll(currentSubstitutions); - currentSubstitutions.clear(); - // Continue on next lower level. - substitutionStack.pop(); - currentOrderPosition--; - continue; - } - // 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). - 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. - ArrayList furtheredSubstitutions = new ArrayList<>(); - for (ImmutablePair resultSubstitution : currentLiteralResult.getSubstitutions()) { - furtheredSubstitutions.add(resultSubstitution.left); - } - substitutionStack.push(furtheredSubstitutions); - // Continue work on the higher level. - currentOrderPosition++; - } - } - return fullSubstitutions; - } - - private void fireRule(InternalRule rule, Substitution substitution) { - CoreAtom newAtom = rule.getHeadAtom().substitute(substitution); - if (!newAtom.isGround()) { - throw new IllegalStateException("Trying to fire rule " + rule.toString() + " with incompatible substitution " + substitution.toString()); - } - LOGGER.debug("Firing rule - got head atom: {}", newAtom); - workingMemory.addInstance(newAtom, true); - } - - private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { - Set nonRecursiveRules = new HashSet<>(); - Set recursiveRules = new HashSet<>(); - - // Collect all predicates occurring in heads of rules of the given component. - Set headPredicates = new HashSet<>(); - for (Node node : comp.getNodes()) { - headPredicates.add(node.getPredicate()); - } - // Check each predicate whether its defining rules depend on some of the head predicates, i.e., whether there is a - // cycle. - for (CorePredicate headPredicate : headPredicates) { - HashSet definingRules = predicateDefiningRules.get(headPredicate); - if (definingRules == null) { - // Predicate only occurs in facts, skip. - continue; - } - // Note: here we assume that all rules defining a predicate belong to the same SC component. - for (InternalRule rule : definingRules) { - boolean isRuleRecursive = false; - for (CoreLiteral lit : rule.getPositiveBody()) { - if (headPredicates.contains(lit.getPredicate())) { - // The rule body contains a predicate that is defined in the same - // component, the rule is therefore part of a cyclic dependency within - // this component. - isRuleRecursive = true; - } - } - if (isRuleRecursive) { - recursiveRules.add(rule); - } else { - nonRecursiveRules.add(rule); - } - } - } - return new ComponentEvaluationInfo(nonRecursiveRules, recursiveRules); - } - - /** - * Internal helper class to group rules within an {@SCComponent} into rules that are recursive, i.e. part of some cyclic - * 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 { - final Set nonRecursiveRules; - final Set recursiveRules; - - ComponentEvaluationInfo(Set nonRecursive, Set recursive) { - nonRecursiveRules = Collections.unmodifiableSet(nonRecursive); - recursiveRules = Collections.unmodifiableSet(recursive); - } - - boolean isEmpty() { - return nonRecursiveRules.isEmpty() && recursiveRules.isEmpty(); - } - - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java deleted file mode 100644 index c12827fa7..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/SumNormalization.java +++ /dev/null @@ -1,201 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import static at.ac.tuwien.kr.alpha.grounder.transformation.PredicateInternalizer.makePredicatesInternal; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Unifier; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Rewrites #sum aggregates into normal rules. - * Note: Currently only works for a restricted form. - * - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class SumNormalization extends ProgramTransformation { - - private int aggregateCount; - private ProgramParser parser = new ProgramParser(); - - private InputProgram parse(String program) { - return parser.parse(program); - } - - @Override - public InputProgram apply(InputProgram inputProgram) { - if (!rewritingNecessary(inputProgram)) { - return inputProgram; - } - String summationSubprogram = "interesting_number(R, 1..I1) :- input_number_with_first(R, I, _), I1 = I - 1.\n" - + "prefix_subset_sum(R, 0, 0) :- input_number_with_first(R, _, _).\n" - + "prefix_subset_sum(R, I, S) :- prefix_subset_sum(R, I1, S), I1 = I - 1, interesting_number(R, I).\n" - + "prefix_subset_sum(R, I, SF) :- prefix_subset_sum(R, I1, S), I1 = I - 1, SF = S + F, input_number_with_first(R, I, F), bound(R, K), SF < K.\n" - + "output(R, K) :- bound(R, K), K <= 0." - + "output(R, K) :- prefix_subset_sum(R, I1, S), I1 = I - 1, input_number_with_first(R, I, F), bound(R, K), K <= S + F."; - - // Connect/Rewrite every aggregate in each rule. - List rewrittenRules = rewriteAggregates(inputProgram.getRules()); - - InputProgram.Builder prgBuilder = InputProgram.builder(); - prgBuilder.addFacts(inputProgram.getFacts()); - InputProgram summationEncoding = makePredicatesInternal(new ProgramParser().parse(summationSubprogram)); - prgBuilder.accumulate(summationEncoding); - prgBuilder.addRules(rewrittenRules); - - // Add enumeration rule that uses the special EnumerationAtom. - // The enumeration rule is: "input_number_with_first(A, I, F) :- input_with_first(A, X, F), _index(A, X, I)." - BasicRule tmpEnumRule = makePredicatesInternal(parse("input_number_with_first(A, I, F) :- input_with_first(A, X, F).")).getRules().get(0); - EnumerationAtom enumerationAtom = new EnumerationAtom(parse("index(A, X, I).").getFacts().get(0).getTerms()); - List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); - enumerationRuleBody.add(enumerationAtom.toLiteral()); - BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); - prgBuilder.addRule(enumerationRule); - - return prgBuilder.build(); - } - - /** - * Checks if rewriting of sum aggregates is necessary for the given program, i.e. if such aggregates exist. - * - * @param program the program. - * @return true if sum aggregates occur, false otherwise. - */ - private boolean rewritingNecessary(InputProgram program) { - for (BasicRule rule : program.getRules()) { - for (CoreLiteral lit : rule.getBody()) { - if (lit instanceof AggregateLiteral) { - AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); - if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.SUM) { - return true; - } - } - } - } - return false; - } - - private List rewriteAggregates(List srcRules) { - List rewrittenRules = new ArrayList<>(); - for (BasicRule rule : srcRules) { - rewrittenRules.addAll(rewriteAggregatesInRule(rule)); - } - return rewrittenRules; - } - - private List rewriteAggregatesInRule(BasicRule rule) { - - // Example rewriting/connection: - // x :- 6 <= #sum {3,a:a; 4,b:b; 5,c:c}. - // is rewritten to: - // x :- output(aggregate(1), 6). - // input_with_first(aggregate(1), element_tuple(3, a), 3) :- a. - // input_with_first(aggregate(1), element_tuple(4, b), 4) :- b. - // input_with_first(aggregate(1), element_tuple(5, c), 5) :- c. - // bound(aggregate(1), 6). - - // Create interface atoms to the aggregate encoding. - final BasicAtom aggregateOutputAtom = (BasicAtom) makePredicatesInternal(parse( - "output(aggregate(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - final BasicAtom aggregateInputAtom = (BasicAtom) makePredicatesInternal(parse( - "input_with_first(aggregate(AGGREGATE_ID), ELEMENT_TUPLE, FIRST_VARIABLE).")).getFacts().get(0); - final BasicAtom lowerBoundAtom = (BasicAtom) makePredicatesInternal(parse( - "bound(aggregate(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - - ArrayList aggregateOutputAtoms = new ArrayList<>(); - int aggregatesInRule = 0; // Only needed for limited rewriting. - ArrayList additionalRules = new ArrayList<>(); - - List rewrittenBody = new ArrayList<>(rule.getBody()); - for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { - CoreLiteral bodyElement = iterator.next(); - // Skip non-aggregates. - if (!(bodyElement instanceof AggregateLiteral)) { - continue; - } - AggregateLiteral aggregateLiteral = (AggregateLiteral) bodyElement; - AggregateAtom aggregateAtom = aggregateLiteral.getAtom(); - - // Check that aggregate is limited to what we currently can deal with. - if (aggregateLiteral.isNegated() || aggregateAtom.getUpperBoundOperator() != null - || (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.COUNT - && aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.SUM) - || aggregatesInRule++ > 0) { - throw new UnsupportedOperationException("Only limited #count/#sum aggregates without upper bound are currently supported." + "No rule may have more than one aggregate."); - } - - // Only treat sum aggregates. - if (aggregateAtom.getAggregatefunction() != AggregateAtom.AGGREGATEFUNCTION.SUM) { - continue; - } - // Remove aggregate from rule body. - iterator.remove(); - - // Prepare aggregate parameters. - aggregateCount++; - Unifier aggregateUnifier = new Unifier(); - Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); - if (globalVariables.isEmpty()) { - aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); - } else { - // In case some variables are not local to the aggregate, add them to the aggregate identifier - ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); - globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); - aggregateUnifier.put(VariableTerm.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); - } - aggregateUnifier.put(VariableTerm.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); - - // Create new output atom for addition to rule body instead of the aggregate. - aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateUnifier).toLiteral()); - - // Create input to sorting network from aggregate elements. - for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { - // Prepare element substitution. - List elementTerms = aggregateElement.getElementTerms(); - FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); - Unifier elementUnifier = new Unifier(aggregateUnifier); - elementUnifier.put(VariableTerm.getInstance("ELEMENT_TUPLE"), elementTuple); - elementUnifier.put(VariableTerm.getInstance("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); - - // Create new rule for input. - BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementUnifier); - List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); - - // If there are global variables used inside the aggregate, add original rule body (minus the aggregate itself) to input rule. - if (!globalVariables.isEmpty()) { - elementLiterals.addAll(rewrittenBody); - } - BasicRule inputRule = new BasicRule(new NormalHead(inputHeadAtom), elementLiterals); - additionalRules.add(inputRule); - } - - // Create lower bound for the aggregate. - BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateUnifier); - List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. - additionalRules.add(new BasicRule(new NormalHead(lowerBoundHeadAtom), lowerBoundBody)); - } - if (aggregatesInRule > 0) { - rewrittenBody.addAll(aggregateOutputAtoms); - additionalRules.add(new BasicRule(rule.getHead(), rewrittenBody)); - } else { - // Return original rule if no aggregate occurs in it. - additionalRules.add(rule); - } - return additionalRules; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java b/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java deleted file mode 100644 index 7a86941fc..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/grounder/transformation/VariableEqualityRemoval.java +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.grounder.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 at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Unifier; - -/** - * Removes variable equalities from rules by replacing one variable with the other. - * - * Copyright (c) 2017-2020, the Alpha Team. - */ -public class VariableEqualityRemoval extends ProgramTransformation { - - @Override - public NormalProgram apply(NormalProgram inputProgram) { - List rewrittenRules = new ArrayList<>(); - for (NormalRule rule : inputProgram.getRules()) { - rewrittenRules.add(findAndReplaceVariableEquality(rule)); - } - return new NormalProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); - } - - private NormalRule findAndReplaceVariableEquality(NormalRule rule) { - // Collect all equal variables. - HashMap> variableToEqualVariables = new LinkedHashMap<>(); - HashSet equalitiesToRemove = new HashSet<>(); - for (CoreLiteral bodyElement : rule.getBody()) { - if (!(bodyElement instanceof ComparisonLiteral)) { - continue; - } - ComparisonLiteral comparisonLiteral = (ComparisonLiteral) bodyElement; - if (!comparisonLiteral.isNormalizedEquality()) { - continue; - } - if (comparisonLiteral.getTerms().get(0) instanceof VariableTerm && comparisonLiteral.getTerms().get(1) instanceof VariableTerm) { - VariableTerm leftVariable = (VariableTerm) comparisonLiteral.getTerms().get(0); - VariableTerm rightVariable = (VariableTerm) comparisonLiteral.getTerms().get(1); - HashSet leftEqualVariables = variableToEqualVariables.get(leftVariable); - HashSet rightEqualVariables = variableToEqualVariables.get(rightVariable); - if (leftEqualVariables == null && rightEqualVariables == null) { - HashSet equalVariables = new LinkedHashSet<>(Arrays.asList(leftVariable, rightVariable)); - variableToEqualVariables.put(leftVariable, equalVariables); - variableToEqualVariables.put(rightVariable, equalVariables); - } - if (leftEqualVariables == null && rightEqualVariables != null) { - rightEqualVariables.add(leftVariable); - variableToEqualVariables.put(leftVariable, rightEqualVariables); - } - if (leftEqualVariables != null && rightEqualVariables == null) { - leftEqualVariables.add(rightVariable); - variableToEqualVariables.put(rightVariable, leftEqualVariables); - } - if (leftEqualVariables != null && rightEqualVariables != null) { - leftEqualVariables.addAll(rightEqualVariables); - for (VariableTerm rightEqualVariable : rightEqualVariables) { - variableToEqualVariables.put(rightEqualVariable, leftEqualVariables); - } - } - equalitiesToRemove.add(comparisonLiteral); - } - } - if (variableToEqualVariables.isEmpty()) { - // Skip rule if there is no equality between variables. - return rule; - } - - List rewrittenBody = new ArrayList<>(rule.getBody()); - NormalHead rewrittenHead = rule.isConstraint() ? null : new NormalHead(rule.getHeadAtom()); - - // Use substitution for actual replacement. - Unifier replacementSubstitution = new Unifier(); - // For each set of equal variables, take the first variable and replace all others by it. - for (Map.Entry> variableEqualityEntry : variableToEqualVariables.entrySet()) { - VariableTerm variableToReplace = variableEqualityEntry.getKey(); - VariableTerm replacementVariable = variableEqualityEntry.getValue().iterator().next(); - if (variableToReplace == replacementVariable) { - continue; - } - replacementSubstitution.put(variableToReplace, replacementVariable); - } - // Replace/Substitute in each literal every term where one of the common variables occurs. - Iterator bodyIterator = rewrittenBody.iterator(); - while (bodyIterator.hasNext()) { - CoreLiteral literal = bodyIterator.next(); - if (equalitiesToRemove.contains(literal)) { - bodyIterator.remove(); - } - for (int i = 0; i < literal.getTerms().size(); i++) { - CoreTerm replaced = literal.getTerms().get(i).substitute(replacementSubstitution); - literal.getTerms().set(i, replaced); - } - } - // Replace variables in head. - if (rewrittenHead != null) { - CoreAtom headAtom = rewrittenHead.getAtom(); - for (int i = 0; i < headAtom.getTerms().size(); i++) { - CoreTerm replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); - headAtom.getTerms().set(i, replaced); - } - } - return new NormalRule(rewrittenHead, rewrittenBody); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java deleted file mode 100644 index 254d0ed05..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AbstractSolver.java +++ /dev/null @@ -1,38 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.grounder.Grounder; - -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.Consumer; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -abstract class AbstractSolver implements Solver { - protected final Grounder grounder; - protected final AtomStore atomStore; - - protected AbstractSolver(AtomStore atomStore, Grounder grounder) { - this.atomStore = atomStore; - this.grounder = grounder; - } - - protected AnswerSet translate(Iterable assignment) { - return grounder.assignmentToAnswerSet(assignment); - } - - protected abstract boolean tryAdvance(Consumer action); - - @Override - public Spliterator spliterator() { - return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 0) { - @Override - public boolean tryAdvance(Consumer action) { - return AbstractSolver.this.tryAdvance(action); - } - }; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java deleted file mode 100644 index c841ecc0e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Antecedent.java +++ /dev/null @@ -1,17 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -/** - * An interface to reasons of implications as used internally by the solver. This is a lightweight {@link at.ac.tuwien.kr.alpha.common.NoGood} that only - * provides an array of literals (in some order) and has an activity that may change. - * - * Copyright (c) 2019, the Alpha Team. - */ -public interface Antecedent { - - int[] getReasonLiterals(); - - void bumpActivity(); - - void decreaseActivity(); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java deleted file mode 100644 index 506dddbcd..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/AtomCounter.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2019 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.solver; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Counts the number of ground atoms stored for each type (i.e., subclass of {@link CoreAtom}. - * For every atom, only the counter for one class (the most specific one) is incremented, - * not the counters for more general classes of which the atom is also an instance. - */ -public class AtomCounter { - - private final Map, Integer> countByType = new HashMap<>(); - - public void add(CoreAtom atom) { - countByType.compute(atom.getClass(), (k, v) -> (v == null) ? 1 : v + 1); - } - - /** - * @param type the class of atoms to count - * @return the number of atoms of the given type - */ - public int getNumberOfAtoms(Class type) { - return countByType.getOrDefault(type, 0); - } - - /** - * @return a string giving statistics on numbers of atoms by type - */ - public String getStatsByType() { - List statsList = new ArrayList<>(); - for (Map.Entry, Integer> entry : countByType.entrySet()) { - statsList.add(entry.getKey().getSimpleName() + ": " + entry.getValue()); - } - Collections.sort(statsList); - return String.join(" ", statsList); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java deleted file mode 100644 index de6f02a6a..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Atoms.java +++ /dev/null @@ -1,9 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -public final class Atoms { - - public static boolean isAtom(int atom) { - return atom >= 0; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java deleted file mode 100644 index edf3423fc..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/BinaryNoGoodPropagationEstimation.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver; - -/** - * Offers methods to estimate the effect of propagating binary nogoods. - */ -public interface BinaryNoGoodPropagationEstimation { - - /** - * Uses {@code strategy} to estimate the number of direct consequences of propagating binary nogoods after assigning - * {@code truth} to {@code atom}. - * - * If {@code strategy} is {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation}, {@code truth} is assigned to {@code atom}, - * only binary nogoods are propagated, a backtrack is executed, and the number of atoms that have been assigned - * additionally during this process is returned. - * - * If {@code strategy} is {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches}, on the other hand, the number of binary watches on - * the literal given by {@code atom} and {@code truth} is returned. - * - * @param atom the atom to estimate effects for - * @param truth gives, together with {@code atom}, a literal to estimate effects for - * @param strategy the strategy to use for estimation. If {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation} is given but - * no binary nogoods exist, {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches} will be used instead. - * @return an estimate on the effects of propagating binary nogoods after assigning {@code truth} to {@code atom}. - */ - int estimate(int atom, boolean truth, BinaryNoGoodPropagationEstimationStrategy strategy); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java deleted file mode 100644 index 369389d50..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Checkable.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -/** - * Marks classes that implement some "checking" logic that can perform - * exhaustive validation of the internal state of an object. This is - * mainly used in debugging and should not be done for production - * purposes. - */ -@FunctionalInterface -public interface Checkable { - void setChecksEnabled(boolean checksEnabled); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java deleted file mode 100644 index eb70acd5d..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Choice.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.solver; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; - -class Choice { - private final int atom; - private final boolean value; - private final boolean backtracked; - - Choice(int atom, boolean value, boolean backtracked) { - this.atom = atom; - this.value = value; - this.backtracked = backtracked; - } - - Choice(int literal, boolean backtracked) { - this(atomOf(literal), isPositive(literal), backtracked); - } - - public int getAtom() { - return atom; - } - - public boolean getValue() { - return value; - } - - public boolean isBacktracked() { - return backtracked; - } - - @Override - public String toString() { - return atom + "=" + (value ? "TRUE" : "FALSE"); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java deleted file mode 100644 index 62624eecd..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceInfluenceManager.java +++ /dev/null @@ -1,235 +0,0 @@ -/** - * 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. - * - * 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.solver; - -import org.apache.commons.lang3.tuple.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; - -/** - * Manages influence of atoms on the activity of certain other atoms. Can be used for either choice points or heuristic atoms. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class ChoiceInfluenceManager implements Checkable { - - private static final Logger LOGGER = LoggerFactory.getLogger(ChoiceInfluenceManager.class); - - // Active choice points and all atoms that influence a choice point (enabler, disabler, choice atom itself). - private final Set activeChoicePoints = new LinkedHashSet<>(); - private final Set activeChoicePointsAtoms = new LinkedHashSet<>(); - private ChoicePoint[] influencers = new ChoicePoint[0]; - private ActivityListener activityListener; - - private final WritableAssignment assignment; - - private boolean checksEnabled; - - /** - * @param assignment - * - */ - public ChoiceInfluenceManager(WritableAssignment assignment) { - this.assignment = assignment; - } - - void addInformation(Pair, Map> choiceAtoms) { - // Assumption: we get all enabler/disabler pairs in one call. - Map enablers = choiceAtoms.getLeft(); - Map disablers = choiceAtoms.getRight(); - for (Map.Entry atomToEnabler : enablers.entrySet()) { - addInformation(atomToEnabler, disablers); - } - } - - private void addInformation(Map.Entry atomToEnabler, Map disablers) { - // Construct and record ChoicePoint. - Integer atom = atomToEnabler.getKey(); - if (atom == null) { - throw oops("Incomplete choice point description found (no atom)"); - } - if (influencers[atom] != null) { - throw oops("Received choice information repeatedly"); - } - Integer enabler = atomToEnabler.getValue(); - Integer disabler = disablers.get(atom); - if (enabler == null || disabler == null) { - throw oops("Incomplete choice point description found (no enabler or disabler)"); - } - assignment.registerCallbackOnChange(atom); - assignment.registerCallbackOnChange(enabler); - assignment.registerCallbackOnChange(disabler); - ChoicePoint choicePoint = new ChoicePoint(atom, enabler, disabler); - influencers[atom] = choicePoint; - influencers[enabler] = choicePoint; - influencers[disabler] = choicePoint; - choicePoint.recomputeActive(); - } - - void checkActiveChoicePoints() { - HashSet actualActiveChoicePoints = new HashSet<>(); - for (int i = 0; i < influencers.length; i++) { - ChoicePoint choicePoint = influencers[i]; - if (choicePoint == null) { - continue; - } - if (checkActiveChoicePoint(choicePoint)) { - actualActiveChoicePoints.add(choicePoint); - } - } - if (!actualActiveChoicePoints.equals(activeChoicePoints)) { - throw oops("ChoiceInfluenceManager internal checker detected wrong activeChoicePoints"); - } - LOGGER.trace("Checking internal choice manger: all ok."); - } - - private boolean checkActiveChoicePoint(ChoicePoint choicePoint) { - ThriceTruth enablerTruth = assignment.getTruth(choicePoint.enabler); - ThriceTruth disablerTruth = assignment.getTruth(choicePoint.disabler); - boolean isActive = enablerTruth == TRUE - && (disablerTruth == null || !disablerTruth.toBoolean()); - ThriceTruth atomTruth = assignment.getTruth(choicePoint.atom); - boolean isNotChosen = atomTruth == null || atomTruth == MBT; - return isActive && isNotChosen; - } - - boolean isActive(int atom) { - if (checksEnabled) { - checkActiveChoicePoints(); - } - ChoicePoint choicePoint = influencers[atom]; - return choicePoint != null && choicePoint.isActive && choicePoint.atom == atom; - } - - int getNextActiveAtomOrDefault(int defaultAtom) { - if (checksEnabled) { - checkActiveChoicePoints(); - } - return activeChoicePointsAtoms.size() > 0 ? activeChoicePointsAtoms.iterator().next() : defaultAtom; - } - - boolean isAtomInfluenced(int atom) { - ChoicePoint choicePoint = influencers[atom]; - return choicePoint != null && choicePoint.atom == atom; - } - - @Override - public void setChecksEnabled(boolean checksEnabled) { - this.checksEnabled = checksEnabled; - } - - void callbackOnChanged(int atom) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Callback received on influencer atom: {}", atom); - } - ChoicePoint choicePoint = influencers[atom]; - if (choicePoint != null) { - choicePoint.recomputeActive(); - } - } - - public void growForMaxAtomId(int maxAtomId) { - // Grow arrays only if needed. - if (influencers.length > maxAtomId) { - return; - } - // Grow to default size, except if bigger array is required due to maxAtomId. - int newCapacity = arrayGrowthSize(influencers.length); - if (newCapacity < maxAtomId + 1) { - newCapacity = maxAtomId + 1; - } - influencers = Arrays.copyOf(influencers, newCapacity); - } - - void setActivityListener(ActivityListener listener) { - this.activityListener = listener; - } - - private class ChoicePoint { - final Integer atom; - final int enabler; - final int disabler; - boolean isActive; - - private ChoicePoint(Integer atom, Integer enabler, int disabler) { - this.atom = atom; - this.enabler = enabler; - this.disabler = disabler; - } - - private boolean isActiveChoicePoint() { - ThriceTruth enablerTruth = assignment.getTruth(enabler); - ThriceTruth disablerTruth = assignment.getTruth(disabler); - return enablerTruth == TRUE - && (disablerTruth == null || !disablerTruth.toBoolean()); - } - - private boolean isNotChosen() { - ThriceTruth atomTruth = assignment.getTruth(atom); - return atomTruth == null || atomTruth == MBT; - } - - void recomputeActive() { - LOGGER.trace("Recomputing activity of atom {}.", atom); - final boolean wasActive = isActive; - isActive = isNotChosen() && isActiveChoicePoint(); - boolean changed = false; - if (isActive && !wasActive) { - activeChoicePoints.add(this); - activeChoicePointsAtoms.add(atom); - changed = true; - LOGGER.debug("Activating choice point for atom {}", this.atom); - } else if (wasActive && !isActive) { - activeChoicePoints.remove(this); - activeChoicePointsAtoms.remove(atom); - changed = true; - LOGGER.debug("Deactivating choice point for atom {}", this.atom); - } - if (changed && activityListener != null) { - activityListener.callbackOnChanged(atom, isActive); - } - } - - @Override - public String toString() { - return String.valueOf(atom); - } - } - - public static interface ActivityListener { - void callbackOnChanged(int atom, boolean active); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java deleted file mode 100644 index 5feb085a3..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ChoiceManager.java +++ /dev/null @@ -1,325 +0,0 @@ -/** - * 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. - * - * 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.solver; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import org.apache.commons.lang3.tuple.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; - -/** - * This class provides functionality for choice point management, detection of active choice points, etc. - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class ChoiceManager implements Checkable { - - public static final int DEFAULT_CHOICE_ATOM = 0; - - private static final Logger LOGGER = LoggerFactory.getLogger(ChoiceManager.class); - private final WritableAssignment assignment; - private final Stack choiceStack; - private final Map> headsToBodies = new HashMap<>(); - private final Map bodiesToHeads = new HashMap<>(); - - // An "influence manager" managing active choice points and heuristics. - private final ChoiceInfluenceManager choicePointInfluenceManager; - - private final NoGoodStore store; - private final BinaryNoGoodPropagationEstimation bnpEstimation; - - private boolean checksEnabled; - private DebugWatcher debugWatcher; - - private int choices; - private int backtracks; - private int backtracksWithinBackjumps; - private int backjumps; - - public ChoiceManager(WritableAssignment assignment, NoGoodStore store) { - this.store = store; - this.assignment = assignment; - this.choicePointInfluenceManager = new ChoiceInfluenceManager(assignment); - this.choiceStack = new Stack<>(); - assignment.setCallback(this); - this.bnpEstimation = store instanceof BinaryNoGoodPropagationEstimation - ? (BinaryNoGoodPropagationEstimation)store - : null; - } - - public WritableAssignment getAssignment() { - return assignment; - } - - NoGood computeEnumeration() { - int[] enumerationLiterals = new int[choiceStack.size()]; - int enumerationPos = 0; - for (Choice e : choiceStack) { - enumerationLiterals[enumerationPos++] = atomToLiteral(e.getAtom(), e.getValue()); - } - return new NoGood(enumerationLiterals); - } - - @Override - public void setChecksEnabled(boolean checksEnabled) { - this.checksEnabled = checksEnabled; - this.choicePointInfluenceManager.setChecksEnabled(checksEnabled); - - if (checksEnabled) { - debugWatcher = new DebugWatcher(); - } else { - debugWatcher = null; - } - } - - public boolean isChecksEnabled() { - return checksEnabled; - } - - public void callbackOnChanged(int atom) { - choicePointInfluenceManager.callbackOnChanged(atom); - } - - public int getBackjumps() { - return backjumps; - } - - /** - * Returns the total number of backtracks. - * - * The number of backtracks excluding those within backjumps is {@link #getBacktracks()} minus {@link #getBacktracksWithinBackjumps()}. - * - * @return the total number of backtracks - */ - public int getBacktracks() { - return backtracks; - } - - /** - * Returns the number of backtracks made within backjumps. - * - * @return the number of backtracks made within backjumps. - */ - public int getBacktracksWithinBackjumps() { - return backtracksWithinBackjumps; - } - - public int getChoices() { - return choices; - } - - public void updateAssignments() { - LOGGER.trace("Updating assignments of ChoiceManager."); - if (checksEnabled) { - choicePointInfluenceManager.checkActiveChoicePoints(); - } - } - - public void choose(Choice choice) { - if (!choice.isBacktracked()) { - choices++; - } - - if (assignment.choose(choice.getAtom(), choice.getValue()) != null) { - throw oops("Picked choice is incompatible with current assignment"); - } - LOGGER.debug("Choice {} is {}@{}", choices, choice, assignment.getDecisionLevel()); - - if (debugWatcher != null) { - debugWatcher.runWatcher(); - } - - choiceStack.push(choice); - } - - public void backjump(int target) { - if (target < 0) { - throw oops("Backjumping to decision level less than 0"); - } - - backjumps++; - LOGGER.debug("Backjumping to decision level {}.", target); - - // Remove everything above the target level, but keep the target level unchanged. - int currentDecisionLevel = assignment.getDecisionLevel(); - assignment.backjump(target); - while (currentDecisionLevel-- > target) { - final Choice choice = choiceStack.pop(); - backtracksWithinBackjumps++; - backtracks++; - LOGGER.debug("Backjumping removed choice {}", choice); - } - } - - /** - * Fast backtracking will backtrack but not give any information about which choice was backtracked. This is - * handy in cases where higher level backtracking mechanisms already know what caused the backtracking and what - * to do next. - * - * In order to analyze the choice that was backtracked, use the more expensive {@link #backtrackSlow()}. - */ - public void backtrackFast() { - backtrack(); - - final Choice choice = choiceStack.pop(); - - LOGGER.debug("Backtracked (fast) to level {} from choice {}", assignment.getDecisionLevel(), choice); - } - - /** - * Slow backtracking will take more time, but allow to analyze the {@link Assignment.Entry} corresponding to the - * choice that is being backtracked. Higher level backtracking mechanisms can use this information to change - * their plans. - * - * @return the assignment entry of the choice being backtracked, or {@code null} if the choice cannot be - * backtracked any futher (it already is a backtracking choice) - */ - public Assignment.Entry backtrackSlow() { - final Choice choice = choiceStack.pop(); - final Assignment.Entry lastChoiceEntry = assignment.get(choice.getAtom()); - - backtrack(); - LOGGER.debug("Backtracked (slow) to level {} from choice {}", assignment.getDecisionLevel(), choice); - - if (choice.isBacktracked()) { - return null; - } - - return lastChoiceEntry; - } - - /** - * This method implements the backtracking "core" that will be executed for both slow and fast backtracking. - * It backtracks the NoGoodStore and recomputes choice points. - */ - private void backtrack() { - store.backtrack(); - backtracks++; - } - - void addChoiceInformation(Pair, Map> choiceAtoms, Map> headsToBodies) { - choicePointInfluenceManager.addInformation(choiceAtoms); - addHeadsToBodies(headsToBodies); - } - - public void growForMaxAtomId(int maxAtomId) { - choicePointInfluenceManager.growForMaxAtomId(maxAtomId); - } - - private void addHeadsToBodies(Map> headsToBodies) { - for (Entry> entry : headsToBodies.entrySet()) { - Integer head = entry.getKey(); - Set newBodies = entry.getValue(); - addHeadsToBodies(head, newBodies); - addBodiesToHeads(head, newBodies); - } - } - - private void addHeadsToBodies(Integer head, Set bodies) { - Set existingBodies = this.headsToBodies.get(head); - if (existingBodies == null) { - existingBodies = new HashSet<>(); - this.headsToBodies.put(head, existingBodies); - } - existingBodies.addAll(bodies); - } - - private void addBodiesToHeads(Integer head, Set bodies) { - for (Integer body : bodies) { - bodiesToHeads.put(body, head); - } - } - - public boolean isActiveChoiceAtom(int atom) { - return choicePointInfluenceManager.isActive(atom); - } - - public int getNextActiveChoiceAtom() { - return choicePointInfluenceManager.getNextActiveAtomOrDefault(DEFAULT_CHOICE_ATOM); - } - - public boolean isAtomChoice(int atom) { - return choicePointInfluenceManager.isAtomInfluenced(atom); - } - - public void setChoicePointActivityListener(ChoiceInfluenceManager.ActivityListener activityListener) { - choicePointInfluenceManager.setActivityListener(activityListener); - } - - public Integer getHeadDerivedByChoiceAtom(int choiceAtomId) { - return bodiesToHeads.get(choiceAtomId); - } - - public BinaryNoGoodPropagationEstimation getBinaryNoGoodPropagationEstimation() { - return bnpEstimation; - } - - /** - * A helper class for halting the debugger when certain assignments occur on the choice stack. - * - * Example usage (called from DefaultSolver): - * choiceStack = new ChoiceStack(grounder, true); - * choiceStack.getDebugWatcher().watchAssignments("_R_(0,_C:red_V:7)=TRUE", "_R_(0,_C:green_V:8)=TRUE", "_R_(0,_C:red_V:9)=TRUE", "_R_(0,_C:red_V:4)=TRUE"); - */ - class DebugWatcher { - ArrayList toWatchFor = new ArrayList<>(); - - private void runWatcher() { - if (toWatchFor.size() == 0) { - return; - } - String current = choiceStack.stream().map(Choice::toString).collect(Collectors.joining(", ")); - boolean contained = true; - for (String s : toWatchFor) { - if (!current.contains(s)) { - contained = false; - break; - } - } - if (contained && toWatchFor.size() != 0) { - LOGGER.debug("Marker hit."); // Set debug breakpoint here to halt when desired assignment occurs. - } - } - - /** - * Registers atom assignments to watch for. - * @param toWatch one or more strings as they occur in ChoiceStack.toString() - */ - public void watchAssignments(String... toWatch) { - toWatchFor = new ArrayList<>(); - Collections.addAll(toWatchFor, toWatch); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java deleted file mode 100644 index b9b72ca58..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ConflictCause.java +++ /dev/null @@ -1,26 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -/** - * Indicates the presence of a conflict and contains its reason in terms of a violated Antecedent. - * Throughout the solver the absence of a conflict is indicated by {@code ConflictCause = null}. - */ -public class ConflictCause { - // Note: Storing the Antecedent is necessary in order to distinguish the cases of no conflict occurring - // {@code ConflictCause==null} from the case where a choice (with no Antecedent, i.e., - // {@code violatedNoGood==null}) is the cause of the conflict. - // Resolving ConflictCause by Antecedent would require an indicator flag to distinguish these cases. - private final Antecedent violatedNoGood; - - public ConflictCause(Antecedent violatedNoGood) { - this.violatedNoGood = violatedNoGood; - } - - public Antecedent getAntecedent() { - return violatedNoGood; - } - - @Override - public String toString() { - return String.valueOf(violatedNoGood); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java deleted file mode 100644 index 34560c693..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/DefaultSolver.java +++ /dev/null @@ -1,599 +0,0 @@ -/** - * 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 - * 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.solver; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToNegatedLiteral; -import static at.ac.tuwien.kr.alpha.solver.NoGoodStore.LBD_NO_VALUE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; -import static at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; -import java.util.Set; -import java.util.function.Consumer; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.common.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.ProgramAnalyzingGrounder; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristic; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; -import at.ac.tuwien.kr.alpha.solver.heuristics.ChainedBranchingHeuristics; -import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.solver.heuristics.NaiveHeuristic; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner; - -/** - * The new default solver employed in Alpha. - * - * Copyright (c) 2016-2020, the Alpha Team. - */ -public class DefaultSolver extends AbstractSolver implements SolverMaintainingStatistics { - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSolver.class); - - private final NoGoodStore store; - private final ChoiceManager choiceManager; - private final WritableAssignment assignment; - - private final GroundConflictNoGoodLearner learner; - - private final BranchingHeuristic branchingHeuristic; - - private boolean initialize = true; - private int mbtAtFixpoint; - private int conflictsAfterClosing; - private final boolean disableJustifications; - private boolean disableJustificationAfterClosing = true; // Keep disabled for now, case not fully worked out yet. - private final boolean disableNoGoodDeletion; - - private final PerformanceLog performanceLog; - - public DefaultSolver(AtomStore atomStore, Grounder grounder, NoGoodStore store, WritableAssignment assignment, Random random, SystemConfig config, HeuristicsConfiguration heuristicsConfiguration) { - super(atomStore, grounder); - - this.assignment = assignment; - this.store = store; - this.choiceManager = new ChoiceManager(assignment, store); - this.learner = new GroundConflictNoGoodLearner(assignment, atomStore); - this.branchingHeuristic = chainFallbackHeuristic(grounder, assignment, random, heuristicsConfiguration); - this.disableJustifications = config.isDisableJustificationSearch(); - this.disableNoGoodDeletion = config.isDisableNoGoodDeletion(); - this.performanceLog = new PerformanceLog(choiceManager, (TrailAssignment) assignment, 1000); - } - - private BranchingHeuristic chainFallbackHeuristic(Grounder grounder, WritableAssignment assignment, Random random, HeuristicsConfiguration heuristicsConfiguration) { - BranchingHeuristic branchingHeuristic = BranchingHeuristicFactory.getInstance(heuristicsConfiguration, grounder, assignment, choiceManager, random); - if (branchingHeuristic instanceof NaiveHeuristic) { - return branchingHeuristic; - } - if (branchingHeuristic instanceof ChainedBranchingHeuristics && ((ChainedBranchingHeuristics)branchingHeuristic).getLastElement() instanceof NaiveHeuristic) { - return branchingHeuristic; - } - return ChainedBranchingHeuristics.chainOf(branchingHeuristic, new NaiveHeuristic(choiceManager)); - } - - @Override - protected boolean tryAdvance(Consumer action) { - boolean didChange = false; - - // Initially, get NoGoods from grounder. - if (initialize) { - performanceLog.initialize(); - Map obtained = grounder.getNoGoods(assignment); - didChange = !obtained.isEmpty(); - if (!ingest(obtained)) { - logStats(); - return false; - } - initialize = false; - } else if (assignment.getDecisionLevel() == 0) { - logStats(); - return false; - } else { - // We already found one Answer-Set and are requested to find another one. - // Create enumeration NoGood to avoid finding the same Answer-Set twice. - final NoGood enumerationNoGood = choiceManager.computeEnumeration(); - final int backjumpLevel = assignment.minimumConflictLevel(enumerationNoGood); - if (backjumpLevel == -1) { - throw oops("Enumeration nogood is not violated"); - } - if (backjumpLevel == 0) { - // Search space exhausted (only happens if first choice is for TRUE at decision level 1 for an atom that was MBT at decision level 0 already). - return false; - } - // Backjump instead of backtrackSlow, enumerationNoGood will invert last choice. - choiceManager.backjump(backjumpLevel - 1); - LOGGER.debug("Adding enumeration nogood: {}", enumerationNoGood); - if (!addAndBackjumpIfNecessary(grounder.register(enumerationNoGood), enumerationNoGood, Integer.MAX_VALUE)) { - return false; - } - } - - boolean afterAllAtomsAssigned = false; - - // Try all assignments until grounder reports no more NoGoods and all of them are satisfied - while (true) { - performanceLog.infoIfTimeForOutput(LOGGER); - ConflictCause conflictCause = store.propagate(); - didChange |= store.didPropagate(); - LOGGER.trace("Assignment after propagation is: {}", assignment); - if (!disableNoGoodDeletion && conflictCause == null) { - // Run learned NoGood deletion strategy. - store.cleanupLearnedNoGoods(); - } - if (conflictCause != null) { - // Learn from conflict. - LOGGER.debug("Violating assignment is: {}", assignment); - Antecedent conflictAntecedent = conflictCause.getAntecedent(); - NoGood violatedNoGood = new NoGood(conflictAntecedent.getReasonLiterals().clone()); - // TODO: The violatedNoGood should not be necessary here, but this requires major type changes in heuristics. - branchingHeuristic.violatedNoGood(violatedNoGood); - if (!afterAllAtomsAssigned) { - if (!learnBackjumpAddFromConflict(conflictCause)) { - logStats(); - return false; - } - } else { - LOGGER.debug("Assignment is violated after all unassigned atoms have been assigned false."); - conflictsAfterClosing++; - if (!treatConflictAfterClosing(conflictAntecedent)) { - return false; - } - afterAllAtomsAssigned = false; - } - } else if (didChange) { - // Ask the grounder for new NoGoods, then propagate (again). - LOGGER.trace("Doing propagation step."); - - grounder.updateAssignment(assignment.getNewPositiveAssignmentsIterator()); - - Map obtained = grounder.getNoGoods(assignment); - didChange = !obtained.isEmpty(); - if (!ingest(obtained)) { - logStats(); - return false; - } - } else if (choose()) { - LOGGER.debug("Did choice."); - didChange = true; - } else if (close()) { - LOGGER.debug("Closed unassigned known atoms (assigning FALSE)."); - afterAllAtomsAssigned = true; - } else if (assignment.getMBTCount() == 0) { - // NOTE: If we would do optimization, we would now have a guaranteed upper bound. - AnswerSet as = translate(assignment.getTrueAssignments()); - LOGGER.debug("Answer-Set found: {}", as); - action.accept(as); - logStats(); - return true; - } else { - LOGGER.debug("Backtracking from wrong choices ({} MBTs).", assignment.getMBTCount()); - if (!justifyMbtAndBacktrack()) { - return false; - } - afterAllAtomsAssigned = false; - } - } - } - - /** - * Adds a noGood to the store and in case of out-of-order literals causing another conflict, triggers further backjumping. - * @param noGoodId the unique identifier of the NoGood to add. - * @param noGood the NoGood to add. - * @param lbd the LBD (literal blocks distance) value of the NoGood. - */ - private boolean addAndBackjumpIfNecessary(int noGoodId, NoGood noGood, int lbd) { - while (store.add(noGoodId, noGood, lbd) != null) { - LOGGER.debug("Adding noGood (again) caused conflict, computing real backjumping level now."); - int backjumpLevel = learner.computeConflictFreeBackjumpingLevel(noGood); - if (backjumpLevel < 0) { - return false; - } - choiceManager.backjump(backjumpLevel); - if (store.propagate() != null) { - throw oops("Violated NoGood after backtracking."); - } - } - return true; - } - - /** - * Analyzes the conflict and either learns a new NoGood (causing backjumping and addition to the NoGood store), - * or backtracks the choice causing the conflict. - * @return false iff the analysis result shows that the set of NoGoods is unsatisfiable. - */ - private boolean learnBackjumpAddFromConflict(ConflictCause conflictCause) { - GroundConflictNoGoodLearner.ConflictAnalysisResult analysisResult = learner.analyzeConflictingNoGood(conflictCause.getAntecedent()); - - LOGGER.debug("Analysis result: {}", analysisResult); - - if (analysisResult == UNSAT) { - // Halt if unsatisfiable. - return false; - } - - branchingHeuristic.analyzedConflict(analysisResult); - - if (analysisResult.learnedNoGood != null) { - choiceManager.backjump(analysisResult.backjumpLevel); - - final NoGood learnedNoGood = analysisResult.learnedNoGood; - int noGoodId = grounder.register(learnedNoGood); - if (!addAndBackjumpIfNecessary(noGoodId, learnedNoGood, analysisResult.lbd)) { - return false; - } - return true; - } - - choiceManager.backjump(analysisResult.backjumpLevel); - - choiceManager.backtrackFast(); - if (store.propagate() != null) { - throw oops("Violated NoGood after backtracking."); - } - if (!store.didPropagate()) { - throw oops("Nothing to propagate after backtracking from conflict-causing choice"); - } - - return true; - } - - private boolean justifyMbtAndBacktrack() { - mbtAtFixpoint++; - // Run justification only if enabled and possible. - if (disableJustifications || !(grounder instanceof ProgramAnalyzingGrounder)) { - if (!backtrack()) { - logStats(); - return false; - } - return true; - } - ProgramAnalyzingGrounder analyzingGrounder = (ProgramAnalyzingGrounder) grounder; - // Justify one MBT assigned atom. - int atomToJustify = assignment.getBasicAtomAssignedMBT(); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Searching for justification of {} / {}", atomToJustify, atomStore.atomToString(atomToJustify)); - LOGGER.debug("Assignment is (TRUE part only): {}", translate(assignment.getTrueAssignments())); - } - Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomToJustify, assignment); - NoGood noGood = noGoodFromJustificationReasons(atomToJustify, reasonsForUnjustified); - - - int noGoodID = grounder.register(noGood); - Map obtained = new LinkedHashMap<>(); - obtained.put(noGoodID, noGood); - LOGGER.debug("Learned NoGood is: {}", atomStore.noGoodToString(noGood)); - // Add NoGood and trigger backjumping. - if (!ingest(obtained)) { - logStats(); - return false; - } - return true; - } - - private NoGood noGoodFromJustificationReasons(int atomToJustify, Set reasonsForUnjustified) { - // Turn the justification into a NoGood. - int[] reasons = new int[reasonsForUnjustified.size() + 1]; - reasons[0] = atomToLiteral(atomToJustify); - int arrpos = 1; - for (CoreLiteral literal : reasonsForUnjustified) { - reasons[arrpos++] = atomToLiteral(atomStore.get(literal.getAtom()), !literal.isNegated()); - } - return NoGood.learnt(reasons); - } - - private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { - if (disableJustificationAfterClosing || disableJustifications || !(grounder instanceof ProgramAnalyzingGrounder)) { - // Will not learn from violated NoGood, do simple backtrack. - LOGGER.debug("NoGood was violated after all unassigned atoms were assigned to false; will not learn from it; skipping."); - if (!backtrack()) { - logStats(); - return false; - } - return true; - } - ProgramAnalyzingGrounder analyzingGrounder = (ProgramAnalyzingGrounder) grounder; - LOGGER.debug("Justifying atoms in violated nogood."); - LinkedHashSet toJustify = new LinkedHashSet<>(); - // Find those literals in violatedNoGood that were just assigned false. - for (Integer literal : violatedNoGood.getReasonLiterals()) { - if (assignment.getImpliedBy(atomOf(literal)) == TrailAssignment.CLOSING_INDICATOR_ANTECEDENT) { - toJustify.add(literal); - } - } - // Since the violatedNoGood may contain atoms other than BasicAtom, these have to be treated. - Map obtained = new LinkedHashMap<>(); - Iterator toJustifyIterator = toJustify.iterator(); - ArrayList ruleAtomReplacements = new ArrayList<>(); - while (toJustifyIterator.hasNext()) { - Integer literal = toJustifyIterator.next(); - CoreAtom atom = atomStore.get(atomOf(literal)); - if (atom instanceof BasicAtom) { - continue; - } - if (!(atom instanceof RuleAtom)) { - // Ignore atoms other than RuleAtom. - toJustifyIterator.remove(); - continue; - } - // For RuleAtoms in toJustify the corresponding ground body contains BasicAtoms that have been assigned FALSE in the closing. - // First, translate RuleAtom back to NonGroundRule + Substitution. - String ruleId = (String) ((CoreConstantTerm)atom.getTerms().get(0)).getObject(); - InternalRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); - String substitution = (String) ((CoreConstantTerm)atom.getTerms().get(1)).getObject(); - Substitution groundingSubstitution = Substitution.fromString(substitution); - // Find ground literals in the body that have been assigned false and justify those. - for (CoreLiteral bodyLiteral : nonGroundRule.getBody()) { - CoreAtom groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); - if (groundAtom instanceof ComparisonAtom || analyzingGrounder.isFact(groundAtom)) { - // Facts and ComparisonAtoms are always true, no justification needed. - continue; - } - int groundAtomId = atomStore.get(groundAtom); - Antecedent impliedBy = assignment.getImpliedBy(groundAtomId); - // Check if atom was assigned to FALSE during the closing. - if (impliedBy == TrailAssignment.CLOSING_INDICATOR_ANTECEDENT) { - ruleAtomReplacements.add(atomToNegatedLiteral(groundAtomId)); - } - } - toJustifyIterator.remove(); - } - toJustify.addAll(ruleAtomReplacements); - for (Integer literalToJustify : toJustify) { - LOGGER.debug("Searching for justification(s) of {} / {}", toJustify, atomStore.atomToString(atomOf(literalToJustify))); - Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomOf(literalToJustify), assignment); - NoGood noGood = noGoodFromJustificationReasons(atomOf(literalToJustify), reasonsForUnjustified); - int noGoodID = grounder.register(noGood); - obtained.put(noGoodID, noGood); - LOGGER.debug("Learned NoGood is: {}", atomStore.noGoodToString(noGood)); - } - // Backtrack to remove the violation. - if (!backtrack()) { - logStats(); - return false; - } - // Add newly obtained noGoods. - if (!ingest(obtained)) { - logStats(); - return false; - } - return true; - } - - private boolean close() { - return assignment.closeUnassignedAtoms(); - } - - /** - * Iterative implementation of recursive backtracking. - * - * @return {@code true} iff it is possible to backtrack even further, {@code false} otherwise - */ - private boolean backtrack() { - while (assignment.getDecisionLevel() != 0) { - final Assignment.Entry choice = choiceManager.backtrackSlow(); - store.propagate(); - - if (choice == null) { - LOGGER.debug("Backtracking further, because last choice was already backtracked."); - continue; - } - - final int lastChoice = choice.getAtom(); - final boolean choiceValue = choice.getTruth().toBoolean(); - - // Chronological backtracking: choose inverse now. - // Choose FALSE if the previous choice was for TRUE and the atom was not already MBT at that time. - ThriceTruth lastChoiceTruth = assignment.getTruth(lastChoice); - if (choiceValue && MBT.equals(lastChoiceTruth)) { - LOGGER.debug("Backtracking further, because last choice was MBT before choosing TRUE."); - continue; - } - - // If choice was assigned at lower decision level (due to added NoGoods), no inverted choice should be done. - if (choice.getImpliedBy() != null) { - LOGGER.debug("Last choice is now implied by {}", choice.getImpliedBy()); - //if (choice.getDecisionLevel() == assignment.getDecisionLevel() + 1) { - // throw oops("Choice was assigned but not at a lower decision level"); - //} - LOGGER.debug("Backtracking further, because last choice was assigned at a lower decision level."); - continue; - } - - // Choose inverse if it is not yet already assigned TRUE or FALSE. - if (lastChoiceTruth == null || (lastChoiceTruth.isMBT() && !choiceValue)) { - LOGGER.debug("Choosing inverse."); - choiceManager.choose(new Choice(lastChoice, !choiceValue, true)); - break; - } - // Continue backtracking. - } - - return assignment.getDecisionLevel() != 0; - } - - private boolean ingest(Map obtained) { - assignment.growForMaxAtomId(); - int maxAtomId = atomStore.getMaxAtomId(); - store.growForMaxAtomId(maxAtomId); - choiceManager.growForMaxAtomId(maxAtomId); - branchingHeuristic.growForMaxAtomId(maxAtomId); - branchingHeuristic.newNoGoods(obtained.values()); - - LinkedList> noGoodsToAdd = new LinkedList<>(obtained.entrySet()); - Map.Entry entry; - while ((entry = noGoodsToAdd.poll()) != null) { - if (NoGood.UNSAT.equals(entry.getValue())) { - // Empty NoGood cannot be satisfied, program is unsatisfiable. - return false; - } - - final ConflictCause conflictCause = store.add(entry.getKey(), entry.getValue(), Integer.MAX_VALUE); - if (conflictCause == null) { - // There is no conflict, all is fine. Just skip conflict treatment and carry on. - continue; - } - - if (!fixContradiction(entry, conflictCause)) { - return false; - } - } - return true; - } - - /** - * Attempts to fix a given conflict that arose from adding a nogood. - * @param noGoodEntry the description of the NoGood that caused the conflict. - * @param conflictCause a description of the cause of the conflict. - * @return true if the contradiction could be resolved (by backjumping) and the NoGood was added. - * False otherwise, i.e., iff the program is UNSAT. - */ - private boolean fixContradiction(Map.Entry noGoodEntry, ConflictCause conflictCause) { - LOGGER.debug("Attempting to fix violation of {} caused by {}", noGoodEntry.getValue(), conflictCause); - - GroundConflictNoGoodLearner.ConflictAnalysisResult conflictAnalysisResult = learner.analyzeConflictFromAddingNoGood(conflictCause.getAntecedent()); - if (conflictAnalysisResult == UNSAT) { - return false; - } - branchingHeuristic.analyzedConflict(conflictAnalysisResult); - if (conflictAnalysisResult.learnedNoGood != null) { - throw oops("Unexpectedly learned NoGood after addition of new NoGood caused a conflict."); - } - - choiceManager.backjump(conflictAnalysisResult.backjumpLevel); - - // If NoGood was learned, add it to the store. - // Note that the learned NoGood may cause further conflicts, since propagation on lower decision levels is lazy, - // hence backtracking once might not be enough to remove the real conflict cause. - return addAndBackjumpIfNecessary(noGoodEntry.getKey(), noGoodEntry.getValue(), LBD_NO_VALUE); - - } - - private boolean choose() { - choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); - choiceManager.updateAssignments(); - - // Hint: for custom heuristics, evaluate them here and pick a value if the heuristics suggests one. - - int literal; - - if ((literal = branchingHeuristic.chooseLiteral()) == DEFAULT_CHOICE_LITERAL) { - LOGGER.debug("No choices!"); - return false; - } else if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Branching heuristic chose literal {}", atomStore.literalToString(literal)); - } - - choiceManager.choose(new Choice(literal, false)); - return true; - } - - @Override - public int getNumberOfChoices() { - return choiceManager.getChoices(); - } - - @Override - public int getNumberOfBacktracks() { - return choiceManager.getBacktracks(); - } - - @Override - public int getNumberOfBacktracksWithinBackjumps() { - return choiceManager.getBacktracksWithinBackjumps(); - } - - @Override - public int getNumberOfBackjumps() { - return choiceManager.getBackjumps(); - } - - @Override - public int getNumberOfBacktracksDueToRemnantMBTs() { - return mbtAtFixpoint; - } - - @Override - public int getNumberOfConflictsAfterClosing() { - return conflictsAfterClosing; - } - - @Override - public int getNumberOfDeletedNoGoods() { - if (!(store instanceof NoGoodStoreAlphaRoaming)) { - return 0; - } - return ((NoGoodStoreAlphaRoaming)store).getLearnedNoGoodDeletion().getNumberOfDeletedNoGoods(); - } - - @Override - public NoGoodCounter getNoGoodCounter() { - return store.getNoGoodCounter(); - } - - private void logStats() { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(getStatisticsString()); - if (branchingHeuristic instanceof ChainedBranchingHeuristics) { - LOGGER.debug("Decisions made by each heuristic:"); - for (Entry heuristicToDecisionCounter : ((ChainedBranchingHeuristics)branchingHeuristic).getNumberOfDecisions().entrySet()) { - LOGGER.debug("{}: {}", heuristicToDecisionCounter.getKey(), heuristicToDecisionCounter.getValue()); - } - } - NoGoodCounter noGoodCounter = store.getNoGoodCounter(); - LOGGER.debug("Number of NoGoods by type: {}", noGoodCounter.getStatsByType()); - LOGGER.debug("Number of NoGoods by cardinality: {}", noGoodCounter.getStatsByCardinality()); - AtomCounter atomCounter = atomStore.getAtomCounter(); - LOGGER.debug("Number of atoms by type: {}", atomCounter.getStatsByType()); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java deleted file mode 100644 index a17264654..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletion.java +++ /dev/null @@ -1,116 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -/** - * Realizes a learned NoGood deletion strategy based on LBD and activity of NoGoods. - * - * Copyright (c) 2019, the Alpha Team. - */ -class LearnedNoGoodDeletion { - private static final Logger LOGGER = LoggerFactory.getLogger(LearnedNoGoodDeletion.class); - public static final int RESET_SEQUENCE_AFTER = 20; - public static final int RUN_AFTER_AT_LEAST = 2000; - public static final int GROWTH_FACTOR = 100; - private final ArrayList learnedNoGoods = new ArrayList<>(); // List of learned NoGoods that can be removed again. Note: should only contain NoGoods of size > 2. - private final NoGoodStoreAlphaRoaming store; - private final Assignment assignment; - private int conflictCounter; - private int cleanupCounter; - private int numberOfDeletedNoGoods; - - LearnedNoGoodDeletion(NoGoodStoreAlphaRoaming store, Assignment assignment) { - this.store = store; - this.assignment = assignment; - } - - void reset() { - learnedNoGoods.clear(); - conflictCounter = 0; - cleanupCounter = 0; - numberOfDeletedNoGoods = 0; - } - - /** - * Returns WatchedNoGoods known to {@link LearnedNoGoodDeletion}. - * Note: this is likely just a subset of all learned nogoods. - * @return an unmodifiable list of {@link WatchedNoGood}s. - */ - public List inspectLearnedNoGoods() { - return Collections.unmodifiableList(learnedNoGoods); - } - - void recordLearnedNoGood(WatchedNoGood learnedWatchedNoGood) { - learnedNoGoods.add(learnedWatchedNoGood); - } - - void increaseConflictCounter() { - conflictCounter++; - } - - boolean needToRunNoGoodDeletion() { - return conflictCounter > RUN_AFTER_AT_LEAST + (GROWTH_FACTOR * cleanupCounter); - } - - void runNoGoodDeletion() { - conflictCounter = 0; - cleanupCounter++; - // Reset the sequence after enough growth cycles. - if (cleanupCounter > RESET_SEQUENCE_AFTER) { - cleanupCounter = 0; - } - int deletedNoGoods = 0; - int originalSize = learnedNoGoods.size(); - if (originalSize == 0) { - return; - } - int toDeleteMax = originalSize / 2; - long activitySum = 0; - for (WatchedNoGood learnedNoGood : learnedNoGoods) { - activitySum += learnedNoGood.getActivity(); - } - double avgActivity = (double) activitySum / originalSize; - double scoreThreshold = avgActivity * 1.5; - for (Iterator iterator = learnedNoGoods.iterator(); iterator.hasNext();) { - WatchedNoGood learnedNoGood = iterator.next(); - if (deletedNoGoods >= toDeleteMax) { - break; - } - boolean keepNoGood = isLocked(learnedNoGood, assignment) - || learnedNoGood.getActivity() > scoreThreshold - || learnedNoGood.isLbdLessOrEqual2(); - if (!keepNoGood) { - iterator.remove(); - store.removeFromWatches(learnedNoGood); - learnedNoGood.decreaseActivity(); - deletedNoGoods++; - LOGGER.trace("Removed from store the NoGood: {}", learnedNoGood); - } - } - LOGGER.debug("Removed {} NoGoods from store.", deletedNoGoods); - this.numberOfDeletedNoGoods += deletedNoGoods; - } - - private boolean isLocked(WatchedNoGood noGood, Assignment assignment) { - int watchedAtom1 = atomOf(noGood.getLiteral(0)); - int watchedAtom2 = atomOf(noGood.getLiteral(1)); - if (!assignment.isAssigned(watchedAtom1) || !assignment.isAssigned(watchedAtom2)) { - return false; - } - return noGood == assignment.getImpliedBy(watchedAtom1) - || noGood == assignment.getImpliedBy(watchedAtom2); - } - - public int getNumberOfDeletedNoGoods() { - return numberOfDeletedNoGoods; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java deleted file mode 100644 index 28af2719c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStore.java +++ /dev/null @@ -1,231 +0,0 @@ -/** - * 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. - * - * 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.solver; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; - -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; - -public class NaiveNoGoodStore implements NoGoodStore { - private static final Logger LOGGER = LoggerFactory.getLogger(NaiveNoGoodStore.class); - - private HashMap delegate = new HashMap<>(); - private final WritableAssignment assignment; - private final NoGoodCounter counter = new NoGoodCounter(); - - private boolean hasInferredAssignments; - - public NaiveNoGoodStore(WritableAssignment assignment) { - this.assignment = assignment; - } - - void clear() { - assignment.clear(); - delegate.clear(); - } - - @Override - public ConflictCause add(int id, NoGood noGood, int lbd) { - counter.add(noGood); - if (assignment.violates(noGood)) { - return new ConflictCause(noGood.asAntecedent()); - } - - delegate.put(id, noGood); - return null; - } - - @Override - public ConflictCause add(int id, NoGood noGood) { - return add(id, noGood, Integer.MAX_VALUE); - } - - @Override - public ConflictCause propagate() { - hasInferredAssignments = false; - - boolean any = false; - boolean retry; - - do { - retry = false; - ConflictCause conflictCause; - for (NoGood noGood : delegate.values()) { - hasInferredAssignments = false; - conflictCause = propagateWeakly(noGood); - if (conflictCause != null) { - return conflictCause; - } - if (hasInferredAssignments) { - any = true; - hasInferredAssignments = false; - retry = true; - } - } - for (NoGood noGood : delegate.values()) { - hasInferredAssignments = false; - conflictCause = propagateStrongly(noGood); - if (conflictCause != null) { - return conflictCause; - } - if (hasInferredAssignments) { - any = true; - hasInferredAssignments = false; - retry = true; - } - } - } while (retry); - - for (NoGood noGood : delegate.values()) { - if (assignment.violates(noGood)) { - return new ConflictCause(noGood.asAntecedent()); - } - } - - if (any) { - hasInferredAssignments = true; - } - - return null; - } - - @Override - public boolean didPropagate() { - return hasInferredAssignments; - } - - @Override - public void backtrack() { - assignment.backtrack(); - } - - @Override - public void growForMaxAtomId(int maxAtomId) { - } - - @Override - public NoGoodCounter getNoGoodCounter() { - return counter; - } - - @Override - public void cleanupLearnedNoGoods() { - } - - /** - * Infer an assignment from a nogood if it is weakly unit. - * - * This method iterates over all literals in the given nogood - * in order to check whether it is weakly unit. If the nogood - * turns out to be unit, then an assignment is generated and - * {@code true} is returned. Otherwise, {@code false} is - * returned. - * - * @param noGood the nogood to analyze. - * @return {@code true} iff an assignment was inferred, - * {@code false} otherwise. - */ - private ConflictCause propagateWeakly(NoGood noGood) { - int index = -1; - for (int i = 0; i < noGood.size(); i++) { - final int literal = noGood.getLiteral(i); - - if (assignment.isAssigned(atomOf(literal))) { - if (!assignment.isViolated(literal)) { - // Literal is satisfied! - return null; - } - } else if (index != -1) { - // There is more than one unassigned literal! - return null; - } else { - index = i; - } - } - - if (index == -1) { - return null; - } - - hasInferredAssignments = true; - - final int literal = noGood.getLiteral(index); - return assignment.assign(atomOf(literal), isNegated(literal) ? MBT : FALSE, noGood.asAntecedent()); - } - - /** - * Infer an assignment from a nogood if it is strongly unit. - * - * This method iterates over all literals in the given nogood - * in order to check whether it is strongly unit. If the nogood - * turns out to be unit, then an assignment for the head is - * generated and {@code true} is returned. Otherwise, - * {@code false} is returned. - * - * @param noGood the nogood to analyze. - * @return {@code true} iff an assignment was inferred, - * {@code false} otherwise. - */ - private ConflictCause propagateStrongly(NoGood noGood) { - if (!noGood.hasHead()) { - return null; - } - - final int headAtom = atomOf(noGood.getHead()); - - if (assignment.getTruth(headAtom) != MBT) { - return null; - } - - // Check that NoGood is violated except for the head - // (i.e., without the head set it would be unit) and - // that none of the true values are assigned MBT, but - // instead are all TRUE. - for (int i = 1; i < noGood.size(); i++) { - final int literal = noGood.getLiteral(i); - - if (!assignment.isViolated(literal)) { - return null; - } - - // Skip if positive literal is assigned MBT. - if (isPositive(literal) && assignment.getTruth(atomOf(literal)) != TRUE) { - return null; - } - } - - hasInferredAssignments = true; - - return assignment.assign(headAtom, TRUE, noGood.asAntecedent()); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java deleted file mode 100644 index bf8f08268..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NaiveSolver.java +++ /dev/null @@ -1,432 +0,0 @@ -/** - * Copyright (c) 2016, 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.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import org.apache.commons.lang3.tuple.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.function.Consumer; - -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static java.lang.Math.abs; - -/** - * Copyright (c) 2016-2020, the Alpha Team. - */ -public class NaiveSolver extends AbstractSolver { - private static final Logger LOGGER = LoggerFactory.getLogger(NaiveSolver.class); - private final Stack choiceStack; - private HashMap truthAssignments = new HashMap<>(); - private ArrayList newTruthAssignments = new ArrayList<>(); - private ArrayList> decisionLevels = new ArrayList<>(); - - private HashMap knownNoGoods = new HashMap<>(); - - private boolean doInit = true; - private boolean didChange; - private int decisionLevel; - - private Map choiceOn = new HashMap<>(); - private Map choiceOff = new HashMap<>(); - private Integer nextChoice; - private HashSet mbtAssigned = new HashSet<>(); - private ArrayList> mbtAssignedFromUnassigned = new ArrayList<>(); - private ArrayList> trueAssignedFromMbt = new ArrayList<>(); - private List unassignedAtoms; - - NaiveSolver(AtomStore atomStore, Grounder grounder) { - super(atomStore, grounder); - - this.choiceStack = new Stack<>(); - - decisionLevels.add(0, new ArrayList<>()); - mbtAssignedFromUnassigned.add(0, new ArrayList<>()); - trueAssignedFromMbt.add(0, new ArrayList<>()); - } - - @Override - protected boolean tryAdvance(Consumer action) { - // Get basic rules and facts from grounder - if (doInit) { - obtainNoGoodsFromGrounder(); - doInit = false; - } else { - // We already found one Answer-Set and are requested to find another one - doBacktrack(); - if (isSearchSpaceExhausted()) { - return false; - } - } - - // Try all assignments until grounder reports no more NoGoods and all of them are satisfied - while (true) { - if (!propagationFixpointReached()) { - LOGGER.trace("Propagating."); - updateGrounderAssignments(); // After a choice, it would be more efficient to propagate first and only then ask the grounder. - obtainNoGoodsFromGrounder(); - doUnitPropagation(); - doMBTPropagation(); - LOGGER.trace("Assignment after propagation is: {}", truthAssignments); - } else if (assignmentViolatesNoGoods()) { - LOGGER.trace("Backtracking from wrong choices:"); - LOGGER.trace("Choice stack: {}", choiceStack); - doBacktrack(); - if (isSearchSpaceExhausted()) { - return false; - } - } else if (choicesLeft()) { - doChoice(); - } else if (!allAtomsAssigned()) { - LOGGER.trace("Closing unassigned known atoms (assigning FALSE)."); - assignUnassignedToFalse(); - didChange = true; - } else if (noMBTValuesReamining()) { - AnswerSet as = getAnswerSetFromAssignment(); - LOGGER.debug("Answer-Set found: {}", as); - LOGGER.trace("Choice stack: {}", choiceStack); - action.accept(as); - return true; - } else { - LOGGER.debug("Backtracking from wrong choices (MBT remaining):"); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Currently MBT:"); - for (Integer integer : mbtAssigned) { - LOGGER.trace(atomStore.atomToString(atomOf(integer))); - } - LOGGER.trace("Choice stack: {}", choiceStack); - } - doBacktrack(); - if (isSearchSpaceExhausted()) { - return false; - } - } - } - } - - private void assignUnassignedToFalse() { - for (Integer atom : unassignedAtoms) { - truthAssignments.put(atom, false); - newTruthAssignments.add(atom); - decisionLevels.get(decisionLevel).add(atom); - } - } - - private boolean allAtomsAssigned() { - unassignedAtoms = new ArrayList<>(); - HashSet knownAtoms = new HashSet<>(); - for (Map.Entry entry : knownNoGoods.entrySet()) { - for (Integer integer : entry.getValue()) { - knownAtoms.add(abs(integer)); - } - } - for (Integer atom : knownAtoms) { - if (!truthAssignments.containsKey(atom)) { - unassignedAtoms.add(atom); - } - } - return unassignedAtoms.isEmpty(); - } - - private boolean noMBTValuesReamining() { - return mbtAssigned.size() == 0; - } - - private void doMBTPropagation() { - boolean didPropagate = true; - while (didPropagate) { - didPropagate = false; - for (Map.Entry noGoodEntry : knownNoGoods.entrySet()) { - if (propagateMBT(noGoodEntry.getValue())) { - didPropagate = true; - didChange = true; - } - } - } - } - - private String reportTruthAssignments() { - StringBuilder report = new StringBuilder("Current Truth assignments: "); - for (Integer atomId : truthAssignments.keySet()) { - report.append(truthAssignments.get(atomId) ? "+" : "-").append(atomId).append(" "); - } - return report.toString(); - } - - private boolean propagationFixpointReached() { - // Check if anything changed. - // didChange is updated in places of change. - boolean changeCopy = didChange; - didChange = false; - return !changeCopy; - } - - private AnswerSet getAnswerSetFromAssignment() { - ArrayList trueAtoms = new ArrayList<>(); - for (Map.Entry atomAssignment : truthAssignments.entrySet()) { - if (atomAssignment.getValue()) { - trueAtoms.add(atomAssignment.getKey()); - } - } - return translate(trueAtoms); - } - - private void doChoice() { - decisionLevel++; - ArrayList list = new ArrayList<>(); - list.add(nextChoice); - decisionLevels.add(decisionLevel, list); - trueAssignedFromMbt.add(decisionLevel, new ArrayList<>()); - mbtAssignedFromUnassigned.add(decisionLevel, new ArrayList<>()); - // We choose true for any unassigned choice atom (backtrackFast tries false) - truthAssignments.put(nextChoice, true); - newTruthAssignments.add(nextChoice); - choiceStack.push(new Choice(nextChoice, true, false)); - // Record change to compute propagation fixpoint again. - didChange = true; - } - - private boolean choicesLeft() { - // Check if there is an enabled choice that is not also disabled - for (Map.Entry e : choiceOn.entrySet()) { - final int atom = e.getKey(); - - // Only consider unassigned choices that are enabled. - if (truthAssignments.containsKey(atom) || !truthAssignments.getOrDefault(e.getValue(), false)) { - continue; - } - - // Check that candidate is not disabled already - if (!truthAssignments.getOrDefault(choiceOff.getOrDefault(atom, 0), false)) { - nextChoice = atom; - return true; - } - } - return false; - } - - private void doBacktrack() { - if (decisionLevel <= 0) { - return; - } - - Choice lastChoice = choiceStack.pop(); - - int lastChoiceAtom = lastChoice.getAtom(); - boolean lastChoiceValue = lastChoice.getValue(); - - // Remove truth assignments of current decision level - for (Integer atomId : decisionLevels.get(decisionLevel)) { - truthAssignments.remove(atomId); - } - - // Handle MBT assigned values: - // First, restore mbt when it got assigned true in this decision level - mbtAssigned.addAll(trueAssignedFromMbt.get(decisionLevel)); - - // Second, remove mbt indicator for values that were unassigned - for (Integer atomId : mbtAssignedFromUnassigned.get(decisionLevel)) { - mbtAssigned.remove(atomId); - } - - // Clear atomIds in current decision level - decisionLevels.set(decisionLevel, new ArrayList<>()); - mbtAssignedFromUnassigned.set(decisionLevel, new ArrayList<>()); - trueAssignedFromMbt.set(decisionLevel, new ArrayList<>()); - - if (lastChoiceValue) { - // Choose false now - truthAssignments.put(lastChoiceAtom, false); - choiceStack.push(new Choice(lastChoiceAtom, false, true)); - newTruthAssignments.add(lastChoiceAtom); - decisionLevels.get(decisionLevel).add(lastChoiceAtom); - didChange = true; - } else { - decisionLevel--; - doBacktrack(); - } - } - - private static IntIterator fromIterator(Iterator it) { - return new IntIterator() { - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public int next() { - return it.next(); - } - }; - } - - private void updateGrounderAssignments() { - grounder.updateAssignment(fromIterator(newTruthAssignments.stream().filter(atom -> truthAssignments.get(atom)).iterator())); - newTruthAssignments.clear(); - } - - - private void obtainNoGoodsFromGrounder() { - final int oldSize = knownNoGoods.size(); - knownNoGoods.putAll(grounder.getNoGoods(null)); - if (oldSize != knownNoGoods.size()) { - // Record to detect propagation fixpoint, checking if new NoGoods were reported would be better here. - didChange = true; - } - - // Record choice atoms - final Pair, Map> choiceAtoms = grounder.getChoiceAtoms(); - choiceOn.putAll(choiceAtoms.getKey()); - choiceOff.putAll(choiceAtoms.getValue()); - } - - private boolean isSearchSpaceExhausted() { - return decisionLevel == 0; - } - - private void doUnitPropagation() { - // Check each NoGood if it is unit (naive algorithm) - for (NoGood noGood : knownNoGoods.values()) { - int implied = unitPropagate(noGood); - if (implied == -1) { // NoGood is not unit, skip. - continue; - } - int impliedLiteral = noGood.getLiteral(implied); - int impliedAtomId = atomOf(impliedLiteral); - boolean impliedTruthValue = isNegated(impliedLiteral); - if (truthAssignments.get(impliedAtomId) != null) { // Skip if value already was assigned. - continue; - } - truthAssignments.put(impliedAtomId, impliedTruthValue); - newTruthAssignments.add(impliedAtomId); - didChange = true; // Record to detect propagation fixpoint - decisionLevels.get(decisionLevel).add(impliedAtomId); - if (impliedTruthValue) { // Record MBT value in case true is assigned - mbtAssigned.add(impliedAtomId); - mbtAssignedFromUnassigned.get(decisionLevel).add(impliedAtomId); - } - } - } - - private boolean isLiteralAssigned(int literal) { - return truthAssignments.get(atomOf(literal)) != null; - } - - private boolean isLiteralViolated(int literal) { - final int atom = atomOf(literal); - final Boolean assignment = truthAssignments.get(atom); - - // For unassigned atoms, any literal is not violated. - return assignment != null && isNegated(literal) != assignment; - } - - /** - * Returns position of implied literal if input NoGood is unit. - * @param noGood - * @return -1 if NoGood is not unit. - */ - private int unitPropagate(NoGood noGood) { - int lastUnassignedPosition = -1; - for (int i = 0; i < noGood.size(); i++) { - int literal = noGood.getLiteral(i); - if (isLiteralAssigned(literal)) { - if (!isLiteralViolated(literal)) { - // The NoGood is satisfied, hence it cannot be unit. - return -1; - } - } else if (lastUnassignedPosition != -1) { - // NoGood is not unit, if there is not exactly one unassigned literal - return -1; - } else { - lastUnassignedPosition = i; - } - } - return lastUnassignedPosition; - } - - private boolean propagateMBT(NoGood noGood) { - // The MBT propagation checks whether the head-indicated literal is MBT - // and the remaining literals are violated - // and none of them are MBT, - // then the head literal is set from MBT to true. - - if (!noGood.hasHead()) { - return false; - } - - int headAtom = atomOf(noGood.getHead()); - - // Check whether head is assigned MBT. - if (!mbtAssigned.contains(headAtom)) { - return false; - } - - // Check that NoGood is violated except for the head (i.e., without the head set it would be unit) - // and that none of the true values is MBT. - for (int i = 1; i < noGood.size(); i++) { - int literal = noGood.getLiteral(i); - if (!(isLiteralAssigned(literal) && isLiteralViolated(literal))) { - return false; - } - // Skip if positive literal is assigned MBT. - if (isPositive(literal) && mbtAssigned.contains(atomOf(literal))) { - return false; - } - } - - // Set truth value from MBT to true. - mbtAssigned.remove(headAtom); - trueAssignedFromMbt.get(decisionLevel).add(headAtom); - return true; - } - - private boolean assignmentViolatesNoGoods() { - // Check each NoGood, if it is violated - for (NoGood noGood : knownNoGoods.values()) { - boolean isSatisfied = false; - for (Integer noGoodLiteral : noGood) { - if (!isLiteralAssigned(noGoodLiteral) || !isLiteralViolated(noGoodLiteral)) { - isSatisfied = true; - break; - } - } - if (!isSatisfied) { - LOGGER.trace("Violated NoGood: {}", noGood); - return true; - } - } - return false; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java deleted file mode 100644 index 432419ab1..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodCounter.java +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright (c) 2019 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.solver; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; - -import java.util.ArrayList; -import java.util.List; - -/** - * Maintains statistics on numbers of various types of {@link NoGood}s. - */ -public class NoGoodCounter { - - private static final int CARD_NARY = 0; - private static final int CARD_UNARY = 1; - private static final int CARD_BINARY = 2; - - private int[] countByType = new int[Type.values().length]; - private int[] countByCardinality = new int[3]; - - /** - * Increases counters for the types of the given NoGood - * @param noGood - */ - void add(NoGoodInterface noGood) { - countByType[noGood.getType().ordinal()]++; - countByCardinality[getAbstractCardinality(noGood)]++; - } - - /** - * Decreases counters for the types of the given NoGood - * @param noGood - */ - void remove(NoGoodInterface noGood) { - countByType[noGood.getType().ordinal()]--; - countByCardinality[getAbstractCardinality(noGood)]--; - } - - private int getAbstractCardinality(NoGoodInterface noGood) { - if (noGood.isUnary()) { - return CARD_UNARY; - } - if (noGood.isBinary()) { - return CARD_BINARY; - } - return CARD_NARY; - } - - /** - * @param type - * @return the number of nogoods of the given type - */ - public int getNumberOfNoGoods(Type type) { - return countByType[type.ordinal()]; - } - - /** - * @return the number of unary nogoods - */ - public int getNumberOfUnaryNoGoods() { - return countByCardinality[CARD_UNARY]; - } - - /** - * @return the number of binary nogoods - */ - public int getNumberOfBinaryNoGoods() { - return countByCardinality[CARD_BINARY]; - } - - /** - * @return the number of nogoods that are neither unary nor binary - */ - public int getNumberOfNAryNoGoods() { - return countByCardinality[CARD_NARY]; - } - - /** - * @return {@code true} iff there is at least one binary nogood - */ - public boolean hasBinaryNoGoods() { - return countByCardinality[CARD_BINARY] > 0; - } - - /** - * @return a string giving statistics on numbers of nogoods by type - */ - public String getStatsByType() { - List statsList = new ArrayList<>(Type.values().length); - for (Type type : Type.values()) { - statsList.add(type.name() + ": " + countByType[type.ordinal()]); - } - return String.join(" ", statsList); - } - - /** - * @return a string giving statistics on numbers of nogoods by cardinality - */ - public String getStatsByCardinality() { - return "unary: " + getNumberOfUnaryNoGoods() + " binary: " + getNumberOfBinaryNoGoods() + " larger: " + getNumberOfNAryNoGoods(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java deleted file mode 100644 index 7cd516b40..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStore.java +++ /dev/null @@ -1,58 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import at.ac.tuwien.kr.alpha.common.NoGood; - -/** - * An interface defining the use of a NoGood store. - * - * Copyright (c) 2016-2019, the Alpha Team. - */ -public interface NoGoodStore { - int LBD_NO_VALUE = -1; - - /** - * Adds a nogood with the given id. - * @param id the unique identifier of the nogood. - * @param noGood the nogood to add. - * @param lbd the literals block distance. - * @return {@code null} if the noGood was added without conflict, a {@link ConflictCause} describing - * the conflict otherwise. - */ - ConflictCause add(int id, NoGood noGood, int lbd); - - /** - * Adds a NoGood with no LBD value set. - * @param id the unique identifier of the NoGood. - * @param noGood the NoGood to add. - * @return {@code null} if the noGood was added without conflict, a {@link ConflictCause} describing -* * the conflict otherwise. - */ - ConflictCause add(int id, NoGood noGood); - - /** - * Apply weak propagation and strong propagation. Propagation should stop as soon as some nogood is violated. - * @return some cause iff a conflict was reached or {@code null} otherwise - */ - ConflictCause propagate(); - - /** - * After a call to {@link #propagate()} this method provides - * whether propagation was successful, i.e. at least one new - * assignment was inferred. - * @return {@code true} iff the last call to {@link #propagate()} - * inferred at least one assignment, {@code false} otherwise. - */ - boolean didPropagate(); - - void backtrack(); - - void growForMaxAtomId(int maxAtomId); - - /** - * Tests whether a cleanup of the learned NoGoods database is appropriate and exectutes the cleaning if - * necessary. - */ - void cleanupLearnedNoGoods(); - - NoGoodCounter getNoGoodCounter(); -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java deleted file mode 100644 index 125b70976..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoaming.java +++ /dev/null @@ -1,1003 +0,0 @@ -/* - * Copyright (c) 2016-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.solver; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.isNegated; -import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; -import static at.ac.tuwien.kr.alpha.common.Literals.literalToString; -import static at.ac.tuwien.kr.alpha.common.NoGood.HEAD; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; - -/** - * NoGoodStore using for each NoGood three watches, two ordinary ones and an alpha watch. - * The alpha watch may point to positive or negative literals but not the head of the NoGood. - * - * Note the following invariant for watches: - * (Inv): For every NoGood it either holds that both watched literals are unassigned, or for one watch holds: it - * points to a literal that is assigned a satisfying truth value at decision level d and the other - * watched literal is assigned at decision level d' such that d <= d'. - * The second condition ensures that after backtracking the NoGood is still satisfied or both watches - * point to unassigned literals. Observe that for an assignment to TRUE the (potentially lower) decision level of MBT - * is taken. - * - * Copyright (c) 2017-2020, the Alpha Team. - */ -public class NoGoodStoreAlphaRoaming implements NoGoodStore, BinaryNoGoodPropagationEstimation, Checkable { - private static final Logger LOGGER = LoggerFactory.getLogger(NoGoodStoreAlphaRoaming.class); - private static final int UNASSIGNED = Integer.MAX_VALUE; - - private final WritableAssignment assignment; - private final LearnedNoGoodDeletion learnedNoGoodDeletion; - @SuppressWarnings("unchecked") - private ArrayList[] watches = new ArrayList[0]; - @SuppressWarnings("unchecked") - private ArrayList[] watchesAlpha = new ArrayList[0]; - private BinaryWatchList[] binaryWatches = new BinaryWatchList[0]; - private int maxAtomId; - - private boolean checksEnabled; - private boolean didPropagate; - private boolean hasBinaryNoGoods; - - private final NoGoodCounter counter = new NoGoodCounter(); - - public NoGoodStoreAlphaRoaming(WritableAssignment assignment, boolean checksEnabled) { - this.assignment = assignment; - this.checksEnabled = checksEnabled; - this.learnedNoGoodDeletion = new LearnedNoGoodDeletion(this, assignment); - } - - public NoGoodStoreAlphaRoaming(WritableAssignment assignment) { - this(assignment, false); - } - - @SuppressWarnings("unchecked") - void clear() { - assignment.clear(); - learnedNoGoodDeletion.reset(); - binaryWatches = new BinaryWatchList[0]; - watches = new ArrayList[0]; - watchesAlpha = new ArrayList[0]; - maxAtomId = 0; - } - - public LearnedNoGoodDeletion getLearnedNoGoodDeletion() { - return learnedNoGoodDeletion; - } - - @Override - public void backtrack() { - didPropagate = false; - assignment.backtrack(); - if (checksEnabled) { - if (assignment.getAssignmentsToProcess().isEmpty()) { - new WatchedNoGoodsChecker().doWatchesCheck(); - } else { - LOGGER.trace("Skipping watches check since there are assignments to process first."); - } - } - } - - @Override - public void growForMaxAtomId(int maxAtomId) { - int requiredMaxSize = 2 * (maxAtomId + 2); - if (requiredMaxSize < binaryWatches.length) { - return; - } - int newCapacity = arrayGrowthSize(binaryWatches.length); - if (newCapacity < requiredMaxSize) { - newCapacity = requiredMaxSize; - } - int oldlength = binaryWatches.length; - binaryWatches = Arrays.copyOf(binaryWatches, newCapacity); - for (int i = oldlength; i < binaryWatches.length; i++) { - binaryWatches[i] = new BinaryWatchList(i); - } - watches = Arrays.copyOf(watches, newCapacity); - for (int i = oldlength; i < watches.length; i++) { - watches[i] = new ArrayList<>(); - } - watchesAlpha = Arrays.copyOf(watchesAlpha, newCapacity); - for (int i = oldlength; i < watchesAlpha.length; i++) { - watchesAlpha[i] = new ArrayList<>(); - } - this.maxAtomId = maxAtomId; - } - - @Override - public NoGoodCounter getNoGoodCounter() { - return counter; - } - - @Override - public void cleanupLearnedNoGoods() { - if (learnedNoGoodDeletion.needToRunNoGoodDeletion()) { - learnedNoGoodDeletion.runNoGoodDeletion(); - } - } - - void removeFromWatches(WatchedNoGood toRemove) { - counter.remove(toRemove); - int watchedLiteral1 = toRemove.getLiteral(0); - int watchedLiteral2 = toRemove.getLiteral(1); - if (!watches(watchedLiteral2).remove(toRemove) - || !watches(watchedLiteral1).remove(toRemove)) { - throw oops("Could not remove learned NoGood from watch lists."); - } - if (toRemove.hasHead()) { - throw oops("NoGood has a head."); // If this occurs, we need to remove the alpha watch too. - } - } - - private ArrayList watches(int literal) { - return watches[literal]; - } - - private ArrayList watchesAlpha(int literal) { - return watchesAlpha[literal]; - } - - private void addOrdinaryWatch(WatchedNoGood wng, int pointer) { - final int literal = wng.getLiteral(pointer); - watches(literal).add(wng); - } - - private void addAlphaWatch(WatchedNoGood wng) { - final int literal = wng.getLiteralAtAlpha(); - watchesAlpha(literal).add(wng); - } - - @Override - public ConflictCause add(int id, NoGood noGood, int lbd) { - LOGGER.trace("Adding {}", noGood); - - final ConflictCause conflictCause; - if (noGood.isUnary()) { - conflictCause = addUnary(noGood); - } else if (noGood.isBinary()) { - conflictCause = addAndWatchBinary(noGood); - } else { - conflictCause = addAndWatch(noGood, lbd); - } - - if (conflictCause == null) { - counter.add(noGood); - } - return conflictCause; - } - - public ConflictCause add(int id, NoGood noGood) { - return add(id, noGood, -1); - } - - /** - * Takes a noGood containing only a single literal and translates it into an assignment (because it - * is trivially unit). Still, a check for conflict is performed. - */ - private ConflictCause addUnary(final NoGood noGood) { - if (noGood.hasHead()) { - return assignStrongComplement(noGood, 0); - } else { - return assignWeakComplement(0, noGood, 0); - } - } - - private static boolean isComplementaryAssigned(int literal, ThriceTruth literalTruth) { - return literalTruth != null && literalTruth.toBoolean() != isPositive(literal); - } - - private int strongDecisionLevel(int atom) { - int strongDecisionLevel = assignment.getStrongDecisionLevel(atom); - return strongDecisionLevel == -1 ? UNASSIGNED : strongDecisionLevel; - } - - private ConflictCause addAndWatch(final NoGood noGood, int lbd) { - // Collect potential watch candidates. - int posWeakUnassigned1 = -1; - int posWeakUnassigned2 = -1; - int posSatisfiedLiteral1 = -1; - int posSatisfiedLiteral2 = -1; - int posWeakHighestAssigned = -1; - int weakDecisionLevelHighestAssigned = -1; - int posStrongHighestAssigned = -1; - int strongDecisionLevelHighestAssigned = -1; - int posPotentialAlphaWatch = -1; - int satisfiedLiteralWeakDecisionLevel = -1; - - // Used to detect always-satisfied NoGoods of form { L, -L, ... }. - Map occurringAtomPolarity = new HashMap<>(); - - // Iterate noGood and record satisfying/unassigned/etc positions. - int headAtom = atomOf(noGood.getHead()); - final ThriceTruth headTruth = noGood.hasHead() ? assignment.getTruth(headAtom) : null; - final boolean isHeadTrue = headTruth == TRUE; - for (int i = 0; i < noGood.size(); i++) { - final int literal = noGood.getLiteral(i); - final int atom = atomOf(literal); - final ThriceTruth atomTruthValue = assignment.getTruth(atom); - final int atomWeakDecisionLevel = assignment.getWeakDecisionLevel(atom); - final int atomStrongDecisionLevel = assignment.getStrongDecisionLevel(atom); - - // Check if NoGood can never be violated (atom occurring positive and negative) - if (occurringAtomPolarity.containsKey(atomOf(literal))) { - if (occurringAtomPolarity.get(atomOf(literal)) != isNegated(literal)) { - // NoGood cannot be violated or propagate, ignore it. - LOGGER.debug("Added NoGood can never propagate or be violated, ignoring it. NoGood is: {}", noGood); - return null; - } - } else { - occurringAtomPolarity.put(atomOf(literal), isNegated(literal)); - } - - // Check weak unassigned. - if (atomTruthValue == null) { - if (posWeakUnassigned1 == -1) { - posWeakUnassigned1 = i; - } else { - posWeakUnassigned2 = i; - } - } - // Alpha watch: - if (posPotentialAlphaWatch == -1 && noGood.hasHead() && i != HEAD) { - // Current literal is potential alpha watch if: - // 1) the head of the nogood is true and the literal is assigned at a higher-or-equal decision level. - // 2) the literal is complementary assigned and thus satisfies the nogood, or - // 3) the literal is unassigned or assigned must-be-true. - if (isHeadTrue && strongDecisionLevel(atomOf(literal)) >= strongDecisionLevel(headAtom) - || isComplementaryAssigned(noGood.getLiteral(i), atomTruthValue) - || strongDecisionLevel(atomOf(literal)) == Integer.MAX_VALUE) { - posPotentialAlphaWatch = i; - } - } - // Check satisfaction - if (atomTruthValue != null && atomTruthValue.toBoolean() != isPositive(literal)) { - if (posSatisfiedLiteral1 == -1) { - posSatisfiedLiteral1 = i; - satisfiedLiteralWeakDecisionLevel = atomWeakDecisionLevel; - } else { - posSatisfiedLiteral2 = i; - } - } - // Check violation. - if (atomTruthValue != null && atomTruthValue.toBoolean() == isPositive(literal)) { - if (atomWeakDecisionLevel > weakDecisionLevelHighestAssigned) { - weakDecisionLevelHighestAssigned = atomWeakDecisionLevel; - posWeakHighestAssigned = i; - } - if (!atomTruthValue.isMBT() && noGood.hasHead() // Ensure strong violation. - && atomStrongDecisionLevel > strongDecisionLevelHighestAssigned) { - strongDecisionLevelHighestAssigned = atomStrongDecisionLevel; - posStrongHighestAssigned = i; - } - } - } - - // Set ordinary and alpha watches now. - // Compute ordinary watches: - final int watch1; - final int watch2; - - - if (posWeakUnassigned1 != -1 && posWeakUnassigned2 != -1) { - // NoGood has two unassigned literals. - watch1 = posWeakUnassigned1; - watch2 = posWeakUnassigned2; - } else if (posSatisfiedLiteral1 != -1) { - // NoGood is satisfied. - int bestSecondPointer = posSatisfiedLiteral2 != -1 ? posSatisfiedLiteral2 - : posWeakUnassigned1 != -1 ? posWeakUnassigned1 - : posWeakHighestAssigned; - if (posSatisfiedLiteral2 == -1 && posWeakUnassigned1 == -1) { - // The NoGood has only one satisfied literal and is unit without it. - // If it is unit on lower decision level than it is satisfied, it propagates the satisfying literal on lower decision level. - if (satisfiedLiteralWeakDecisionLevel > weakDecisionLevelHighestAssigned) { - ConflictCause conflictCause = assignWeakComplement(posSatisfiedLiteral1, noGood, weakDecisionLevelHighestAssigned); - if (conflictCause != null) { - return conflictCause; - } - } - } - watch1 = posSatisfiedLiteral1; - watch2 = bestSecondPointer; - } else if (posWeakUnassigned1 != -1) { - // NoGood is weakly unit; propagate. - ConflictCause conflictCause = assignWeakComplement(posWeakUnassigned1, noGood, weakDecisionLevelHighestAssigned); - if (conflictCause != null) { - return conflictCause; - } - watch1 = posWeakUnassigned1; - watch2 = posWeakHighestAssigned; - } else { - // NoGood is violated. - return new ConflictCause(noGood.asAntecedent()); - } - - // Compute alpha watch: - int watchAlpha = -1; - if (noGood.hasHead()) { - if (posPotentialAlphaWatch != -1) { - // Found potential alpha watch. - watchAlpha = posPotentialAlphaWatch; - } else { - // No potential alpha watch found: noGood must be strongly unit. - ConflictCause conflictCause = assignStrongComplement(noGood, strongDecisionLevelHighestAssigned); - if (conflictCause != null) { - return conflictCause; - } - watchAlpha = posStrongHighestAssigned; - } - } - WatchedNoGood wng = new WatchedNoGood(noGood, watch1, watch2, watchAlpha); - LOGGER.trace("WatchedNoGood is {}.", wng); - - // Record for eventual removal if this NoGood is learned. - if (noGood.getType() == Type.LEARNT) { - wng.setLBD(lbd); - learnedNoGoodDeletion.recordLearnedNoGood(wng); - } - - if (wng.getAlphaPointer() == -1 && noGood.hasHead()) { - throw oops("Did not set alpha watch for nogood with head."); - } - - // Register alpha watch if present. - if (wng.getAlphaPointer() != -1) { - addAlphaWatch(wng); - } - // Set ordinary watches. - addOrdinaryWatch(wng, 0); - addOrdinaryWatch(wng, 1); - return null; - } - - private ConflictCause addAndWatchBinary(final NoGood noGood) { - // Shorthands for viewing the nogood as { a, b }. - final int a = noGood.getLiteral(0); - final int b = noGood.getLiteral(1); - final int atomA = atomOf(a); - final int atomB = atomOf(b); - - // Ignore NoGoods of the form { -a, a }. - if (a != b && atomA == atomB) { - return null; - } - - // Note: it might be faster to not check explicitly for violation but wait for conflict from assign. - final ThriceTruth atomATruthValue = assignment.getTruth(atomA); - final ThriceTruth atomBTruthValue = assignment.getTruth(atomB); - - final boolean isViolatedA = atomATruthValue != null && isPositive(a) == atomATruthValue.toBoolean(); - final boolean isViolatedB = atomBTruthValue != null && isPositive(b) == atomBTruthValue.toBoolean(); - - // Check for violation. - if (isViolatedA && isViolatedB) { - return new ConflictCause(noGood.asAntecedent()); - } - - // The above violation check guarantees that adding (and propagation on other literal) results in no conflict. - binaryWatches[a].add(noGood); - binaryWatches[b].add(noGood); - hasBinaryNoGoods = true; - return null; - } - - private ConflictCause assignWeakComplement(final int literalIndex, final NoGoodInterface impliedBy, int decisionLevel) { - final int literal = impliedBy.getLiteral(literalIndex); - ThriceTruth truth = isNegated(literal) ? MBT : FALSE; - return assignTruth(atomOf(literal), truth, impliedBy.asAntecedent(), decisionLevel); - } - - private ConflictCause assignStrongComplement(final NoGoodInterface impliedBy, int decisionLevel) { - return assignTruth(atomOf(impliedBy.getHead()), TRUE, impliedBy.asAntecedent(), decisionLevel); - } - - private ConflictCause assignTruth(int atom, ThriceTruth truth, Antecedent impliedBy, int decisionLevel) { - ConflictCause cause = assignment.assign(atom, truth, impliedBy, decisionLevel); - if (cause == null) { - didPropagate = true; - } - return cause; - } - - /** - * Propagates from Unassigned to MBT/FALSE. - * @param literal the literal that triggers the propagation. - */ - private ConflictCause propagateWeakly(int literal, int currentDecisionLevel, boolean restrictToBinaryNoGoods) { - final ArrayList watchesOfAssignedAtom = watches(literal); - - // Propagate binary watches. - ConflictCause conflictCause = binaryWatches[literal].propagateWeakly(); - if (conflictCause != null || restrictToBinaryNoGoods) { - return conflictCause; - } - - // Check all watched multi-ary NoGoods. - Iterator watchIterator = watchesOfAssignedAtom.iterator(); - clearOrdinaryWatchList(literal); - while (watchIterator.hasNext()) { - WatchedNoGood nextNoGood = watchIterator.next(); - conflictCause = processWeaklyWatchedNoGood(literal, nextNoGood, currentDecisionLevel); - if (conflictCause != null) { - // Copy over all non-treated NoGoods, so that they can be treated after backtracking. - ArrayList watchlist = watches(literal); - watchlist.add(nextNoGood); - while (watchIterator.hasNext()) { - watchlist.add(watchIterator.next()); - } - return conflictCause; - } - } - return null; - } - - private ConflictCause processWeaklyWatchedNoGood(int assignedLiteral, WatchedNoGood watchedNoGood, int currentDecisionLevel) { - final int assignedWatch = watchedNoGood.getLiteral(0) == assignedLiteral ? 0 : 1; - final int otherWatch = 1 - assignedWatch; - - final int otherLiteral = watchedNoGood.getLiteral(otherWatch); - final ThriceTruth otherAtomTruth = assignment.getTruth(atomOf(otherLiteral)); - - // Find new literal to watch. - - // Check if the other watch already satisfies the noGood. - if (otherAtomTruth != null && otherAtomTruth.toBoolean() != isPositive(otherLiteral)) { - // Keep this watch and return early. - addOrdinaryWatch(watchedNoGood, assignedWatch); - return null; - } else { - for (int i = 2; i < watchedNoGood.size(); i++) { - final int currentLiteral = watchedNoGood.getLiteral(i); - final ThriceTruth currentTruth = assignment.getTruth(atomOf(currentLiteral)); - - // Break if: 1) current literal is unassigned, or 2) satisfies the nogood. - if (currentTruth == null || currentTruth.toBoolean() != isPositive(currentLiteral)) { - // Move pointer to new literal. - watchedNoGood.setWatch(assignedWatch, i); - addOrdinaryWatch(watchedNoGood, assignedWatch); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Moved watch pointers of nogood:"); - logNoGoodAndAssignment(watchedNoGood, assignment); - } - return null; - } - } - } - - // NoGood is unit, propagate the other watched literal. - // Note: Violation is detected by Assignment. - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Nogood is unit:"); - logNoGoodAndAssignment(watchedNoGood, assignment); - } - ConflictCause conflictCause = assignWeakComplement(otherWatch, watchedNoGood, currentDecisionLevel); - // Return conflict if noGood is violated. - if (conflictCause != null) { - return conflictCause; - } - // Watch same literal again. - addOrdinaryWatch(watchedNoGood, assignedWatch); - return null; - } - - private void logNoGoodAndAssignment(WatchedNoGood noGood, Assignment assignment) { - if (!LOGGER.isTraceEnabled()) { - return; - } - StringBuilder sb = new StringBuilder("Watched NoGood is: " + noGood + "\t\t Assigned: "); - for (Integer literal : noGood) { - Assignment.Entry assignmentEntry = assignment.get(atomOf(literal)); - sb.append(atomOf(literal)); - sb.append("="); - sb.append(assignmentEntry); - sb.append(", "); - } - LOGGER.trace(sb.toString()); - } - - private ConflictCause propagateStrongly(int literal, int currentDecisionLevel, boolean restrictToBinaryNoGoods) { - - // Propagate binary watches. - ConflictCause conflictCause = binaryWatches[literal].propagateStrongly(); - if (conflictCause != null || restrictToBinaryNoGoods) { - return conflictCause; - } - - // Check all watched multi-ary NoGoods. - Iterator watchIterator = watchesAlpha(literal).iterator(); - clearAlphaWatchList(literal); - while (watchIterator.hasNext()) { - WatchedNoGood nextNoGood = watchIterator.next(); - if (!nextNoGood.hasHead()) { - throw oops("Strong propagation encountered NoGood without head"); - } - conflictCause = processStronglyWatchedNoGood(nextNoGood, currentDecisionLevel); - if (conflictCause != null) { - // Copy over all non-treated NoGoods, so that they can be treated after backtracking. - ArrayList watchlist = watchesAlpha(literal); - watchlist.add(nextNoGood); - while (watchIterator.hasNext()) { - watchlist.add(watchIterator.next()); - } - return conflictCause; - } - } - return null; - } - - private ConflictCause processStronglyWatchedNoGood(WatchedNoGood watchedNoGood, int currentDecisionLevel) { - - final int headAtom = atomOf(watchedNoGood.getHead()); - final ThriceTruth headAtomTruth = assignment.getTruth(headAtom); - // Check if the other watch, i.e., the head, already satisfies the noGood. - if (headAtomTruth != null && TRUE == headAtomTruth) { - // Keep this watch and return early. - addAlphaWatch(watchedNoGood); - return null; - } - - final int assignedIndex = watchedNoGood.getAlphaPointer(); - - // Find new literal to watch. - for (int i = 0; i < watchedNoGood.size(); i++) { - if (i == assignedIndex || i == watchedNoGood.getHeadIndex()) { - continue; - } - int currentLiteral = watchedNoGood.getLiteral(i); - int currentAtom = atomOf(currentLiteral); - ThriceTruth currentAtomTruth = assignment.getTruth(currentAtom); - - // Break if: 1) current literal is unassigned (or MBT), or 2) satisfies the nogood. - if (currentAtomTruth == null || currentAtomTruth.isMBT() || currentAtomTruth.toBoolean() != isPositive(currentLiteral)) { - // Move pointer to new literal. - watchedNoGood.setAlphaPointer(i); - addAlphaWatch(watchedNoGood); - return null; - } - } - - // NoGood is unit, propagate. - ConflictCause conflictCause = assignStrongComplement(watchedNoGood, currentDecisionLevel); - if (conflictCause != null) { - return conflictCause; - } - // Watch same literal again. - addAlphaWatch(watchedNoGood); - return null; - } - - @Override - public ConflictCause propagate() { - ConflictCause conflictCause = propagate(false); - if (conflictCause != null) { - learnedNoGoodDeletion.increaseConflictCounter(); - } - return conflictCause; - } - - private ConflictCause propagateOnlyBinaryNoGoods() { - return propagate(true); - } - - private ConflictCause propagate(boolean restrictToBinaryNoGoods) { - didPropagate = false; - - Assignment.Pollable assignmentsToProcess = assignment.getAssignmentsToProcess(); - int currentDecisionLevel = assignment.getDecisionLevel(); - while (!assignmentsToProcess.isEmpty()) { - final int atom = assignmentsToProcess.peek(); - final ThriceTruth currentTruth = assignment.getTruth(atom); - final int literal = atomToLiteral(atom, currentTruth.toBoolean()); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Propagation processing atom: {}={}", atom, currentTruth); - } - - // Propagate weakly, except if there is an earlier MBT, where propagation already took place. - if (currentTruth != TRUE || assignment.getWeakDecisionLevel(atom) == currentDecisionLevel) { - ConflictCause conflictCause = propagateWeakly(literal, currentDecisionLevel, restrictToBinaryNoGoods); - if (conflictCause != null) { - LOGGER.trace("Halting propagation due to conflict. Current assignment: {}.", assignment); - return conflictCause; - } - } - - // Propagate strongly only for TRUE/FALSE assignments. - if (currentTruth != MBT) { - ConflictCause conflictCause = propagateStrongly(literal, currentDecisionLevel, restrictToBinaryNoGoods); - if (conflictCause != null) { - LOGGER.trace("Halting propagation due to conflict. Current assignment: {}.", assignment); - return conflictCause; - } - } - assignmentsToProcess.remove(); - } - if (checksEnabled && !restrictToBinaryNoGoods) { - runInternalChecks(); - } - return null; - } - - @Override - public boolean didPropagate() { - return didPropagate; - } - - @Override - public void setChecksEnabled(boolean checksEnabled) { - this.checksEnabled = checksEnabled; - } - - class BinaryWatchList implements ShallowAntecedent { - private int[] noGoodsWithoutHead = new int[10]; - private int noGoodsWithoutHeadSize; - private int[] noGoodsWithHead = new int[10]; - private int noGoodsWithHeadSize; - private final int forLiteral; - - private BinaryWatchList(int forLiteral) { - this.forLiteral = forLiteral; - } - - ConflictCause add(NoGood noGood) { - if (!noGood.isBinary()) { - throw oops("Received noGood is not binary."); - } - if (noGood.hasHead() && noGood.getHead() != forLiteral) { - return addHeadedNoGood(noGood); - } else { - return addOrdinaryNoGood(noGood); - } - } - - private ConflictCause addHeadedNoGood(NoGood noGood) { - if (noGoodsWithHeadSize + 1 > noGoodsWithHead.length) { - noGoodsWithHead = Arrays.copyOf(noGoodsWithHead, arrayGrowthSize(noGoodsWithHeadSize)); - } - int otherLiteral = noGood.getLiteral(0) == forLiteral ? noGood.getLiteral(1) : noGood.getLiteral(0); - if (isPositive(otherLiteral)) { - throw oops("NoGood has wrong head."); - } - noGoodsWithHead[noGoodsWithHeadSize++] = otherLiteral; - // Assign (weakly) otherLiteral if the newly added NoGood is unit. - ThriceTruth literalTruth = assignment.getTruth(atomOf(forLiteral)); - if (literalTruth != null && literalTruth.toBoolean() == isPositive(forLiteral)) { - int weakDecisionLevel = assignment.getWeakDecisionLevel(atomOf(forLiteral)); - ConflictCause conflictCause = assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this, weakDecisionLevel); - if (conflictCause != null) { - return conflictCause; - } - } - // Assign head (strongly) if the newly added NoGood is unit. - int strongDecisionLevel = assignment.getStrongDecisionLevel(atomOf(forLiteral)); - if (strongDecisionLevel != -1 && assignment.getTruth(atomOf(forLiteral)).toBoolean() == isPositive(forLiteral)) { - return assignment.assign(atomOf(otherLiteral), TRUE, this, strongDecisionLevel); - } - return null; - } - - private ConflictCause addOrdinaryNoGood(NoGood noGood) { - if (noGoodsWithoutHeadSize + 1 > noGoodsWithoutHead.length) { - noGoodsWithoutHead = Arrays.copyOf(noGoodsWithoutHead, arrayGrowthSize(noGoodsWithoutHeadSize)); - } - int otherLiteral = noGood.getLiteral(0) == forLiteral ? noGood.getLiteral(1) : noGood.getLiteral(0); - noGoodsWithoutHead[noGoodsWithoutHeadSize++] = otherLiteral; - // Assign otherLiteral if the newly added NoGood is unit. - ThriceTruth literalTruth = assignment.getTruth(atomOf(forLiteral)); - if (literalTruth != null && literalTruth.toBoolean() == isPositive(forLiteral)) { - int weakDecisionLevel = assignment.getWeakDecisionLevel(atomOf(forLiteral)); - return assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this, weakDecisionLevel); - } - return null; - } - - ConflictCause propagateWeakly() { - didPropagate |= noGoodsWithHeadSize > 0 || noGoodsWithoutHeadSize > 0; - for (int i = 0; i < noGoodsWithoutHeadSize; i++) { - final int otherLiteral = noGoodsWithoutHead[i]; - ConflictCause conflictCause = assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this); - if (conflictCause != null) { - return conflictCause; - } - } - for (int i = 0; i < noGoodsWithHeadSize; i++) { - final int otherLiteral = noGoodsWithHead[i]; - ConflictCause conflictCause = assignment.assign(atomOf(otherLiteral), isPositive(otherLiteral) ? FALSE : MBT, this); - if (conflictCause != null) { - return conflictCause; - } - } - return null; - } - - ConflictCause propagateStrongly() { - didPropagate |= noGoodsWithHeadSize > 0; - for (int i = 0; i < noGoodsWithHeadSize; i++) { - final int headLiteral = noGoodsWithHead[i]; - ConflictCause conflictCause = assignment.assign(atomOf(headLiteral), TRUE, this); - if (conflictCause != null) { - return conflictCause; - } - } - return null; - } - - public int size() { - return noGoodsWithHeadSize + noGoodsWithoutHeadSize; - } - - @Override - public String toString() { - return "BinaryWatchList(" + forLiteral + ")"; - } - - @Override - public Antecedent instantiateAntecedent(int impliedLiteral) { - return new BinaryAntecedent(impliedLiteral, forLiteral); - } - - private class BinaryAntecedent implements Antecedent { - private final int[] literals = new int[2]; - - BinaryAntecedent(int lit1, int lit2) { - literals[0] = lit1; - literals[1] = lit2; - } - - @Override - public int[] getReasonLiterals() { - return literals; - } - - @Override - public void bumpActivity() { - } - - @Override - public void decreaseActivity() { - } - - @Override - public String toString() { - return "{" + literalToString(literals[0]) + ", " + literalToString(literals[1]) + "}"; - } - } - } - - private void clearOrdinaryWatchList(int literal) { - watches[literal] = new ArrayList<>(); - } - - private void clearAlphaWatchList(int literal) { - watchesAlpha[literal] = new ArrayList<>(); - } - - @Override - public int estimate(int atom, boolean truth, BinaryNoGoodPropagationEstimationStrategy strategy) { - switch (strategy) { - case BinaryNoGoodPropagation: - if (hasBinaryNoGoods) { - return estimateEffectsOfBinaryNoGoodPropagation(atom, truth) - 1; - } - case CountBinaryWatches: - default: - return getNumberOfBinaryWatches(atom, truth); - } - } - - private int getNumberOfBinaryWatches(int atom, boolean truth) { - return binaryWatches[atomToLiteral(atom, truth)].size(); - } - - private int estimateEffectsOfBinaryNoGoodPropagation(int atom, boolean truth) { - assignment.choose(atom, truth); - propagateOnlyBinaryNoGoods(); - int assignedNewly = assignment.getNumberOfAtomsAssignedSinceLastDecision(); - assignment.backtrack(); - return assignedNewly; - } - - private void runInternalChecks() { - new WatchedNoGoodsChecker().doWatchesCheck(); - } - - /** - * This class provides helper methods to detect NoGoods that are not properly watched by this NoGoodStore. - * This should be used only during debugging since checking is costly. - */ - private class WatchedNoGoodsChecker { - - void doWatchesCheck() { - LOGGER.debug("Checking watch invariant."); - // Check all watched NoGoods, if their pointers adhere to the watch-pointer invariant. - for (int literal = 0; literal < watches.length; literal++) { - if (isNegated(literal)) { - // We treat positive and negative ones at the iteration of the positive literal. - continue; - } - final int atom = atomOf(literal); - if (atom > maxAtomId) { - break; - } - checkOrdinaryWatchesInvariant(atom, true); - checkOrdinaryWatchesInvariant(atom, false); - checkAlphaWatchesInvariant(atom, true); - checkAlphaWatchesInvariant(atom, false); - } - LOGGER.debug("Checking watch invariant: all good."); - } - - int weakDecisionLevel(Assignment.Entry entry) { - return entry == null ? UNASSIGNED : entry.hasPreviousMBT() ? entry.getMBTDecisionLevel() : entry.getDecisionLevel(); - } - - int weakReplayLevel(int atom) { - if (assignment instanceof TrailAssignment) { - return ((TrailAssignment) assignment).getOutOfOrderDecisionLevel(atom); - } - return UNASSIGNED; - } - - int trailAwareStrongDecisionLevel(int atom) { - int trailStrongDecisionLevel = UNASSIGNED; - if (assignment instanceof TrailAssignment) { - trailStrongDecisionLevel = ((TrailAssignment) assignment).getOutOfOrderStrongDecisionLevel(atom); - } - int atomStrongDecisionLevel = strongDecisionLevel(atom); - return Math.min(trailStrongDecisionLevel, atomStrongDecisionLevel); - } - - private void checkAlphaWatchesInvariant(int atom, boolean truth) { - Assignment.Entry atomEntry = assignment.get(atom); - int atomLiteral = atomToLiteral(atom, truth); - boolean atomSatisfies = atomEntry != null && isPositive(atomLiteral) != atomEntry.getTruth().toBoolean(); - int atomDecisionLevel = strongDecisionLevel(atom); - BinaryWatchList binaryWatchList = binaryWatches[atomLiteral]; - for (int i = 0; i < binaryWatchList.noGoodsWithHeadSize; i++) { - int headLiteral = binaryWatchList.noGoodsWithHead[i]; - if (headLiteral == atomLiteral) { - throw oops("Watch invariant violated: alpha watch points at head."); - } - Assignment.Entry headEntry = assignment.get(atomOf(headLiteral)); - boolean headViolates = headEntry != null && isPositive(headLiteral) == headEntry.getTruth().toBoolean(); - int headDecisionLevel = trailAwareStrongDecisionLevel(atomOf(headLiteral)); - if (watchInvariant(atomSatisfies, atomDecisionLevel, headLiteral, headDecisionLevel, headEntry) - || headViolates) { // Head "pointer" is never moved and violation is checked by weak propagation, hence a violated head is okay. - continue; - } - throw oops("Watch invariant (alpha) violated"); - } - for (WatchedNoGood watchedNoGood : watchesAlpha(atomLiteral)) { - int headLiteral = watchedNoGood.getHead(); - if (headLiteral == atomLiteral) { - throw oops("Watch invariant violated: alpha watch points at head."); - } - Assignment.Entry headEntry = assignment.get(atomOf(headLiteral)); - boolean headViolates = headEntry != null && isPositive(headLiteral) == headEntry.getTruth().toBoolean(); - int headDecisionLevel = trailAwareStrongDecisionLevel(atomOf(headLiteral)); - if (watchInvariant(atomSatisfies, atomDecisionLevel, headLiteral, headDecisionLevel, headEntry) - || headViolates) { // Head "pointer" is never moved and violation is checked by weak propagation, hence a violated head is okay. - continue; - } - throw oops("Watch invariant (alpha) violated"); - } - } - - private void checkOrdinaryWatchesInvariant(int atom, boolean truth) { - Assignment.Entry atomEntry = assignment.get(atom); - int atomLiteral = atomToLiteral(atom, truth); - boolean atomSatisfies = atomEntry != null && isPositive(atomLiteral) != atomEntry.getTruth().toBoolean(); - int atomDecisionLevel = weakDecisionLevel(atomEntry); - int atomReplayLevel = weakReplayLevel(atom); - BinaryWatchList binaryWatchList = binaryWatches[atomLiteral]; - for (int i = 0; i < binaryWatchList.noGoodsWithoutHeadSize; i++) { - int otherLiteral = binaryWatchList.noGoodsWithoutHead[i]; - checkBinaryWatch(atomSatisfies, atomDecisionLevel, atomReplayLevel, otherLiteral); - } - for (int i = 0; i < binaryWatchList.noGoodsWithHeadSize; i++) { - int otherLiteral = binaryWatchList.noGoodsWithHead[i]; - checkBinaryWatch(atomSatisfies, atomDecisionLevel, atomReplayLevel, otherLiteral); - } - for (WatchedNoGood watchedNoGood : watches(atomLiteral)) { - // Ensure both watches are either unassigned, or one satisfies NoGood, or both are on highest decision level. - int otherPointer = atom == atomOf(watchedNoGood.getLiteral(1)) ? 0 : 1; - int otherLiteral = watchedNoGood.getLiteral(otherPointer); - int otherAtom = atomOf(otherLiteral); - int thisAtom = atomOf(watchedNoGood.getLiteral(1 - otherPointer)); - if (thisAtom != atom) { - throw oops("Watched atom is not at first/second position in literals array."); - } - Assignment.Entry otherEntry = assignment.get(otherAtom); - int otherDecisionLevel = weakDecisionLevel(otherEntry); - int otherReplayLevel = weakReplayLevel(otherAtom); - boolean otherSatisfies = otherEntry != null && isPositive(otherLiteral) != otherEntry.getTruth().toBoolean(); - if (watchInvariant(atomSatisfies, otherSatisfies, atomDecisionLevel, atomReplayLevel, otherDecisionLevel, otherReplayLevel)) { - continue; - } - throw oops("Watch invariant violated"); - } - } - - private void checkBinaryWatch(boolean atomSatisfies, int atomDecisionLevel, int atomReplayLevel, int otherLiteral) { - int otherAtom = atomOf(otherLiteral); - Assignment.Entry otherEntry = assignment.get(otherAtom); - boolean otherSatisfies = otherEntry != null && isPositive(otherLiteral) != otherEntry.getTruth().toBoolean(); - int otherDecisionLevel = weakDecisionLevel(otherEntry); - int otherReplayLevel = weakReplayLevel(otherAtom); - if (watchInvariant(atomSatisfies, otherSatisfies, atomDecisionLevel, atomReplayLevel, otherDecisionLevel, otherReplayLevel)) { - return; - } - throw oops("Watch invariant violated"); - } - - private boolean watchInvariant(boolean atomSatisfies, boolean otherAtomSatisfies, int atomDecisionLevel, int atomReplayLevel, int otherAtomDecisionLevel, int otherAtomReplayLevel) { - if (atomDecisionLevel == UNASSIGNED && otherAtomDecisionLevel == UNASSIGNED) { - // Both watches are unassigned. - return true; - } - if ((atomSatisfies && (otherAtomDecisionLevel >= atomDecisionLevel || otherAtomDecisionLevel >= atomReplayLevel)) - || (otherAtomSatisfies && (atomDecisionLevel >= otherAtomDecisionLevel || atomDecisionLevel >= otherAtomReplayLevel))) { - // One watch satisfies the nogood and the other is assigned at higher decision level (or higher than the replay level of the satisfying one). - return true; - } - return false; - } - - private boolean watchInvariant(boolean atomSatisfies, int atomDecisionLevel, int otherLiteral, int otherDecisionLevel, Assignment.Entry otherEntry) { - boolean otherSatisfies = otherEntry != null && isPositive(otherLiteral) != otherEntry.getTruth().toBoolean(); - if (atomDecisionLevel == Integer.MAX_VALUE && otherDecisionLevel == Integer.MAX_VALUE) { - // Both watches are unassigned. - return true; - } - if ((atomSatisfies && otherDecisionLevel >= atomDecisionLevel) - || (otherSatisfies && atomDecisionLevel >= otherDecisionLevel)) { - // One watch satisfies the nogood and the other is assigned at higher decision level. - return true; - } - return false; - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java deleted file mode 100644 index 9c4d74601..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/PerformanceLog.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (c) 2019 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.solver; - -import org.slf4j.Logger; - -/** - * Collects performance data (mainly number of decisions per second) and outputs them on demand. - */ -public class PerformanceLog { - - private ChoiceManager choiceManager; - private TrailAssignment assignment; - private long msBetweenOutputs; - - private Long timeFirstEntry; - private Long timeLastPerformanceLog; - private int numberOfChoicesLastPerformanceLog; - - /** - * @param msBetweenOutputs - */ - public PerformanceLog(ChoiceManager choiceManager, TrailAssignment assignment, long msBetweenOutputs) { - super(); - this.choiceManager = choiceManager; - this.assignment = assignment; - this.msBetweenOutputs = msBetweenOutputs; - } - - public void initialize() { - timeFirstEntry = System.currentTimeMillis(); - timeLastPerformanceLog = timeFirstEntry; - } - - /** - * @param logger - */ - public void infoIfTimeForOutput(Logger logger) { - long currentTime = System.currentTimeMillis(); - int currentNumberOfChoices = choiceManager.getChoices(); - if (currentTime >= timeLastPerformanceLog + msBetweenOutputs) { - logger.info("Decisions in {}s: {}", (currentTime - timeLastPerformanceLog) / 1000.0f, currentNumberOfChoices - numberOfChoicesLastPerformanceLog); - timeLastPerformanceLog = currentTime; - numberOfChoicesLastPerformanceLog = currentNumberOfChoices; - float overallTime = (currentTime - timeFirstEntry) / 1000.0f; - float decisionsPerSec = currentNumberOfChoices / overallTime; - logger.info("Overall performance: {} decisions in {}s or {} decisions per sec. Overall replayed assignments: {}.", currentNumberOfChoices, overallTime, decisionsPerSec, assignment.replayCounter); - } - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java deleted file mode 100644 index 54be1ceca..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ShallowAntecedent.java +++ /dev/null @@ -1,33 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -/** - * Represents a shallow {@link Antecedent} that must be instantiated before use. - * - * Copyright (c) 2020, the Alpha Team. - */ -public interface ShallowAntecedent extends Antecedent { - - /** - * Instantiates the shallow antecedent. - * @param impliedLiteral the literal that is implied by this {@link ShallowAntecedent}. - * @return a (full) {@link Antecedent}. - */ - Antecedent instantiateAntecedent(int impliedLiteral); - - @Override - default int[] getReasonLiterals() { - throw oops("ShallowAntecedent must be instantiated first."); - } - - @Override - default void bumpActivity() { - throw oops("ShallowAntecedent must be instantiated first."); - } - - @Override - default void decreaseActivity() { - throw oops("ShallowAntecedent must be instantiated first."); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java deleted file mode 100644 index d6900d382..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/Solver.java +++ /dev/null @@ -1,27 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; - -import java.util.List; -import java.util.Set; -import java.util.Spliterator; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -@FunctionalInterface -public interface Solver { - Spliterator spliterator(); - - default Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - default Set collectSet() { - return stream().collect(Collectors.toSet()); - } - - default List collectList() { - return stream().collect(Collectors.toList()); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java deleted file mode 100644 index 36bbe668d..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverFactory.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (c) 2016-2017, 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.solver; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.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); - - NoGoodStore store; - - switch (nogoodStoreName.toLowerCase()) { - case "naive": - store = new NaiveNoGoodStore(assignment); - break; - case "alpharoaming": - store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); - break; - default: - throw new IllegalArgumentException("Unknown store requested."); - } - - switch (solverName.toLowerCase()) { - case "naive" : - return new NaiveSolver(atomStore, grounder); - case "default": - return new DefaultSolver(atomStore, grounder, store, assignment, random, config, heuristicsConfiguration); - } - 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/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java deleted file mode 100644 index 0c29abef7..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/SolverMaintainingStatistics.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (c) 2017-2019 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.solver; - -import java.io.PrintStream; - -public interface SolverMaintainingStatistics { - - int getNumberOfChoices(); - - int getNumberOfBacktracks(); - - int getNumberOfBacktracksWithinBackjumps(); - - int getNumberOfBackjumps(); - - int getNumberOfBacktracksDueToRemnantMBTs(); - - int getNumberOfDeletedNoGoods(); - - /** - * @return the number of times the solver had to backtrack after closing unassigned atoms - */ - int getNumberOfConflictsAfterClosing(); - - NoGoodCounter getNoGoodCounter(); - - default String getStatisticsString() { - return "g=" + getNumberOfChoices() + ", bt=" + getNumberOfBacktracks() + ", bj=" + getNumberOfBackjumps() + ", bt_within_bj=" - + getNumberOfBacktracksWithinBackjumps() + ", mbt=" + getNumberOfBacktracksDueToRemnantMBTs() + ", cac=" + getNumberOfConflictsAfterClosing() - + ", del_ng=" + getNumberOfDeletedNoGoods(); - } - - default String getStatisticsCSV() { - return String.format("%d,%d,%d,%d,%d,%d,%d", getNumberOfChoices(), getNumberOfBacktracks(), getNumberOfBackjumps(), getNumberOfBacktracksWithinBackjumps(), getNumberOfBacktracksDueToRemnantMBTs(), getNumberOfConflictsAfterClosing(), getNumberOfDeletedNoGoods()); - } - - default void printStatistics(PrintStream out) { - out.println(getStatisticsString()); - } - - default void printStatistics() { - printStatistics(System.out); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java deleted file mode 100644 index ade2ccb9c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/ThriceTruth.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2016, 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.solver; - -import at.ac.tuwien.kr.alpha.common.Truth; - -public enum ThriceTruth implements Truth { - TRUE("T", true), - FALSE("F", false), - MBT("M", true); - - private final String asString; - private final boolean asBoolean; - - ThriceTruth(String asString, boolean asBoolean) { - this.asString = asString; - this.asBoolean = asBoolean; - } - - @Override - public boolean toBoolean() { - return asBoolean; - } - - @Override - public String toString() { - return asString; - } - - public static ThriceTruth valueOf(boolean value) { - return value ? TRUE : FALSE; - } - - /** - * @return true if this is MBT. - */ - public boolean isMBT() { - return this == ThriceTruth.MBT; - } - - /** - * Returns true if the two truth values are not compatible with each other. - * Each truth value is compatible with itself and both MBT and TRUE are compatible. All other combinations are - * conflicting. - * @param value1 the first truth value. - * @param value2 the second truth value. - * @return true iff first and second truth value are conflicting (i.e., not compatible). - */ - public static boolean isConflicting(ThriceTruth value1, ThriceTruth value2) { - return (FALSE == value1 || FALSE == value2) && value1 != value2; - } -} \ No newline at end of file diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java deleted file mode 100644 index 4e2974d51..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/TrailAssignment.java +++ /dev/null @@ -1,783 +0,0 @@ -/** - * 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 - * 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.solver; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.Atoms.isAtom; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; - -/** - * An implementation of Assignment using a trail (of literals) and arrays as underlying structures for storing - * assignments. - * - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class TrailAssignment implements WritableAssignment, Checkable { - private static final Logger LOGGER = LoggerFactory.getLogger(TrailAssignment.class); - static final Antecedent CLOSING_INDICATOR_ANTECEDENT = new Antecedent() { - int[] literals = new int[0]; - - @Override - public int[] getReasonLiterals() { - return literals; - } - - @Override - public void bumpActivity() { - } - - @Override - public void decreaseActivity() { - - } - }; - - private final AtomStore atomStore; - private ChoiceManager choiceManagerCallback; - - /** - * Contains for each known atom a value whose two least - * significant bits encode the atom's truth value - * (cf. {@link TrailAssignment#translateTruth(int)} - * and whose remaining bits encode the atom's weak decision level. - */ - private int[] values; - - private int[] strongDecisionLevels; - private Antecedent[] impliedBy; - private boolean[] callbackUponChange; - private ArrayList outOfOrderLiterals = new ArrayList<>(); - private int highestDecisionLevelContainingOutOfOrderLiterals; - private int[] trail = new int[0]; - private int trailSize; - private ArrayList trailIndicesOfDecisionLevels = new ArrayList<>(); - - private int nextPositionInTrail; - private int newAssignmentsPositionInTrail; - private int newAssignmentsIterator; - private int assignmentsForChoicePosition; - private int mbtCount; - private boolean checksEnabled; - long replayCounter; - - public TrailAssignment(AtomStore atomStore, boolean checksEnabled) { - this.checksEnabled = checksEnabled; - this.atomStore = atomStore; - this.values = new int[0]; - this.strongDecisionLevels = new int[0]; - this.impliedBy = new Antecedent[0]; - this.callbackUponChange = new boolean[0]; - this.trailIndicesOfDecisionLevels.add(0); - nextPositionInTrail = 0; - newAssignmentsIterator = 0; - newAssignmentsPositionInTrail = 0; - assignmentsForChoicePosition = 0; - } - - public TrailAssignment(AtomStore atomStore) { - this(atomStore, false); - } - - @Override - public void clear() { - mbtCount = 0; - Arrays.fill(values, 0); - Arrays.fill(strongDecisionLevels, -1); - Arrays.fill(impliedBy, null); - Arrays.fill(callbackUponChange, false); - outOfOrderLiterals = new ArrayList<>(); - highestDecisionLevelContainingOutOfOrderLiterals = 0; - Arrays.fill(trail, 0); - trailSize = 0; - trailIndicesOfDecisionLevels = new ArrayList<>(); - trailIndicesOfDecisionLevels.add(0); - nextPositionInTrail = 0; - newAssignmentsIterator = 0; - newAssignmentsPositionInTrail = 0; - assignmentsForChoicePosition = 0; - } - - @Override - public void registerCallbackOnChange(int atom) { - callbackUponChange[atom] = true; - } - - @Override - public void setCallback(ChoiceManager choiceManager) { - choiceManagerCallback = choiceManager; - } - - @Override - public boolean isAssigned(int atom) { - return values[atom] != 0; - } - - @Override - public int getBasicAtomAssignedMBT() { - for (int atom = 1; atom <= atomStore.getMaxAtomId(); atom++) { - if (getTruth(atom) == MBT && atomStore.get(atom) instanceof BasicAtom) { - return atom; - } - } - throw oops("No BasicAtom is assigned MBT."); - } - - @Override - public Pollable getAssignmentsToProcess() { - return new TrailPollable(); - } - - @Override - public int getRealWeakDecisionLevel(int atom) { - if (getTruth(atom) == null) { - return -1; - } - int lowestDecisionLevelForAtom = getWeakDecisionLevel(atom); - for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { - if (outOfOrderLiteral.atom == atom && outOfOrderLiteral.decisionLevel < lowestDecisionLevelForAtom) { - lowestDecisionLevelForAtom = outOfOrderLiteral.decisionLevel; - } - } - return lowestDecisionLevelForAtom; - } - - /** - * Searches out-of-order literals for the lowest decision level the atom is assigned in. - * @param atom the atom to check. - * @return Integer.MAX_VALUE if the atom is not assigned out-of-order, otherwise the lowest decision level it is assigned. - */ - public int getOutOfOrderDecisionLevel(int atom) { - int lowestDecisionLevel = Integer.MAX_VALUE; - for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { - if (outOfOrderLiteral.atom == atom && outOfOrderLiteral.decisionLevel < lowestDecisionLevel) { - lowestDecisionLevel = outOfOrderLiteral.decisionLevel; - } - } - return lowestDecisionLevel; - } - - int getOutOfOrderStrongDecisionLevel(int atom) { - int lowestDecisionLevel = Integer.MAX_VALUE; - for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { - if (outOfOrderLiteral.atom == atom && outOfOrderLiteral.value == TRUE && outOfOrderLiteral.decisionLevel < lowestDecisionLevel) { - lowestDecisionLevel = outOfOrderLiteral.decisionLevel; - } - } - return lowestDecisionLevel; - } - - private void informCallback(int atom) { - if (callbackUponChange[atom]) { - choiceManagerCallback.callbackOnChanged(atom); - } - } - - private void removeLastDecisionLevel() { - // Remove all atoms recorded in the highest decision level. - int start = trailIndicesOfDecisionLevels.get(getDecisionLevel()); - for (int i = start; i < trailSize; i++) { - int backtrackAtom = atomOf(trail[i]); //atomOf(backtrackIterator.next()); - // Skip already backtracked atoms. - if (getTruth(backtrackAtom) == null) { - continue; - } - if (getWeakDecisionLevel(backtrackAtom) < getDecisionLevel()) { - // Restore TRUE to MBT if this was assigned at a lower level. - if (getTruth(backtrackAtom) != TRUE) { - throw oops("Backtracking assignment with lower decision level whose value is not TRUE."); - } - values[backtrackAtom] = (getWeakDecisionLevel(backtrackAtom) << 2) | translateTruth(MBT); - mbtCount++; - } else { - if (getTruth(backtrackAtom) == MBT) { - mbtCount--; - } - values[backtrackAtom] = 0; - } - strongDecisionLevels[backtrackAtom] = -1; - informCallback(backtrackAtom); - } - // Remove atoms from trail. - trailSize = start; - trailIndicesOfDecisionLevels.remove(trailIndicesOfDecisionLevels.size() - 1); - } - - private void replayOutOfOrderLiterals() { - // Replay out-of-order assigned literals. - if (highestDecisionLevelContainingOutOfOrderLiterals >= getDecisionLevel()) { - // Replay all still-valid literals and remove invalid ones. - LOGGER.trace("Replaying out-of-order literals."); - int k = 0; // counter for out-of-order literals to keep further. - for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { - if (outOfOrderLiteral.decisionLevel <= getDecisionLevel()) { - // Replay assignment at current decision level. - assign(outOfOrderLiteral.atom, outOfOrderLiteral.value, outOfOrderLiteral.impliedBy); - // If literal is actually below current decision level, keep it. - if (outOfOrderLiteral.decisionLevel < getDecisionLevel()) { - outOfOrderLiterals.set(k++, outOfOrderLiteral); - } - } - } - replayCounter += outOfOrderLiterals.size(); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Replay list contained {} literals, {} were again assigned. Overall replays: {}.", outOfOrderLiterals.size(), k, replayCounter); - } - // Remove remaining entries from k onwards. - while (outOfOrderLiterals.size() > k) { - outOfOrderLiterals.remove(outOfOrderLiterals.size() - 1); - } - highestDecisionLevelContainingOutOfOrderLiterals = outOfOrderLiterals.isEmpty() ? 0 : getDecisionLevel(); - } - } - - private void resetTrailPointersAndReplayOutOfOrderLiterals() { - nextPositionInTrail = Math.min(nextPositionInTrail, trailSize); - newAssignmentsPositionInTrail = Math.min(newAssignmentsPositionInTrail, trailSize); - newAssignmentsIterator = Math.min(newAssignmentsIterator, trailSize); - assignmentsForChoicePosition = Math.min(assignmentsForChoicePosition, trailSize); - replayOutOfOrderLiterals(); - if (checksEnabled) { - runInternalChecks(); - } - } - - @Override - public void backjump(int decisionLevel) { - // Remove everything above the target level, but keep the target level unchanged. - while (getDecisionLevel() > decisionLevel) { - removeLastDecisionLevel(); - } - resetTrailPointersAndReplayOutOfOrderLiterals(); - } - - @Override - public void backtrack() { - removeLastDecisionLevel(); - resetTrailPointersAndReplayOutOfOrderLiterals(); - } - - @Override - public int getMBTCount() { - return mbtCount; - } - - @Override - public ConflictCause choose(int atom, ThriceTruth value) { - if (checksEnabled) { - runInternalChecks(); - } - trailIndicesOfDecisionLevels.add(trailSize); - return assign(atom, value, null); - } - - @Override - public ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy) { - ConflictCause conflictCause = assignWithTrail(atom, value, impliedBy); - if (conflictCause != null && LOGGER.isDebugEnabled()) { - LOGGER.debug("Assign is conflicting: atom: {}, value: {}, impliedBy: {}.", atom, value, impliedBy); - } - return conflictCause; - } - - @Override - public ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy, int decisionLevel) { - ConflictCause conflictCause = assign(atom, value, impliedBy); - if (conflictCause == null && decisionLevel < getDecisionLevel()) { - outOfOrderLiterals.add(new OutOfOrderLiteral(atom, value, decisionLevel, impliedBy)); - if (highestDecisionLevelContainingOutOfOrderLiterals < getDecisionLevel()) { - highestDecisionLevelContainingOutOfOrderLiterals = getDecisionLevel(); - } - } - return conflictCause; - } - - private boolean assignmentsConsistent(ThriceTruth oldTruth, ThriceTruth value) { - return oldTruth == null || oldTruth.toBoolean() == value.toBoolean(); - } - - private ConflictCause assignWithTrail(int atom, ThriceTruth value, Antecedent impliedBy) { - if (!isAtom(atom)) { - throw new IllegalArgumentException("not an atom"); - } - if (value == null) { - throw new IllegalArgumentException("value must not be null"); - } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Recording assignment {}={}@{} impliedBy: {}", atom, value, getDecisionLevel(), impliedBy); - if (impliedBy != null) { - for (Integer literal : impliedBy.getReasonLiterals()) { - LOGGER.trace("impliedBy literal assignment: {}={}.", atomOf(literal), get(atomOf(literal))); - } - } - } - - // If the atom currently is not assigned, simply record the assignment. - final ThriceTruth currentTruth = getTruth(atom); - if (currentTruth == null) { - trail[trailSize++] = atomToLiteral(atom, value.toBoolean()); - values[atom] = (getDecisionLevel() << 2) | translateTruth(value); - this.impliedBy[atom] = impliedBy; - // Adjust MBT counter. - if (value == MBT) { - mbtCount++; - } - if (value == TRUE) { - strongDecisionLevels[atom] = getDecisionLevel(); - } - informCallback(atom); - return null; - } - - // Nothing to do if the new value is the same as the current one (or current is TRUE and new is MBT). - if (value == currentTruth || value == MBT && currentTruth == TRUE) { - return null; - } - - // Check if the new assignments contradicts the current one. - if (!assignmentsConsistent(currentTruth, value)) { - // Assignments are inconsistent, prepare the reason. - // Due to the conflict, the impliedBy NoGood is not the recorded one but the one this method is invoked with.stems from this assignment. - if (impliedBy instanceof ShallowAntecedent) { - // Instantiate Antecedent in case it is a shallow one for binary nogoods. - return new ConflictCause(((ShallowAntecedent) impliedBy).instantiateAntecedent(atomToLiteral(atom, !value.toBoolean()))); - } - return new ConflictCause(impliedBy); - } - if (value == TRUE && currentTruth != MBT) { - throw oops("Assigning TRUE without assigning MBT before."); - } - - // Previous assignment exists, and the new one is consistent with it. - // There is nothing to do except if MBT becomes TRUE. - if (currentTruth == MBT && value == TRUE) { - // Record new truth value but keep weak decision level unchanged. - trail[trailSize++] = atomToLiteral(atom, true); - values[atom] = (getWeakDecisionLevel(atom) << 2) | translateTruth(TRUE); - // Record strong decision level. - strongDecisionLevels[atom] = getDecisionLevel(); - // Adjust MBT counter. - mbtCount--; - informCallback(atom); - return null; - } - throw oops("Assignment conditions are not covered."); - } - - private ThriceTruth translateTruth(int value) { - switch (value & 0x3) { - case 0: - return null; - case 1: - return FALSE; - case 2: - return MBT; - case 3: - return TRUE; - default: - throw oops("Unknown truth value."); - } - } - - private int translateTruth(ThriceTruth value) { - if (value == null) { - return 0; - } - switch (value) { - case FALSE: - return 1; - case MBT: - return 2; - case TRUE: - return 3; - } - throw oops("Unknown truth value."); - } - - @Override - public ThriceTruth getTruth(int atom) { - return translateTruth(values[atom]); - } - - @Override - public int getWeakDecisionLevel(int atom) { - return values[atom] >> 2; - } - - @Override - public int getStrongDecisionLevel(int atom) { - return getTruth(atom) == FALSE ? getWeakDecisionLevel(atom) : strongDecisionLevels[atom]; - } - - @Override - public Antecedent getImpliedBy(int atom) { - Antecedent antecedent = impliedBy[atom]; - // Check if the Antecedent is a shallow one from binary nogoods, in this case instantiate it to a full Antecedent. - if (antecedent instanceof ShallowAntecedent) { - return ((ShallowAntecedent) antecedent).instantiateAntecedent(atomToLiteral(atom, !getTruth(atom).toBoolean())); - } - return antecedent; - } - - @Override - public Set getTrueAssignments() { - Set result = new HashSet<>(); - for (int i = 0; i < values.length; i++) { - if (getTruth(i) == TRUE) { - result.add(i); - } - } - return result; - } - - @Override - public Entry get(int atom) { - if (values[atom] == 0) { - return null; - } - if (strongDecisionLevels[atom] == -1) { - return new Entry(getTruth(atom), atom, getWeakDecisionLevel(atom), getImpliedBy(atom)); - } else { - return new Entry(getTruth(atom), atom, strongDecisionLevels[atom], getImpliedBy(atom), getWeakDecisionLevel(atom)); - } - } - - private void runInternalChecks() { - // Ensure that incrementally updated values agree with actual values. - LOGGER.trace("Checking assignment."); - // Check that MBT counter is correct. - if (getMBTCount() != getMBTAssignedAtoms().size()) { - throw oops("MBT counter and amount of actually MBT-assigned atoms disagree"); - } else { - LOGGER.trace("MBT count agrees with amount of MBT-assigned atoms."); - } - // Check that out of order literals are actually assigned. - for (OutOfOrderLiteral outOfOrderLiteral : outOfOrderLiterals) { - if (outOfOrderLiteral.decisionLevel <= getDecisionLevel()) { - ThriceTruth atomTruth = getTruth(outOfOrderLiteral.atom); - if (outOfOrderLiteral.value == atomTruth || outOfOrderLiteral.value == MBT && atomTruth == TRUE) { - continue; - } - throw oops("Out-of-order assigned literal is not in current assignment."); - } - } - LOGGER.trace("Checking assignment: all good."); - } - - /** - * Debug helper collecting all atoms that are assigned MBT. - * @return a list of all atomIds that are assigned MBT (and not TRUE). - */ - private List getMBTAssignedAtoms() { - List ret = new ArrayList<>(); - for (int i = 0; i < values.length; i++) { - if (getTruth(i) == MBT) { - ret.add(i); - } - } - return ret; - } - - @Override - public boolean closeUnassignedAtoms() { - boolean didAssign = false; - for (int i = 1; i <= atomStore.getMaxAtomId(); i++) { - if (!isAssigned(i)) { - assign(i, FALSE, CLOSING_INDICATOR_ANTECEDENT); - didAssign = true; - } - } - return didAssign; - } - - @Override - public void growForMaxAtomId() { - int maxAtomId = atomStore.getMaxAtomId(); - // Grow arrays only if needed. - if (values.length > maxAtomId) { - return; - } - // Grow by 1.5 current size, except if bigger array is required due to maxAtomId. - int newCapacity = arrayGrowthSize(values.length); - if (newCapacity < maxAtomId + 1) { - newCapacity = maxAtomId + 1; - } - values = Arrays.copyOf(values, newCapacity); - int oldLength = strongDecisionLevels.length; - strongDecisionLevels = Arrays.copyOf(strongDecisionLevels, newCapacity); - Arrays.fill(strongDecisionLevels, oldLength, strongDecisionLevels.length, -1); - impliedBy = Arrays.copyOf(impliedBy, newCapacity); - callbackUponChange = Arrays.copyOf(callbackUponChange, newCapacity); - trail = Arrays.copyOf(trail, newCapacity * 2); // Trail has at most 2 assignments (MBT+TRUE) for each atom. - } - - public int getNumberOfAssignedAtoms() { - int n = 0; - for (int value : values) { - if (translateTruth(value) != null) { - n++; - } - } - return n; - } - - @Override - public int getNumberOfAtomsAssignedSinceLastDecision() { - Set newlyAssignedAtoms = new HashSet<>(); - int trailIndex = trailIndicesOfDecisionLevels.get(getDecisionLevel()); - for (; trailIndex < trailSize; trailIndex++) { - newlyAssignedAtoms.add(atomOf(trail[trailIndex])); - } - return newlyAssignedAtoms.size(); - } - - @Override - public int getDecisionLevel() { - return trailIndicesOfDecisionLevels.size() - 1; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("["); - boolean isFirst = true; - for (int i = 0; i < values.length; i++) { - ThriceTruth atomTruth = getTruth(i); - if (atomTruth == null) { - continue; - } - if (!isFirst) { - sb.append(", "); - } - isFirst = false; - sb.append(atomTruth); - sb.append("_"); - if (atomStore != null) { - sb.append(atomStore.atomToString(i)); - } else { - sb.append(i); - } - sb.append("@"); - sb.append(getWeakDecisionLevel(i)); - } - sb.append("]"); - return sb.toString(); - } - - @Override - public AssignmentIterator getNewPositiveAssignmentsIterator() { - return new AssignmentIterator(); - } - - @Override - public void setChecksEnabled(boolean checksEnabled) { - this.checksEnabled = checksEnabled; - } - - private class AssignmentIterator implements IntIterator { - - private void advanceCursorToNextPositiveAssignment() { - while (newAssignmentsIterator < trailSize) { - ThriceTruth truth = getTruth(atomOf(trail[newAssignmentsIterator])); - if (truth != null && truth.toBoolean()) { - return; - } - newAssignmentsIterator++; - } - } - - @Override - public boolean hasNext() { - advanceCursorToNextPositiveAssignment(); - return newAssignmentsIterator < trailSize; - } - - @Override - public int next() { - return atomOf(trail[newAssignmentsIterator++]); - - } - } - - private static class OutOfOrderLiteral { - final int atom; - final ThriceTruth value; - final int decisionLevel; - final Antecedent impliedBy; - - private OutOfOrderLiteral(int atom, ThriceTruth value, int decisionLevel, Antecedent impliedBy) { - this.atom = atom; - this.decisionLevel = decisionLevel; - this.impliedBy = impliedBy; - this.value = value; - } - - @Override - public String toString() { - return atom + "=" + value + "@" + decisionLevel + " implied by " + impliedBy; - } - } - - private class TrailPollable implements Pollable { - - @Override - public int peek() { - return atomOf(trail[nextPositionInTrail]); - } - - @Override - public int remove() { - int current = peek(); - nextPositionInTrail++; - return current; - } - - @Override - public boolean isEmpty() { - return nextPositionInTrail >= trailSize; - } - } - - public TrailBackwardsWalker getTrailBackwardsWalker() { - return new TrailBackwardsWalker(); - } - - public class TrailBackwardsWalker { - - int trailPos; - - TrailBackwardsWalker() { - trailPos = trailSize; - } - - public int getNextLowerLiteral() { - return trail[--trailPos]; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("["); - for (int i = 0; i < trailSize; i++) { - int literalOnTrail = trail[i]; - sb.append(isPositive(literalOnTrail) ? "+" + atomOf(literalOnTrail) : "-" + atomOf(literalOnTrail)); - sb.append("@"); - sb.append(TrailAssignment.this.getWeakDecisionLevel(atomOf(literalOnTrail))); - sb.append(", "); - } - sb.append("]"); - return sb.toString(); - } - } - - private static final class Entry implements Assignment.Entry { - private final ThriceTruth value; - private final int decisionLevel; - private final int previousDecisionLevel; - private final Antecedent impliedBy; - private final int atom; - - Entry(ThriceTruth value, int atom, int decisionLevel, Antecedent noGood) { - this(value, atom, decisionLevel, noGood, -1); - } - - Entry(ThriceTruth value, int atom, int decisionLevel, Antecedent impliedBy, int previousDecisionLevel) { - this.value = value; - this.decisionLevel = decisionLevel; - this.impliedBy = impliedBy; - this.previousDecisionLevel = previousDecisionLevel; - this.atom = atom; - if (previousDecisionLevel != -1 && value != TRUE) { - throw oops("Assignment.Entry instantiated with previous entry set and truth values other than TRUE now and MBT previous"); - } - } - - @Override - public ThriceTruth getTruth() { - return value; - } - - @Override - public int getDecisionLevel() { - return decisionLevel; - } - - @Override - public boolean hasPreviousMBT() { - return previousDecisionLevel != -1; - } - - @Override - public int getMBTDecisionLevel() { - return previousDecisionLevel; - } - - @Override - public Antecedent getImpliedBy() { - return impliedBy; - } - - @Override - public int getAtom() { - return atom; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Entry entry = (Entry) o; - - return atom == entry.atom; - } - - @Override - public int hashCode() { - return atom; - } - - @Override - public String toString() { - return atom + "=" + value.toString() + "(DL" + decisionLevel + ")" - + (hasPreviousMBT() ? "MBT(DL" + getMBTDecisionLevel() + ")" : ""); - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java deleted file mode 100644 index 4395d9ed5..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WatchedNoGood.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2016-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.solver; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface; - -import java.util.Iterator; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.literalToString; - -public final class WatchedNoGood implements NoGoodInterface, Antecedent { - private int activity; - private final int[] literals; - private int alpha; - private int head; - private final Type type; - private boolean isLbdLessOrEqual2; - - WatchedNoGood(NoGood noGood, int a, int b, int alpha) { - if (noGood.size() < 3) { - throw oops("WatchedNoGood should not be used for small NoGoods."); - } - literals = new int[noGood.size()]; - checkPointers(a, b, alpha); - int i = 0; - for (Integer lit : noGood) { - literals[i++] = lit; - } - this.alpha = alpha; - head = noGood.hasHead() ? 0 : -1; - activity = 0; - if (b == 0) { - swap(1, a); - } else { - swap(0, a); - swap(1, b); - } - this.type = noGood.getType(); - } - - private void checkPointers(int a, int b, int alpha) { - if (a == b) { - throw new IllegalArgumentException("First two pointers must not point at the same literal."); - } - if (a < 0 || b < 0 || alpha < -1 || a >= literals.length || b >= literals.length || alpha >= literals.length) { - throw new IllegalArgumentException("Pointers must be within bounds."); - } - } - - private void swap(int a, int b) { - int tmp = literals[a]; - literals[a] = literals[b]; - literals[b] = tmp; - if (hasHead()) { - // If WatchedNoGood has a head, ensure the head pointer and alpha watch follow the swap. - if (head == a) { - head = b; - } else if (head == b) { - head = a; - } - if (alpha == a) { - alpha = b; - } else if (alpha == b) { - alpha = a; - } - } - } - - @Override - public boolean hasHead() { - return head != -1; - } - - @Override - public int getHead() { - return literals[head]; - } - - int getHeadIndex() { - return head; - } - - void setWatch(int index, int value) { - if (index != 0 && index != 1) { - throw new IndexOutOfBoundsException(); - } - swap(index, value); - } - - @Override - public int getLiteral(int index) { - return literals[index]; - } - - int getAlphaPointer() { - return alpha; - } - - void setAlphaPointer(int value) { - alpha = value; - } - - int getLiteralAtAlpha() { - return literals[alpha]; - } - - @Override - public int size() { - return literals.length; - } - - @Override - public Type getType() { - return type; - } - - @Override - public Antecedent asAntecedent() { - return this; - } - - @Override - public Iterator iterator() { - return new Iterator() { - private int i; - - public boolean hasNext() { - return literals.length > i; - } - - public Integer next() { - return literals[i++]; - } - }; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (hasHead()) { - sb.append("*"); - } - - sb.append("{ "); - - int hcount = 0; - for (int literal : literals) { - sb.append(literalToString(literal)); - sb.append(hasHead() && head == hcount ? "h" : ""); - sb.append(" "); - hcount++; - } - - sb.append("}{"); - sb.append(alpha); - sb.append("}"); - return sb.toString(); - } - - @Override - public int[] getReasonLiterals() { - return literals; - } - - public int getActivity() { - return activity; - } - - @Override - public void decreaseActivity() { - activity >>= 1; - } - - @Override - public void bumpActivity() { - activity++; - } - - void setLBD(int lbd) { - isLbdLessOrEqual2 = lbd <= 2; - } - - boolean isLbdLessOrEqual2() { - return isLbdLessOrEqual2; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java deleted file mode 100644 index 806a29957..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/WritableAssignment.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Copyright (c) 2016, 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.solver; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.isPositive; - -public interface WritableAssignment extends Assignment { - /** - * Delete all information stored in the assignment. - */ - void clear(); - - /** - * Backtracks the most recent decision level. - */ - void backtrack(); - - /** - * Backtracks to the indicated decision level. Every assignment on a higher decisionLevel is removed. - * All assignments below (or equal to) decisionLevel are kept. Note that for atoms being TRUE this may require - * setting the assigned value to MBT during backtracking. - * @param decisionLevel the decision level to backjump to (this decision level is the highest that is kept). - */ - void backjump(int decisionLevel); - - /** - * Assigns an atom some value on a lower decision level than the current one. - * @param atom - * @param value - * @param impliedBy - * @param decisionLevel - * @return - */ - ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy, int decisionLevel); - - default ConflictCause assign(int atom, ThriceTruth value, Antecedent impliedBy) { - return assign(atom, value, impliedBy, getDecisionLevel()); - } - - default ConflictCause assign(int atom, ThriceTruth value) { - return assign(atom, value, null); - } - - ConflictCause choose(int atom, ThriceTruth value); - - void registerCallbackOnChange(int atom); - - void setCallback(ChoiceManager choiceManager); - - default ConflictCause choose(int atom, boolean value) { - return choose(atom, ThriceTruth.valueOf(value)); - } - - default int minimumConflictLevel(NoGood noGood) { - int minimumConflictLevel = -1; - for (Integer literal : noGood) { - ThriceTruth atomTruth = getTruth(atomOf(literal)); - if (atomTruth == null || isPositive(literal) != atomTruth.toBoolean()) { - return -1; - } - int literalDecisionLevel = getWeakDecisionLevel(atomOf(literal)); - if (literalDecisionLevel > minimumConflictLevel) { - minimumConflictLevel = literalDecisionLevel; - } - } - return minimumConflictLevel; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java deleted file mode 100644 index dd17bb114..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ActivityBasedBranchingHeuristic.java +++ /dev/null @@ -1,42 +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.solver.heuristics; - -/** - * A heuristic that selects an atom to choose on by maintaining activity values for literals. - * - */ -public interface ActivityBasedBranchingHeuristic extends BranchingHeuristic { - - /** - * Gets the activity value associated with the given literal - * - * @param literal - * @return the activity value associated with the given literal - */ - double getActivity(int literal); - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java deleted file mode 100644 index b2b76ba26..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaActiveRuleHeuristic.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; - -import java.util.Random; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -/** - * A variant of {@link DependencyDrivenHeuristic} that counts the activity of non-body-representing atoms towards bodies of rules in which they occur. - */ -public class AlphaActiveRuleHeuristic extends DependencyDrivenHeuristic { - - public AlphaActiveRuleHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { - super(assignment, choiceManager, decayPeriod, decayFactor, random, BodyActivityType.DEFAULT); - } - - public AlphaActiveRuleHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { - super(assignment, choiceManager, random); - } - - @Override - protected void incrementActivityCounter(int literal) { - int atom = atomOf(literal); - if (choiceManager.isAtomChoice(atom)) { - activityCounters.compute(atom, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); - } else { - for (int body : atomsToBodiesAtoms.get(atom)) { - activityCounters.compute(body, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); - } - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java deleted file mode 100644 index 52df83cd4..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeadMustBeTrueHeuristic.java +++ /dev/null @@ -1,68 +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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; - -import java.util.Comparator; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.stream.Stream; - -/** - * A variant of {@link DependencyDrivenHeuristic} that prefers to choose atoms representing bodies of rules whose heads - * are assigned {@link at.ac.tuwien.kr.alpha.solver.ThriceTruth#MBT}. - */ -public class AlphaHeadMustBeTrueHeuristic extends DependencyDrivenHeuristic { - - private int rememberedAtom; - - public AlphaHeadMustBeTrueHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { - super(assignment, choiceManager, decayPeriod, decayFactor, random, BodyActivityType.DEFAULT); - } - - public AlphaHeadMustBeTrueHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { - super(assignment, choiceManager, random); - } - - @Override - public int chooseLiteral() { - Set heads = headToBodies.keySet(); - Stream bodiesOfMbtHeads = heads.stream().filter(a -> assignment.getTruth(a) == ThriceTruth.MBT).flatMap(h -> headToBodies.get(h).stream()); - Optional mostActiveBody = bodiesOfMbtHeads.filter(this::isUnassigned).filter(choiceManager::isActiveChoiceAtom) - .max(Comparator.comparingDouble(bodyActivity::get)); - if (mostActiveBody.isPresent()) { - rememberedAtom = mostActiveBody.get(); - return rememberedAtom; - } - return super.chooseLiteral(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java deleted file mode 100644 index f14a96b17..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaRandomSignHeuristic.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; - -import java.util.Random; - -import static at.ac.tuwien.kr.alpha.solver.Atoms.isAtom; - -public class AlphaRandomSignHeuristic extends DependencyDrivenHeuristic { - - public AlphaRandomSignHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { - super(assignment, choiceManager, decayPeriod, decayFactor, random, BodyActivityType.DEFAULT); - } - - public AlphaRandomSignHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { - super(assignment, choiceManager, random); - } - - @Override - protected void incrementSignCounter(Integer literal) { - LOGGER.trace("AlphaRandomSignHeuristic does NOT increment sign counters because they are not needed."); - } - - @Override - public boolean chooseSign(int atom) { - if (!isAtom(atom)) { - throw new IllegalArgumentException("Atom must be a positive integer."); - } - - if (assignment.getTruth(atom) == ThriceTruth.MBT) { - return true; - } - - return rand.nextBoolean(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java deleted file mode 100644 index 48e523932..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMin.java +++ /dev/null @@ -1,280 +0,0 @@ -/** - * Copyright (c) 2016-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.stream.Stream; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; - -/** - * The BerkMin heuristic, as described in (but adapted for lazy grounding): - * Goldberg, E.; Novikov, Y. (2002): BerkMin: A fast and robust SAT-solver. - * In : Design, Automation and Test in Europe Conference and Exhibition, 2002. Proceedings. IEEE, pp. 142-149. - * - * Copyright (c) 2016-2018 Siemens AG - */ -public class BerkMin implements ActivityBasedBranchingHeuristic { - private static final Logger LOGGER = LoggerFactory.getLogger(BerkMin.class); - - static final double DEFAULT_ACTIVITY = 0.0; - static final int DEFAULT_SIGN_COUNTER = 0; - - static final int DEFAULT_DECAY_PERIOD = 10; - static final double DEFAULT_DECAY_FACTOR = 0.25; - - final Assignment assignment; - final ChoiceManager choiceManager; - final Random rand; - - private Map activityCounters = new LinkedHashMap<>(); - private Map signCounters = new LinkedHashMap<>(); - private Deque stackOfNoGoods = new ArrayDeque<>(); - private int decayPeriod; - private double decayFactor; - private int stepsSinceLastDecay; - - BerkMin(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random) { - this.assignment = assignment; - this.choiceManager = choiceManager; - this.decayPeriod = decayPeriod; - this.decayFactor = decayFactor; - this.rand = random; - } - - BerkMin(Assignment assignment, ChoiceManager choiceManager, Random random) { - this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, random); - } - - /** - * Gets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. - */ - public int getDecayPeriod() { - return decayPeriod; - } - - /** - * Sets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. - */ - public void setDecayPeriod(int decayPeriod) { - this.decayPeriod = decayPeriod; - } - - /** - * Gets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. - */ - public double getDecayFactor() { - return decayFactor; - } - - /** - * Sets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. - */ - public void setDecayFactor(double decayFactor) { - this.decayFactor = decayFactor; - } - - @Override - public void violatedNoGood(NoGood violatedNoGood) { - pushToStack(violatedNoGood); - } - - @Override - public void analyzedConflict(ConflictAnalysisResult analysisResult) { - pushToStack(analysisResult.learnedNoGood); - if (analysisResult.resolutionAtoms != null) { - for (int resolutionAtom : analysisResult.resolutionAtoms) { - incrementActivityCounter(atomToLiteral(resolutionAtom, true)); - incrementActivityCounter(atomToLiteral(resolutionAtom, false)); - } - } - if (analysisResult.learnedNoGood != null) { - for (int literal : analysisResult.learnedNoGood) { - incrementActivityCounter(literal); - } - } - decayAllIfTimeHasCome(); - } - - @Override - public void newNoGood(NoGood newNoGood) { - pushToStack(newNoGood); - for (Integer literal : newNoGood) { - incrementSignCounter(literal); - } - } - - private int numChoicePoints(NoGood noGood) { - int numChoicePoints = 0; - for (Integer literal : noGood) { - if (choiceManager.isAtomChoice(literal)) { - numChoicePoints++; - } - } - return numChoicePoints; - } - - @Override - public double getActivity(int literal) { - return activityCounters.getOrDefault(atomOf(literal), DEFAULT_ACTIVITY); - } - - /** - * {@inheritDoc} - * In BerkMin, the atom to choose on is the most active atom in the current top clause. - * Here, we can only consider atoms which are currently active choice points. If we do - * not find such an atom in the current top clause, we consider the next undefined - * nogood in the stack, then the one after that and so on. - */ - @Override - public int chooseLiteral() { - int atom = chooseAtom(); - boolean sign = chooseSign(atom); - return atomToLiteral(atom, sign); - } - - protected int chooseAtom() { - for (NoGood noGood : stackOfNoGoods) { - if (assignment.isUndefined(noGood)) { - int mostActiveAtom = getMostActiveChoosableAtom(noGood); - if (mostActiveAtom != DEFAULT_CHOICE_ATOM) { - return mostActiveAtom; - } - } - } - return DEFAULT_CHOICE_ATOM; - } - - private boolean chooseSign(int atom) { - if (assignment.getTruth(atom) == ThriceTruth.MBT) { - return true; - } - - int positiveCounter = signCounters.getOrDefault(+atom, DEFAULT_SIGN_COUNTER); - int negativeCounter = signCounters.getOrDefault(-atom, DEFAULT_SIGN_COUNTER); - - if (positiveCounter > negativeCounter) { - return false; - } else if (negativeCounter > positiveCounter) { - return true; - } else { - return atom == DEFAULT_CHOICE_ATOM || rand.nextBoolean(); - } - } - - protected void pushToStack(NoGood noGood) { - if (noGood != null) { - stackOfNoGoods.push(noGood); - } - } - - private void incrementActivityCounter(int literal) { - int atom = atomOf(literal); - if (choiceManager.isAtomChoice(atom)) { - activityCounters.compute(atom, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); - } - // TODO: check performance - // note that here (and in incrementSignCounter) we only count atoms that are - // choice points, which might affect performance. - // alternative approaches: - // 1. count everything and from time to time do a garbage collection (i.e. - // remove atoms that are no choice points) - // 2. make check cheaper, e.g. by using dedicated atom IDs (e.g. even - // integers for rule bodies, uneven for other atoms) - } - - private void incrementSignCounter(Integer literal) { - if (choiceManager.isAtomChoice(atomOf(literal))) { - signCounters.compute(literal, (k, v) -> (v == null ? DEFAULT_SIGN_COUNTER : v) + 1); - } - } - - private void decayAllIfTimeHasCome() { - stepsSinceLastDecay++; - if (stepsSinceLastDecay >= decayPeriod) { - // Decay all: - activityCounters.replaceAll((k, v) -> v * decayFactor); - stepsSinceLastDecay = 0; - } - } - - /** - * Gets the most recent conflict that is still violated. - * @return the violated nogood closest to the top of the stack of nogoods. - */ - NoGood getCurrentTopClause() { - for (NoGood noGood : stackOfNoGoods) { - if (assignment.isUndefined(noGood)) { - return noGood; - } - } - return null; - } - - /** - * If {@code noGood != null}, returns the most active unassigned literal from {@code noGood}. Else, returns the most active atom of all the known atoms. - * @param noGood - * @return - */ - private int getMostActiveChoosableAtom(NoGood noGood) { - if (noGood != null) { - return getMostActiveChoosableAtom(noGood.stream().boxed().map(Literals::atomOf)); - } else { - return getMostActiveChoosableAtom(activityCounters.keySet().stream()); - } - } - - protected int getMostActiveChoosableAtom(Stream streamOfLiterals) { - return streamOfLiterals - .map(Literals::atomOf) - .filter(this::isUnassigned) - .filter(choiceManager::isActiveChoiceAtom) - .max(Comparator.comparingDouble(this::getActivity)) - .orElse(DEFAULT_CHOICE_ATOM); - } - - private boolean isUnassigned(int atom) { - ThriceTruth truth = assignment.getTruth(atom); - return truth != FALSE && truth != TRUE; // do not use assignment.isAssigned(atom) because we may also choose MBTs - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java deleted file mode 100644 index b916b1b7c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinLiteral.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; - -import java.util.Deque; -import java.util.LinkedList; -import java.util.Random; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -/** - * A BerkMin-like heuristics that uses activity of literals and a fixed-size queue instead of a stack of NoGoods. - * Copyright (c) 2017-2018, the Alpha Team. - */ -public class BerkMinLiteral extends BerkMin { - - private Deque activeLiterals = new LinkedList<>(); - private static final int DEFAULT_QUEUE_SIZE = 32; - private final int queueSize; - - BerkMinLiteral(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, int queueSize) { - super(assignment, choiceManager, decayPeriod, decayFactor, random); - this.queueSize = queueSize; - } - - BerkMinLiteral(Assignment assignment, ChoiceManager choiceManager, Random random) { - this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, random, DEFAULT_QUEUE_SIZE); - } - - @Override - public int chooseAtom() { - return getMostActiveChoosableAtom(activeLiterals.stream()); - } - - private void pushToStack(Integer literal) { - if (choiceManager.isAtomChoice(atomOf(literal))) { - activeLiterals.addFirst(literal); - // Restrict the size of the queue. - if (activeLiterals.size() > queueSize) { - activeLiterals.removeLast(); - } - } - } - - @Override - protected void pushToStack(NoGood noGood) { - if (noGood != null) { - for (Integer literal : noGood) { - pushToStack(literal); - } - } - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java deleted file mode 100644 index 78be2e6de..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristic.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2016, 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner; - -import java.util.Collection; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; - -/** - * A heuristic that selects an atom to choose on. - * - * Copyright (c) 2016, 2018 Siemens AG - * - */ -public interface BranchingHeuristic { - int DEFAULT_CHOICE_ATOM = 0; - int DEFAULT_CHOICE_LITERAL = atomToLiteral(DEFAULT_CHOICE_ATOM); - - /** - * Stores a newly violated {@link NoGood} and updates associated activity and sign counters. - * - * @param violatedNoGood - */ - void violatedNoGood(NoGood violatedNoGood); - - /** - * Processes the result of a conflict analysis, i.e. counts literals in - * {@link NoGood}s responsible for the conflict and stores a newly learned - * {@link NoGood}. - * - * @param analysisResult - */ - void analyzedConflict(GroundConflictNoGoodLearner.ConflictAnalysisResult analysisResult); - - /** - * Stores a newly grounded {@link NoGood} and updates associated activity counters. - * - * @param newNoGood - */ - void newNoGood(NoGood newNoGood); - - /** - * @see #newNoGood(NoGood) - */ - default void newNoGoods(Collection newNoGoods) { - newNoGoods.forEach(this::newNoGood); - } - - /** - * Determines a literal (= atom + sign) to choose. - * - * @return the literal to choose, or {@link BranchingHeuristic#DEFAULT_CHOICE_LITERAL} if no such atom can be determined. - */ - int chooseLiteral(); - - default void growForMaxAtomId(int maxAtomId) { - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java deleted file mode 100644 index 87afa8c6a..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2017-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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; - -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; - -public final class BranchingHeuristicFactory { - - public static BranchingHeuristic getInstance(HeuristicsConfiguration heuristicsConfiguration, Grounder grounder, WritableAssignment assignment, ChoiceManager choiceManager, Random random) { - BranchingHeuristic heuristicWithoutReplay = getInstanceWithoutReplay(heuristicsConfiguration, grounder, assignment, choiceManager, random); - List replayChoices = heuristicsConfiguration.getReplayChoices(); - if (replayChoices != null && !replayChoices.isEmpty()) { - return ChainedBranchingHeuristics.chainOf( - new ReplayHeuristic(replayChoices, choiceManager), - heuristicWithoutReplay); - } - return heuristicWithoutReplay; - } - - private static BranchingHeuristic getInstanceWithoutReplay(HeuristicsConfiguration heuristicsConfiguration, Grounder grounder, WritableAssignment assignment, ChoiceManager choiceManager, Random random) { - switch (heuristicsConfiguration.getHeuristic()) { - case NAIVE: - return new NaiveHeuristic(choiceManager); - case BERKMIN: - return new BerkMin(assignment, choiceManager, random); - case BERKMINLITERAL: - return new BerkMinLiteral(assignment, choiceManager, random); - case DD: - return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); - case DD_SUM: - return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.SUM); - case DD_AVG: - return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.AVG); - case DD_MAX: - return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MAX); - case DD_MIN: - return new DependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MIN); - case DD_PYRO: - return new DependencyDrivenPyroHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); - case GDD: - return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); - case GDD_SUM: - return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.SUM); - case GDD_AVG: - return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.AVG); - case GDD_MAX: - return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MAX); - case GDD_MIN: - return new GeneralizedDependencyDrivenHeuristic(assignment, choiceManager, random, BodyActivityType.MIN); - case GDD_PYRO: - return new GeneralizedDependencyDrivenPyroHeuristic(assignment, choiceManager, random, BodyActivityType.DEFAULT); - case ALPHA_ACTIVE_RULE: - return new AlphaActiveRuleHeuristic(assignment, choiceManager, random); - case ALPHA_HEAD_MBT: - return new AlphaHeadMustBeTrueHeuristic(assignment, choiceManager, random); - case VSIDS: - return new VSIDS(assignment, choiceManager, heuristicsConfiguration.getMomsStrategy()); - case GDD_VSIDS: - return new DependencyDrivenVSIDS(assignment, choiceManager, random, heuristicsConfiguration.getMomsStrategy()); - } - throw new IllegalArgumentException("Unknown branching heuristic requested."); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java deleted file mode 100644 index 6d6eb8761..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ChainedBranchingHeuristics.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.Util.oops; - -/** - * A "chained" list of branching heuristics in which the entry at position n+1 is used as a fallback if the entry at position n cannot make a decision. - */ -public class ChainedBranchingHeuristics implements BranchingHeuristic { - - private List chain = new LinkedList<>(); - private int[] decisionCounters; - - private ChainedBranchingHeuristics(BranchingHeuristic... branchingHeuristics) { - for (BranchingHeuristic element : branchingHeuristics) { - add(element); - } - this.decisionCounters = new int[chain.size()]; - } - - @Override - public void violatedNoGood(NoGood violatedNoGood) { - for (BranchingHeuristic element : chain) { - element.violatedNoGood(violatedNoGood); - } - } - - @Override - public void analyzedConflict(ConflictAnalysisResult analysisResult) { - for (BranchingHeuristic element : chain) { - element.analyzedConflict(analysisResult); - } - } - - @Override - public void newNoGood(NoGood newNoGood) { - for (BranchingHeuristic element : chain) { - element.newNoGood(newNoGood); - } - } - - @Override - public int chooseLiteral() { - for (int i = 0; i < chain.size(); i++) { - BranchingHeuristic element = chain.get(i); - int chosenLiteral = element.chooseLiteral(); - if (chosenLiteral != DEFAULT_CHOICE_LITERAL) { - decisionCounters[i]++; - return chosenLiteral; - } - } - return DEFAULT_CHOICE_LITERAL; - } - - @Override - public void growForMaxAtomId(int maxAtomId) { - for (BranchingHeuristic element : chain) { - element.growForMaxAtomId(maxAtomId); - } - } - - public void add(BranchingHeuristic element) { - if (chain.contains(element)) { - throw oops("Cycle detected in chain of branching heuristics"); - } - chain.add(element); - if (decisionCounters != null) { - decisionCounters = Arrays.copyOf(decisionCounters, decisionCounters.length + 1); - } - } - - public BranchingHeuristic getLastElement() { - return chain.get(chain.size() - 1); - } - - public static ChainedBranchingHeuristics chainOf(BranchingHeuristic... branchingHeuristics) { - return new ChainedBranchingHeuristics(branchingHeuristics); - } - - /** - * Returns a mapping from individual heuristics to number of decisions made by them. - */ - public Map getNumberOfDecisions() { - Map map = new HashMap<>(); - for (int i = 0; i < chain.size(); i++) { - map.put(chain.get(i), decisionCounters[i]); - } - return map; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + chain; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java deleted file mode 100644 index e24f29da0..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenHeuristic.java +++ /dev/null @@ -1,361 +0,0 @@ -/** - * Copyright (c) 2017-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProvider; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.HashSetValuedHashMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.function.Predicate; -import java.util.stream.Stream; - -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; - -/** - * The BerkMin variants {@link BerkMin} and {@link BerkMinLiteral} suffer from the fact that choice points - * comprise only a small portion of all the literals occuring in nogoods and therefore do not influence - * activity and sign counters as much as other atoms. - * The basic idea of {@link DependencyDrivenHeuristic} is therefore to find dependent atoms that can - * enrich the information available for a choice point. Intuitively, all atoms occurring in the head or the - * body of a rule depend on a choice point representing the body of this rule. - * - * Copyright (c) 2017-2018 Siemens AG - */ -public class DependencyDrivenHeuristic implements ActivityBasedBranchingHeuristic { - protected static final Logger LOGGER = LoggerFactory.getLogger(DependencyDrivenHeuristic.class); - - public static final double DEFAULT_ACTIVITY = 0.0; - public static final int DEFAULT_SIGN_COUNTER = 0; - - public static final int DEFAULT_DECAY_AGE = 10; - public static final double DEFAULT_DECAY_FACTOR = 0.25; - - protected final Assignment assignment; - protected final ChoiceManager choiceManager; - protected final Random rand; - protected final BodyActivityProvider bodyActivity; - - protected final Map activityCounters = new HashMap<>(); - protected final Map signCounters = new HashMap<>(); - protected final Deque stackOfNoGoods = new ArrayDeque<>(); - private int decayPeriod; - private double decayFactor; - private int stepsSinceLastDecay; - - /** - * Maps body-representing atoms to rule heads. - */ - protected final Map bodyAtomToHeadAtom = new HashMap<>(); - - /** - * Maps rule heads to atoms representing corresponding bodies. - */ - protected final MultiValuedMap headToBodies = new HashSetValuedHashMap<>(); - - /** - * Maps body-representing atoms to literals occuring in the rule body. - */ - protected final MultiValuedMap bodyAtomToLiterals = new HashSetValuedHashMap<>(); - - /** - * Maps atoms to atoms representing bodies of rules in which the former atoms occur (in the head or the body). - */ - protected final MultiValuedMap atomsToBodiesAtoms = new HashSetValuedHashMap<>(); - - public DependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BodyActivityType bodyActivityType) { - this.assignment = assignment; - this.choiceManager = choiceManager; - this.decayPeriod = decayPeriod; - this.decayFactor = decayFactor; - this.rand = random; - this.bodyActivity = BodyActivityProviderFactory.getInstance(bodyActivityType, bodyAtomToLiterals, activityCounters, DEFAULT_ACTIVITY); - } - - public DependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { - this(assignment, choiceManager, DEFAULT_DECAY_AGE, DEFAULT_DECAY_FACTOR, random, bodyActivityType); - } - - public DependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { - this(assignment, choiceManager, random, BodyActivityType.DEFAULT); - } - - /** - * Gets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. - */ - public int getDecayPeriod() { - return decayPeriod; - } - - /** - * Sets the number of steps after which all counters are decayed (i.e. multiplied by {@link #getDecayFactor()}. - */ - public void setDecayPeriod(int decayPeriod) { - this.decayPeriod = decayPeriod; - } - - /** - * Gets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. - */ - public double getDecayFactor() { - return decayFactor; - } - - /** - * Sets the factor by which all counters are multiplied to decay after {@link #getDecayPeriod()}. - */ - public void setDecayFactor(double decayFactor) { - this.decayFactor = decayFactor; - } - - @Override - public void violatedNoGood(NoGood violatedNoGood) { - pushToStack(violatedNoGood); - } - - @Override - public void analyzedConflict(ConflictAnalysisResult analysisResult) { - pushToStack(analysisResult.learnedNoGood); - for (int resolutionAtom : analysisResult.resolutionAtoms) { - incrementActivityCounter(atomToLiteral(resolutionAtom, true)); - incrementActivityCounter(atomToLiteral(resolutionAtom, false)); - } - if (analysisResult.learnedNoGood != null) { - for (Integer literal : analysisResult.learnedNoGood) { - incrementSignCounter(literal); - } - } - decayAllIfTimeHasCome(); - } - - @Override - public void newNoGood(NoGood newNoGood) { - recordAtomRelationships(newNoGood); - pushToStack(newNoGood); - for (Integer literal : newNoGood) { - incrementSignCounter(literal); - } - } - - @Override - public void newNoGoods(Collection newNoGoods) { - newNoGoods.forEach(this::newNoGood); - } - - @Override - public double getActivity(int literal) { - return activityCounters.getOrDefault(atomOf(literal), DEFAULT_ACTIVITY); - } - - /** - * {@link DependencyDrivenHeuristic} manages a stack of nogoods in the fashion of {@link BerkMin} - * and starts by looking at the most active atom a in the nogood currently at the top of the stack. - * If a is an active choice point (i.e. representing the body of an applicable rule), it is immediately chosen; - * else the most active choice point dependent on a is. - * If there is no such atom, we continue further down the stack. - * When choosing between dependent atoms, a {@link BodyActivityProvider} is employed to define the activity of a choice point. - */ - @Override - public int chooseLiteral() { - int atom = chooseAtom(); - if (atom == DEFAULT_CHOICE_ATOM) { - return DEFAULT_CHOICE_LITERAL; - } - boolean sign = chooseSign(atom); - return atomToLiteral(atom, sign); - } - - protected int chooseAtom() { - for (NoGood noGood : stackOfNoGoods) { - int mostActiveAtom = getMostActiveAtom(noGood); - if (choiceManager.isActiveChoiceAtom(mostActiveAtom)) { - return mostActiveAtom; - } - - Collection bodies = atomsToBodiesAtoms.get(mostActiveAtom); - Optional mostActiveBody = bodies.stream().filter(this::isUnassigned).filter(choiceManager::isActiveChoiceAtom) - .max(Comparator.comparingDouble(bodyActivity::get)); - if (mostActiveBody.isPresent()) { - return mostActiveBody.get(); - } - } - return DEFAULT_CHOICE_ATOM; - } - - protected boolean chooseSign(int atom) { - atom = getAtomForChooseSign(atom); - - if (assignment.getTruth(atom) == ThriceTruth.MBT) { - return true; - } - - int positiveCounter = signCounters.getOrDefault(atomToLiteral(atom, true), DEFAULT_SIGN_COUNTER); - int negativeCounter = signCounters.getOrDefault(atomToLiteral(atom, false), DEFAULT_SIGN_COUNTER); - - if (positiveCounter > negativeCounter) { - return false; - } else if (negativeCounter > positiveCounter) { - return true; - } else { - return rand.nextBoolean(); - } - } - - protected int getAtomForChooseSign(int atom) { - Integer head = bodyAtomToHeadAtom.get(atom); - if (head != null) { - atom = head; // head atom can give more relevant information than atom representing rule body - } - return atom; - } - - protected void recordAtomRelationships(NoGood noGood) { - if (isBodyNotHead(noGood, choiceManager::isAtomChoice)) { - int body = atomOf(noGood.getLiteral(1)); - int head = atomOf(noGood.getHead()); - bodyAtomToHeadAtom.put(body, head); - headToBodies.put(head, body); - atomsToBodiesAtoms.put(head, body); - } else if (isBodyElementsNotBody(noGood, choiceManager::isAtomChoice)) { - Set literals = new HashSet<>(); - int bodyAtom = atomOf(noGood.getHead()); - for (int i = 0; i < noGood.size(); i++) { - int literal = noGood.getLiteral(i); - literals.add(literal); - if (bodyAtom != 0) { - atomsToBodiesAtoms.put(atomOf(literal), bodyAtom); - } // else { - // TODO - // } - } - assert bodyAtom != 0; - bodyAtomToLiterals.putAll(bodyAtom, literals); - } - } - - private void pushToStack(NoGood noGood) { - if (noGood != null) { - stackOfNoGoods.push(noGood); - } - } - - protected void incrementActivityCounter(int literal) { - int atom = atomOf(literal); - if (choiceManager.isAtomChoice(atom)) { - activityCounters.compute(atom, (k, v) -> (v == null ? DEFAULT_ACTIVITY : v) + 1); - } - // TODO: check performance - // note that here (and in incrementSignCounter) we only count atoms that are - // choice points, which might affect performance. - // alternative approaches: - // 1. count everything and from time to time do a garbage collection (i.e. - // remove atoms that are no choice points) - // 2. make check cheaper, e.g. by using dedicated atom IDs (e.g. even - // integers for rule bodies, uneven for other atoms) - } - - protected void incrementSignCounter(Integer literal) { - signCounters.compute(literal, (k, v) -> (v == null ? DEFAULT_SIGN_COUNTER : v) + 1); - } - - private void decayAllIfTimeHasCome() { - stepsSinceLastDecay++; - if (stepsSinceLastDecay >= decayPeriod) { - // Decay all: - activityCounters.replaceAll((k, v) -> v * decayFactor); - stepsSinceLastDecay = 0; - } - } - - /** - * Gets the most recent conflict that is still violated. - * @return the violated nogood closest to the top of the stack of nogoods. - */ - NoGood getCurrentTopClause() { - for (NoGood noGood : stackOfNoGoods) { - if (assignment.isUndefined(noGood)) { - return noGood; - } - } - return null; - } - - protected boolean isUnassigned(int atom) { - ThriceTruth truth = assignment.getTruth(atom); - return truth != FALSE && truth != TRUE; // do not use assignment.isAssigned(atom) because we may also choose MBTs - } - - private int getMostActiveAtom(NoGood noGood) { - if (noGood != null) { - return getMostActiveAtom(noGood.stream().boxed()); - } else { - return getMostActiveAtom(activityCounters.keySet().stream()); - } - } - - private int getMostActiveAtom(Stream streamOfLiterals) { - return streamOfLiterals.map(Literals::atomOf).max(Comparator.comparingDouble(this::getActivity)).orElse(DEFAULT_CHOICE_ATOM); - // TODO: exploit synergy with getMostActiveChoosableAtom - } - - /** - * Analyzes the type of this NoGood and checks if it is the so-called "body, not head" type. Uses the given {@code isRuleBody} predicate to check whether an - * atom represents a rule body. - * - * @return {@code true} iff: the NoGood is binary, and it has a head, and its tail is an atom representing a rule body. - */ - public static boolean isBodyNotHead(NoGood noGood, Predicate isRuleBody) { - return noGood.isBinary() && noGood.hasHead() && isRuleBody.test(atomOf(noGood.getLiteral(1))); - } - - /** - * Analyzes the type of this NoGood and checks if it is the so-called "body elements, not body" type. Uses the given {@code isRuleBody} predicate to check - * whether an atom represents a rule body. - * - * @return {@code true} iff: the NoGood contains at least two literals, and the head is a negative literal whose atom represents a rule body. - */ - public static boolean isBodyElementsNotBody(NoGood noGood, Predicate isRuleBody) { - return noGood.size() > 1 && noGood.hasHead() && isNegated(noGood.getHead()) && isRuleBody.test(atomOf(noGood.getHead())); - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java deleted file mode 100644 index 181a2299b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenPyroHeuristic.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; - -import java.util.Random; - -/** - * One weakness of Alpha that has to be addressed in future work is its lack of support nogoods (except in one special case). - * This means that the solver cannot recognize when an atom occurring negatively in a rule body cannot be satisfied anymore, - * thus exploring large portions of the search space in search for a witness. - * Therefore, Alpha currently benefits in many cases from heuristics that assign true to choice points whenever they can. - * We apply this modification to {@link DependencyDrivenHeuristic}, which then always assigns true first and tries false - * only when backtracking, and call these variants pyromaniacal since they prefer the firing of a rule over its non-firing. - - * Copyright (c) 2017 Siemens AG - * - */ -public class DependencyDrivenPyroHeuristic extends DependencyDrivenHeuristic { - - public DependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BodyActivityType bodyActivityType) { - super(assignment, choiceManager, decayPeriod, decayFactor, random, bodyActivityType); - } - - public DependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { - super(assignment, choiceManager, random, bodyActivityType); - } - - public DependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { - super(assignment, choiceManager, random); - } - - @Override - public boolean chooseSign(int atom) { - return true; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java deleted file mode 100644 index b2d8b194e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/DependencyDrivenVSIDS.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; - -import java.util.Random; - -/** - * Non-dependency-driven heuristics like {@link BerkMin}, {@link BerkMinLiteral}, and {@link VSIDS} - * suffer from the fact that choice points comprise only a small portion of all the literals - * occurring in nogoods and therefore do not influence activity and sign counters as much as - * other atoms. - *

      - * The basic idea of {@link DependencyDrivenVSIDS} is therefore to find dependent atoms that can - * enrich the information available for a choice point. Intuitively, all atoms occurring in the head or the - * body of a rule depend on a choice point representing the body of this rule. - *

      - * In contrast to {@link DependencyDrivenHeuristic} and {@link GeneralizedDependencyDrivenHeuristic}, - * this heuristic is based on ideas from VSIDS instead of BerkMin. - */ -public class DependencyDrivenVSIDS extends VSIDS { - - public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - super(assignment, choiceManager, new HeapOfActiveChoicePoints(decayPeriod, decayFactor, choiceManager), momsStrategy); - } - - public DependencyDrivenVSIDS(Assignment assignment, ChoiceManager choiceManager, Random random, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, random, momsStrategy); - } - - /** - * Returns the head derived by the rule corresponding to the given choice point, - * since the head atom may give more relevant information than the atom representing rule body. - */ - @Override - protected int getAtomForChooseSign(int atom) { - Integer head = choiceManager.getHeadDerivedByChoiceAtom(atom); - if (head != null) { - atom = head; - } - return atom; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java deleted file mode 100644 index 3b6defcf1..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenHeuristic.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; - -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -/** - * {@link DependencyDrivenHeuristic} needs to know a lot about the structure of nogoods, i.e. the role their members play in rules. - * However, the solving component of Alpha usually deals only with nogoods and cannot naturally access this information. - * Therefore, {@link GeneralizedDependencyDrivenHeuristic} both generalizes and simplifies {@link DependencyDrivenHeuristic} - * by redefining the set of atoms dependent on a choice point. - * This set is constructed by adding to it, every time a new nogood containing a choice point is added to the stack, - * all other atoms in the nogood. - * To choose an atom, {@link GeneralizedDependencyDrivenHeuristic} then proceeds as {@link DependencyDrivenHeuristic}. - * Because {@link GeneralizedDependencyDrivenHeuristic} does not know the head belonging to a choice point, - * it just uses the {@link BerkMin} method to choose a truth value. - - * Copyright (c) 2017 Siemens AG - * - */ -public class GeneralizedDependencyDrivenHeuristic extends DependencyDrivenHeuristic { - - public GeneralizedDependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, BodyActivityType bodyActivityType) { - super(assignment, choiceManager, decayPeriod, decayFactor, random, bodyActivityType); - } - - public GeneralizedDependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { - super(assignment, choiceManager, random, bodyActivityType); - } - - public GeneralizedDependencyDrivenHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { - super(assignment, choiceManager, random); - } - - @Override - protected void recordAtomRelationships(NoGood noGood) { - // TODO: use HeapOfActiveChoicePoints.recordAtomRelationships, which does similar things - int body = DEFAULT_CHOICE_ATOM; - Set others = new HashSet<>(); - for (int literal : noGood) { - int atom = atomOf(literal); - if (body == DEFAULT_CHOICE_ATOM && choiceManager.isAtomChoice(atom)) { - body = atom; - } else { - others.add(atom); - } - } - for (Integer atom : others) { - atomsToBodiesAtoms.put(atom, body); - bodyAtomToLiterals.put(body, atom); - } - } - - @Override - protected int getAtomForChooseSign(int atom) { - return atom; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java deleted file mode 100644 index e8deefa8b..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/GeneralizedDependencyDrivenPyroHeuristic.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; - -import java.util.Random; - -/** - * One weakness of Alpha that has to be addressed in future work is its lack of support nogoods (except in one special case). - * This means that the solver cannot recognize when an atom occurring negatively in a rule body cannot be satisfied anymore, - * thus exploring large portions of the search space in search for a witness. - * Therefore, Alpha currently benefits in many cases from heuristics that assign true to choice points whenever they can. - * We apply this modification to {@link GeneralizedDependencyDrivenHeuristic}, which then always assigns true first and tries false - * only when backtracking, and call these variants pyromaniacal since they prefer the firing of a rule over its non-firing. - - * Copyright (c) 2017 Siemens AG - * - */ -public class GeneralizedDependencyDrivenPyroHeuristic extends GeneralizedDependencyDrivenHeuristic { - - public GeneralizedDependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, Random random, - BodyActivityType bodyActivityType) { - super(assignment, choiceManager, decayPeriod, decayFactor, random, bodyActivityType); - } - - public GeneralizedDependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random, BodyActivityType bodyActivityType) { - super(assignment, choiceManager, random, bodyActivityType); - } - - public GeneralizedDependencyDrivenPyroHeuristic(Assignment assignment, ChoiceManager choiceManager, Random random) { - super(assignment, choiceManager, random); - } - - @Override - public boolean chooseSign(int atom) { - return true; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java deleted file mode 100644 index 45f9faf43..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtoms.java +++ /dev/null @@ -1,283 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.ChoiceInfluenceManager; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.PriorityQueue; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -/** - * Manages a heap of atoms that are assigned an activity, such that the most active atom - * resides at the top of the heap. - * In contrast to standard heuristics like VSIDS, activities are not periodically decayed but - * the increment added when increasing activities is constantly increased itself, which has the - * same effect. - * - */ -public class HeapOfActiveAtoms { - protected static final Logger LOGGER = LoggerFactory.getLogger(HeapOfActiveAtoms.class); - - private static final double NORMALIZATION_THRESHOLD = 1E100; - private static final double INCREMENT_TO_AVOID_DENORMALS = Double.MIN_VALUE * NORMALIZATION_THRESHOLD; - private static final double SCORE_EPSILON = 1E-100; - - private boolean[] incrementedActivityScores = new boolean[0]; - protected double[] activityScores = new double[0]; - protected final PriorityQueue heap = new PriorityQueue<>(new AtomActivityComparator().reversed()); - - protected ChoiceManager choiceManager; - private int decayPeriod; - private double decayFactor; - private int stepsSinceLastDecay; - private double currentActivityIncrement = 1.0; - private int numberOfNormalizations; - - private final MOMs moms; - - public HeapOfActiveAtoms(int decayPeriod, double decayFactor, ChoiceManager choiceManager) { - this.decayPeriod = decayPeriod; - this.decayFactor = decayFactor; - this.choiceManager = choiceManager; - this.choiceManager.setChoicePointActivityListener(new ChoicePointActivityListener()); - BinaryNoGoodPropagationEstimation bnpEstimation = choiceManager.getBinaryNoGoodPropagationEstimation(); - this.moms = bnpEstimation == null ? null : new MOMs(bnpEstimation); - } - - public double getActivity(int literal) { - return activityScores[atomOf(literal)]; - } - - /** - * Gets the number of steps after which activity scores are decayed. - */ - public int getDecayPeriod() { - return decayPeriod; - } - - /** - * @see #getDecayPeriod() - */ - public void setDecayPeriod(int decayPeriod) { - this.decayPeriod = decayPeriod; - } - - /** - * Gets the factor by which the activity increment is multiplied every {@link #getDecayPeriod()} steps. - */ - public double getDecayFactor() { - return decayFactor; - } - - /** - * @see #getDecayFactor() - */ - public void setDecayFactor(double decayFactor) { - this.decayFactor = decayFactor; - } - - /** - * Updates the current activity increment by multiplying it with the decay factor, if time for decay has come. - * - * Time for decay has come if the number of conflicts since the last decay has reached the decay period. - */ - void decayIfTimeHasCome() { - stepsSinceLastDecay++; - if (stepsSinceLastDecay >= decayPeriod) { - currentActivityIncrement *= decayFactor; - stepsSinceLastDecay = 0; - } - } - - /** - * Stores newly grounded {@link NoGood}s and updates associated activity counters. - */ - public void newNoGoods(Collection newNoGoods) { - for (NoGood newNoGood : newNoGoods) { - Type type = newNoGood.getType(); - if (type != Type.LEARNT && type != Type.INTERNAL) { - analyzeNewNoGood(newNoGood); - initActivity(newNoGood); - } - } - } - - /** - * May be implemented in subclasses to add specific analysis of nogoods. - */ - protected void analyzeNewNoGood(NoGood newNoGood) { - } - - /** - * Computes and stores initial activity values for the atoms occurring in the given nogood. - */ - protected void initActivity(NoGood newNoGood) { - if (moms != null) { - initActivityMOMs(newNoGood); - } else { - initActivityNaive(newNoGood); - } - } - - /** - * Uses {@link MOMs} to initialize activity scores, which are then scaled to the interval [0,1]. - * This is done by computing 1 - 1/log(s+1.01) for original score s. - * This guarantees a normalized score between 0 and 1 and retains relative order. - * 1.01 is added to avoid computing the logarithm of a number between 0 and 1 (input scores have to be greater or equal to 0!) - * @param newNoGood a new nogood, the atoms occurring in which will be initialized - */ - private void initActivityMOMs(NoGood newNoGood) { - LOGGER.debug("Initializing activity scores with MOMs"); - for (int literal : newNoGood) { - int atom = atomOf(literal); - if (!incrementedActivityScores[atom]) { // update initial value as long as not incremented yet by VSIDS - double score = moms.getScore(atom); - if (score > 0.0) { - double newActivity = 1 - 1 / (Math.log(score + 1.01)); - if (newActivity - activityScores[atom] > SCORE_EPSILON) { // avoid computation overhead if score does not increase - if (numberOfNormalizations > 0) { - newActivity = normalizeNewActivityScore(newActivity); - } - setActivity(atom, newActivity); - } - } - } - } - } - - void growToCapacity(int newCapacity) { - activityScores = Arrays.copyOf(activityScores, newCapacity); - incrementedActivityScores = Arrays.copyOf(incrementedActivityScores, newCapacity); - } - - private void initActivityNaive(NoGood newNoGood) { - LOGGER.debug("Initializing activity scores naively"); - for (Integer literal : newNoGood) { - int atom = atomOf(literal); - incrementActivity(atom); - } - } - - /** - * Returns the atom with the highest activity score and removes it from the heap. - */ - public Integer getMostActiveAtom() { - return heap.poll(); - } - - /** - * Increments the activity of the given atom - * - * by adding to it the current activity increment times the increment factor. - * If the new value exceeds a certain threshold, all activity scores are normalized. - */ - public void incrementActivity(int atom) { - incrementActivity(atom, currentActivityIncrement); - } - - protected void incrementActivity(int atom, double increment) { - // newActivity := oldActivity + increment - double newActivity = activityScores[atom] + increment; - setActivity(atom, newActivity); - incrementedActivityScores[atom] = true; - } - - private void setActivity(int atom, double newActivity) { - activityScores[atom] = newActivity; - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Activity of atom {} set to {}", atom, newActivity); - } - - if (newActivity > NORMALIZATION_THRESHOLD) { - normalizeActivityScores(); - } - - heap.add(atom); // ignores the fact that atom may already be in the heap for performance reasons (may be revised in future) - } - - /** - * Makes all activity scores smaller if they get too high. - * - * Avoids denormal numbers similarly as done in clasp. - */ - private void normalizeActivityScores() { - LOGGER.debug("Normalizing activity scores"); - numberOfNormalizations++; - currentActivityIncrement /= NORMALIZATION_THRESHOLD; - for (int atom = 1; atom < activityScores.length; atom++) { - activityScores[atom] = (activityScores[atom] + INCREMENT_TO_AVOID_DENORMALS) / NORMALIZATION_THRESHOLD; - } - } - - private double normalizeNewActivityScore(double newActivity) { - for (int i = 0; i < numberOfNormalizations; i++) { - newActivity = (newActivity + INCREMENT_TO_AVOID_DENORMALS) / NORMALIZATION_THRESHOLD; - } - return newActivity; - } - - private class AtomActivityComparator implements Comparator { - - @Override - public int compare(Integer a1, Integer a2) { - return Double.compare(activityScores[a1], activityScores[a2]); - } - - } - - private class ChoicePointActivityListener implements ChoiceInfluenceManager.ActivityListener { - - @Override - public void callbackOnChanged(int atom, boolean active) { - if (active && choiceManager.isActiveChoiceAtom(atom)) { - if (atom < activityScores.length) { - /* if atom has no activity score, probably the atom is still being buffered - by DependencyDrivenVSIDSHeuristic and will get an initial activity - when the buffer is ingested */ - heap.add(atom); - } - } - } - } - - public void setMOMsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - if (moms != null) { - moms.setStrategy(momsStrategy); - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java deleted file mode 100644 index 94c768bee..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveChoicePoints.java +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.HashSetValuedHashMap; - -import java.util.HashSet; -import java.util.Set; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -/** - * Extends {@code HeapOfActiveAtoms} by a mechanism that, - * when the activity of an atom is increased, the increase counts towards dependent choice point - * if the given atom is not a choice point itself. - * Also, only choice points are maintained in the heap and only choice points are returned by - * {@link #getMostActiveAtom()}. - * - */ -public class HeapOfActiveChoicePoints extends HeapOfActiveAtoms { - - /** - * Maps atoms to choice points representing bodies of rules in which the former atoms occur - * (in the head or the body). - */ - protected final MultiValuedMap atomsToChoicePoints = new HashSetValuedHashMap<>(); - - public HeapOfActiveChoicePoints(int decayPeriod, double decayFactor, ChoiceManager choiceManager) { - super(decayPeriod, decayFactor, choiceManager); - } - - @Override - public void incrementActivity(int atom, double increment) { - if (choiceManager.isAtomChoice(atom)) { - super.incrementActivity(atom, increment); - } else { - for (Integer dependentBody : atomsToChoicePoints.get(atom)) { - super.incrementActivity(dependentBody, increment); - } - } - } - - /** - * Records the dependency relationships between atoms occurring in the given nogood. - * @param noGood - */ - private void recordAtomRelationships(NoGood noGood) { - final int none = -1; - int body = none; - Set others = new HashSet<>(); - - for (int literal : noGood) { - int atom = atomOf(literal); - if (body == none && choiceManager.isAtomChoice(atom)) { - body = atom; - } else { - if (choiceManager.isChecksEnabled() && choiceManager.isAtomChoice(atom)) { - throw oops("More than one choice point in a nogood: " + body + ", " + atom); - } - others.add(atom); - } - } - - if (body == none) { - return; - } - - for (Integer atom : others) { - atomsToChoicePoints.put(atom, body); - } - } - - @Override - public void analyzeNewNoGood(NoGood newNoGood) { - recordAtomRelationships(newNoGood); - } - - @Override - public String toString() { - return heap.toString(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java deleted file mode 100644 index 26d3d74a4..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfiguration.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; - -import java.util.List; - -/** - * Configuration class holding parameters for {@link BranchingHeuristic}s. - */ -public class HeuristicsConfiguration { - - private Heuristic heuristic; - private BinaryNoGoodPropagationEstimationStrategy momsStrategy; - private List replayChoices; - /** - * @param heuristic - * @param momsStrategy - * @param replayChoices - */ - public HeuristicsConfiguration(Heuristic heuristic, BinaryNoGoodPropagationEstimationStrategy momsStrategy, List replayChoices) { - super(); - this.heuristic = heuristic; - this.momsStrategy = momsStrategy; - this.replayChoices = replayChoices; - } - - /** - * @return the heuristic - */ - public Heuristic getHeuristic() { - return heuristic; - } - - /** - * @param heuristic the heuristic to set - */ - public void setHeuristic(Heuristic heuristic) { - this.heuristic = heuristic; - } - - /** - * @return the momsStrategy - */ - public BinaryNoGoodPropagationEstimationStrategy getMomsStrategy() { - return momsStrategy; - } - - /** - * @param momsStrategy the momsStrategy to set - */ - public void setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - this.momsStrategy = momsStrategy; - } - - /** - * @return the replayChoices - */ - public List getReplayChoices() { - return replayChoices; - } - - /** - * @param replayChoices the replayChoices to set - */ - public void setReplayChoices(List replayChoices) { - this.replayChoices = replayChoices; - } - - public static HeuristicsConfigurationBuilder builder() { - return new HeuristicsConfigurationBuilder(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java deleted file mode 100644 index b1ee79ccf..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicsConfigurationBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; - -import java.util.List; - -/** - * Builder for {@link HeuristicsConfiguration} objects - */ -public class HeuristicsConfigurationBuilder { - - private Heuristic heuristic; - private BinaryNoGoodPropagationEstimationStrategy momsStrategy; - private List replayChoices; - - /** - * @param heuristic the heuristic to set - */ - public HeuristicsConfigurationBuilder setHeuristic(Heuristic heuristic) { - this.heuristic = heuristic; - return this; - } - - /** - * @param momsStrategy the momsStrategy to set - */ - public HeuristicsConfigurationBuilder setMomsStrategy(BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - this.momsStrategy = momsStrategy; - return this; - } - - /** - * @param replayChoices the replayChoices to set - */ - public HeuristicsConfigurationBuilder setReplayChoices(List replayChoices) { - this.replayChoices = replayChoices; - return this; - } - - public HeuristicsConfiguration build() { - return new HeuristicsConfiguration(heuristic, momsStrategy, replayChoices); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java deleted file mode 100644 index 223cb7ad7..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/MOMs.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; - -/** - * The well-known MOMs (Maximum Occurrences in clauses of Minimum size) heuristic - * used to initialize atom scores. - * This implementation is inspired by the MOMs implementation in clasp - * but differs from it in several ways, e.g.: - *

        - *
      • The default strategy is {@link BinaryNoGoodPropagationEstimationStrategy#CountBinaryWatches}, not {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation}.
      • - *
      • {@link BinaryNoGoodPropagationEstimationStrategy#BinaryNoGoodPropagation} does not do only one iteration of propagation, but exhaustive propagation.
      • - *
      - * - */ -public class MOMs { - - static final BinaryNoGoodPropagationEstimationStrategy DEFAULT_STRATEGY = BinaryNoGoodPropagationEstimationStrategy.CountBinaryWatches; - - private BinaryNoGoodPropagationEstimation bnpEstimation; - private BinaryNoGoodPropagationEstimationStrategy strategy = DEFAULT_STRATEGY; - - public MOMs(BinaryNoGoodPropagationEstimation bnpEstimation) { - super(); - this.bnpEstimation = bnpEstimation; - } - - /** - * @param atom - * @return - */ - public double getScore(Integer atom) { - int s1 = bnpEstimation.estimate(atom, true, strategy); - int s2 = bnpEstimation.estimate(atom, false, strategy); - return ((s1 * s2) << 10) + s1 + s2; - } - - public void setStrategy(BinaryNoGoodPropagationEstimationStrategy strategy) { - this.strategy = strategy != null ? strategy : DEFAULT_STRATEGY; - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java deleted file mode 100644 index 506cc345c..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/NaiveHeuristic.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; - -import java.util.Collection; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; - -/** - * The default heuristic that had been used by {@link at.ac.tuwien.kr.alpha.solver.DefaultSolver} before {@link BerkMin} was implemented. - * - */ -public class NaiveHeuristic implements BranchingHeuristic { - - private final ChoiceManager choiceManager; - - public NaiveHeuristic(ChoiceManager choiceManager) { - this.choiceManager = choiceManager; - } - - @Override - public void violatedNoGood(NoGood violatedNoGood) { - } - - @Override - public void analyzedConflict(ConflictAnalysisResult analysisResult) { - } - - @Override - public void newNoGood(NoGood newNoGood) { - } - - @Override - public void newNoGoods(Collection newNoGoods) { - } - - @Override - public int chooseLiteral() { - return atomToLiteral(choiceManager.getNextActiveChoiceAtom()); - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java deleted file mode 100644 index cda9f35ac..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristic.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) 2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; - -import java.util.Iterator; -import java.util.List; - -/** - * A heuristic that replays a fixed list of choices. - */ -public class ReplayHeuristic implements BranchingHeuristic { - - private final Iterator choicesIterator; - private final ChoiceManager choiceManager; - - /** - * Initializes the heuristic - * @param choices a list of signed atoms (positive if atom shall be made true, negative otherwise) - * @param choiceManager - */ - public ReplayHeuristic(List choices, ChoiceManager choiceManager) { - super(); - this.choicesIterator = choices.iterator(); - this.choiceManager = choiceManager; - } - - @Override - public void violatedNoGood(NoGood violatedNoGood) { - } - - @Override - public void analyzedConflict(ConflictAnalysisResult analysisResult) { - } - - @Override - public void newNoGood(NoGood newNoGood) { - } - - @Override - public int chooseLiteral() { - if (!choicesIterator.hasNext()) { - return DEFAULT_CHOICE_LITERAL; - } - int replayChoiceSignedAtom = choicesIterator.next(); - if (replayChoiceSignedAtom == 0) { - // Use 0 to signal no more choices. - return DEFAULT_CHOICE_LITERAL; - } - int replayChoiceAtom = Math.abs(replayChoiceSignedAtom); - int replayChoiceLiteral = Literals.atomToLiteral(replayChoiceAtom, replayChoiceSignedAtom > 0); - if (!choiceManager.isActiveChoiceAtom(replayChoiceAtom)) { - throw new IllegalStateException("Replay choice is not an active choice point: " + replayChoiceAtom); - } - return replayChoiceLiteral; - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java deleted file mode 100644 index 7b8b60232..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDS.java +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimationStrategy; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.heuristics.activity.BodyActivityProvider; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.HashSetValuedHashMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - -import static at.ac.tuwien.kr.alpha.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.common.Literals.*; - -/** - * This implementation is inspired by the VSIDS implementation in clasp. - * Therefore, for example, decay is not realized by decreasing activity scores with age, but by - * steadily increasing the increment added to the score of active atoms - * (such that the activity score of older atoms does not have to be changed later). - *

      - * The implementation is simplified in some ways, e.g. it is not possible to specify a frequency in which the activity - * increment is updated (which corresponds to decay), but it is updated after every conflict. - *

      - * Reference for VSIDS: - * Moskewicz, Matthew W.; Madigan, Conor F.; Zhao, Ying; Zhang, Lintao; Malik, Sharad (2001): - * Chaff: engineering an efficient SAT solver. - * In: Proceedings of the 38th Design Automation Conference. IEEE, pp. 530–535. - */ -public class VSIDS implements ActivityBasedBranchingHeuristic { - protected static final Logger LOGGER = LoggerFactory.getLogger(VSIDS.class); - - public static final int DEFAULT_DECAY_PERIOD = 1; - - /** - * The default factor by which VSID's activity increment will be multiplied when the decay period has expired. - * The value is taken from clasp's tweety configuration which clasp uses by default. - */ - public static final double DEFAULT_DECAY_FACTOR = 1 / 0.92; - - protected final Assignment assignment; - protected final ChoiceManager choiceManager; - - protected final HeapOfActiveAtoms heapOfActiveAtoms; - protected int[] signBalances = new int[0]; - - private final Collection bufferedNoGoods = new ArrayList<>(); - - private int nChoicesTrue; - private int nChoicesFalse; - private int nChoicesRand; - - /** - * Maps rule heads to atoms representing corresponding bodies. - */ - protected final MultiValuedMap headToBodies = new HashSetValuedHashMap<>(); - - protected VSIDS(Assignment assignment, ChoiceManager choiceManager, HeapOfActiveAtoms heapOfActiveAtoms, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - this.assignment = assignment; - this.choiceManager = choiceManager; - this.heapOfActiveAtoms = heapOfActiveAtoms; - this.heapOfActiveAtoms.setMOMsStrategy(momsStrategy); - } - - public VSIDS(Assignment assignment, ChoiceManager choiceManager, int decayPeriod, double decayFactor, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - this(assignment, choiceManager, new HeapOfActiveAtoms(decayPeriod, decayFactor, choiceManager), momsStrategy); - } - - public VSIDS(Assignment assignment, ChoiceManager choiceManager, BinaryNoGoodPropagationEstimationStrategy momsStrategy) { - this(assignment, choiceManager, DEFAULT_DECAY_PERIOD, DEFAULT_DECAY_FACTOR, momsStrategy); - } - - @Override - public void violatedNoGood(NoGood violatedNoGood) { - } - - @Override - public void analyzedConflict(ConflictAnalysisResult analysisResult) { - ingestBufferedNoGoods(); //analysisResult may contain new atoms whose activity must be initialized - for (int resolutionAtom : analysisResult.resolutionAtoms) { - heapOfActiveAtoms.incrementActivity(resolutionAtom); - } - if (analysisResult.learnedNoGood != null) { - for (int literal : analysisResult.learnedNoGood) { - incrementSignCounter(literal); - heapOfActiveAtoms.incrementActivity(atomOf(literal)); - } - } - heapOfActiveAtoms.decayIfTimeHasCome(); - } - - @Override - public void newNoGood(NoGood newNoGood) { - this.bufferedNoGoods.add(newNoGood); - } - - @Override - public void newNoGoods(Collection newNoGoods) { - this.bufferedNoGoods.addAll(newNoGoods); - } - - private void ingestBufferedNoGoods() { - heapOfActiveAtoms.newNoGoods(bufferedNoGoods); - bufferedNoGoods.clear(); - } - - /** - * {@link VSIDS} manages a stack of nogoods in the fashion of {@link BerkMin} - * and starts by looking at the most active atom a in the nogood currently at the top of the stack. - * If a is an active choice point (i.e. representing the body of an applicable rule), it is immediately chosen; - * else the most active choice point dependent on a is. - * If there is no such atom, we continue further down the stack. - * When choosing between dependent atoms, a {@link BodyActivityProvider} is employed to define the activity of a choice point. - */ - @Override - public int chooseLiteral() { - int atom = chooseAtom(); - if (atom == DEFAULT_CHOICE_ATOM) { - return DEFAULT_CHOICE_LITERAL; - } - boolean sign = chooseSign(atom); - return atomToLiteral(atom, sign); - } - - protected int chooseAtom() { - ingestBufferedNoGoods(); - Integer mostActiveAtom; - while ((mostActiveAtom = heapOfActiveAtoms.getMostActiveAtom()) != null) { - if (choiceManager.isActiveChoiceAtom(mostActiveAtom)) { - return mostActiveAtom; - } - } - return DEFAULT_CHOICE_ATOM; - } - - /** - * Chooses a sign (truth value) to assign to the given atom. - * - * To make this decision, sign counters are maintained that reflect how often an atom - * occurs positively or negatively in learnt nogoods. - * If the sign balance for the given atom is positive, {@code true} will be chosen. - * If it is negative, {@code false} will be chosen. - * If the sign balance is zero, the default sign is selected, which is {@code true} - * iff the atom represents a rule body (which is currently always the case for atoms chosen in Alpha). - * - * @param atom - * the chosen atom - * @return the truth value to assign to the given atom - */ - protected boolean chooseSign(int atom) { - atom = getAtomForChooseSign(atom); - - if (assignment.getTruth(atom) == ThriceTruth.MBT) { - return true; - } - - int signBalance = getSignBalance(atom); - if (LOGGER.isDebugEnabled() && (nChoicesFalse + nChoicesTrue + nChoicesRand) % 100 == 0) { - LOGGER.debug("chooseSign stats: f={}, t={}, r={}", nChoicesFalse, nChoicesTrue, nChoicesRand); - LOGGER.debug("chooseSign stats: signBalance={}", signBalance); - } - - if (signBalance >= 0) { - nChoicesTrue++; - return true; - } else { - nChoicesFalse++; - return false; - } - } - - /** - * This method just returns {@code atom} by default but can be overridden in subclasses. - * @param atom the atom chosen by VSIDS - * @return the atom to base the choice of sign upon - */ - protected int getAtomForChooseSign(int atom) { - return atom; - } - - protected void incrementSignCounter(int literal) { - int atom = atomOf(literal); - boolean sign = isPositive(literal); - growForMaxAtomId(atom); - signBalances[atom] += sign ? 1 : -1; - } - - public void growForMaxAtomId(int maxAtomId) { - // Grow arrays only if needed. - if (signBalances.length > maxAtomId) { - return; - } - // Grow to default size, except if bigger array is required due to maxAtomId. - int newCapacity = arrayGrowthSize(signBalances.length); - if (newCapacity < maxAtomId + 1) { - newCapacity = maxAtomId + 1; - } - signBalances = Arrays.copyOf(signBalances, newCapacity); - heapOfActiveAtoms.growToCapacity(newCapacity); - } - - @Override - public double getActivity(int literal) { - return heapOfActiveAtoms.getActivity(literal); - } - - /** - * Returns the sign balance for the given atom in learnt nogoods. - * @param atom - * @return the number of times the given atom occurrs positively more often than negatively (which may be negative) - */ - int getSignBalance(int atom) { - return signBalances.length > atom ? signBalances[atom] : 0; - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java deleted file mode 100644 index 35a5c1f0e..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/AvgBodyActivityProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics.activity; - -import org.apache.commons.collections4.MultiValuedMap; - -import java.util.Map; - -public class AvgBodyActivityProvider extends BodyActivityProvider { - - public AvgBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { - super(bodyToLiterals, activityCounters, defaultActivity); - } - - @Override - public double get(int bodyRepresentingAtom) { - return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).average().orElse(defaultActivity); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java deleted file mode 100644 index 7591eea47..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics.activity; - -import org.apache.commons.collections4.MultiValuedMap; - -import java.util.Map; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; - -public abstract class BodyActivityProvider { - - protected final MultiValuedMap bodyToLiterals; - protected final Map activityCounters; - protected final double defaultActivity; - - public BodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { - this.bodyToLiterals = bodyToLiterals; - this.activityCounters = activityCounters; - this.defaultActivity = defaultActivity; - } - - public abstract double get(int bodyRepresentingAtom); - - protected double getActivity(int literal) { - return activityCounters.getOrDefault(atomOf(literal), defaultActivity); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java deleted file mode 100644 index f3ded2a85..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/BodyActivityProviderFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics.activity; - -import org.apache.commons.collections4.MultiValuedMap; - -import java.util.Map; - -public final class BodyActivityProviderFactory { - - public enum BodyActivityType { - DEFAULT, SUM, AVG, MAX, MIN - } - - public static BodyActivityProvider getInstance(BodyActivityType type, MultiValuedMap bodyToLiterals, Map activityCounters, - double defaultActivity) { - switch (type) { - case DEFAULT: - return new DefaultBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); - case SUM: - return new SumBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); - case AVG: - return new AvgBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); - case MAX: - return new MaxBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); - case MIN: - return new MinBodyActivityProvider(bodyToLiterals, activityCounters, defaultActivity); - default: - throw new IllegalArgumentException("Unknown body activity type requested."); - } - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java deleted file mode 100644 index a2e599790..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/DefaultBodyActivityProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics.activity; - -import org.apache.commons.collections4.MultiValuedMap; - -import java.util.Map; - -public class DefaultBodyActivityProvider extends BodyActivityProvider { - - public DefaultBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { - super(bodyToLiterals, activityCounters, defaultActivity); - } - - @Override - public double get(int bodyRepresentingAtom) { - return activityCounters.getOrDefault(bodyRepresentingAtom, defaultActivity); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java deleted file mode 100644 index 324c4ccce..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MaxBodyActivityProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics.activity; - -import org.apache.commons.collections4.MultiValuedMap; - -import java.util.Map; - -public class MaxBodyActivityProvider extends BodyActivityProvider { - - public MaxBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { - super(bodyToLiterals, activityCounters, defaultActivity); - } - - @Override - public double get(int bodyRepresentingAtom) { - return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).max().orElse(defaultActivity); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java deleted file mode 100644 index 33d73c237..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/MinBodyActivityProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics.activity; - -import org.apache.commons.collections4.MultiValuedMap; - -import java.util.Map; - -public class MinBodyActivityProvider extends BodyActivityProvider { - - public MinBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { - super(bodyToLiterals, activityCounters, defaultActivity); - } - - @Override - public double get(int bodyRepresentingAtom) { - return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).min().orElse(defaultActivity); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java deleted file mode 100644 index 4cb116748..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/heuristics/activity/SumBodyActivityProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2017 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.solver.heuristics.activity; - -import org.apache.commons.collections4.MultiValuedMap; - -import java.util.Map; - -public class SumBodyActivityProvider extends BodyActivityProvider { - - public SumBodyActivityProvider(MultiValuedMap bodyToLiterals, Map activityCounters, double defaultActivity) { - super(bodyToLiterals, activityCounters, defaultActivity); - } - - @Override - public double get(int bodyRepresentingAtom) { - return bodyToLiterals.get(bodyRepresentingAtom).stream().mapToDouble(this::getActivity).sum(); - } - -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java deleted file mode 100644 index d5b26f9bf..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearner.java +++ /dev/null @@ -1,361 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.solver.learning; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.Antecedent; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static at.ac.tuwien.kr.alpha.Util.oops; -import static at.ac.tuwien.kr.alpha.common.Literals.*; -import static at.ac.tuwien.kr.alpha.solver.NoGoodStore.LBD_NO_VALUE; - -/** - * Conflict-driven learning on ground clauses. - * - * Copyright (c) 2016-2020, the Alpha Team. - */ -public class GroundConflictNoGoodLearner { - private static final Logger LOGGER = LoggerFactory.getLogger(GroundConflictNoGoodLearner.class); - - private final Assignment assignment; - private final AtomStore atomStore; - - /** - * Given a conflicting NoGood, computes a conflict-free backjumping level such that the given NoGood is not - * violated. - * - * @param violatedNoGood the conflicting NoGood. - * @return -1 if the violatedNoGood cannot be satisfied, otherwise - * 0 if violatedNoGood is unary, and else - * the highest backjumping level such that the NoGood is no longer violated. - */ - public int computeConflictFreeBackjumpingLevel(NoGood violatedNoGood) { - // If violatedNoGood is unary, backjump to decision level 0 if it can be satisfied. - if (violatedNoGood.isUnary()) { - int literal = violatedNoGood.getLiteral(0); - int literalDecisionLevel = assignment.getRealWeakDecisionLevel(atomOf(literal)); - if (literalDecisionLevel > 0) { - return 0; - } else { - return -1; - } - } - int highestDecisionLevel = -1; - int secondHighestDecisionLevel = -1; - int numAtomsInHighestLevel = 0; - int[] reasonLiterals = violatedNoGood.asAntecedent().getReasonLiterals(); - for (int literal : reasonLiterals) { - int literalDecisionLevel = assignment.getRealWeakDecisionLevel(atomOf(literal)); - if (literalDecisionLevel == highestDecisionLevel) { - numAtomsInHighestLevel++; - } else if (literalDecisionLevel > highestDecisionLevel) { - secondHighestDecisionLevel = highestDecisionLevel; - highestDecisionLevel = literalDecisionLevel; - numAtomsInHighestLevel = 1; - } else if (literalDecisionLevel > secondHighestDecisionLevel) { - secondHighestDecisionLevel = literalDecisionLevel; - } - } - if (numAtomsInHighestLevel == 1) { - return secondHighestDecisionLevel; - } - return highestDecisionLevel - 1; - } - - public static class ConflictAnalysisResult { - public static final ConflictAnalysisResult UNSAT = new ConflictAnalysisResult(); - - public final NoGood learnedNoGood; - public final int backjumpLevel; - public final Collection resolutionAtoms; - public final int lbd; - - private ConflictAnalysisResult() { - learnedNoGood = null; - backjumpLevel = -1; - resolutionAtoms = null; - lbd = LBD_NO_VALUE; - } - - public ConflictAnalysisResult(NoGood learnedNoGood, int backjumpLevel, Collection resolutionAtoms) { - this(learnedNoGood, backjumpLevel, resolutionAtoms, LBD_NO_VALUE); - } - - public ConflictAnalysisResult(NoGood learnedNoGood, int backjumpLevel, Collection resolutionAtoms, int lbd) { - if (backjumpLevel < 0) { - throw oops("Backjumping level is smaller than 0"); - } - - this.learnedNoGood = learnedNoGood; - this.backjumpLevel = backjumpLevel; - this.resolutionAtoms = resolutionAtoms; - this.lbd = lbd; - } - - @Override - public String toString() { - if (this == UNSAT) { - return "UNSATISFIABLE"; - } - return learnedNoGood + "@" + backjumpLevel; - } - } - - public GroundConflictNoGoodLearner(Assignment assignment, AtomStore atomStore) { - this.assignment = assignment; - this.atomStore = atomStore; - } - - public ConflictAnalysisResult analyzeConflictingNoGood(Antecedent violatedNoGood) { - LOGGER.trace("Analyzing violated nogood: {}", violatedNoGood); - return analyzeTrailBased(violatedNoGood); - } - - public ConflictAnalysisResult analyzeConflictFromAddingNoGood(Antecedent violatedNoGood) { - LOGGER.trace("Analyzing conflict caused by adding the (violated) nogood: {}", violatedNoGood); - // Simply compute appropriate backjumping level. - int removingConflict = backjumpLevelRemovingConflict(violatedNoGood); - if (removingConflict < 0) { - return ConflictAnalysisResult.UNSAT; - } - return new ConflictAnalysisResult(null, removingConflict, Collections.emptyList(), LBD_NO_VALUE); - } - - private int backjumpLevelRemovingConflict(Antecedent violatedNoGood) { - int highestDL = 0; - int[] reasonLiterals = violatedNoGood.getReasonLiterals(); - for (int literal : reasonLiterals) { - int literalDL = assignment.getWeakDecisionLevel(atomOf(literal)); - if (literalDL > highestDL) { - highestDL = literalDL; - } - } - return highestDL - 1; - } - - private String reasonsToString(Collection reasons) { - StringBuilder sb = new StringBuilder("{"); - for (int reasonLiteral : reasons) { - sb.append(isPositive(reasonLiteral) ? "+" + atomOf(reasonLiteral) : "-" + atomOf(reasonLiteral)); - sb.append("@"); - sb.append(assignment.getWeakDecisionLevel(atomOf(reasonLiteral))); - sb.append(", "); - } - sb.append("}"); - return sb.toString(); - } - - private String reasonsToString(int[] reasons) { - return reasonsToString(IntStream.of(reasons != null ? reasons : new int[0]).boxed().collect(Collectors.toList())); - } - - private ConflictAnalysisResult analyzeTrailBased(Antecedent conflictReason) { - LOGGER.trace("Analyzing trail based."); - if (assignment.getDecisionLevel() == 0) { - LOGGER.trace("Conflict on decision level 0."); - return ConflictAnalysisResult.UNSAT; - } - int numLiteralsInConflictLevel = 0; - List resolutionLiterals = new ArrayList<>(); - List resolutionAtoms = new ArrayList<>(); - int currentDecisionLevel = assignment.getDecisionLevel(); - Set seenAtoms = new HashSet<>(); // NOTE: other solvers use a global array for seen atoms, this might be slightly faster (initial tests with local arrays showed no significant improvement). - Set processedAtoms = new HashSet<>(); // Since trail contains 2 entries for MBT->TRUE assigned atoms, explicitly record which seen atoms have ben processed to avoid processing seen atoms twice. - int[] currentConflictReason = conflictReason.getReasonLiterals(); - int backjumpLevel = -1; - conflictReason.bumpActivity(); - TrailAssignment.TrailBackwardsWalker trailWalker = ((TrailAssignment)assignment).getTrailBackwardsWalker(); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Current trail is: {}", trailWalker); - LOGGER.trace("Violated nogood is: {}", reasonsToString(conflictReason.getReasonLiterals())); - } - int nextAtom = -1; - do { - // Add current conflict reasons; only add those of lower decision levels, since from current one, only the 1UIP literal will be added. - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Atom {} implied by {}, resolving with that nogood", nextAtom, reasonsToString(currentConflictReason)); - } - for (int literal : currentConflictReason) { - // Seen atoms have already been dealt with. - if (!seenAtoms.contains(atomOf(literal))) { - seenAtoms.add(atomOf(literal)); - int literalDecisionLevel = assignment.getWeakDecisionLevel(atomOf(literal)); - if (literalDecisionLevel == currentDecisionLevel) { - numLiteralsInConflictLevel++; - } else { - resolutionLiterals.add(literal); - if (literalDecisionLevel > backjumpLevel) { - backjumpLevel = literalDecisionLevel; - } - } - resolutionAtoms.add(atomOf(literal)); - } - } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("LiteralsInConflictLevel now: {}", numLiteralsInConflictLevel); - LOGGER.trace("Seen atoms are {}.", seenAtoms); - LOGGER.trace("Intermediate learned literals: {}", reasonsToString(resolutionLiterals)); - } - // Find next literal, i.e. first from top of trail that has been seen but is not yet processed, also skip atoms whose TRUE assignment is on current level but their MBT/weak assignment is lower. - do { - int nextLiteral = trailWalker.getNextLowerLiteral(); - nextAtom = atomOf(nextLiteral); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Next literal on trail is: {}", isPositive(nextLiteral) ? "+" + nextAtom : "-" + nextAtom); - } - } while (assignment.getWeakDecisionLevel(nextAtom) != currentDecisionLevel || !seenAtoms.contains(nextAtom) || processedAtoms.contains(nextAtom)); - Antecedent impliedBy = assignment.getImpliedBy(nextAtom); - if (impliedBy != null) { - currentConflictReason = impliedBy.getReasonLiterals(); - impliedBy.bumpActivity(); - } - processedAtoms.add(nextAtom); - } while (numLiteralsInConflictLevel-- > 1); - // Add the 1UIP literal. - resolutionLiterals.add(atomToLiteral(nextAtom, assignment.getTruth(nextAtom).toBoolean())); - - int[] learnedLiterals = minimizeLearnedLiterals(resolutionLiterals, seenAtoms); - - NoGood learnedNoGood = NoGood.learnt(learnedLiterals); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Learned NoGood is: {}", atomStore.noGoodToString(learnedNoGood)); - } - - int backjumpingDecisionLevel = computeBackjumpingDecisionLevel(learnedNoGood); - if (backjumpingDecisionLevel < 0) { - // Due to out-of-order assigned literals, the learned nogood may be not assigning. - backjumpingDecisionLevel = computeConflictFreeBackjumpingLevel(learnedNoGood); - if (backjumpingDecisionLevel < 0) { - return ConflictAnalysisResult.UNSAT; - } - } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Backjumping decision level: {}", backjumpingDecisionLevel); - } - return new ConflictAnalysisResult(learnedNoGood, backjumpingDecisionLevel, resolutionAtoms, computeLBD(learnedLiterals)); - } - - private int[] minimizeLearnedLiterals(List resolutionLiterals, Set seenAtoms) { - int[] learnedLiterals = new int[resolutionLiterals.size()]; - int i = 0; - // Do local clause minimization: if an implied literal has all its antecedents seen (i.e., in the clause already), it can be removed. - learnedLiteralsLoop: - for (Integer resolutionLiteral : resolutionLiterals) { - if (assignment.getWeakDecisionLevel(atomOf(resolutionLiteral)) == 0) { - // Skip literals from decision level 0. - continue; - } - Antecedent antecedent = assignment.getImpliedBy(atomOf(resolutionLiteral)); - if (antecedent == null) { - // The resolutionLiteral is a decision, keep it. - learnedLiterals[i++] = resolutionLiteral; - } else { - for (int antecedentReasonLiteral : antecedent.getReasonLiterals()) { - // Only add current resolutionLiteral if at least one of its antecedents has not been seen already. - if (!seenAtoms.contains(atomOf(antecedentReasonLiteral))) { - learnedLiterals[i++] = resolutionLiteral; - continue learnedLiteralsLoop; - } - } - } - } - // Shrink array if we did not copy over all literals from resolutionLiterals. - if (i < resolutionLiterals.size()) { - learnedLiterals = Arrays.copyOf(learnedLiterals, i); - } - return learnedLiterals; - } - - private int computeLBD(int[] literals) { - HashSet occurringDecisionLevels = new HashSet<>(); - for (int literal : literals) { - if (!assignment.isAssigned(atomOf(literal))) { - throw oops("Atom is not assigned: " + atomOf(literal)); - } - occurringDecisionLevels.add(assignment.getWeakDecisionLevel(atomOf(literal))); - } - return occurringDecisionLevels.size(); - } - - /** - * Compute the backjumping decision level, i.e., the decision level on which the learned NoGood is assigning (NoGood is unit and propagates). - * This usually is the second highest decision level occurring in the learned NoGood, but due to assignments of MBT no such decision level may exist. - * @param learnedNoGood - * @return -1 if there is no decisionLevel such that backjumping to it makes the learnedNoGood unit. - */ - private int computeBackjumpingDecisionLevel(NoGood learnedNoGood) { - LOGGER.trace("Computing backjumping decision level for {}.", learnedNoGood); - int highestDecisionLevel = -1; - int secondHighestDecisionLevel = -1; - int numLiteralsOfHighestDecisionLevel = -1; - if (learnedNoGood.isUnary()) { - // Singleton NoGoods induce a backjump to the decision level before the NoGood got violated. - int singleLiteralDecisionLevel = assignment.get(atomOf(learnedNoGood.getLiteral(0))).getDecisionLevel(); - if (assignment instanceof TrailAssignment) { - singleLiteralDecisionLevel = Math.min(singleLiteralDecisionLevel, ((TrailAssignment) assignment).getOutOfOrderDecisionLevel(learnedNoGood.getPositiveLiteral(0))); - } - int singleLiteralBackjumpingLevel = singleLiteralDecisionLevel - 1 >= 0 ? singleLiteralDecisionLevel - 1 : 0; - LOGGER.trace("NoGood has only one literal, backjumping to level: {}", singleLiteralBackjumpingLevel); - return singleLiteralBackjumpingLevel; - } - int[] reasonLiterals = learnedNoGood.asAntecedent().getReasonLiterals(); - for (int integer : reasonLiterals) { - int atomDecisionLevel = assignment.getWeakDecisionLevel(atomOf(integer)); - if (assignment instanceof TrailAssignment) { - atomDecisionLevel = Math.min(atomDecisionLevel, ((TrailAssignment) assignment).getOutOfOrderDecisionLevel(atomOf(integer))); - } - if (atomDecisionLevel == highestDecisionLevel) { - numLiteralsOfHighestDecisionLevel++; - } - if (atomDecisionLevel > highestDecisionLevel) { - secondHighestDecisionLevel = highestDecisionLevel; - highestDecisionLevel = atomDecisionLevel; - numLiteralsOfHighestDecisionLevel = 1; - } else { - if (atomDecisionLevel < highestDecisionLevel && atomDecisionLevel > secondHighestDecisionLevel) { - secondHighestDecisionLevel = atomDecisionLevel; - } - } - } - if (numLiteralsOfHighestDecisionLevel != 1) { - LOGGER.trace("NoGood contains not just one literal in the second-highest decision level. Backjumping decision level is -1."); - return -1; - } - LOGGER.trace("Backjumping decision level is: {}", secondHighestDecisionLevel); - return secondHighestDecisionLevel; - } -} diff --git a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java b/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java deleted file mode 100644 index 66f870674..000000000 --- a/core/src/main/java/at/ac/tuwien/kr/alpha/solver/learning/ResolutionSequence.java +++ /dev/null @@ -1,7 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver.learning; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public class ResolutionSequence { -} From e75f6946c76190afccb3123213d71bef04cde94b Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 29 Jan 2021 01:35:46 +0100 Subject: [PATCH 015/111] globally use interface types for API constructs --- .../kr/alpha/api/grounder/Substitution.java | 16 ++ .../ac/tuwien/kr/alpha/api/program/Atom.java | 10 + .../alpha/api/program/InlineDirectives.java | 14 ++ .../kr/alpha/api/program/InputProgram.java | 20 -- .../tuwien/kr/alpha/api/program/Literal.java | 13 +- .../kr/alpha/api/program/Predicate.java | 4 + .../tuwien/kr/alpha/api/rules/ChoiceHead.java | 22 ++- .../tuwien/kr/alpha/api/rules/NormalHead.java | 6 + .../at/ac/tuwien/kr/alpha/api/terms/Term.java | 31 ++- .../kr/alpha/api/terms/VariableTerm.java | 2 +- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 4 +- .../kr/alpha/core/atoms/AggregateAtom.java | 56 +++--- .../kr/alpha/core/atoms/AggregateLiteral.java | 16 +- .../tuwien/kr/alpha/core/atoms/BasicAtom.java | 28 +-- .../kr/alpha/core/atoms/BasicLiteral.java | 28 +-- .../kr/alpha/core/atoms/ChoiceAtom.java | 24 +-- .../kr/alpha/core/atoms/ComparisonAtom.java | 26 +-- .../alpha/core/atoms/ComparisonLiteral.java | 54 ++--- .../tuwien/kr/alpha/core/atoms/CoreAtom.java | 39 ++-- .../kr/alpha/core/atoms/CoreLiteral.java | 40 ++-- .../kr/alpha/core/atoms/EnumerationAtom.java | 22 ++- .../alpha/core/atoms/EnumerationLiteral.java | 19 +- .../kr/alpha/core/atoms/ExternalAtom.java | 38 ++-- .../kr/alpha/core/atoms/ExternalLiteral.java | 77 ++++---- .../atoms/FixedInterpretationLiteral.java | 5 +- .../kr/alpha/core/atoms/IntervalAtom.java | 21 +- .../kr/alpha/core/atoms/IntervalLiteral.java | 33 ++-- .../tuwien/kr/alpha/core/atoms/RuleAtom.java | 20 +- .../core/atoms/VariableNormalizableAtom.java | 4 +- .../alpha/core/common/AnswerSetBuilder.java | 26 +-- .../kr/alpha/core/common/AtomStore.java | 10 +- .../kr/alpha/core/common/AtomStoreImpl.java | 15 +- .../kr/alpha/core/common/BasicAnswerSet.java | 27 +-- .../kr/alpha/core/common/CoreAnswerSet.java | 7 +- .../core/common/SimpleAnswerSetFormatter.java | 7 +- .../core/common/terms/ArithmeticTerm.java | 65 +++--- .../core/common/terms/CoreConstantTerm.java | 24 ++- .../kr/alpha/core/common/terms/CoreTerm.java | 39 ++-- .../alpha/core/common/terms/FunctionTerm.java | 53 ++--- .../alpha/core/common/terms/IntervalTerm.java | 40 ++-- .../kr/alpha/core/common/terms/Terms.java | 17 +- .../core/common/terms/VariableTermImpl.java | 20 +- .../alpha/core/depgraph/DependencyGraph.java | 40 ++-- .../tuwien/kr/alpha/core/depgraph/Node.java | 8 +- .../core/grounder/FactIntervalEvaluator.java | 24 +-- .../core/grounder/IndexedInstanceStorage.java | 30 +-- .../kr/alpha/core/grounder/Instance.java | 12 +- .../kr/alpha/core/grounder/NaiveGrounder.java | 142 ++++++------- .../alpha/core/grounder/NoGoodGenerator.java | 25 +-- .../grounder/ProgramAnalyzingGrounder.java | 8 +- .../core/grounder/RuleGroundingOrder.java | 12 +- .../core/grounder/RuleGroundingOrders.java | 61 +++--- ...ubstitution.java => SubstitutionImpl.java} | 88 +++++---- .../kr/alpha/core/grounder/Unification.java | 35 ++-- .../kr/alpha/core/grounder/Unifier.java | 54 ++--- .../kr/alpha/core/grounder/WorkingMemory.java | 24 +-- .../AbstractLiteralInstantiationStrategy.java | 38 ++-- .../grounder/instantiation/BindingResult.java | 2 +- ...ultLazyGroundingInstantiationStrategy.java | 21 +- .../LiteralInstantiationResult.java | 6 +- .../LiteralInstantiationStrategy.java | 17 +- .../instantiation/LiteralInstantiator.java | 28 +-- ...rkingMemoryBasedInstantiationStrategy.java | 10 +- .../structure/AnalyzeUnjustified.java | 113 ++++++----- .../alpha/core/grounder/structure/LitSet.java | 20 +- .../core/parser/InlineDirectivesImpl.java | 12 +- .../alpha/core/parser/ParseTreeVisitor.java | 187 +++++++++--------- .../alpha/core/programs/AbstractProgram.java | 39 ++-- .../alpha/core/programs/AnalyzedProgram.java | 6 +- .../kr/alpha/core/programs/InputProgram.java | 117 +++++++++++ .../alpha/core/programs/InputProgramImpl.java | 183 ----------------- .../alpha/core/programs/InternalProgram.java | 28 +-- .../kr/alpha/core/programs/NormalProgram.java | 8 +- .../kr/alpha/core/programs/Programs.java | 6 +- .../CardinalityNormalization.java | 52 ++--- .../transformation/ChoiceHeadToNormal.java | 46 ++--- .../transformation/EnumerationRewriting.java | 25 +-- .../IntervalTermToIntervalAtom.java | 34 ++-- .../NormalizeProgramTransformation.java | 8 +- .../transformation/PredicateInternalizer.java | 22 ++- .../transformation/StratifiedEvaluation.java | 51 ++--- .../transformation/SumNormalization.java | 40 ++-- .../VariableEqualityRemoval.java | 49 ++--- .../kr/alpha/core/rules/AbstractRule.java | 22 +-- .../tuwien/kr/alpha/core/rules/BasicRule.java | 6 +- .../kr/alpha/core/rules/InternalRule.java | 30 +-- .../kr/alpha/core/rules/NormalRule.java | 17 +- .../tuwien/kr/alpha/core/rules/RuleImpl.java | 129 ++++++++++++ .../ac/tuwien/kr/alpha/core/rules/Rules.java | 21 +- .../core/rules/heads/ChoiceHeadImpl.java | 38 ++-- ...tiveHead.java => DisjunctiveHeadImpl.java} | 15 +- .../rules/heads/{Head.java => HeadImpl.java} | 2 +- .../core/rules/heads/NormalHeadImpl.java | 10 +- .../kr/alpha/core/solver/AtomCounter.java | 9 +- .../kr/alpha/core/solver/DefaultSolver.java | 22 +-- 95 files changed, 1706 insertions(+), 1388 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java delete mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/{Substitution.java => SubstitutionImpl.java} (70%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/{DisjunctiveHead.java => DisjunctiveHeadImpl.java} (73%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/{Head.java => HeadImpl.java} (92%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java new file mode 100644 index 000000000..faafc3660 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java @@ -0,0 +1,16 @@ +package at.ac.tuwien.kr.alpha.api.grounder; + +import java.util.TreeMap; + +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; + +public interface Substitution { + + Term eval(VariableTerm variableTerm); + + TreeMap getSubstitution(); + + > Term put(VariableTerm variableTerm, Term groundTerm); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java index e7e0a283d..4cd81c93e 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java @@ -1,7 +1,9 @@ package at.ac.tuwien.kr.alpha.api.program; import java.util.List; +import java.util.Set; +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.terms.VariableTerm; @@ -26,4 +28,12 @@ public interface Atom extends Comparable { * @return a literal that is positive iff the given parameter is true. */ Literal toLiteral(boolean positive); + + Set getOccurringVariables(); + + Atom substitute(Substitution substitution); + + Atom renameVariables(String newVariablePrefix); + + Atom withTerms(List terms); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java index fc17bc531..985b9bb4e 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java @@ -1,5 +1,19 @@ package at.ac.tuwien.kr.alpha.api.program; +import java.util.Map; + public interface InlineDirectives { + public enum DIRECTIVE { + enum_predicate_is + } + + void accumulate(InlineDirectives other); + + Map getDirectives(); + + void addDirective(DIRECTIVE directive, String text); + + String getDirectiveValue(DIRECTIVE directive); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java deleted file mode 100644 index 68a5f2d24..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InputProgram.java +++ /dev/null @@ -1,20 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.program; - -import java.util.Set; - -import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; -import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; -import at.ac.tuwien.kr.alpha.api.rules.NormalHead; -import at.ac.tuwien.kr.alpha.api.rules.Rule; - -public interface InputProgram extends Program{ - - InlineDirectives getInlineDirectives(); - - Set> getChoiceRules(); - - Set> getDisjunctiveRules(); - - Set> getNormalRules(); - -} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java index c095a50f8..4a6c81e3a 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java @@ -1,8 +1,11 @@ package at.ac.tuwien.kr.alpha.api.program; import java.util.List; +import java.util.Set; +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.terms.VariableTerm; public interface Literal { Atom getAtom(); @@ -13,7 +16,15 @@ public interface Literal { Predicate getPredicate(); - List getTerms(); + List getTerms(); + + Set getOccurringVariables(); boolean isGround(); + + Set getBindingVariables(); + + Set getNonBindingVariables(); + + Literal substitute(Substitution substitution); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java index 085259bd3..9ddc0695f 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java @@ -15,4 +15,8 @@ default int compareTo(Predicate other) { return Integer.compare(getArity(), other.getArity()); } + + boolean isInternal(); + + boolean isSolverInternal(); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java index 893295604..3e68c1704 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java @@ -1,5 +1,25 @@ package at.ac.tuwien.kr.alpha.api.rules; -public interface ChoiceHead extends Head{ +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; + +public interface ChoiceHead extends Head { + + Term getLowerBound(); + + Term getUpperBound(); + + List getChoiceElements(); + + public static interface ChoiceElement { + + Atom getChoiceAtom(); + + List getConditionLiterals(); + + } } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java index ed4d33679..d0c741941 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java @@ -1,5 +1,11 @@ package at.ac.tuwien.kr.alpha.api.rules; +import at.ac.tuwien.kr.alpha.api.program.Atom; + public interface NormalHead extends Head{ + Atom getAtom(); + + boolean isGround(); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/Term.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/Term.java index 5c95dfe6d..112ac5ed8 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/Term.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/Term.java @@ -1,7 +1,34 @@ package at.ac.tuwien.kr.alpha.api.terms; +import java.util.Map; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; + public interface Term extends Comparable { - + boolean isGround(); - + + Set getOccurringVariables(); + + Term substitute(Substitution substitution); + + /** + * Rename all variables occurring in this Term by prefixing their name. + * + * @param renamePrefix the name to prefix all occurring variables. + * @return the term with all variables renamed. + */ + Term renameVariables(String renamePrefix); + + Term normalizeVariables(String renamePrefix, RenameCounter counter); + + public static interface RenameCounter { + + Map getRenamedVariables(); + + int getAndIncrement(); + + } + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java index 78eab1ea4..e5a28d53f 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/VariableTerm.java @@ -1,5 +1,5 @@ package at.ac.tuwien.kr.alpha.api.terms; -public interface VariableTerm { +public interface VariableTerm extends Term{ } 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 f2e2ae8fb..a943c0588 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 @@ -47,6 +47,7 @@ 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.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.program.InputProgram; import at.ac.tuwien.kr.alpha.app.ComponentGraphWriter; import at.ac.tuwien.kr.alpha.app.DependencyGraphWriter; import at.ac.tuwien.kr.alpha.config.CommandLineParser; @@ -56,7 +57,6 @@ import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -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.NormalProgram; import at.ac.tuwien.kr.alpha.core.solver.Solver; @@ -83,7 +83,7 @@ public static void main(String[] args) { Alpha alpha = new AlphaImpl(cfg.getSystemConfig()); - InputProgramImpl program = null; + InputProgram program = null; try { program = alpha.readProgram(cfg.getInputConfig()); } catch (RecognitionException e) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index 5f70e3fc1..ef195b9f1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -34,22 +34,26 @@ import java.util.LinkedList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; public class AggregateAtom extends CoreAtom { private final ComparisonOperator lowerBoundOperator; - private final CoreTerm lowerBoundTerm; + private final Term lowerBoundTerm; private final ComparisonOperator upperBoundOperator; - private final CoreTerm upperBoundTerm; + private final Term upperBoundTerm; private final AGGREGATEFUNCTION aggregatefunction; private final List aggregateElements; - public AggregateAtom(ComparisonOperator lowerBoundOperator, CoreTerm lowerBoundTerm, ComparisonOperator upperBoundOperator, CoreTerm upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { + public AggregateAtom(ComparisonOperator lowerBoundOperator, Term lowerBoundTerm, ComparisonOperator upperBoundOperator, Term upperBoundTerm, + AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { this.lowerBoundOperator = lowerBoundOperator; this.lowerBoundTerm = lowerBoundTerm; this.upperBoundOperator = upperBoundOperator; @@ -69,28 +73,27 @@ public boolean isGround() { } } if (lowerBoundTerm != null && !lowerBoundTerm.isGround() - || upperBoundTerm != null && !upperBoundTerm.isGround()) { + || upperBoundTerm != null && !upperBoundTerm.isGround()) { return false; } return true; } - @Override public AggregateLiteral toLiteral(boolean positive) { return new AggregateLiteral(this, positive); } @Override - public List getTerms() { + public List getTerms() { throw oops("Aggregate atom cannot report terms."); } @Override - public CoreAtom withTerms(List terms) { + public Atom withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for aggregate atoms!"); } - + @Override public CorePredicate getPredicate() { throw oops("Aggregate atom cannot report predicate."); @@ -98,10 +101,11 @@ public CorePredicate getPredicate() { /** * Returns all variables occurring inside the aggregate, between { ... }. + * * @return each variable occurring in some aggregate element. */ - public List getAggregateVariables() { - List occurringVariables = new LinkedList<>(); + public List getAggregateVariables() { + List occurringVariables = new LinkedList<>(); for (AggregateElement aggregateElement : aggregateElements) { occurringVariables.addAll(aggregateElement.getOccurringVariables()); } @@ -164,7 +168,7 @@ public ComparisonOperator getLowerBoundOperator() { return lowerBoundOperator; } - public CoreTerm getLowerBoundTerm() { + public Term getLowerBoundTerm() { return lowerBoundTerm; } @@ -172,7 +176,7 @@ public ComparisonOperator getUpperBoundOperator() { return upperBoundOperator; } - public CoreTerm getUpperBoundTerm() { + public Term getUpperBoundTerm() { return upperBoundTerm; } @@ -192,29 +196,29 @@ public enum AGGREGATEFUNCTION { } public static class AggregateElement { - final List elementTerms; - final List elementLiterals; + final List elementTerms; + final List elementLiterals; - public AggregateElement(List elementTerms, List elementLiterals) { + public AggregateElement(List elementTerms, List elementLiterals) { this.elementTerms = elementTerms; this.elementLiterals = elementLiterals; } - public List getElementTerms() { + public List getElementTerms() { return elementTerms; } - public List getElementLiterals() { + public List getElementLiterals() { return elementLiterals; } public boolean isGround() { - for (CoreTerm elementTerm : elementTerms) { + for (Term elementTerm : elementTerms) { if (!elementTerm.isGround()) { return false; } } - for (CoreLiteral elementLiteral : elementLiterals) { + for (Literal elementLiteral : elementLiterals) { if (!elementLiteral.isGround()) { return false; } @@ -222,14 +226,14 @@ public boolean isGround() { return true; } - public List getOccurringVariables() { - List occurringVariables = new LinkedList<>(); - for (CoreTerm term : elementTerms) { + public List getOccurringVariables() { + List occurringVariables = new LinkedList<>(); + for (Term term : elementTerms) { if (term instanceof VariableTermImpl) { occurringVariables.add((VariableTermImpl) term); } } - for (CoreLiteral literal : elementLiterals) { + for (Literal literal : elementLiterals) { occurringVariables.addAll(literal.getBindingVariables()); occurringVariables.addAll(literal.getNonBindingVariables()); } @@ -265,5 +269,5 @@ public String toString() { return join("", elementTerms, " : ") + join("", elementLiterals, ""); } } - + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index f91d9a383..19166fb46 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -3,10 +3,12 @@ import java.util.HashSet; import java.util.Set; +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.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Copyright (c) 2018, the Alpha Team. @@ -27,7 +29,7 @@ public AggregateLiteral negate() { } /** - * @see CoreAtom#substitute(Substitution) + * @see CoreAtom#substitute(SubstitutionImpl) */ @Override public AggregateLiteral substitute(Substitution substitution) { @@ -35,8 +37,8 @@ public AggregateLiteral substitute(Substitution substitution) { } @Override - public Set getBindingVariables() { - Set bindingVariables = new HashSet<>(); + public Set getBindingVariables() { + Set bindingVariables = new HashSet<>(); if (boundBindingVariable(getAtom().getLowerBoundOperator(), getAtom().getLowerBoundTerm(), positive) != null) { bindingVariables.add((VariableTermImpl) getAtom().getLowerBoundTerm()); } @@ -47,13 +49,13 @@ public Set getBindingVariables() { } @Override - public Set getNonBindingVariables() { + public Set getNonBindingVariables() { // Note: every local variable that also occurs globally in the rule is a nonBindingVariable, hence an // aggregate literal alone cannot detect its non-binding (i.e. global) variables. throw new UnsupportedOperationException(); } - private static VariableTermImpl boundBindingVariable(ComparisonOperator op, CoreTerm bound, boolean positive) { + private static VariableTerm boundBindingVariable(ComparisonOperator op, Term bound, boolean positive) { boolean isNormalizedEquality = op == ComparisonOperator.EQ && positive || op == ComparisonOperator.NE && !positive; if (isNormalizedEquality && bound instanceof VariableTermImpl) { return (VariableTermImpl) bound; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java index 5587ab9e0..45c512f4d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java @@ -34,16 +34,20 @@ import java.util.List; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** * Represents ordinary ASP atoms. */ public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { - private final CorePredicate predicate; - private final List terms; + private final Predicate predicate; + private final List terms; private final boolean ground; /** @@ -52,12 +56,12 @@ public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { * @param predicate * @param terms */ - public BasicAtom(CorePredicate predicate, List terms) { + public BasicAtom(Predicate predicate, List terms) { this.predicate = predicate; this.terms = terms; boolean ground = true; - for (CoreTerm term : terms) { + for (Term term : terms) { if (!term.isGround()) { ground = false; break; @@ -67,21 +71,21 @@ public BasicAtom(CorePredicate predicate, List terms) { this.ground = ground; } - public BasicAtom(CorePredicate predicate, CoreTerm... terms) { + public BasicAtom(Predicate predicate, Term... terms) { this(predicate, Arrays.asList(terms)); } - public BasicAtom(CorePredicate predicate) { + public BasicAtom(Predicate predicate) { this(predicate, Collections.emptyList()); } @Override - public CorePredicate getPredicate() { + public Predicate getPredicate() { return predicate; } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -99,7 +103,7 @@ public BasicAtom substitute(Substitution substitution) { @Override public BasicAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = Terms.renameTerms(terms, prefix, counterStartingValue); return new BasicAtom(predicate, renamedTerms); } @@ -119,7 +123,7 @@ public String toString() { } @Override - public int compareTo(CoreAtom o) { + public int compareTo(Atom o) { if (this.terms.size() != o.getTerms().size()) { return this.terms.size() - o.getTerms().size(); } @@ -160,7 +164,7 @@ public int hashCode() { } @Override - public CoreAtom withTerms(List terms) { + public Atom withTerms(List terms) { return new BasicAtom(predicate, terms); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java index 6559fcd59..68b2b706e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java @@ -27,15 +27,16 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; - import java.util.Collections; import java.util.HashSet; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; + /** * Contains a potentially negated {@link BasicAtom}. * @@ -61,7 +62,7 @@ public BasicLiteral negate() { } /** - * @see CoreAtom#substitute(Substitution) + * @see CoreAtom#substitute(SubstitutionImpl) */ @Override public BasicLiteral substitute(Substitution substitution) { @@ -74,31 +75,32 @@ public BasicLiteral substitute(Substitution substitution) { * @return */ @Override - public Set getBindingVariables() { + public Set getBindingVariables() { if (!positive) { // Negative literal has no binding variables. return Collections.emptySet(); } - Set bindingVariables = new HashSet<>(); - for (CoreTerm term : atom.getTerms()) { + Set bindingVariables = new HashSet<>(); + for (Term term : atom.getTerms()) { bindingVariables.addAll(term.getOccurringVariables()); } return bindingVariables; } /** - * Set of all variables occurring in the Atom that are never binding, not even in positive atoms, e.g., variables in intervals or built-in atoms. + * Set of all variables occurring in the Atom that are never binding, not even in positive atoms, e.g., variables in intervals or built-in + * atoms. * * @return */ @Override - public Set getNonBindingVariables() { + public Set getNonBindingVariables() { if (positive) { // Positive literal has only binding variables. return Collections.emptySet(); } - Set nonbindingVariables = new HashSet<>(); - for (CoreTerm term : atom.getTerms()) { + Set nonbindingVariables = new HashSet<>(); + for (Term term : atom.getTerms()) { nonbindingVariables.addAll(term.getOccurringVariables()); } return nonbindingVariables; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java index dd8a2cb60..b8df895cb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java @@ -32,25 +32,27 @@ import java.util.Collections; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; public class ChoiceAtom extends CoreAtom { - public static final CorePredicate ON = CorePredicate.getInstance("ChoiceOn", 1, true, true); - public static final CorePredicate OFF = CorePredicate.getInstance("ChoiceOff", 1, true, true); + public static final Predicate ON = CorePredicate.getInstance("ChoiceOn", 1, true, true); + public static final Predicate OFF = CorePredicate.getInstance("ChoiceOff", 1, true, true); - private final CorePredicate predicate; - private final List terms; + private final Predicate predicate; + private final List terms; - private ChoiceAtom(CorePredicate predicate, CoreTerm term) { + private ChoiceAtom(Predicate predicate, Term term) { this.predicate = predicate; this.terms = Collections.singletonList(term); } - private ChoiceAtom(CorePredicate predicate, int id) { + private ChoiceAtom(Predicate predicate, int id) { this(predicate, CoreConstantTerm.getInstance(Integer.toString(id))); } @@ -63,12 +65,12 @@ public static ChoiceAtom off(int id) { } @Override - public CorePredicate getPredicate() { + public Predicate getPredicate() { return predicate; } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -94,7 +96,7 @@ public String toString() { } @Override - public CoreAtom withTerms(List terms) { + public Atom withTerms(List terms) { throw new UnsupportedOperationException("Changing terms is not supported for ChoiceAtoms!"); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java index 229dfac0b..c29d36267 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java @@ -31,36 +31,38 @@ import java.util.List; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** * Represents a builtin comparison atom according to the standard. */ public class ComparisonAtom extends CoreAtom implements VariableNormalizableAtom { - private final CorePredicate predicate; + private final Predicate predicate; final ComparisonOperator operator; - private final List terms; + private final List terms; - private ComparisonAtom(List terms, ComparisonOperator operator) { + private ComparisonAtom(List terms, ComparisonOperator operator) { this.terms = terms; this.operator = operator; this.predicate = operator.predicate(); } - public ComparisonAtom(CoreTerm term1, CoreTerm term2, ComparisonOperator operator) { + public ComparisonAtom(Term term1, Term term2, ComparisonOperator operator) { this(Arrays.asList(term1, term2), operator); } @Override - public CorePredicate getPredicate() { + public Predicate getPredicate() { return predicate; } @Override - public List getTerms() { + public List getTerms() { return terms; } @@ -71,7 +73,7 @@ public boolean isGround() { @Override public ComparisonAtom substitute(Substitution substitution) { - List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); + List substitutedTerms = getTerms().stream().map(t -> t.substitute(substitution)).collect(Collectors.toList()); return new ComparisonAtom(substitutedTerms, operator); } @@ -115,12 +117,12 @@ public int hashCode() { @Override public ComparisonAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = Terms.renameTerms(terms, prefix, counterStartingValue); return new ComparisonAtom(renamedTerms.get(0), renamedTerms.get(1), operator); } @Override - public CoreAtom withTerms(List terms) { + public Atom withTerms(List terms) { return new ComparisonAtom(terms, operator); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index 04d00e921..f8e1460cd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -35,13 +35,15 @@ import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Contains a potentially negated {@link ComparisonAtom}. @@ -74,21 +76,21 @@ public ComparisonLiteral negate() { } /** - * @see CoreAtom#substitute(Substitution) + * @see CoreAtom#substitute(SubstitutionImpl) */ @Override public ComparisonLiteral substitute(Substitution substitution) { return new ComparisonLiteral(getAtom().substitute(substitution), positive); } - private boolean assignable(CoreTerm term) { + private boolean assignable(Term term) { return isNormalizedEquality && term instanceof VariableTermImpl; } @Override - public Set getBindingVariables() { - final CoreTerm left = getTerms().get(0); - final CoreTerm right = getTerms().get(1); + public Set getBindingVariables() { + final Term left = getTerms().get(0); + final Term right = getTerms().get(1); if (assignable(left) && assignable(right)) { // In case this is "X = Y" or "not X != Y" then both sides are binding given that the other is. // In this case non-binding and binding variables cannot be reported accurately, in fact, the double variable could be compiled away. @@ -104,12 +106,12 @@ public Set getBindingVariables() { } @Override - public Set getNonBindingVariables() { - final CoreTerm left = getTerms().get(0); - final CoreTerm right = getTerms().get(1); - HashSet occurringVariables = new HashSet<>(); - List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); - List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); + public Set getNonBindingVariables() { + final Term left = getTerms().get(0); + final Term right = getTerms().get(1); + HashSet occurringVariables = new HashSet<>(); + List leftOccurringVariables = new LinkedList<>(left.getOccurringVariables()); + List rightOccurringVariables = new LinkedList<>(right.getOccurringVariables()); if (assignable(left)) { leftOccurringVariables.remove(left); } @@ -128,17 +130,17 @@ public Set getNonBindingVariables() { @Override public List getSatisfyingSubstitutions(Substitution partialSubstitution) { // Treat case where this is just comparison with all variables bound by partialSubstitution. - final CoreTerm left = getAtom().getTerms().get(0).substitute(partialSubstitution); - final CoreTerm right = getAtom().getTerms().get(1).substitute(partialSubstitution); + final Term left = getAtom().getTerms().get(0).substitute(partialSubstitution); + final Term right = getAtom().getTerms().get(1).substitute(partialSubstitution); final boolean leftAssigning = assignable(left); final boolean rightAssigning = assignable(right); if (!leftAssigning && !rightAssigning) { // No assignment (variables are bound by partialSubstitution), thus evaluate comparison only. - CoreTerm leftEvaluatedSubstitute = evaluateTerm(left); + Term leftEvaluatedSubstitute = evaluateTerm(left); if (leftEvaluatedSubstitute == null) { return Collections.emptyList(); } - CoreTerm rightEvaluatedSubstitute = evaluateTerm(right); + Term rightEvaluatedSubstitute = evaluateTerm(right); if (rightEvaluatedSubstitute == null) { return Collections.emptyList(); } @@ -149,8 +151,8 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit } } // Treat case that this is X = t or t = X. - VariableTermImpl variable = null; - CoreTerm expression = null; + VariableTerm variable = null; + Term expression = null; if (leftAssigning) { variable = (VariableTermImpl) left; expression = right; @@ -159,8 +161,8 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit variable = (VariableTermImpl) right; expression = left; } - CoreTerm groundTerm = expression.substitute(partialSubstitution); - CoreTerm resultTerm = null; + Term groundTerm = expression.substitute(partialSubstitution); + Term resultTerm = null; // Check if the groundTerm is an arithmetic expression and evaluate it if so. if (groundTerm instanceof ArithmeticTerm) { Integer result = evaluateGroundTerm(groundTerm); @@ -172,18 +174,18 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit // Ground term is another term (constant, or function term). resultTerm = groundTerm; } - Substitution extendedSubstitution = new Substitution(partialSubstitution); + SubstitutionImpl extendedSubstitution = new SubstitutionImpl(partialSubstitution); extendedSubstitution.put(variable, resultTerm); return Collections.singletonList(extendedSubstitution); } public boolean isLeftOrRightAssigning() { - final CoreTerm left = getTerms().get(0); - final CoreTerm right = getTerms().get(1); + final Term left = getTerms().get(0); + final Term right = getTerms().get(1); return isNormalizedEquality && (assignable(left) && right.isGround() || assignable(right) && left.isGround()); } - private CoreTerm evaluateTerm(CoreTerm term) { + private Term evaluateTerm(Term term) { // Evaluate arithmetics. if (term instanceof ArithmeticTerm) { Integer result = ArithmeticTerm.evaluateGroundTerm(term); @@ -195,7 +197,7 @@ private CoreTerm evaluateTerm(CoreTerm term) { return term; } - private boolean compare(CoreTerm x, CoreTerm y) { + private boolean compare(Term x, Term y) { final int comparisonResult = x.compareTo(y); ComparisonOperator operator = isNegated() ? getAtom().operator.getNegation() : getAtom().operator; switch (operator) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index 2ad6c4221..1b353ecaf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -30,17 +30,19 @@ import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; /** * An Atom is the common superclass of all representations of ASP atoms used by Alpha. */ -public abstract class CoreAtom implements Atom, Comparable { +public abstract class CoreAtom implements Atom { /** * Creates a new Atom that represents this Atom, but has the given term list instead. @@ -48,12 +50,12 @@ public abstract class CoreAtom implements Atom, Comparable { * @param terms the terms to set. * @return a new Atom with the given terms set. */ - public abstract CoreAtom withTerms(List terms); + public abstract Atom withTerms(List terms); /** * Returns the set of all variables occurring in the Atom. */ - public Set getOccurringVariables() { + public Set getOccurringVariables() { return toLiteral().getOccurringVariables(); } @@ -64,45 +66,50 @@ public Set getOccurringVariables() { * @param substitution the variable substitution to apply. * @return the atom resulting from the application of the substitution. */ - public abstract CoreAtom substitute(Substitution substitution); + public abstract Atom substitute(Substitution substitution); - public abstract List getTerms(); + @Override + public abstract List getTerms(); - public abstract CorePredicate getPredicate(); + @Override + public abstract Predicate getPredicate(); /** * Returns whether this atom is ground, i.e., variable-free. * * @return true iff the terms of this atom contain no {@link VariableTermImpl}. */ + @Override public abstract boolean isGround(); /** * Creates a non-negated literal containing this atom. */ - public CoreLiteral toLiteral() { + @Override + public Literal toLiteral() { return toLiteral(true); } - public abstract CoreLiteral toLiteral(boolean positive); + @Override + public abstract Literal toLiteral(boolean positive); - public CoreAtom renameVariables(String newVariablePrefix) { + public Atom renameVariables(String newVariablePrefix) { Unifier renamingSubstitution = new Unifier(); int counter = 0; - for (VariableTermImpl variable : getOccurringVariables()) { + for (VariableTerm variable : getOccurringVariables()) { renamingSubstitution.put(variable, VariableTermImpl.getInstance(newVariablePrefix + counter++)); } return this.substitute(renamingSubstitution); } @Override - public int compareTo(CoreAtom o) { + public int compareTo(Atom o) { if (o == null) { return 1; } - final List aTerms = this.getTerms(); - final List bTerms = o.getTerms(); + final List aTerms = this.getTerms(); + final List bTerms = o.getTerms(); if (aTerms.size() != bTerms.size()) { return Integer.compare(aTerms.size(), bTerms.size()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java index 10be39e43..947f98926 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java @@ -32,11 +32,12 @@ import org.apache.commons.collections4.SetUtils; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; /** * A potentially negated {@link CoreAtom} @@ -45,54 +46,61 @@ */ public abstract class CoreLiteral implements Literal { - protected final CoreAtom atom; + protected final Atom atom; protected final boolean positive; - public CoreLiteral(CoreAtom atom, boolean positive) { + public CoreLiteral(Atom atom, boolean positive) { this.atom = atom; this.positive = positive; } - public CoreAtom getAtom() { + @Override + public Atom getAtom() { return atom; } + @Override public boolean isNegated() { return !positive; } - public abstract CoreLiteral negate(); + @Override + public abstract Literal negate(); - public abstract CoreLiteral substitute(Substitution substitution); + public abstract Literal substitute(Substitution substitution); - public abstract Set getBindingVariables(); + public abstract Set getBindingVariables(); - public abstract Set getNonBindingVariables(); + public abstract Set getNonBindingVariables(); /** * Union of {@link #getBindingVariables()} and {@link #getNonBindingVariables()} */ - public Set getOccurringVariables() { + @Override + public Set getOccurringVariables() { return SetUtils.union(getBindingVariables(), getNonBindingVariables()); } /** * @see CoreAtom#getPredicate() */ - public CorePredicate getPredicate() { + @Override + public Predicate getPredicate() { return atom.getPredicate(); } /** * @see CoreAtom#getTerms() */ - public List getTerms() { + @Override + public List getTerms() { return atom.getTerms(); } /** * @see CoreAtom#isGround() */ + @Override public boolean isGround() { return atom.isGround(); } @@ -111,9 +119,9 @@ public boolean equals(Object o) { return false; } - CoreLiteral that = (CoreLiteral) o; + Literal that = (Literal) o; - return atom.equals(that.atom) && positive == that.positive; + return atom.equals(that.getAtom()) && positive == !that.isNegated(); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 5289a65fc..6cab45522 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -5,11 +5,13 @@ import java.util.HashMap; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Represents a ground-instance enumeration atom of form: @@ -23,10 +25,10 @@ * Copyright (c) 2017, the Alpha Team. */ public class EnumerationAtom extends BasicAtom { - public static final CorePredicate ENUMERATION_PREDICATE = CorePredicate.getInstance("_Enumeration", 3); - private static final HashMap> ENUMERATIONS = new HashMap<>(); + public static final Predicate ENUMERATION_PREDICATE = CorePredicate.getInstance("_Enumeration", 3); + private static final HashMap> ENUMERATIONS = new HashMap<>(); - public EnumerationAtom(List terms) { + public EnumerationAtom(List terms) { super(ENUMERATION_PREDICATE, terms); if (terms.size() != 3) { throw new RuntimeException("EnumerationAtom must have arity three. Given terms are of wrong size: " + terms); @@ -40,9 +42,9 @@ public static void resetEnumerations() { ENUMERATIONS.clear(); } - private Integer getEnumerationIndex(CoreTerm identifier, CoreTerm enumerationTerm) { + private Integer getEnumerationIndex(Term identifier, Term enumerationTerm) { ENUMERATIONS.putIfAbsent(identifier, new HashMap<>()); - HashMap enumeratedTerms = ENUMERATIONS.get(identifier); + HashMap enumeratedTerms = ENUMERATIONS.get(identifier); Integer assignedInteger = enumeratedTerms.get(enumerationTerm); if (assignedInteger == null) { int enumerationIndex = enumeratedTerms.size() + 1; @@ -63,13 +65,13 @@ private Integer getEnumerationIndex(CoreTerm identifier, CoreTerm enumerationTer * @return a new substitution where the third term of the enumeration atom is bound to an integer. */ public Substitution addEnumerationIndexToSubstitution(Substitution substitution) { - CoreTerm idTerm = this.getTerms().get(0).substitute(substitution); - CoreTerm enumerationTerm = this.getTerms().get(1).substitute(substitution); + Term idTerm = this.getTerms().get(0).substitute(substitution); + Term enumerationTerm = this.getTerms().get(1).substitute(substitution); if (!enumerationTerm.isGround()) { throw new RuntimeException("Enumeration term is not ground after substitution. Should not happen."); } Integer enumerationIndex = getEnumerationIndex(idTerm, enumerationTerm); - Substitution retVal = new Substitution(substitution); + SubstitutionImpl retVal = new SubstitutionImpl(substitution); retVal.put((VariableTermImpl) getTerms().get(2), CoreConstantTerm.getInstance(enumerationIndex)); return retVal; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java index 16ad53420..f36577640 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java @@ -4,9 +4,10 @@ import java.util.HashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +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.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Copyright (c) 2018, the Alpha Team. @@ -33,19 +34,19 @@ public EnumerationLiteral substitute(Substitution substitution) { } @Override - public Set getBindingVariables() { + public Set getBindingVariables() { return Collections.singleton((VariableTermImpl)getTerms().get(2)); } @Override - public Set getNonBindingVariables() { - Set ret = new HashSet<>(2); - CoreTerm idTerm = getTerms().get(0); - CoreTerm enumTerm = getTerms().get(1); - if (idTerm instanceof VariableTermImpl) { + public Set getNonBindingVariables() { + Set ret = new HashSet<>(2); + Term idTerm = getTerms().get(0); + Term enumTerm = getTerms().get(1); + if (idTerm instanceof VariableTerm) { ret.add((VariableTermImpl) idTerm); } - if (enumTerm instanceof VariableTermImpl) { + if (enumTerm instanceof VariableTerm) { ret.add((VariableTermImpl) enumTerm); } return ret; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index 718ab820c..1eaaf3151 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -34,19 +34,21 @@ import java.util.stream.Collectors; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.common.terms.Terms; public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { - private final List input; - private final List output; + private final List input; + private final List output; - protected final CorePredicate predicate; + protected final Predicate predicate; protected final PredicateInterpretation interpretation; - public ExternalAtom(CorePredicate predicate, PredicateInterpretation interpretation, List input, List output) { + public ExternalAtom(Predicate predicate, PredicateInterpretation interpretation, List input, List output) { if (predicate == null) { throw new IllegalArgumentException("predicate must not be null!"); } @@ -70,7 +72,7 @@ public boolean hasOutput() { } @Override - public CorePredicate getPredicate() { + public Predicate getPredicate() { return predicate; } @@ -78,27 +80,27 @@ public PredicateInterpretation getInterpretation() { return interpretation; } - public List getInput() { + public List getInput() { return Collections.unmodifiableList(input); } - public List getOutput() { + public List getOutput() { return Collections.unmodifiableList(output); } @Override - public List getTerms() { + public List getTerms() { return input; } @Override public boolean isGround() { - for (CoreTerm t : input) { + for (Term t : input) { if (!t.isGround()) { return false; } } - for (CoreTerm t : output) { + for (Term t : output) { if (!t.isGround()) { return false; } @@ -108,8 +110,8 @@ public boolean isGround() { @Override public ExternalAtom 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()); + 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 ExternalAtom(predicate, interpretation, substitutedInput, substitutedOutput); } @@ -131,7 +133,7 @@ public String toString() { } @Override - public CoreAtom withTerms(List terms) { + public Atom withTerms(List terms) { throw new UnsupportedOperationException("Editing term list is not supported for external atoms!"); } @@ -171,8 +173,8 @@ public boolean equals(Object obj) { @Override public ExternalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedInput = CoreTerm.renameTerms(this.input, prefix + "_IN_", counterStartingValue); - List renamedOutput = CoreTerm.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); + List renamedInput = Terms.renameTerms(this.input, prefix + "_IN_", counterStartingValue); + List renamedOutput = Terms.renameTerms(this.output, prefix + "_OUT_", counterStartingValue); return new ExternalAtom(this.predicate, this.interpretation, renamedInput, renamedOutput); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java index 5a494c3e1..54ce0fbe5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java @@ -27,14 +27,19 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; +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.program.Literal; -import at.ac.tuwien.kr.alpha.api.terms.*; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +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.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; - -import java.util.*; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Contains a potentially negated {@link ExternalAtom}. @@ -60,7 +65,7 @@ public ExternalLiteral negate() { } /** - * @see CoreAtom#substitute(Substitution) + * @see CoreAtom#substitute(SubstitutionImpl) */ @Override public ExternalLiteral substitute(Substitution substitution) { @@ -68,7 +73,7 @@ public ExternalLiteral substitute(Substitution substitution) { } @Override - public Set getBindingVariables() { + 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. @@ -77,11 +82,11 @@ public Set getBindingVariables() { return Collections.emptySet(); } - List output = getAtom().getOutput(); + List output = getAtom().getOutput(); - Set binding = new HashSet<>(output.size()); + Set binding = new HashSet<>(output.size()); - for (CoreTerm out : output) { + for (Term out : output) { if (out instanceof VariableTermImpl) { binding.add((VariableTermImpl) out); } @@ -91,23 +96,23 @@ public Set getBindingVariables() { } @Override - public Set getNonBindingVariables() { - List input = getAtom().getInput(); - List output = getAtom().getOutput(); + 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 (CoreTerm term : 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 (!positive) { - for (CoreTerm out : output) { - if (out instanceof VariableTermImpl) { - nonbindingVariables.add((VariableTermImpl) out); + for (Term out : output) { + if (out instanceof VariableTerm) { + nonbindingVariables.add((VariableTerm) out); } } } @@ -117,15 +122,15 @@ public Set getNonBindingVariables() { @Override public List getSatisfyingSubstitutions(Substitution partialSubstitution) { - List input = getAtom().getInput(); - List substitutes = new ArrayList<>(input.size()); + List input = getAtom().getInput(); + List substitutes = new ArrayList<>(input.size()); // In preparation for evaluating the external atom, set the input values according // to the partial substitution supplied by the grounder. - for (CoreTerm t : input) { + for (Term t : input) { substitutes.add(t.substitute(partialSubstitution)); } - Set>> results = getAtom().getInterpretation().evaluate(substitutes); + Set>> results = getAtom().getInterpretation().evaluate(substitutes); if (results == null) { throw new NullPointerException("Predicate " + getPredicate().getName() + " returned null. It must return a Set."); } @@ -154,14 +159,14 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit * non-binding. * * @param externalMethodResult The term lists obtained from evaluating the external atom - * (i.e. calling the java method) encapsulated by this literal + * (i.e. calling the java method) encapsulated by this literal * @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) { - List externalAtomOutTerms = this.getAtom().getOutput(); + 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))) { @@ -180,22 +185,22 @@ private boolean isNegatedLiteralSatisfied(Set 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) { + List externalAtomOutputTerms = this.getAtom().getOutput(); + for (List> bindings : outputs) { if (bindings.size() < externalAtomOutputTerms.size()) { throw new RuntimeException( - "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() - + " were expected."); + "Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() + + " were expected."); } - Substitution ith = new Substitution(partialSubstitution); + SubstitutionImpl ith = new SubstitutionImpl(partialSubstitution); boolean skip = false; for (int i = 0; i < externalAtomOutputTerms.size(); i++) { - CoreTerm out = externalAtomOutputTerms.get(i); + Term out = externalAtomOutputTerms.get(i); - if (out instanceof VariableTermImpl) { - ith.put((VariableTermImpl) out, bindings.get(i)); + if (out instanceof VariableTerm) { + ith.put((VariableTerm) out, bindings.get(i)); } else { if (!bindings.get(i).equals(out)) { skip = true; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java index a98798777..1c39ed31b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java @@ -29,7 +29,8 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Represents a literal whose ground truth value(s) are independent of the @@ -45,7 +46,7 @@ public FixedInterpretationLiteral(CoreAtom atom, boolean positive) { } /** - * Creates a list of {@link Substitution}s based on the given partial + * Creates a list of {@link SubstitutionImpl}s based on the given partial * substitution, such that * this {@link FixedInterpretationLiteral} is true in every returned * substitution. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java index 5fb846375..bf6706157 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java @@ -33,10 +33,13 @@ import java.util.Arrays; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** * Helper for treating IntervalTerms in rules. @@ -53,25 +56,25 @@ public class IntervalAtom extends CoreAtom implements VariableNormalizableAtom { private static final CorePredicate PREDICATE = CorePredicate.getInstance("_interval", 2, true); - private final List terms; + private final List terms; - public IntervalAtom(IntervalTerm intervalTerm, CoreTerm intervalRepresentingVariable) { + public IntervalAtom(IntervalTerm intervalTerm, Term intervalRepresentingVariable) { this.terms = Arrays.asList(intervalTerm, intervalRepresentingVariable); } @Override - public CorePredicate getPredicate() { + public Predicate getPredicate() { return PREDICATE; } @Override - public List getTerms() { + public List getTerms() { return terms; } @Override public boolean isGround() { - for (CoreTerm t : this.terms) { + for (Term t : this.terms) { if (!t.isGround()) { return false; } @@ -123,12 +126,12 @@ public IntervalAtom substitute(Substitution substitution) { @Override public IntervalAtom normalizeVariables(String prefix, int counterStartingValue) { - List renamedTerms = CoreTerm.renameTerms(terms, prefix, counterStartingValue); + List renamedTerms = Terms.renameTerms(terms, prefix, counterStartingValue); return new IntervalAtom((IntervalTerm) renamedTerms.get(0), renamedTerms.get(1)); } @Override - public CoreAtom withTerms(List terms) { + public Atom withTerms(List terms) { throw new UnsupportedOperationException("IntervalAtoms do not support setting of terms!"); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index 34250f35c..6d69467a1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java @@ -34,11 +34,14 @@ import com.google.common.collect.Sets; +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.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * @see IntervalAtom @@ -48,7 +51,7 @@ public class IntervalLiteral extends FixedInterpretationLiteral { public IntervalLiteral(IntervalAtom atom) { super(atom, true); } - + @Override public IntervalAtom getAtom() { return (IntervalAtom) atom; @@ -61,22 +64,22 @@ public IntervalLiteral negate() { private List getIntervalSubstitutions(Substitution partialSubstitution) { List substitutions = new ArrayList<>(); - List terms = getTerms(); - CoreTerm intervalRepresentingVariable = terms.get(1); + List terms = getTerms(); + Term intervalRepresentingVariable = terms.get(1); IntervalTerm intervalTerm = (IntervalTerm) terms.get(0); // Check whether intervalRepresentingVariable is bound already. - if (intervalRepresentingVariable instanceof VariableTermImpl) { + if (intervalRepresentingVariable instanceof VariableTerm) { // Still a variable, generate all elements in the interval. for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) { - Substitution ith = new Substitution(partialSubstitution); + Substitution ith = new SubstitutionImpl(partialSubstitution); ith.put((VariableTermImpl) intervalRepresentingVariable, CoreConstantTerm.getInstance(i)); substitutions.add(ith); } return substitutions; } else { // The intervalRepresentingVariable is bound already, check if it is in the interval. - if (!(intervalRepresentingVariable instanceof CoreConstantTerm) - || !(((CoreConstantTerm) intervalRepresentingVariable).getObject() instanceof Integer)) { + if (!(intervalRepresentingVariable instanceof ConstantTerm) + || !(((ConstantTerm) intervalRepresentingVariable).getObject() instanceof Integer)) { // Term is not bound to an integer constant, not in the interval. return Collections.emptyList(); } @@ -89,16 +92,16 @@ private List getIntervalSubstitutions(Substitution partialSubstitu } @Override - public Set getBindingVariables() { - CoreTerm term = getTerms().get(1); - if (term instanceof VariableTermImpl) { - return Collections.singleton((VariableTermImpl) term); + public Set getBindingVariables() { + Term term = getTerms().get(1); + if (term instanceof VariableTerm) { + return Collections.singleton((VariableTerm) term); } return Collections.emptySet(); } @Override - public Set getNonBindingVariables() { + public Set getNonBindingVariables() { return Sets.newHashSet(getTerms().get(0).getOccurringVariables()); } @@ -109,7 +112,7 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit // Generate all substitutions for the interval representing variable. return groundInterval.getIntervalSubstitutions(partialSubstitution); } - + @Override public IntervalLiteral substitute(Substitution substitution) { return new IntervalLiteral(getAtom().substitute(substitution)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java index f7171a9ac..3bf3a0512 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java @@ -32,10 +32,12 @@ import java.util.Arrays; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** @@ -43,11 +45,11 @@ * second is a term containing variable substitutions. */ public class RuleAtom extends CoreAtom { - public static final CorePredicate PREDICATE = CorePredicate.getInstance("_R_", 2, true, true); + public static final Predicate PREDICATE = CorePredicate.getInstance("_R_", 2, true, true); - private final List> terms; + private final List> terms; - private RuleAtom(List> terms) { + private RuleAtom(List> terms) { if (terms.size() != 2) { throw new IllegalArgumentException(); } @@ -64,12 +66,12 @@ public RuleAtom(InternalRule nonGroundRule, Substitution substitution) { } @Override - public CorePredicate getPredicate() { + public Predicate getPredicate() { return PREDICATE; } @Override - public List getTerms() { + public List getTerms() { return Arrays.asList(terms.get(0), terms.get(1)); } @@ -114,7 +116,7 @@ public String toString() { } @Override - public CoreAtom withTerms(List terms) { + public Atom withTerms(List terms) { throw new UnsupportedOperationException("RuleAtoms do not support setting of terms!"); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java index 8e4ae2dcb..fc2e973c5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java @@ -1,5 +1,7 @@ package at.ac.tuwien.kr.alpha.core.atoms; +import at.ac.tuwien.kr.alpha.api.program.Atom; + /** * Interface for atom whose variables can be normalized, i.e., enumerated from * left to right. @@ -15,6 +17,6 @@ public interface VariableNormalizableAtom { * @return the Atom where all variables are renamed and enumerated * left-to-right. */ - CoreAtom normalizeVariables(String prefix, int counterStartingValue); + Atom normalizeVariables(String prefix, int counterStartingValue); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java index 7bd2c5481..efb690392 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java @@ -10,18 +10,20 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; public class AnswerSetBuilder { private boolean firstInstance = true; private String predicateSymbol; - private CorePredicate predicate; - private SortedSet predicates = new TreeSet<>(); - private SortedSet instances = new TreeSet<>(); - private Map> predicateInstances = new HashMap<>(); + private Predicate predicate; + private SortedSet predicates = new TreeSet<>(); + private SortedSet instances = new TreeSet<>(); + private Map> predicateInstances = new HashMap<>(); public AnswerSetBuilder() { } @@ -34,7 +36,7 @@ public AnswerSetBuilder(AnswerSetBuilder copy) { this.instances = new TreeSet<>(copy.instances); this.predicateInstances = new HashMap<>(copy.predicateInstances); this.predicateInstances = copy.predicateInstances.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> new TreeSet<>(e.getValue()))); + .collect(Collectors.toMap(Map.Entry::getKey, e -> new TreeSet<>(e.getValue()))); } private void flush() { @@ -43,7 +45,7 @@ private void flush() { predicates.add(predicate); predicateInstances.put(predicate, new TreeSet<>(singletonList(new BasicAtom(predicate)))); } else { - SortedSet atoms = predicateInstances.get(predicate); + SortedSet atoms = predicateInstances.get(predicate); if (atoms == null) { predicateInstances.put(predicate, new TreeSet<>(instances)); } else { @@ -73,10 +75,10 @@ public final > AnswerSetBuilder instance(final T... term // Note that usage of terms does not pollute the heap, // since we are only reading, not writing. - List termList = Stream - .of(terms) - .map(CoreConstantTerm::getInstance) - .collect(Collectors.toList()); + List termList = Stream + .of(terms) + .map(CoreConstantTerm::getInstance) + .collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); return this; @@ -89,7 +91,7 @@ public AnswerSetBuilder symbolicInstance(String... terms) { predicates.add(predicate); } - List termList = Stream.of(terms).map(CoreConstantTerm::getSymbolicInstance).collect(Collectors.toList()); + List termList = Stream.of(terms).map(CoreConstantTerm::getSymbolicInstance).collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); return this; } 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 daaefc7ad..6e8f2dcf8 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 @@ -32,7 +32,7 @@ import java.util.Iterator; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; /** @@ -58,14 +58,14 @@ public interface AtomStore { * @param atom the atom to translate. * @return the Atom object represented by the int. */ - CoreAtom get(int atom); + Atom get(int atom); /** * Translates an atom represented as Atom object into an int. * @param atom the Atom object to translate. * @return the int representing the Atom object. */ - int get(CoreAtom atom); + int get(Atom atom); /** * If the given ground atom is not already stored, associates it with a new integer (ID) and stores it, else @@ -74,14 +74,14 @@ public interface AtomStore { * @param groundAtom the ground atom to look up in the store. * @return the integer ID of the ground atom, possibly newly assigned. */ - int putIfAbsent(CoreAtom groundAtom); + int putIfAbsent(Atom groundAtom); /** * Returns whether the given ground atom is known to the AtomStore. * @param groundAtom the ground atom to test. * @return true if the ground atom is already associated an integer ID. */ - boolean contains(CoreAtom groundAtom); + boolean contains(Atom groundAtom); String atomToString(int atom); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java index 780cad94a..ce41da6cd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; @@ -43,8 +44,8 @@ * This class stores ground atoms and provides the translation from an (integer) atomId to a (structured) predicate instance. */ public class AtomStoreImpl implements AtomStore { - private final List atomIdsToInternalBasicAtoms = new ArrayList<>(); - private final Map predicateInstancesToAtomIds = new HashMap<>(); + private final List atomIdsToInternalBasicAtoms = new ArrayList<>(); + private final Map predicateInstancesToAtomIds = new HashMap<>(); private final IntIdGenerator atomIdGenerator = new IntIdGenerator(1); private final AtomCounter atomCounter = new AtomCounter(); @@ -56,7 +57,7 @@ public AtomStoreImpl() { } @Override - public int putIfAbsent(CoreAtom groundAtom) { + public int putIfAbsent(Atom groundAtom) { if (!groundAtom.isGround()) { throw new IllegalArgumentException("Atom must be ground: " + groundAtom); } @@ -74,7 +75,7 @@ public int putIfAbsent(CoreAtom groundAtom) { } @Override - public boolean contains(CoreAtom groundAtom) { + public boolean contains(Atom groundAtom) { return predicateInstancesToAtomIds.containsKey(groundAtom); } @@ -89,7 +90,7 @@ public void releaseAtomId(int atomId) { public String printAtomIdTermMapping() { StringBuilder ret = new StringBuilder(); - for (Map.Entry entry : predicateInstancesToAtomIds.entrySet()) { + for (Map.Entry entry : predicateInstancesToAtomIds.entrySet()) { ret.append(entry.getValue()).append(" <-> ").append(entry.getKey().toString()).append(System.lineSeparator()); } return ret.toString(); @@ -111,7 +112,7 @@ public int getMaxAtomId() { } @Override - public CoreAtom get(int atom) { + public Atom get(int atom) { try { return atomIdsToInternalBasicAtoms.get(atom); } catch (IndexOutOfBoundsException e) { @@ -120,7 +121,7 @@ public CoreAtom get(int atom) { } @Override - public int get(CoreAtom atom) { + public int get(Atom atom) { return predicateInstancesToAtomIds.get(atom); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java index 0899e6a5d..be25f35b3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java @@ -8,7 +8,8 @@ import java.util.Set; import java.util.SortedSet; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.util.Util; /** @@ -18,21 +19,21 @@ public class BasicAnswerSet implements CoreAnswerSet { public static final BasicAnswerSet EMPTY = new BasicAnswerSet(emptySortedSet(), emptyMap()); - private final SortedSet predicates; - private final Map> predicateInstances; + private final SortedSet predicates; + private final Map> predicateInstances; - public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { + public BasicAnswerSet(SortedSet predicates, Map> predicateInstances) { this.predicates = predicates; this.predicateInstances = predicateInstances; } @Override - public SortedSet getPredicates() { + public SortedSet getPredicates() { return predicates; } @Override - public SortedSet getPredicateInstances(CorePredicate predicate) { + public SortedSet getPredicateInstances(Predicate predicate) { return predicateInstances.get(predicate); } @@ -48,16 +49,16 @@ public String toString() { } final StringBuilder sb = new StringBuilder("{ "); - for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { - CorePredicate predicate = iterator.next(); - Set instances = getPredicateInstances(predicate); + for (Iterator iterator = predicates.iterator(); iterator.hasNext();) { + Predicate predicate = iterator.next(); + Set instances = getPredicateInstances(predicate); if (instances == null || instances.isEmpty()) { sb.append(predicate.getName()); continue; } - for (Iterator instanceIterator = instances.iterator(); instanceIterator.hasNext();) { + for (Iterator instanceIterator = instances.iterator(); instanceIterator.hasNext();) { sb.append(instanceIterator.next()); if (instanceIterator.hasNext()) { sb.append(", "); @@ -92,19 +93,19 @@ public boolean equals(Object o) { @Override public int hashCode() { - return 31 * predicates.hashCode() + predicateInstances.hashCode(); + return 31 * predicates.hashCode() + predicateInstances.hashCode(); } @Override public int compareTo(CoreAnswerSet other) { - final SortedSet predicates = this.getPredicates(); + final SortedSet predicates = this.getPredicates(); int result = Util.compareSortedSets(predicates, other.getPredicates()); if (result != 0) { return result; } - for (CorePredicate predicate : predicates) { + for (Predicate predicate : predicates) { result = Util.compareSortedSets(this.getPredicateInstances(predicate), other.getPredicateInstances(predicate)); if (result != 0) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java index ca7e29c29..a1964b70b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java @@ -2,12 +2,13 @@ import java.util.SortedSet; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; public interface CoreAnswerSet extends Comparable { - SortedSet getPredicates(); + SortedSet getPredicates(); - SortedSet getPredicateInstances(CorePredicate predicate); + SortedSet getPredicateInstances(Predicate predicate); boolean isEmpty(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java index de9271401..e45ee03e9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java @@ -5,7 +5,8 @@ import java.util.SortedSet; import java.util.stream.Collectors; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; public class SimpleAnswerSetFormatter implements AnswerSetFormatter { @@ -18,8 +19,8 @@ public SimpleAnswerSetFormatter(String atomSeparator) { @Override public String format(CoreAnswerSet answerSet) { List predicateInstanceStrings = new ArrayList<>(); - for (CorePredicate p : answerSet.getPredicates()) { - SortedSet instances; + for (Predicate p : answerSet.getPredicates()) { + SortedSet instances; if ((instances = answerSet.getPredicateInstances(p)) == null || instances.isEmpty()) { predicateInstanceStrings.add(p.getName()); } else { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java index 320cf1539..2cf163f5b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java @@ -27,14 +27,16 @@ */ package at.ac.tuwien.kr.alpha.core.common.terms; -import at.ac.tuwien.kr.alpha.core.common.Interner; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import java.util.LinkedHashSet; +import java.util.Set; import com.google.common.math.IntMath; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; +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.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.Interner; /** * This class represents an arithmetic expression occurring as a term. @@ -42,17 +44,17 @@ */ public class ArithmeticTerm extends CoreTerm { private static final Interner INTERNER = new Interner<>(); - protected final CoreTerm left; + protected final Term left; private final ArithmeticOperator arithmeticOperator; - private final CoreTerm right; + private final Term right; - private ArithmeticTerm(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { + private ArithmeticTerm(Term left, ArithmeticOperator arithmeticOperator, Term right) { this.left = left; this.arithmeticOperator = arithmeticOperator; this.right = right; } - public static CoreTerm getInstance(CoreTerm left, ArithmeticOperator arithmeticOperator, CoreTerm right) { + public static Term getInstance(Term left, ArithmeticOperator arithmeticOperator, Term right) { // Evaluate ground arithmetic terms immediately and return result. if (left.isGround() && right.isGround()) { Integer result = new ArithmeticTerm(left, arithmeticOperator, right).evaluateExpression(); @@ -61,49 +63,48 @@ public static CoreTerm getInstance(CoreTerm left, ArithmeticOperator arithmeticO return INTERNER.intern(new ArithmeticTerm(left, arithmeticOperator, right)); } - @Override public boolean isGround() { return left.isGround() && right.isGround(); } @Override - public List getOccurringVariables() { - LinkedHashSet occurringVariables = new LinkedHashSet<>(left.getOccurringVariables()); + public Set getOccurringVariables() { + LinkedHashSet occurringVariables = new LinkedHashSet<>(left.getOccurringVariables()); occurringVariables.addAll(right.getOccurringVariables()); - return new ArrayList<>(occurringVariables); + return occurringVariables; } @Override - public CoreTerm substitute(Substitution substitution) { + public Term substitute(Substitution substitution) { return getInstance(left.substitute(substitution), arithmeticOperator, right.substitute(substitution)); } @Override - public CoreTerm renameVariables(String renamePrefix) { + public Term renameVariables(String renamePrefix) { return getInstance(left.renameVariables(renamePrefix), arithmeticOperator, right.renameVariables(renamePrefix)); } @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); - CoreTerm normalizedRight = right.normalizeVariables(renamePrefix, counter); + public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) { + Term normalizedLeft = left.normalizeVariables(renamePrefix, counter); + Term normalizedRight = right.normalizeVariables(renamePrefix, counter); return ArithmeticTerm.getInstance(normalizedLeft, arithmeticOperator, normalizedRight); } - public static Integer evaluateGroundTerm(CoreTerm term) { + public static Integer evaluateGroundTerm(Term term) { if (!term.isGround()) { throw new RuntimeException("Cannot evaluate arithmetic term since it is not ground: " + term); } return evaluateGroundTermHelper(term); } - private static Integer evaluateGroundTermHelper(CoreTerm term) { - if (term instanceof CoreConstantTerm - && ((CoreConstantTerm) term).getObject() instanceof Integer) { + private static Integer evaluateGroundTermHelper(Term term) { + if (term instanceof ConstantTerm + && ((ConstantTerm) term).getObject() instanceof Integer) { // Extract integer from the constant. - return (Integer) ((CoreConstantTerm) term).getObject(); + return (Integer) ((ConstantTerm) term).getObject(); } else if (term instanceof ArithmeticTerm) { return ((ArithmeticTerm) term).evaluateExpression(); } else { @@ -160,7 +161,6 @@ public enum ArithmeticOperator { MODULO("\\"), BITXOR("^"); - private String asString; ArithmeticOperator(String asString) { @@ -197,12 +197,11 @@ public Integer eval(Integer left, Integer right) { public static class MinusTerm extends ArithmeticTerm { - private MinusTerm(CoreTerm term) { + private MinusTerm(Term term) { super(term, null, null); } - - public static CoreTerm getInstance(CoreTerm term) { + public static Term getInstance(Term term) { // Evaluate ground arithmetic terms immediately and return result. if (term.isGround()) { Integer result = evaluateGroundTermHelper(term) * -1; @@ -222,23 +221,23 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { + public Set getOccurringVariables() { return left.getOccurringVariables(); } @Override - public CoreTerm substitute(Substitution substitution) { + public Term substitute(Substitution substitution) { return getInstance(left.substitute(substitution)); } @Override - public CoreTerm renameVariables(String renamePrefix) { + public Term renameVariables(String renamePrefix) { return getInstance(left.renameVariables(renamePrefix)); } - + @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - CoreTerm normalizedLeft = left.normalizeVariables(renamePrefix, counter); + public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) { + Term normalizedLeft = left.normalizeVariables(renamePrefix, counter); return MinusTerm.getInstance(normalizedLeft); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java index d3b45ad13..c470e7555 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java @@ -1,15 +1,18 @@ package at.ac.tuwien.kr.alpha.core.common.terms; -import at.ac.tuwien.kr.alpha.core.common.Interner; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; - import java.util.Collections; -import java.util.List; +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.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.Interner; /** * Copyright (c) 2016-2020, the Alpha Team. */ -public class CoreConstantTerm> extends CoreTerm { +public class CoreConstantTerm> extends CoreTerm implements ConstantTerm { private static final Interner> INTERNER = new Interner<>(); private final T object; @@ -36,12 +39,12 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { - return Collections.emptyList(); + public Set getOccurringVariables() { + return Collections.emptySet(); } @Override - public CoreTerm substitute(Substitution substitution) { + public Term substitute(Substitution substitution) { return this; } @@ -97,7 +100,7 @@ private static final int priority(final Class clazz, CoreConstantTerm term @Override @SuppressWarnings("unchecked") - public int compareTo(CoreTerm o) { + public int compareTo(Term o) { if (this == o) { return 0; } @@ -144,10 +147,11 @@ public CoreTerm renameVariables(String renamePrefix) { } @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + public CoreTerm normalizeVariables(String renamePrefix, Term.RenameCounter counter) { return this; } + @Override public T getObject() { return object; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java index a359d2153..bb040beef 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java @@ -1,12 +1,13 @@ package at.ac.tuwien.kr.alpha.core.common.terms; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; +import java.util.Map; +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.Term; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; //@formatter:off /** @@ -35,7 +36,7 @@ //@formatter:on public abstract class CoreTerm implements Term { - public abstract List getOccurringVariables(); + public abstract Set getOccurringVariables(); /** * Applies a substitution, result may be nonground. @@ -43,10 +44,10 @@ public abstract class CoreTerm implements Term { * @param substitution the variable substitution to apply. * @return the non-substitute term where all variable substitutions have been applied. */ - public abstract CoreTerm substitute(Substitution substitution); + public abstract Term substitute(Substitution substitution); // TODO change this to work on interfaces and break out of this class - private static int priority(CoreTerm term) { + private static int priority(Term term) { final Class clazz = term.getClass(); if (clazz.equals(CoreConstantTerm.class)) { return 1; @@ -71,27 +72,29 @@ public int compareTo(Term o) { * @param renamePrefix the name to prefix all occurring variables. * @return the term with all variables renamed. */ - public abstract CoreTerm renameVariables(String renamePrefix); + public abstract Term renameVariables(String renamePrefix); - public abstract CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter); + public abstract Term normalizeVariables(String renamePrefix, Term.RenameCounter counter); - public static class RenameCounter { + public static class RenameCounter implements Term.RenameCounter { int counter; - final HashMap renamedVariables; + final HashMap renamedVariables; public RenameCounter(int startingValue) { counter = startingValue; renamedVariables = new HashMap<>(); } - } - - public static List renameTerms(List terms, String prefix, int counterStartingValue) { - List renamedTerms = new ArrayList<>(terms.size()); - CoreTerm.RenameCounter renameCounter = new CoreTerm.RenameCounter(counterStartingValue); - for (CoreTerm term : terms) { - renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); + + public Map getRenamedVariables(){ + return renamedVariables; + } + + public int getAndIncrement() { + int retVal = counter; + counter++; + return retVal; } - return renamedTerms; + } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java index 3840f9410..194f02239 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java @@ -1,11 +1,18 @@ package at.ac.tuwien.kr.alpha.core.common.terms; -import at.ac.tuwien.kr.alpha.core.common.Interner; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; - import static at.ac.tuwien.kr.alpha.core.util.Util.join; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.Interner; /** * Copyright (c) 2016-2017, the Alpha Team. @@ -14,10 +21,10 @@ public class FunctionTerm extends CoreTerm { private static final Interner INTERNER = new Interner<>(); private final String symbol; - private final List terms; + private final List terms; private final boolean ground; - private FunctionTerm(String symbol, List terms) { + private FunctionTerm(String symbol, List terms) { if (symbol == null) { throw new IllegalArgumentException(); } @@ -26,7 +33,7 @@ private FunctionTerm(String symbol, List terms) { this.terms = Collections.unmodifiableList(terms); boolean ground = true; - for (CoreTerm term : terms) { + for (Term term : terms) { if (!term.isGround()) { ground = false; break; @@ -35,15 +42,15 @@ private FunctionTerm(String symbol, List terms) { this.ground = ground; } - public static FunctionTerm getInstance(String functionSymbol, List termList) { + public static FunctionTerm getInstance(String functionSymbol, List termList) { return INTERNER.intern(new FunctionTerm(functionSymbol, termList)); } - public static FunctionTerm getInstance(String functionSymbol, CoreTerm... terms) { + public static FunctionTerm getInstance(String functionSymbol, Term... terms) { return getInstance(functionSymbol, Arrays.asList(terms)); } - public List getTerms() { + public List getTerms() { return terms; } @@ -57,9 +64,9 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { - LinkedList vars = new LinkedList<>(); - for (CoreTerm term : terms) { + public Set getOccurringVariables() { + Set vars = new LinkedHashSet<>(); + for (Term term : terms) { vars.addAll(term.getOccurringVariables()); } return vars; @@ -67,8 +74,8 @@ public List getOccurringVariables() { @Override public FunctionTerm substitute(Substitution substitution) { - List groundTermList = new ArrayList<>(terms.size()); - for (CoreTerm term : terms) { + List groundTermList = new ArrayList<>(terms.size()); + for (Term term : terms) { groundTermList.add(term.substitute(substitution)); } return FunctionTerm.getInstance(symbol, groundTermList); @@ -106,7 +113,7 @@ public int hashCode() { } @Override - public int compareTo(CoreTerm o) { + public int compareTo(Term o) { if (this == o) { return 0; } @@ -115,7 +122,7 @@ public int compareTo(CoreTerm o) { return super.compareTo(o); } - FunctionTerm other = (FunctionTerm)o; + FunctionTerm other = (FunctionTerm) o; if (terms.size() != other.terms.size()) { return terms.size() - other.terms.size(); @@ -138,18 +145,18 @@ public int compareTo(CoreTerm o) { } @Override - public CoreTerm renameVariables(String renamePrefix) { - List renamedTerms = new ArrayList<>(terms.size()); - for (CoreTerm term : terms) { + public Term renameVariables(String renamePrefix) { + List renamedTerms = new ArrayList<>(terms.size()); + for (Term term : terms) { renamedTerms.add(term.renameVariables(renamePrefix)); } return FunctionTerm.getInstance(symbol, renamedTerms); } @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - List normalizedTerms = new ArrayList<>(terms.size()); - for (CoreTerm term : terms) { + public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) { + List normalizedTerms = new ArrayList<>(terms.size()); + for (Term term : terms) { normalizedTerms.add(term.normalizeVariables(renamePrefix, counter)); } return FunctionTerm.getInstance(symbol, normalizedTerms); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java index 02d9f8305..e0dbd225e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java @@ -1,12 +1,14 @@ package at.ac.tuwien.kr.alpha.core.common.terms; -import at.ac.tuwien.kr.alpha.core.common.Interner; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; - import static at.ac.tuwien.kr.alpha.core.util.Util.oops; -import java.util.LinkedList; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; + +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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.Interner; /** * An IntervalTerm represents the shorthand notation for a set of rules where all elements in this interval occur once, e.g., fact(2..5). @@ -15,20 +17,20 @@ */ public class IntervalTerm extends CoreTerm { private static final Interner INTERNER = new Interner<>(); - private final CoreTerm lowerBoundTerm; - private final CoreTerm upperBoundTerm; + private final Term lowerBoundTerm; + private final Term upperBoundTerm; private final int lowerBound; private final int upperBound; private final boolean ground; - private IntervalTerm(CoreTerm lowerBound, CoreTerm upperBound) { + private IntervalTerm(Term lowerBound, Term upperBound) { if (lowerBound == null || upperBound == null) { throw new IllegalArgumentException(); } - this.ground = !((lowerBound instanceof VariableTermImpl) || (upperBound instanceof VariableTermImpl)); + this.ground = !((lowerBound instanceof VariableTerm) || (upperBound instanceof VariableTerm)); this.lowerBoundTerm = lowerBound; this.upperBoundTerm = upperBound; @@ -42,7 +44,7 @@ private IntervalTerm(CoreTerm lowerBound, CoreTerm upperBound) { } } - public static IntervalTerm getInstance(CoreTerm lowerBound, CoreTerm upperBound) { + public static IntervalTerm getInstance(Term lowerBound, Term upperBound) { return INTERNER.intern(new IntervalTerm(lowerBound, upperBound)); } @@ -66,12 +68,12 @@ public int getUpperBound() { } @Override - public List getOccurringVariables() { - LinkedList variables = new LinkedList<>(); - if (lowerBoundTerm instanceof VariableTermImpl) { + public Set getOccurringVariables() { + Set variables = new LinkedHashSet<>(); + if (lowerBoundTerm instanceof VariableTerm) { variables.add((VariableTermImpl) lowerBoundTerm); } - if (upperBoundTerm instanceof VariableTermImpl) { + if (upperBoundTerm instanceof VariableTerm) { variables.add((VariableTermImpl) upperBoundTerm); } return variables; @@ -114,17 +116,17 @@ public int hashCode() { } @Override - public int compareTo(CoreTerm o) { + public int compareTo(Term o) { throw new UnsupportedOperationException("Intervals cannot be compared."); } @Override - public CoreTerm renameVariables(String renamePrefix) { + public Term renameVariables(String renamePrefix) { return new IntervalTerm(lowerBoundTerm.renameVariables(renamePrefix), upperBoundTerm.renameVariables(renamePrefix)); } @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { + public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) { return IntervalTerm.getInstance( lowerBoundTerm.normalizeVariables(renamePrefix, counter), upperBoundTerm.normalizeVariables(renamePrefix, counter)); @@ -135,7 +137,7 @@ public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { * @param term the term to test * @return true iff an IntervalTerm occurs in term. */ - public static boolean termContainsIntervalTerm(CoreTerm term) { + public static boolean termContainsIntervalTerm(Term term) { if (term instanceof IntervalTerm) { return true; } else if (term instanceof FunctionTerm) { @@ -147,7 +149,7 @@ public static boolean termContainsIntervalTerm(CoreTerm term) { public static boolean functionTermContainsIntervals(FunctionTerm functionTerm) { // Test whether a function term contains an interval term (recursively). - for (CoreTerm term : functionTerm.getTerms()) { + for (Term term : functionTerm.getTerms()) { if (term instanceof IntervalTerm) { return true; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java index e150dd7a5..79cc47eb6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java @@ -3,6 +3,9 @@ import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; + /** * Convenience methods for {@link CoreTerm}s. The methods provided here are an * attempt to avoid repeating commonly used code snippets, like wrapping sets of @@ -22,12 +25,22 @@ private Terms() { } @SafeVarargs - public static > List> asTermList(T... values) { - List> retVal = new ArrayList<>(); + public static > List> asTermList(T... values) { + List> retVal = new ArrayList<>(); for (T value : values) { retVal.add(CoreConstantTerm.getInstance(value)); } return retVal; } + public static List renameTerms(List terms, String prefix, int counterStartingValue) { + List renamedTerms = new ArrayList<>(terms.size()); + CoreTerm.RenameCounter renameCounter = new CoreTerm.RenameCounter(counterStartingValue); + for (Term term : terms) { + renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); + } + return renamedTerms; + } + + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java index 46af900fc..122b4ca55 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java @@ -1,13 +1,13 @@ package at.ac.tuwien.kr.alpha.core.common.terms; import java.util.Collections; -import java.util.List; +import java.util.Set; +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.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.Interner; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; /** * Copyright (c) 2016-2017, the Alpha Team. @@ -38,13 +38,13 @@ public boolean isGround() { } @Override - public List getOccurringVariables() { - return Collections.singletonList(this); + public Set getOccurringVariables() { + return Collections.singleton(this); } @Override - public CoreTerm substitute(Substitution substitution) { - CoreTerm groundTerm = substitution.eval(this); + public Term substitute(Substitution substitution) { + Term groundTerm = substitution.eval(this); if (groundTerm == null) { // If variable is not substituted, keep term as is. return this; @@ -98,13 +98,13 @@ public CoreTerm renameVariables(String renamePrefix) { } @Override - public CoreTerm normalizeVariables(String renamePrefix, RenameCounter counter) { - VariableTermImpl renamedThis = counter.renamedVariables.get(this); + public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) { + VariableTerm renamedThis = counter.getRenamedVariables().get(this); if (renamedThis != null) { return renamedThis; } else { - VariableTermImpl renamedVariable = VariableTermImpl.getInstance(renamePrefix + counter.counter++); - counter.renamedVariables.put(this, renamedVariable); + VariableTerm renamedVariable = VariableTermImpl.getInstance(renamePrefix + counter.getAndIncrement()); + counter.getRenamedVariables().put(this, renamedVariable); return renamedVariable; } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java index 98bd02fed..7474add51 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java @@ -25,16 +25,6 @@ */ package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.api.program.*; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -42,6 +32,16 @@ import java.util.List; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; + /** * Internal representation of an {@link at.ac.tuwien.kr.alpha.core.programs.InternalProgram}'s dependency graph. The dependency graph tracks dependencies * between rules of a program. Each {@link Node} of the graph represents a {@link CorePredicate} occurring in the program. A node has an incoming {@link Edge} for @@ -64,9 +64,9 @@ public final class DependencyGraph { */ private final Map> adjacencyMap; - private final Map nodesByPredicate; + private final Map nodesByPredicate; - private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { + private DependencyGraph(Map> adjacencyMap, Map nodesByPredicate) { this.adjacencyMap = adjacencyMap; this.nodesByPredicate = nodesByPredicate; } @@ -91,7 +91,7 @@ private static class Builder { private Collection rules; private Map> adjacentNodesMap = new HashMap<>(); - private Map nodesByPredicate = new HashMap<>(); + private Map nodesByPredicate = new HashMap<>(); private Builder(Collection rules) { this.rules = rules; @@ -102,7 +102,7 @@ private DependencyGraph build() { for (InternalRule rule : rules) { LOGGER.debug("Processing rule: {}", rule); Node headNode = handleRuleHead(rule); - for (CoreLiteral literal : rule.getBody()) { + for (Literal literal : rule.getBody()) { LOGGER.trace("Processing rule body literal: {}", literal); if (literal instanceof FixedInterpretationLiteral) { LOGGER.trace("Ignoring FixedInterpretationLiteral {}", literal); @@ -118,7 +118,7 @@ private Node handleRuleHead(InternalRule rule) { LOGGER.trace("Processing head of rule: {}", rule); Node headNode; if (rule.isConstraint()) { - CorePredicate pred = generateConstraintDummyPredicate(); + Predicate pred = generateConstraintDummyPredicate(); headNode = new Node(pred); List dependencies = new ArrayList<>(); dependencies.add(new Edge(headNode, false)); @@ -128,8 +128,8 @@ private Node handleRuleHead(InternalRule rule) { adjacentNodesMap.put(headNode, dependencies); nodesByPredicate.put(pred, headNode); } else { - CoreAtom head = rule.getHeadAtom(); - CorePredicate pred = head.getPredicate(); + Atom head = rule.getHeadAtom(); + Predicate pred = head.getPredicate(); if (!nodesByPredicate.containsKey(pred)) { headNode = new Node(pred); adjacentNodesMap.put(headNode, new ArrayList<>()); @@ -141,10 +141,10 @@ private Node handleRuleHead(InternalRule rule) { return headNode; } - private void handleRuleBodyLiteral(Node headNode, CoreLiteral lit) { + private void handleRuleBodyLiteral(Node headNode, Literal lit) { List dependants; Node bodyNode; - CorePredicate bodyPred = lit.getPredicate(); + Predicate bodyPred = lit.getPredicate(); if (!nodesByPredicate.containsKey(bodyPred)) { LOGGER.trace("Creating new node for bodyPred {}", bodyPred); dependants = new ArrayList<>(); @@ -164,7 +164,7 @@ private void handleRuleBodyLiteral(Node headNode, CoreLiteral lit) { nodesByPredicate.put(bodyPred, bodyNode); } - private CorePredicate generateConstraintDummyPredicate() { + private Predicate generateConstraintDummyPredicate() { return CorePredicate.getInstance(String.format(DependencyGraph.Builder.CONSTRAINT_PREDICATE_FORMAT, ++constraintNumber), 0); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java index af0864e88..f969e45a1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.api.program.Predicate; /** * A node in a dependency graph. One node references exactly one predicate. This means that all rule heads deriving the @@ -36,9 +36,9 @@ */ public class Node { - private final CorePredicate predicate; + private final Predicate predicate; - public Node(CorePredicate predicate) { + public Node(Predicate predicate) { this.predicate = predicate; } @@ -64,7 +64,7 @@ public String getLabel() { return predicate.toString(); } - public CorePredicate getPredicate() { + public Predicate getPredicate() { return predicate; } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index dff9ecf50..4a4ce5f6f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -1,16 +1,16 @@ package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.api.terms.*; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - /** * Helper functions to evaluate facts potentially containing intervals. * Copyright (c) 2017, the Alpha Team. @@ -23,14 +23,14 @@ public class FactIntervalEvaluator { * @param fact the fact potentially containing intervals. * @return all instances stemming from unfolding the intervals. */ - public static List constructFactInstances(CoreAtom fact) { + public static List constructFactInstances(Atom fact) { // Construct instance(s) from the fact. int arity = fact.getPredicate().getArity(); - CoreTerm[] currentTerms = new CoreTerm[arity]; + Term[] currentTerms = new CoreTerm[arity]; boolean containsIntervals = false; // Check if instance contains intervals at all. for (int i = 0; i < arity; i++) { - CoreTerm term = fact.getTerms().get(i); + Term term = fact.getTerms().get(i); currentTerms[i] = term; if (term instanceof IntervalTerm) { containsIntervals = true; @@ -47,11 +47,11 @@ public static List constructFactInstances(CoreAtom fact) { return unrollInstances(currentTerms, 0); } - private static List unrollInstances(CoreTerm[] currentTerms, int currentPosition) { + private static List unrollInstances(Term[] currentTerms, int currentPosition) { if (currentPosition == currentTerms.length) { return Collections.singletonList(new Instance(currentTerms)); } - CoreTerm currentTerm = currentTerms[currentPosition]; + Term currentTerm = currentTerms[currentPosition]; if (!(currentTerm instanceof IntervalTerm)) { return unrollInstances(currentTerms, currentPosition + 1); } @@ -62,7 +62,7 @@ private static List unrollInstances(CoreTerm[] currentTerms, int curre int upper = ((IntervalTerm) currentTerm).getUpperBound(); for (int i = lower; i <= upper; i++) { - CoreTerm[] clonedTerms = currentTerms.clone(); + Term[] clonedTerms = currentTerms.clone(); clonedTerms[currentPosition] = CoreConstantTerm.getInstance(i); instances.addAll(unrollInstances(clonedTerms, currentPosition + 1)); } 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 912355491..ff8c7c317 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 @@ -36,9 +36,9 @@ import java.util.Map; import java.util.Set; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; /** * A storage for instances with a certain arity, where each position of the instance can be indexed. @@ -47,7 +47,7 @@ * Copyright (c) 2016-2020, the Alpha Team. */ public class IndexedInstanceStorage { - private final CorePredicate predicate; + private final Predicate predicate; private final boolean positive; /** @@ -58,11 +58,11 @@ public class IndexedInstanceStorage { /** * For each position, a mapping of termIds to list of instances with this termId at the corresponding position */ - private final ArrayList>> indices = new ArrayList<>(); + private final ArrayList>> indices = new ArrayList<>(); private final ArrayList recentlyAddedInstances = new ArrayList<>(); - public IndexedInstanceStorage(CorePredicate predicate, boolean positive) { + public IndexedInstanceStorage(Predicate predicate, boolean positive) { this.predicate = predicate; this.positive = positive; @@ -72,7 +72,7 @@ public IndexedInstanceStorage(CorePredicate predicate, boolean positive) { } } - public CorePredicate getPredicate() { + public Predicate getPredicate() { return predicate; } @@ -124,7 +124,7 @@ public void addInstance(Instance instance) { recentlyAddedInstances.add(instance); // Add instance to all indices. for (int i = 0; i < indices.size(); i++) { - HashMap> posIndex = indices.get(i); + HashMap> posIndex = indices.get(i); if (posIndex == null) { continue; } @@ -141,7 +141,7 @@ public void removeInstance(Instance instance) { } // Remove from all indices for (int i = 0; i < indices.size(); i++) { - HashMap> posIndex = indices.get(i); + HashMap> posIndex = indices.get(i); if (posIndex == null) { continue; } @@ -169,8 +169,8 @@ public List getRecentlyAddedInstances() { * @param position * @return */ - public List getInstancesMatchingAtPosition(CoreTerm term, int position) { - Map> indexForPosition = indices.get(position); + public List getInstancesMatchingAtPosition(Term term, int position) { + Map> indexForPosition = indices.get(position); if (indexForPosition == null) { throw new RuntimeException("IndexedInstanceStorage queried for position " + position + " which is not indexed."); } @@ -178,11 +178,11 @@ public List getInstancesMatchingAtPosition(CoreTerm term, int position return matchingInstances == null ? Collections.emptyList() : matchingInstances; } - private int getMostSelectiveGroundTermPosition(CoreAtom atom) { + private int getMostSelectiveGroundTermPosition(Atom atom) { int smallestNumberOfInstances = Integer.MAX_VALUE; int mostSelectiveTermPosition = -1; for (int i = 0; i < atom.getTerms().size(); i++) { - CoreTerm testTerm = atom.getTerms().get(i); + Term testTerm = atom.getTerms().get(i); if (testTerm.isGround()) { ArrayList instancesMatchingTest = indices.get(i).get(testTerm); if (instancesMatchingTest == null) { @@ -199,12 +199,12 @@ private int getMostSelectiveGroundTermPosition(CoreAtom atom) { return mostSelectiveTermPosition; } - public List getInstancesFromPartiallyGroundAtom(CoreAtom substitute) { + public List getInstancesFromPartiallyGroundAtom(Atom substitute) { // For selection of the instances, find ground term on which to select. int firstGroundTermPosition = getMostSelectiveGroundTermPosition(substitute); // Select matching instances, select all if no ground term was found. if (firstGroundTermPosition != -1) { - CoreTerm firstGroundTerm = substitute.getTerms().get(firstGroundTermPosition); + Term firstGroundTerm = substitute.getTerms().get(firstGroundTermPosition); return getInstancesMatchingAtPosition(firstGroundTerm, firstGroundTermPosition); } else { return new ArrayList<>(getAllInstances()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java index 0686e439e..8841bd6ba 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java @@ -5,8 +5,8 @@ import java.util.Arrays; import java.util.List; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.util.Util; /** @@ -15,17 +15,17 @@ * Copyright (c) 2016, the Alpha Team. */ public class Instance { - public final List terms; + public final List terms; - public Instance(CoreTerm... terms) { + public Instance(Term... terms) { this(Arrays.asList(terms)); } - public Instance(List terms) { + public Instance(List terms) { this.terms = terms; } - public static Instance fromAtom(CoreAtom atom) { + public static Instance fromAtom(Atom atom) { if (!atom.isGround()) { throw Util.oops("Cannot create instance from non-ground atom " + atom.toString()); } 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 ccdb73ee0..327dab730 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 @@ -48,12 +48,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.AtomStore; @@ -63,7 +65,6 @@ 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.common.NoGoodInterface; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.BindingResult; @@ -91,12 +92,12 @@ public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGr private final InternalProgram program; private final AnalyzeUnjustified analyzeUnjustified; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private final Map> rulesUsingPredicateWorkingMemory = new HashMap<>(); private final Map knownNonGroundRules; private ArrayList fixedRules = new ArrayList<>(); - private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); + private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); private final boolean debugInternalChecks; private final GrounderHeuristicsConfiguration heuristicsConfiguration; @@ -110,11 +111,13 @@ public NaiveGrounder(InternalProgram program, AtomStore atomStore, boolean debug this(program, atomStore, new GrounderHeuristicsConfiguration(), debugInternalChecks, bridges); } - private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, + Bridge... bridges) { this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, bridges); } - NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { + NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { super(filter, bridges); this.atomStore = atomStore; this.heuristicsConfiguration = heuristicsConfiguration; @@ -144,8 +147,8 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur private void initializeFactsAndRules() { // Initialize all facts. - for (CoreAtom fact : program.getFacts()) { - final CorePredicate predicate = fact.getPredicate(); + for (Atom fact : program.getFacts()) { + final Predicate predicate = fact.getPredicate(); // Record predicate workingMemory.initialize(predicate); @@ -159,7 +162,7 @@ private void initializeFactsAndRules() { // Initialize rules and constraints in working memory. for (InternalRule nonGroundRule : program.getRulesById().values()) { // Create working memories for all predicates occurring in the rule. - for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { + for (Predicate predicate : nonGroundRule.getOccurringPredicates()) { // FIXME: this also contains interval/builtin predicates that are not needed. workingMemory.initialize(predicate); } @@ -171,25 +174,26 @@ private void initializeFactsAndRules() { } // Register each starting literal at the corresponding working memory. - for (CoreLiteral literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { + for (Literal literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { registerLiteralAtWorkingMemory(literal, nonGroundRule); } } } private Set getRulesWithUniqueHead() { - // FIXME: below optimisation (adding support nogoods if there is only one rule instantiation per unique atom over the interpretation) could be done as a transformation (adding a non-ground constraint corresponding to the nogood that is generated by the grounder). + // FIXME: below optimisation (adding support nogoods if there is only one rule instantiation per unique atom over the interpretation) could + // be done as a transformation (adding a non-ground constraint corresponding to the nogood that is generated by the grounder). // Record all unique rule heads. final Set uniqueGroundRulePerGroundHead = new HashSet<>(); - for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { + for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { if (headDefiningRules.getValue().size() != 1) { continue; } InternalRule nonGroundRule = headDefiningRules.getValue().iterator().next(); // Check that all variables of the body also occur in the head (otherwise grounding is not unique). - CoreAtom headAtom = nonGroundRule.getHeadAtom(); + Atom headAtom = nonGroundRule.getHeadAtom(); // Rule is not guaranteed unique if there are facts for it. HashSet potentialFacts = factsFromProgram.get(headAtom.getPredicate()); @@ -198,9 +202,9 @@ private Set getRulesWithUniqueHead() { } // Collect head and body variables. - HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); - HashSet occurringVariablesBody = new HashSet<>(); - for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { + HashSet occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables()); + HashSet occurringVariablesBody = new HashSet<>(); + for (Literal lit : nonGroundRule.getPositiveBody()) { occurringVariablesBody.addAll(lit.getBindingVariables()); } occurringVariablesBody.removeAll(occurringVariablesHead); @@ -215,9 +219,10 @@ private Set getRulesWithUniqueHead() { /** * Registers a starting literal of a NonGroundRule at its corresponding working memory. - * @param nonGroundRule the rule in which the literal occurs. + * + * @param nonGroundRule the rule in which the literal occurs. */ - private void registerLiteralAtWorkingMemory(CoreLiteral literal, InternalRule nonGroundRule) { + private void registerLiteralAtWorkingMemory(Literal literal, InternalRule nonGroundRule) { if (literal.isNegated()) { throw new RuntimeException("Literal to register is negated. Should not happen."); } @@ -228,13 +233,13 @@ private void registerLiteralAtWorkingMemory(CoreLiteral literal, InternalRule no @Override public CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms) { - Map> predicateInstances = new LinkedHashMap<>(); - SortedSet knownPredicates = new TreeSet<>(); + Map> predicateInstances = new LinkedHashMap<>(); + SortedSet knownPredicates = new TreeSet<>(); // Iterate over all true atomIds, computeNextAnswerSet instances from atomStore and add them if not filtered. for (int trueAtom : trueAtoms) { - final CoreAtom atom = atomStore.get(trueAtom); - CorePredicate predicate = atom.getPredicate(); + final Atom atom = atomStore.get(trueAtom); + Predicate predicate = atom.getPredicate(); // Skip atoms over internal predicates. if (predicate.isInternal()) { @@ -248,13 +253,13 @@ public CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms) { knownPredicates.add(predicate); predicateInstances.putIfAbsent(predicate, new TreeSet<>()); - Set instances = predicateInstances.get(predicate); + Set instances = predicateInstances.get(predicate); instances.add(atom); } // Add true atoms from facts. - for (Map.Entry> facts : factsFromProgram.entrySet()) { - CorePredicate factPredicate = facts.getKey(); + for (Map.Entry> facts : factsFromProgram.entrySet()) { + Predicate factPredicate = facts.getKey(); // Skip atoms over internal predicates. if (factPredicate.isInternal()) { continue; @@ -270,7 +275,7 @@ public CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms) { knownPredicates.add(factPredicate); predicateInstances.putIfAbsent(factPredicate, new TreeSet<>()); for (Instance factInstance : facts.getValue()) { - SortedSet instances = predicateInstances.get(factPredicate); + SortedSet instances = predicateInstances.get(factPredicate); instances.add(new BasicAtom(factPredicate, factInstance.terms)); } } @@ -284,12 +289,13 @@ public CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms) { /** * Prepares facts of the input program for joining and derives all NoGoods representing ground rules. May only be called once. + * * @return */ protected HashMap bootstrap() { final HashMap groundNogoods = new LinkedHashMap<>(); - for (CorePredicate predicate : factsFromProgram.keySet()) { + for (Predicate predicate : factsFromProgram.keySet()) { // Instead of generating NoGoods, add instance to working memories directly. workingMemory.addInstances(predicate, true, factsFromProgram.get(predicate)); } @@ -297,7 +303,7 @@ protected HashMap bootstrap() { for (InternalRule nonGroundRule : fixedRules) { // Generate NoGoods for all rules that have a fixed grounding. RuleGroundingOrder groundingOrder = nonGroundRule.getGroundingOrders().getFixedGroundingOrder(); - BindingResult bindingResult = getGroundInstantiations(nonGroundRule, groundingOrder, new Substitution(), null); + BindingResult bindingResult = getGroundInstantiations(nonGroundRule, groundingOrder, new SubstitutionImpl(), null); groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), groundNogoods); } @@ -314,7 +320,7 @@ public Map getNoGoods(Assignment currentAssignment) { // Compute new ground rule (evaluate joins with newly changed atoms) for (IndexedInstanceStorage modifiedWorkingMemory : workingMemory.modified()) { // Skip predicates solely used in the solver which do not occur in rules. - CorePredicate workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); + Predicate workingMemoryPredicate = modifiedWorkingMemory.getPredicate(); if (workingMemoryPredicate.isSolverInternal()) { continue; } @@ -335,18 +341,18 @@ public Map getNoGoods(Assignment currentAssignment) { for (Instance instance : modifiedWorkingMemory.getRecentlyAddedInstances()) { // Check instance if it matches with the atom. - final Substitution unifier = Substitution.specializeSubstitution(firstBindingAtom.startingLiteral, instance, Substitution.EMPTY_SUBSTITUTION); + final Substitution unifier = SubstitutionImpl.specializeSubstitution(firstBindingAtom.startingLiteral, instance, + SubstitutionImpl.EMPTY_SUBSTITUTION); if (unifier == null) { continue; } final BindingResult bindingResult = getGroundInstantiations( - nonGroundRule, - nonGroundRule.getGroundingOrders().orderStartingFrom(firstBindingAtom.startingLiteral), - unifier, - currentAssignment - ); + nonGroundRule, + nonGroundRule.getGroundingOrders().orderStartingFrom(firstBindingAtom.startingLiteral), + unifier, + currentAssignment); groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), newNoGoods); } @@ -357,7 +363,7 @@ public Map getNoGoods(Assignment currentAssignment) { } workingMemory.reset(); - for (CoreAtom removeAtom : removeAfterObtainingNewNoGoods) { + for (Atom removeAtom : removeAfterObtainingNewNoGoods) { final IndexedInstanceStorage storage = workingMemory.get(removeAtom, true); Instance instance = new Instance(removeAtom.getTerms()); if (storage.containsInstance(instance)) { @@ -385,11 +391,12 @@ public Map getNoGoods(Assignment currentAssignment) { } /** - * Grounds the given {@code nonGroundRule} by applying the given {@code substitutions} and registers the nogoods generated during that process. + * Grounds the given {@code nonGroundRule} by applying the given {@code substitutions} and registers the nogoods generated during that + * process. * - * @param nonGroundRule the rule to be grounded. - * @param substitutions the substitutions to be applied. - * @param newNoGoods a set of nogoods to which newly generated nogoods will be added. + * @param nonGroundRule the rule to be grounded. + * @param substitutions the substitutions to be applied. + * @param newNoGoods a set of nogoods to which newly generated nogoods will be added. */ private void groundAndRegister(final InternalRule nonGroundRule, final List substitutions, final Map newNoGoods) { for (Substitution substitution : substitutions) { @@ -405,7 +412,7 @@ public int register(NoGood noGood) { // Ideally, this method should be private. It's only visible because NaiveGrounderTest needs to access it. BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder groundingOrder, Substitution partialSubstitution, - Assignment currentAssignment) { + Assignment currentAssignment) { int tolerance = heuristicsConfiguration.getTolerance(rule.isConstraint()); if (tolerance < 0) { tolerance = Integer.MAX_VALUE; @@ -420,7 +427,8 @@ BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder grou for (int i = 0; i < bindingResult.size(); i++) { Integer numberOfUnassignedPositiveBodyAtoms = bindingResult.getNumbersOfUnassignedPositiveBodyAtoms().get(i); if (numberOfUnassignedPositiveBodyAtoms > 0) { - LOGGER.debug("Grounded rule in which {} positive atoms are still unassigned: {} (substitution: {})", numberOfUnassignedPositiveBodyAtoms, rule, bindingResult.getGeneratedSubstitutions().get(i)); + LOGGER.debug("Grounded rule in which {} positive atoms are still unassigned: {} (substitution: {})", numberOfUnassignedPositiveBodyAtoms, + rule, bindingResult.getGeneratedSubstitutions().get(i)); } } } @@ -428,9 +436,9 @@ BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder grou } /** - * Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrder, int, int, int, Substitution)}. + * Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrder, int, int, int, SubstitutionImpl)}. * - * Takes an ImmutablePair of a {@link Substitution} and an accompanying {@link AssignmentStatus} and calls + * Takes an ImmutablePair of a {@link SubstitutionImpl} and an accompanying {@link AssignmentStatus} and calls * bindNextAtomInRule for the next literal in the grounding order. * If the assignment status for the last bound literal was {@link AssignmentStatus#UNASSIGNED}, the remainingTolerance * parameter is decreased by 1. If the remaining tolerance drops below zero, this method returns an empty {@link BindingResult}. @@ -444,15 +452,15 @@ BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder grou * tolerance is less than zero. */ private BindingResult continueBinding(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - ImmutablePair lastLiteralBindingResult) { + ImmutablePair lastLiteralBindingResult) { Substitution substitution = lastLiteralBindingResult.left; AssignmentStatus lastBoundLiteralAssignmentStatus = lastLiteralBindingResult.right; switch (lastBoundLiteralAssignmentStatus) { case TRUE: return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, substitution); case UNASSIGNED: - // The last literal bound to obtain the current substitution has not been assigned a truth value by the solver yet. - // If we still have enough tolerance, we can continue grounding nevertheless. + // The last literal bound to obtain the current substitution has not been assigned a truth value by the solver yet. + // If we still have enough tolerance, we can continue grounding nevertheless. int toleranceForNextRun = remainingTolerance - 1; if (toleranceForNextRun >= 0) { return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, toleranceForNextRun, substitution); @@ -461,20 +469,20 @@ private BindingResult continueBinding(RuleGroundingOrder groundingOrder, int ord } case FALSE: throw Util.oops("Got an assignmentStatus FALSE for literal " + groundingOrder.getLiteralAtOrderPosition(orderPosition) + " and substitution " - + substitution + " - should not happen!"); + + substitution + " - should not happen!"); default: throw Util.oops("Got unsupported assignmentStatus " + lastBoundLiteralAssignmentStatus); } } private BindingResult advanceAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { + Substitution partialSubstitution) { groundingOrder.considerUntilCurrentEnd(); return bindNextAtomInRule(groundingOrder, orderPosition + 1, originalTolerance, remainingTolerance, partialSubstitution); } private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { + Substitution partialSubstitution) { RuleGroundingOrder modifiedGroundingOrder = groundingOrder.pushBack(orderPosition); if (modifiedGroundingOrder == null) { return BindingResult.empty(); @@ -485,7 +493,7 @@ private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder grounding //@formatter:off /** - * Computes ground substitutions for a literal based on a {@link RuleGroundingOrder} and a {@link Substitution}. + * Computes ground substitutions for a literal based on a {@link RuleGroundingOrder} and a {@link SubstitutionImpl}. * * Computes ground substitutions for the literal at position orderPosition of groundingOrder * Actual substitutions are computed by this grounder's {@link LiteralInstantiator}. @@ -500,14 +508,14 @@ private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder grounding */ //@formatter:on private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, - Substitution partialSubstitution) { - CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); + Substitution partialSubstitution) { + Literal currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition); if (currentLiteral == null) { LOGGER.trace("No more literals found in grounding order, therefore stopping binding!"); return BindingResult.singleton(partialSubstitution, originalTolerance - remainingTolerance); } LOGGER.trace("Binding current literal {} with remaining tolerance {} and partial substitution {}.", currentLiteral, - remainingTolerance, partialSubstitution); + remainingTolerance, partialSubstitution); LiteralInstantiationResult instantiationResult = ruleInstantiator.instantiateLiteral(currentLiteral, partialSubstitution); switch (instantiationResult.getType()) { case CONTINUE: @@ -522,7 +530,7 @@ private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int BindingResult retVal = new BindingResult(); for (ImmutablePair substitutionInfo : substitutionInfos) { retVal.add(this.continueBinding(groundingOrder, orderPosition, originalTolerance, remainingTolerance, - substitutionInfo)); + substitutionInfo)); } return retVal; case PUSH_BACK: @@ -538,8 +546,10 @@ private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int * use, push the current literal to the end of the grounding order and proceed with the next one, otherwise return an empty BindingResult. */ if (originalTolerance > 0) { - LOGGER.trace("No substitutions yielded by literal instantiator for literal {}, but using permissive heuristic, therefore pushing the literal back.", currentLiteral); - // This occurs when the grounder heuristic in use is a "permissive" one, + LOGGER.trace( + "No substitutions yielded by literal instantiator for literal {}, but using permissive heuristic, therefore pushing the literal back.", + currentLiteral); + // This occurs when the grounder heuristic in use is a "permissive" one, // i.e. it is deemed acceptable to have ground rules where a number of body atoms are not yet assigned a truth value by the solver. return pushBackAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, partialSubstitution); } else { @@ -582,7 +592,7 @@ public InternalRule getNonGroundRule(Integer ruleId) { } @Override - public boolean isFact(CoreAtom atom) { + public boolean isFact(Atom atom) { LinkedHashSet instances = factsFromProgram.get(atom.getPredicate()); if (instances == null) { return false; @@ -591,11 +601,11 @@ public boolean isFact(CoreAtom atom) { } @Override - public Set justifyAtom(int atomToJustify, Assignment currentAssignment) { - Set literals = analyzeUnjustified.analyze(atomToJustify, currentAssignment); + public Set justifyAtom(int atomToJustify, Assignment currentAssignment) { + Set literals = analyzeUnjustified.analyze(atomToJustify, currentAssignment); // Remove facts from justification before handing it over to the solver. - for (Iterator iterator = literals.iterator(); iterator.hasNext(); ) { - CoreLiteral literal = iterator.next(); + for (Iterator iterator = literals.iterator(); iterator.hasNext();) { + Literal literal = iterator.next(); if (literal.isNegated()) { continue; } @@ -617,7 +627,7 @@ private void checkTypesOfNoGoods(Collection newNoGoods) { for (NoGood noGood : newNoGoods) { if (noGood.getType() != NoGoodInterface.Type.INTERNAL) { for (int literal : noGood) { - CoreAtom atom = atomStore.get(atomOf(literal)); + Atom atom = atomStore.get(atomOf(literal)); if (atom.getPredicate().isSolverInternal() && !(atom instanceof RuleAtom)) { throw oops("NoGood containing atom of internal predicate " + atom + " is " + noGood.getType() + " instead of INTERNAL"); } @@ -628,9 +638,9 @@ private void checkTypesOfNoGoods(Collection newNoGoods) { private static class FirstBindingAtom { final InternalRule rule; - final CoreLiteral startingLiteral; + final Literal startingLiteral; - FirstBindingAtom(InternalRule rule, CoreLiteral startingLiteral) { + FirstBindingAtom(InternalRule rule, Literal startingLiteral) { this.rule = rule; this.startingLiteral = startingLiteral; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java index 8733a0f94..456897772 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java @@ -40,13 +40,14 @@ import java.util.Map; import java.util.Set; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; 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.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.NoGood; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; @@ -58,11 +59,11 @@ public class NoGoodGenerator { private final AtomStore atomStore; private final ChoiceRecorder choiceRecorder; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private final InternalProgram programAnalysis; private final Set uniqueGroundRulePerGroundHead; - NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { + NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { this.atomStore = atomStore; this.choiceRecorder = recorder; this.factsFromProgram = factsFromProgram; @@ -95,7 +96,7 @@ List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundR final List result = new ArrayList<>(); - final CoreAtom groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); + final Atom groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution); final int headId = atomStore.putIfAbsent(groundHeadAtom); // Prepare atom representing the rule body. @@ -140,8 +141,8 @@ List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundR List collectNegLiterals(final InternalRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsNegative = new ArrayList<>(); - for (CoreLiteral lit : nonGroundRule.getNegativeBody()) { - CoreAtom groundAtom = lit.getAtom().substitute(substitution); + for (Literal lit : nonGroundRule.getNegativeBody()) { + Atom groundAtom = lit.getAtom().substitute(substitution); final Set factInstances = factsFromProgram.get(groundAtom.getPredicate()); @@ -162,7 +163,7 @@ List collectNegLiterals(final InternalRule nonGroundRule, final Substit private List collectPosLiterals(final InternalRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsPositive = new ArrayList<>(); - for (CoreLiteral lit : nonGroundRule.getPositiveBody()) { + for (Literal lit : nonGroundRule.getPositiveBody()) { if (lit instanceof FixedInterpretationLiteral) { // TODO: conversion of atom to literal is ugly. NonGroundRule could manage atoms instead of literals, cf. FIXME there // Atom has fixed interpretation, hence was checked earlier that it @@ -170,13 +171,13 @@ private List collectPosLiterals(final InternalRule nonGroundRule, final // FixedInterpretationAtoms need not be shown to the solver, skip it. continue; } - final CoreAtom atom = lit.getAtom(); + final Atom atom = lit.getAtom(); // Skip the special enumeration atom. if (atom instanceof EnumerationAtom) { continue; } - final CoreAtom groundAtom = atom.substitute(substitution); + final Atom groundAtom = atom.substitute(substitution); // Consider facts to eliminate ground atoms from the generated nogoods that are always true // and eliminate nogoods that are always satisfied due to facts. @@ -196,7 +197,7 @@ private List collectPosLiterals(final InternalRule nonGroundRule, final return bodyLiteralsPositive; } - private boolean existsRuleWithPredicateInHead(final CorePredicate predicate) { + private boolean existsRuleWithPredicateInHead(final Predicate predicate) { final HashSet definingRules = programAnalysis.getPredicateDefiningRules().get(predicate); return definingRules != null && !definingRules.isEmpty(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java index 99dd82276..85b9377ce 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java @@ -2,8 +2,8 @@ import java.util.Set; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; @@ -18,14 +18,14 @@ public interface ProgramAnalyzingGrounder extends Grounder { * @param currentAssignment the current assignment. * @return a set of literals who jointly imply the atomToJustify not being TRUE. */ - Set justifyAtom(int atomToJustify, Assignment currentAssignment); + Set justifyAtom(int atomToJustify, Assignment currentAssignment); /** * Returns true iff the given atom is known to the grounder as a fact (hence not occurring in any assignment). * @param atom the atom. * @return true iff atom is a fact. */ - boolean isFact(CoreAtom atom); + boolean isFact(Atom atom); /** * Returns the NonGroundRule identified by the given id. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java index 1af3a4985..6a09549a8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java @@ -28,7 +28,7 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** @@ -36,13 +36,13 @@ */ public class RuleGroundingOrder { - private CoreLiteral startingLiteral; - private List otherLiterals; + private Literal startingLiteral; + private List otherLiterals; private int positionLastVarBound; private int stopBindingAtOrderPosition; private final boolean ground; - RuleGroundingOrder(CoreLiteral startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { + RuleGroundingOrder(Literal startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { super(); this.startingLiteral = startingLiteral; this.otherLiterals = otherLiterals; @@ -66,7 +66,7 @@ private RuleGroundingOrder(RuleGroundingOrder otherRuleGroundingOrder) { * @param orderPosition zero-based index into list of literals except the starting literal * @return the literal at the given position, or {@code null} if it is already known that this literal is not able to yield new bindings */ - public CoreLiteral getLiteralAtOrderPosition(int orderPosition) { + public Literal getLiteralAtOrderPosition(int orderPosition) { if (orderPosition >= stopBindingAtOrderPosition) { return null; } @@ -125,7 +125,7 @@ public void considerUntilCurrentEnd() { this.stopBindingAtOrderPosition = this.otherLiterals.size(); } - public CoreLiteral getStartingLiteral() { + public Literal getStartingLiteral() { return this.startingLiteral; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java index 4b285b8bc..0c8b9adcd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java @@ -37,9 +37,10 @@ import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** @@ -62,9 +63,9 @@ */ public class RuleGroundingOrders { private final InternalRule internalRule; - HashMap groundingOrders; - private HashMap literalSelectivity; - private List startingLiterals; + HashMap groundingOrders; + private HashMap literalSelectivity; + private List startingLiterals; private final boolean fixedGroundingInstantiation; private RuleGroundingOrder fixedGroundingOrder; @@ -79,27 +80,28 @@ public RuleGroundingOrders(InternalRule internalRule) { private void resetLiteralSelectivity() { // Set selectivity of all literals to 1.0f. - for (CoreLiteral literal : internalRule.getBody()) { + for (Literal literal : internalRule.getBody()) { literalSelectivity.put(literal, 1.0f); } } /** * Computes starting literals and indicates whether there is a fixed ground instantiation for this rule. + * * @return true iff the rule has a fixed ground instantiation. */ private boolean computeStartingLiterals() { - LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); - LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); - + LinkedHashSet fixedStartingLiterals = new LinkedHashSet<>(); + LinkedHashSet ordinaryStartingLiterals = new LinkedHashSet<>(); + // If the rule is ground, every body literal is a starting literal and the ground instantiation is fixed. if (internalRule.isGround()) { startingLiterals = new LinkedList<>(internalRule.getBody()); return true; } - + // Check each literal in the rule body whether it is eligible. - for (CoreLiteral literal : internalRule.getBody()) { + for (Literal literal : internalRule.getBody()) { // Only literals that need no variables already bound can start grounding. if (literal.getNonBindingVariables().size() != 0) { continue; @@ -127,25 +129,25 @@ private boolean computeStartingLiterals() { } } - public List getStartingLiterals() { + public List getStartingLiterals() { return Collections.unmodifiableList(startingLiterals); } - public void updateLiteralSelectivity(CoreLiteral literal, int numGivenTuples, int numObtainedTuples) { + public void updateLiteralSelectivity(Literal literal, int numGivenTuples, int numObtainedTuples) { // TODO: add old selectivity (with a decay factor) and new selectivity. } - public RuleGroundingOrder orderStartingFrom(CoreLiteral startingLiteral) { + public RuleGroundingOrder orderStartingFrom(Literal startingLiteral) { return groundingOrders.get(startingLiteral); } - public RuleGroundingOrder getFixedGroundingOrder() { return fixedGroundingOrder; } /** * States whether the rule is without positive ordinary atoms, as for example in: p(Y) :- X = 1..3, not q(X), Y = X + 2, &ext[X,Y](). + * * @return true if the rule has a (limited number of) fixed grounding instantiation(s). */ public boolean fixedInstantiation() { @@ -159,31 +161,32 @@ public void computeGroundingOrders() { return; } // Compute grounding orders for all positive BasicAtoms. - for (CoreLiteral literal : startingLiterals) { + for (Literal literal : startingLiterals) { computeGroundingOrder(literal); } } - private void computeGroundingOrder(CoreLiteral startingLiteral) { - Set bodyLiterals = internalRule.getBody(); - HashSet boundVariables = new HashSet<>(); + private void computeGroundingOrder(Literal startingLiteral) { + Set bodyLiterals = internalRule.getBody(); + HashSet boundVariables = new HashSet<>(); boundVariables.addAll(startingLiteral.getBindingVariables()); - LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); + LinkedHashSet remainingLiterals = new LinkedHashSet<>(bodyLiterals); remainingLiterals.remove(startingLiteral); - ArrayList literalsOrder; + ArrayList literalsOrder; if (fixedGroundingInstantiation) { literalsOrder = new ArrayList<>(bodyLiterals.size()); literalsOrder.add(startingLiteral); } else { literalsOrder = new ArrayList<>(bodyLiterals.size() - 1); } - + int position = 0; int positionLastVarBound = -1; while (!remainingLiterals.isEmpty()) { - CoreLiteral nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); + Literal nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables); if (nextGroundingLiteral == null) { - throw new RuntimeException("Could not find a grounding order for rule " + internalRule + " with starting literal: " + startingLiteral + ". Rule is not safe."); + throw new RuntimeException( + "Could not find a grounding order for rule " + internalRule + " with starting literal: " + startingLiteral + ". Rule is not safe."); } remainingLiterals.remove(nextGroundingLiteral); boolean boundNewVars = boundVariables.addAll(nextGroundingLiteral.getBindingVariables()); @@ -199,13 +202,13 @@ private void computeGroundingOrder(CoreLiteral startingLiteral) { groundingOrders.put(startingLiteral, new RuleGroundingOrder(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); } - private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { + private Literal selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { Float bestSelectivity = Float.MAX_VALUE; - CoreLiteral bestLiteral = null; + Literal bestLiteral = null; boolean bestLiteralSharesVariables = false; // Find the best literal whose nonbinding variables are already bound and whose selectivity is highest. // To avoid cross products, select those first that have some of their variables already bound. - for (CoreLiteral literal : remainingLiterals) { + for (Literal literal : remainingLiterals) { if (!boundVariables.containsAll(literal.getNonBindingVariables())) { // Only consider literals whose nonbinding variables are already bound. continue; @@ -213,8 +216,8 @@ private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remain Float selectivity = literalSelectivity.get(literal); boolean sharesVariables = sharesVariables(boundVariables, literal.getBindingVariables(), literal.getNonBindingVariables()); if (bestLiteral == null - || sharesVariables && selectivity < bestSelectivity - || sharesVariables && !bestLiteralSharesVariables) { + || sharesVariables && selectivity < bestSelectivity + || sharesVariables && !bestLiteralSharesVariables) { bestLiteral = literal; bestSelectivity = selectivity; bestLiteralSharesVariables = sharesVariables; @@ -223,7 +226,7 @@ private CoreLiteral selectNextGroundingLiteral(LinkedHashSet remain return bestLiteral; } - private boolean sharesVariables(Collection set1, Collection set2part1, Collection set2part2) { + private boolean sharesVariables(Collection set1, Collection set2part1, Collection set2part2) { return !Collections.disjoint(set1, set2part1) || !Collections.disjoint(set1, set2part2); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java similarity index 70% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java index b93ae5059..2aaa0b90a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Substitution.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java @@ -27,50 +27,52 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; - import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.TreeMap; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; +import at.ac.tuwien.kr.alpha.core.util.Util; -public class Substitution { +public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Substitution { private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); - public static final Substitution EMPTY_SUBSTITUTION = new Substitution() { + public static final SubstitutionImpl EMPTY_SUBSTITUTION = new SubstitutionImpl() { @Override - public > CoreTerm put(VariableTermImpl variableTerm, CoreTerm groundTerm) { - throw oops("Should not be called on EMPTY_SUBSTITUTION"); + public > CoreTerm put(VariableTerm variableTerm, Term groundTerm) { + throw Util.oops("Should not be called on EMPTY_SUBSTITUTION"); } }; - protected TreeMap substitution; + protected TreeMap substitution; - private Substitution(TreeMap substitution) { + private SubstitutionImpl(TreeMap substitution) { if (substitution == null) { - throw oops("Substitution is null."); + throw Util.oops("Substitution is null."); } this.substitution = substitution; } - public Substitution() { + public SubstitutionImpl() { this(new TreeMap<>()); } - public Substitution(Substitution clone) { - this(new TreeMap<>(clone.substitution)); + public SubstitutionImpl(Substitution clone) { + this(new TreeMap<>(clone.getSubstitution())); } - public static Substitution specializeSubstitution(CoreLiteral literal, Instance instance, Substitution substitution) { + public static Substitution specializeSubstitution(Literal literal, Instance instance, Substitution substitution) { return specializeSubstitution(literal.getAtom(), instance, substitution); } @@ -78,9 +80,10 @@ public static Substitution specializeSubstitution(CoreLiteral literal, Instance * Helper class to lazily clone the input substitution of Substitution.specializeSubstitution only when needed. */ private static class SpecializationHelper { - Substitution updatedSubstitution; // Is null for as long as the given partial substitution is not extended, afterwards holds the updated/extended/specialized substitution. + Substitution updatedSubstitution; // Is null for as long as the given partial substitution is not extended, afterwards holds the + // updated/extended/specialized substitution. - Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { + Substitution unify(List termList, Instance instance, Substitution partialSubstitution) { for (int i = 0; i < termList.size(); i++) { if (!unifyTerms(termList.get(i), instance.terms.get(i), partialSubstitution)) { return null; @@ -93,7 +96,7 @@ Substitution unify(List termList, Instance instance, Substit return updatedSubstitution; } - boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution partialSubstitution) { + boolean unifyTerms(Term termNonGround, Term termGround, Substitution partialSubstitution) { if (termNonGround == termGround) { // Both terms are either the same constant or the same variable term return true; @@ -101,10 +104,14 @@ boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution par // Since right term is ground, both terms differ return false; } else if (termNonGround instanceof VariableTermImpl) { - VariableTermImpl variableTerm = (VariableTermImpl) termNonGround; + VariableTerm variableTerm = (VariableTerm) termNonGround; // Left term is variable, bind it to the right term. Use original substitution if it has // not been cloned yet. - CoreTerm bound = (updatedSubstitution == null ? partialSubstitution : updatedSubstitution).eval(variableTerm); // Get variable binding, either from input substitution if it has not been updated yet, or from the cloned/updated substitution. + Term bound = (updatedSubstitution == null ? partialSubstitution : updatedSubstitution).eval(variableTerm); // Get variable binding, either + // from input substitution if it + // has not been updated yet, or + // from the cloned/updated + // substitution. if (bound != null) { // Variable is already bound, return true if binding is the same as the current ground term. return termGround == bound; @@ -112,7 +119,7 @@ boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution par // Record new variable binding. if (updatedSubstitution == null) { // Clone substitution if it was not yet updated. - updatedSubstitution = new Substitution(partialSubstitution); + updatedSubstitution = new SubstitutionImpl(partialSubstitution); } updatedSubstitution.put(variableTerm, termGround); return true; @@ -152,30 +159,32 @@ boolean unifyTerms(CoreTerm termNonGround, CoreTerm termGround, Substitution par * @param instance the ground instance to unify the atom with. * @param substitution the (partial) substitution for the atom. This is left unchanged in all cases. * @return null if the unification/specialization fails, otherwise it is a unifying substitution. If the - * parameter substitution already is a unifier, it is returned. If the unifying substitution is an - * extension of the input substitution, a new substitution will be returned. + * parameter substitution already is a unifier, it is returned. If the unifying substitution is an + * extension of the input substitution, a new substitution will be returned. */ - public static Substitution specializeSubstitution(CoreAtom atom, Instance instance, Substitution substitution) { + public static Substitution specializeSubstitution(Atom atom, Instance instance, Substitution substitution) { return new SpecializationHelper().unify(atom.getTerms(), instance, substitution); } /** - * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTermImpl} under this substitution. + * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTermImpl} under this + * substitution. * * @param variableTerm the variable term to substitute, if possible * @return a constant term if the substitution contains the given variable, {@code null} otherwise. */ - public CoreTerm eval(VariableTermImpl variableTerm) { + @Override + public Term eval(VariableTerm variableTerm) { return this.substitution.get(variableTerm); } - public > CoreTerm put(VariableTermImpl variableTerm, CoreTerm groundTerm) { + public > Term put(VariableTerm variableTerm, Term groundTerm) { if (!groundTerm.isGround()) { - throw oops("Right-hand term is not ground."); + throw Util.oops("Right-hand term is not ground."); } - CoreTerm alreadyAssigned = substitution.get(variableTerm); + Term alreadyAssigned = substitution.get(variableTerm); if (alreadyAssigned != null && alreadyAssigned != groundTerm) { - throw oops("Variable is already assigned to another term."); + throw Util.oops("Variable is already assigned to another term."); } // Note: We're destroying type information here. return substitution.put(variableTerm, groundTerm); @@ -185,11 +194,11 @@ public boolean isEmpty() { return substitution.isEmpty(); } - public boolean isVariableSet(VariableTermImpl variable) { + public boolean isVariableSet(VariableTerm variable) { return substitution.get(variable) != null; } - public Set getMappedVariables() { + public Set getMappedVariables() { return substitution.keySet(); } @@ -202,7 +211,7 @@ public Set getMappedVariables() { public String toString() { final StringBuilder ret = new StringBuilder("{"); boolean isFirst = true; - for (Map.Entry e : substitution.entrySet()) { + for (Map.Entry e : substitution.entrySet()) { if (isFirst) { isFirst = false; } else { @@ -214,10 +223,10 @@ public String toString() { return ret.toString(); } - public static Substitution fromString(String substitution) { + public static SubstitutionImpl fromString(String substitution) { String bare = substitution.substring(1, substitution.length() - 1); String[] assignments = bare.split(","); - Substitution ret = new Substitution(); + SubstitutionImpl ret = new SubstitutionImpl(); for (String assignment : assignments) { String[] keyVal = assignment.split("->"); VariableTermImpl variable = VariableTermImpl.getInstance(keyVal[0]); @@ -236,7 +245,7 @@ public boolean equals(Object o) { return false; } - Substitution that = (Substitution) o; + SubstitutionImpl that = (SubstitutionImpl) o; return Objects.equals(substitution, that.substitution); } @@ -245,4 +254,11 @@ public boolean equals(Object o) { public int hashCode() { return substitution != null ? substitution.hashCode() : 0; } + + + @Override + public TreeMap getSubstitution() { + return this.substitution; + } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index cfaf9ad7a..129e93af2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -31,8 +31,9 @@ import java.util.Set; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; @@ -41,7 +42,7 @@ */ public class Unification { - public static Unifier unifyAtoms(CoreAtom left, CoreAtom right) { + public static Unifier unifyAtoms(Atom left, Atom right) { return unifyAtoms(left, right, false); } @@ -51,17 +52,17 @@ public static Unifier unifyAtoms(CoreAtom left, CoreAtom right) { * @param specific the specific Atom. * @return a Unifier sigma such that specific == general.substitute(sigma), returns null if no such sigma exists. */ - public static Unifier instantiate(CoreAtom general, CoreAtom specific) { + public static Unifier instantiate(Atom general, Atom specific) { return unifyAtoms(specific, general, true); } - private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLeftAsIs) { - Set leftOccurringVariables = left.getOccurringVariables(); - Set rightOccurringVaribles = right.getOccurringVariables(); + private static Unifier unifyAtoms(Atom left, Atom right, boolean keepLeftAsIs) { + Set leftOccurringVariables = left.getOccurringVariables(); + Set rightOccurringVaribles = right.getOccurringVariables(); boolean leftSmaller = leftOccurringVariables.size() < rightOccurringVaribles.size(); - Set smallerSet = leftSmaller ? leftOccurringVariables : rightOccurringVaribles; - Set largerSet = leftSmaller ? rightOccurringVaribles : leftOccurringVariables; - for (VariableTermImpl variableTerm : smallerSet) { + Set smallerSet = leftSmaller ? leftOccurringVariables : rightOccurringVaribles; + Set largerSet = leftSmaller ? rightOccurringVaribles : leftOccurringVariables; + for (VariableTerm variableTerm : smallerSet) { if (largerSet.contains(variableTerm)) { throw oops("Left and right atom share variables."); } @@ -71,8 +72,8 @@ private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLef return null; } for (int i = 0; i < left.getPredicate().getArity(); i++) { - final CoreTerm leftTerm = left.getTerms().get(i); - final CoreTerm rightTerm = right.getTerms().get(i); + final Term leftTerm = left.getTerms().get(i); + final Term rightTerm = right.getTerms().get(i); if (!unifyTerms(leftTerm, rightTerm, mgu, keepLeftAsIs)) { return null; } @@ -80,9 +81,9 @@ private static Unifier unifyAtoms(CoreAtom left, CoreAtom right, boolean keepLef return mgu; } - private static boolean unifyTerms(CoreTerm left, CoreTerm right, Unifier currentSubstitution, boolean keepLeftAsIs) { - final CoreTerm leftSubs = left.substitute(currentSubstitution); - final CoreTerm rightSubs = right.substitute(currentSubstitution); + private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitution, boolean keepLeftAsIs) { + final Term leftSubs = left.substitute(currentSubstitution); + final Term rightSubs = right.substitute(currentSubstitution); if (leftSubs == rightSubs) { return true; } @@ -102,8 +103,8 @@ private static boolean unifyTerms(CoreTerm left, CoreTerm right, Unifier current return false; } for (int i = 0; i < leftFunction.getTerms().size(); i++) { - final CoreTerm leftTerm = leftFunction.getTerms().get(i); - final CoreTerm rightTerm = rightFunction.getTerms().get(i); + final Term leftTerm = leftFunction.getTerms().get(i); + final Term rightTerm = rightFunction.getTerms().get(i); if (!unifyTerms(leftTerm, rightTerm, currentSubstitution, keepLeftAsIs)) { return false; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java index 30753313c..8e3b7158d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java @@ -9,19 +9,20 @@ import java.util.Set; import java.util.TreeMap; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +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.terms.VariableTerm; /** * A variable substitution allowing variables to occur on the right-hand side. Chains of variable substitutions are * resolved automatically, i.e., adding the substitutions (X -> A) and (A -> d) results in (X -> d), (A -> d). * Copyright (c) 2018-2020, the Alpha Team. */ -public class Unifier extends Substitution { +public class Unifier extends SubstitutionImpl { - private final TreeMap> rightHandVariableOccurrences; + private final TreeMap> rightHandVariableOccurrences; - private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { + private Unifier(TreeMap substitution, TreeMap> rightHandVariableOccurrences) { if (substitution == null) { throw oops("Substitution is null."); } @@ -38,51 +39,51 @@ public Unifier(Unifier clone) { } public Unifier(Substitution clone) { - this(new TreeMap<>(clone.substitution), new TreeMap<>()); + this(new TreeMap<>(clone.getSubstitution()), new TreeMap<>()); } - - public Unifier extendWith(Substitution extension) { - for (Map.Entry extensionVariable : extension.substitution.entrySet()) { + public Unifier extendWith(SubstitutionImpl extension) { + for (Map.Entry extensionVariable : extension.substitution.entrySet()) { this.put(extensionVariable.getKey(), extensionVariable.getValue()); } return this; } /** - * Returns a list of all variables occurring in that unifier, i.e., variables that are mapped and those that occur (nested) in the right-hand side of the unifier. + * Returns a list of all variables occurring in that unifier, i.e., variables that are mapped and those that occur (nested) in the + * right-hand side of the unifier. + * * @return the list of variables occurring somewhere in the unifier. */ @Override - public Set getMappedVariables() { - Set ret = new HashSet<>(); - for (Map.Entry substitution : substitution.entrySet()) { + public Set getMappedVariables() { + Set ret = new HashSet<>(); + for (Map.Entry substitution : substitution.entrySet()) { ret.add(substitution.getKey()); ret.addAll(substitution.getValue().getOccurringVariables()); } return ret; } - @Override - public > CoreTerm put(VariableTermImpl variableTerm, CoreTerm term) { + public > Term put(VariableTerm variableTerm, Term term) { // If term is not ground, store it for right-hand side reverse-lookup. if (!term.isGround()) { - for (VariableTermImpl rightHandVariable : term.getOccurringVariables()) { + for (VariableTerm rightHandVariable : term.getOccurringVariables()) { rightHandVariableOccurrences.putIfAbsent(rightHandVariable, new ArrayList<>()); rightHandVariableOccurrences.get(rightHandVariable).add(variableTerm); } } // Note: We're destroying type information here. - CoreTerm ret = substitution.put(variableTerm, term); + Term ret = substitution.put(variableTerm, term); // Check if the just-assigned variable occurs somewhere in the right-hand side already. - List rightHandOccurrences = rightHandVariableOccurrences.get(variableTerm); + List rightHandOccurrences = rightHandVariableOccurrences.get(variableTerm); if (rightHandOccurrences != null) { // Replace all occurrences on the right-hand side with the just-assigned term. - for (VariableTermImpl rightHandOccurrence : rightHandOccurrences) { + for (VariableTerm rightHandOccurrence : rightHandOccurrences) { // Substitute the right hand where this assigned variable occurs with the new value and store it. - CoreTerm previousRightHand = substitution.get(rightHandOccurrence); + Term previousRightHand = substitution.get(rightHandOccurrence); if (previousRightHand == null) { // Variable does not occur on the lef-hand side, skip. continue; @@ -99,6 +100,7 @@ public > CoreTerm put(VariableTermImpl variableTerm, Cor * Left mappings are seen as equalities, i.e., * if left has A -> B and right has A -> t then the result will have A -> t and B -> t. * If both substitutions are inconsistent, i.e., A -> t1 in left and A -> t2 in right, then null is returned. + * * @param left * @param right * @return @@ -106,20 +108,20 @@ public > CoreTerm put(VariableTermImpl variableTerm, Cor public static Unifier mergeIntoLeft(Unifier left, Unifier right) { // Note: we assume both substitutions are free of chains, i.e., no A->B, B->C but A->C, B->C. Unifier ret = new Unifier(left); - for (Map.Entry mapping : right.substitution.entrySet()) { - VariableTermImpl variable = mapping.getKey(); - CoreTerm term = mapping.getValue(); + for (Map.Entry mapping : right.substitution.entrySet()) { + VariableTerm variable = mapping.getKey(); + Term term = mapping.getValue(); // If variable is unset, simply add. if (!ret.isVariableSet(variable)) { ret.put(variable, term); continue; } // Variable is already set. - CoreTerm setTerm = ret.eval(variable); - if (setTerm instanceof VariableTermImpl) { + Term setTerm = ret.eval(variable); + if (setTerm instanceof VariableTerm) { // Variable maps to another variable in left. // Add a new mapping of the setTerm variable into our right-assigned term. - ret.put((VariableTermImpl) setTerm, term); + ret.put((VariableTerm) setTerm, term); // Note: Unifier.put takes care of resolving the chain variable->setTerm->term. continue; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java index 743579b0b..63ab287e9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java @@ -34,19 +34,19 @@ import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; public class WorkingMemory { - protected HashMap> workingMemory = new HashMap<>(); + protected HashMap> workingMemory = new HashMap<>(); private HashSet modifiedWorkingMemories = new LinkedHashSet<>(); - public boolean contains(CorePredicate predicate) { + public boolean contains(Predicate predicate) { return workingMemory.containsKey(predicate); } - public void initialize(CorePredicate predicate) { + public void initialize(Predicate predicate) { if (workingMemory.containsKey(predicate)) { return; } @@ -62,15 +62,15 @@ public void initialize(CorePredicate predicate) { workingMemory.put(predicate, new ImmutablePair<>(pos, neg)); } - public IndexedInstanceStorage get(CoreLiteral literal) { + public IndexedInstanceStorage get(Literal literal) { return get(literal.getAtom(), !literal.isNegated()); } - public IndexedInstanceStorage get(CoreAtom atom, boolean value) { + public IndexedInstanceStorage get(Atom atom, boolean value) { return get(atom.getPredicate(), value); } - public IndexedInstanceStorage get(CorePredicate predicate, boolean value) { + public IndexedInstanceStorage get(Predicate predicate, boolean value) { ImmutablePair pair = workingMemory.get(predicate); if (value) { return pair.getLeft(); @@ -79,11 +79,11 @@ public IndexedInstanceStorage get(CorePredicate predicate, boolean value) { } } - public void addInstance(CoreAtom atom, boolean value) { + public void addInstance(Atom atom, boolean value) { addInstance(atom.getPredicate(), value, new Instance(atom.getTerms())); } - public void addInstance(CorePredicate predicate, boolean value, Instance instance) { + public void addInstance(Predicate predicate, boolean value, Instance instance) { IndexedInstanceStorage storage = get(predicate, value); if (!storage.containsInstance(instance)) { @@ -92,7 +92,7 @@ public void addInstance(CorePredicate predicate, boolean value, Instance instanc } } - public void addInstances(CorePredicate predicate, boolean value, Iterable instances) { + public void addInstances(Predicate predicate, boolean value, Iterable instances) { IndexedInstanceStorage storage = get(predicate, value); for (Instance instance : instances) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java index d4c0a3701..ec05f3465 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -25,22 +25,22 @@ */ package at.ac.tuwien.kr.alpha.core.grounder.instantiation; -import at.ac.tuwien.kr.alpha.api.program.*; -import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.grounder.Instance; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.lang3.tuple.ImmutablePair; -import java.util.ArrayList; -import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Abstract base implementation of {@link LiteralInstantiationStrategy} that outlines a basic workflow for * {@link LiteralInstantiationStrategy#getTruthForGroundLiteral(Literal)} and - * {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)} while leaving details of when an atom is true and + * {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, SubstitutionImpl)} while leaving details of when an atom is true and * which {@link AssignmentStatus}es to consider valid for getAcceptedSubstitutions to implementations. * * Copyright (c) 2020, the Alpha Team. @@ -56,7 +56,7 @@ public abstract class AbstractLiteralInstantiationStrategy implements LiteralIns * literals is determined using the abstract method {@link AbstractLiteralInstantiationStrategy#getAssignmentStatusForAtom(Atom)}. */ @Override - public final AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral) { + public final AssignmentStatus getTruthForGroundLiteral(Literal groundLiteral) { if (groundLiteral.isNegated()) { return this.getAssignmentStatusForNegatedGroundLiteral(groundLiteral); } @@ -64,7 +64,7 @@ public final AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral } /** - * See {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)}. + * See {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, SubstitutionImpl)}. * * A very general implementation of the basic steps needed to obtain ground substitutions for a positive literal. * Potentially valid ground instances are obtained using {@link AbstractLiteralInstantiationStrategy#computeCandidateInstances(Atom)}, then @@ -73,8 +73,8 @@ public final AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral * {@link AbstractLiteralInstantiationStrategy#assignmentStatusAccepted(AssignmentStatus)}. */ @Override - public final List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution) { - CoreAtom atom = lit.getAtom(); + public final List> getAcceptedSubstitutions(Literal lit, Substitution partialSubstitution) { + Atom atom = lit.getAtom(); Iterable groundInstances = this.computeCandidateInstances(atom); return this.buildSubstitutionsFromInstances(atom, groundInstances, partialSubstitution); } @@ -88,7 +88,7 @@ public final List> getAcceptedSubs * @param partiallyGroundAtom a partially ground atom for which to find fitting ground instances * @return a list of candidate instances */ - protected abstract Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom); + protected abstract Iterable computeCandidateInstances(Atom partiallyGroundAtom); /** * Based on a list of candidate instances (see {@link AbstractLiteralInstantiationStrategy#computeCandidateInstances(Atom)}), create a list @@ -100,14 +100,14 @@ public final List> getAcceptedSubs * @param partialSubstitution * @return */ - protected final List> buildSubstitutionsFromInstances(CoreAtom atomToSubstitute, + protected final List> buildSubstitutionsFromInstances(Atom atomToSubstitute, Iterable candidateInstances, Substitution partialSubstitution) { List> retVal = new ArrayList<>(); // Filter for only instances unifying with partialSubsitution, i.e. "where all joins work out". Substitution currentInstanceSubstitution; - CoreAtom atomForCurrentInstance; + Atom atomForCurrentInstance; for (Instance instance : candidateInstances) { - currentInstanceSubstitution = Substitution.specializeSubstitution(atomToSubstitute, instance, partialSubstitution); + currentInstanceSubstitution = SubstitutionImpl.specializeSubstitution(atomToSubstitute, instance, partialSubstitution); if (currentInstanceSubstitution == null) { // Instance does not unify with partialSubstitution, move on to the next instance. continue; @@ -126,9 +126,9 @@ protected final List> buildSubstit return retVal; } - protected abstract AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom); + protected abstract AssignmentStatus getAssignmentStatusForAtom(Atom atom); - protected abstract AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral); + protected abstract AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(Literal negatedGroundLiteral); protected abstract boolean assignmentStatusAccepted(AssignmentStatus assignmentStatus); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/BindingResult.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/BindingResult.java index 370038df4..c20ff1b67 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/BindingResult.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/BindingResult.java @@ -28,7 +28,7 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; /** * Contains substitutions produced for generating ground substitutions of a rule, diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java index f0dd352db..58d72f7f6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java @@ -28,11 +28,12 @@ import java.util.LinkedHashSet; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; 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.CorePredicate; import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; @@ -70,18 +71,18 @@ public class DefaultLazyGroundingInstantiationStrategy extends AbstractLiteralIn private WorkingMemory workingMemory; private AtomStore atomStore; private Assignment currentAssignment; - private LinkedHashSet staleWorkingMemoryEntries; - private Map> facts; + private LinkedHashSet staleWorkingMemoryEntries; + private Map> facts; public DefaultLazyGroundingInstantiationStrategy(WorkingMemory workingMemory, AtomStore atomStore, - Map> facts) { + Map> facts) { this.workingMemory = workingMemory; this.atomStore = atomStore; this.facts = facts; } @Override - protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { + protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) { IndexedInstanceStorage instanceStorage = this.workingMemory.get(partiallyGroundAtom, true); return instanceStorage.getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); } @@ -105,7 +106,7 @@ protected Iterable computeCandidateInstances(CoreAtom partiallyGroundA */ //@formatter:on @Override - protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { + protected AssignmentStatus getAssignmentStatusForAtom(Atom atom) { if (this.currentAssignment == null || this.isFact(atom)) { // currentAssignment == null is a legitimate case, grounder may be in bootstrap // and will call bindNextAtom with null assignment in that case. @@ -133,7 +134,7 @@ protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { return retVal; } - private boolean isFact(CoreAtom atom) { + private boolean isFact(Atom atom) { if (this.facts.get(atom.getPredicate()) == null) { return false; } else { @@ -142,7 +143,7 @@ private boolean isFact(CoreAtom atom) { } @Override - protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { + protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(Literal negatedGroundLiteral) { return AssignmentStatus.TRUE; } @@ -169,7 +170,7 @@ public void setCurrentAssignment(Assignment currentAssignment) { this.currentAssignment = currentAssignment; } - public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { + public void setStaleWorkingMemoryEntries(LinkedHashSet staleWorkingMemoryEntries) { this.staleWorkingMemoryEntries = staleWorkingMemoryEntries; } 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 4e6567edc..ac4072417 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 @@ -31,13 +31,15 @@ import org.apache.commons.lang3.tuple.ImmutablePair; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Representation of the result of instantiating, i.e. finding ground instances for a literal, as performed by - * {@link LiteralInstantiator#instantiateLiteral(Literal, Substitution)}. + * {@link LiteralInstantiator#instantiateLiteral(Literal, SubstitutionImpl)}. * * 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 diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationStrategy.java index 5b0fdf017..7cf3168f9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/LiteralInstantiationStrategy.java @@ -29,12 +29,13 @@ import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** - * A {@link LiteralInstantiationStrategy} finds and validates {@link Substitution}s for {@link Literal}s based on a specific definition of - * when a {@link Substitution} is valid, i.e. what makes a literal "true", "false" or "unassigned". + * A {@link LiteralInstantiationStrategy} finds and validates {@link SubstitutionImpl}s for {@link Literal}s based on a specific definition of + * when a {@link SubstitutionImpl} is valid, i.e. what makes a literal "true", "false" or "unassigned". * * Copyright (c) 2020, the Alpha Team. */ @@ -46,12 +47,12 @@ public interface LiteralInstantiationStrategy { * @param groundLiteral a ground {@link Literal} for which to compute an {@link AssignmentStatus} * @return the current {@link AssignmentStatus} for the given literal according to the rules of this {@link LiteralInstantiationStrategy} */ - AssignmentStatus getTruthForGroundLiteral(CoreLiteral groundLiteral); + AssignmentStatus getTruthForGroundLiteral(Literal groundLiteral); /** - * Computes {@link Substitution}s that yield ground instances for a given literal and starting substitution along with the + * Computes {@link SubstitutionImpl}s that yield ground instances for a given literal and starting substitution along with the * {@link AssignmentStatus} of respective ground instances. Note that in all implementations it must hold that an {@link AssignmentStatus} - * AS for a {@link Substitution} S as yielded by this method for a {@link Literal} lit is the same as the result of calling + * AS for a {@link SubstitutionImpl} S as yielded by this method for a {@link Literal} lit is the same as the result of calling * getTruthForGroundLiteral(lit.substitute(S)), i.e. both methods must yield the same assignment status for the same ground * literal. * @@ -59,6 +60,6 @@ public interface LiteralInstantiationStrategy { * @param partialSubstitution a (possibly empty) substitution to use as a starting point * @return a list of substitutions along with the assignment status of the respective ground atoms */ - List> getAcceptedSubstitutions(CoreLiteral lit, Substitution partialSubstitution); + List> getAcceptedSubstitutions(Literal lit, Substitution partialSubstitution); } 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 2de02f7a1..91c3aac41 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 @@ -25,20 +25,20 @@ */ package at.ac.tuwien.kr.alpha.core.grounder.instantiation; -import at.ac.tuwien.kr.alpha.api.program.*; -import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.EnumerationLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.IntervalLiteral; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import java.util.List; import org.apache.commons.lang3.tuple.ImmutablePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.IntervalLiteral; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Provides ground instantiations for literals. @@ -65,7 +65,7 @@ public LiteralInstantiator(LiteralInstantiationStrategy instantiationStrategy) { } /** - * Instantiates a literal using an existing {@link Substitution} as starting point. + * Instantiates a literal using an existing {@link SubstitutionImpl} as starting point. * * This method is intended to be called as part of a larger rule instantiation (i.e. grounding) workflow in order to find ground * instantiations of literals, i.e. extensions of the given partial substitution that yield useable ground instances for the given literal. @@ -75,7 +75,7 @@ public LiteralInstantiator(LiteralInstantiationStrategy instantiationStrategy) { * @param partialSubstitution a substitution that serves as a starting point. May be empty. * @return a {@link LiteralInstantiationResult} containing ground substitutions - if any exist - along with some metadata for the grounder */ - public LiteralInstantiationResult instantiateLiteral(CoreLiteral lit, Substitution partialSubstitution) { + public LiteralInstantiationResult instantiateLiteral(Literal lit, Substitution partialSubstitution) { LOGGER.trace("Instantiating literal: {}", lit); if (lit instanceof FixedInterpretationLiteral) { return this.instantiateFixedInterpretationLiteral((FixedInterpretationLiteral) lit, partialSubstitution); @@ -112,7 +112,7 @@ private LiteralInstantiationResult instantiateFixedInterpretationLiteral(FixedIn } /** - * Calculates a substitution that adds an enumeration index (see {@link EnumerationLiteral#addEnumerationIndexToSubstitution(Substitution)}) + * Calculates a substitution that adds an enumeration index (see {@link EnumerationLiteral#addEnumerationIndexToSubstitution(SubstitutionImpl)}) * 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. @@ -135,10 +135,10 @@ private LiteralInstantiationResult instantiateEnumerationLiteral(EnumerationLite * @param lit * @param partialSubstitution */ - private LiteralInstantiationResult instantiateBasicLiteral(CoreLiteral lit, Substitution partialSubstitution) { + private LiteralInstantiationResult instantiateBasicLiteral(Literal lit, Substitution partialSubstitution) { LOGGER.trace("Instantiating basic literal: {}", lit); List> substitutions; - CoreLiteral substitutedLiteral = lit.substitute(partialSubstitution); + Literal substitutedLiteral = lit.substitute(partialSubstitution); LOGGER.trace("Substituted literal is {}", substitutedLiteral); if (substitutedLiteral.isGround()) { LOGGER.trace("Literal {} is already ground, checking truth", substitutedLiteral); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java index 9c86709ab..f69d5f0c7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java @@ -25,8 +25,8 @@ */ package at.ac.tuwien.kr.alpha.core.grounder.instantiation; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; @@ -47,17 +47,17 @@ public WorkingMemoryBasedInstantiationStrategy(WorkingMemory workingMemory) { } @Override - protected Iterable computeCandidateInstances(CoreAtom partiallyGroundAtom) { + protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) { return this.workingMemory.get(partiallyGroundAtom, true).getInstancesFromPartiallyGroundAtom(partiallyGroundAtom); } @Override - protected AssignmentStatus getAssignmentStatusForAtom(CoreAtom atom) { + protected AssignmentStatus getAssignmentStatusForAtom(Atom atom) { return this.workingMemory.get(atom, true).containsInstance(Instance.fromAtom(atom)) ? AssignmentStatus.TRUE : AssignmentStatus.FALSE; } @Override - protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(CoreLiteral negatedGroundLiteral) { + protected AssignmentStatus getAssignmentStatusForNegatedGroundLiteral(Literal negatedGroundLiteral) { return this.getAssignmentStatusForAtom(negatedGroundLiteral.getAtom()) == AssignmentStatus.TRUE ? AssignmentStatus.FALSE : AssignmentStatus.TRUE; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java index 6a6bb1b52..b1fba7404 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java @@ -1,15 +1,31 @@ package at.ac.tuwien.kr.alpha.core.grounder.structure; -import at.ac.tuwien.kr.alpha.api.program.*; +import static at.ac.tuwien.kr.alpha.core.util.Util.oops; + +import java.util.ArrayList; +import java.util.Collections; +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.NoSuchElementException; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; 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.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.Unification; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; @@ -17,13 +33,6 @@ import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; - -import java.util.*; - /** * Copyright (c) 2018-2020, the Alpha Team. */ @@ -31,22 +40,22 @@ public class AnalyzeUnjustified { private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeUnjustified.class); private final InternalProgram programAnalysis; private final AtomStore atomStore; - private final Map> factsFromProgram; + private final Map> factsFromProgram; private int renamingCounter; private int padDepth; - public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { + public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { this.programAnalysis = programAnalysis; this.atomStore = atomStore; this.factsFromProgram = factsFromProgram; padDepth = 0; } - private Map> assignedAtoms; + private Map> assignedAtoms; - public Set analyze(int atomToJustify, Assignment currentAssignment) { + public Set analyze(int atomToJustify, Assignment currentAssignment) { padDepth = 0; - CoreAtom atom = atomStore.get(atomToJustify); + Atom atom = atomStore.get(atomToJustify); if (!(atom instanceof BasicAtom)) { throw oops("Starting atom must be a BasicAtom, but received: " + atom + " of type: " + atom.getClass()); } @@ -63,16 +72,16 @@ public Set analyze(int atomToJustify, Assignment currentAssignment) if (truth == null) { continue; } - CoreAtom assignedAtom = atomStore.get(i); + Atom assignedAtom = atomStore.get(i); assignedAtoms.putIfAbsent(assignedAtom.getPredicate(), new ArrayList<>()); assignedAtoms.get(assignedAtom.getPredicate()).add(assignedAtom); } return analyze((BasicAtom) atom, currentAssignment); } - private Set analyze(BasicAtom atom, Assignment currentAssignment) { + private Set analyze(BasicAtom atom, Assignment currentAssignment) { log(pad("Starting analyze, current assignment is: {}"), currentAssignment); - LinkedHashSet vL = new LinkedHashSet<>(); + LinkedHashSet vL = new LinkedHashSet<>(); LinkedHashSet vToDo = new LinkedHashSet<>(Collections.singleton(new LitSet(atom, new LinkedHashSet<>()))); LinkedHashSet vDone = new LinkedHashSet<>(); while (!vToDo.isEmpty()) { @@ -98,7 +107,7 @@ private Set analyze(BasicAtom atom, Assignment currentAssignment) { private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment) { padDepth += 2; log("Begin explainUnjust(): {}", x); - CoreAtom p = x.getAtom(); + Atom p = x.getAtom(); ReturnExplainUnjust ret = new ReturnExplainUnjust(); @@ -108,8 +117,8 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment rulesLoop: for (RuleAndUnifier ruleUnifier : rulesUnifyingWithP) { Unifier sigma = ruleUnifier.unifier; - Set bodyR = ruleUnifier.ruleBody; - CoreAtom sigmaHr = ruleUnifier.originalHead.substitute(sigma); + Set bodyR = ruleUnifier.ruleBody; + Atom sigmaHr = ruleUnifier.originalHead.substitute(sigma); log("Considering now: {}", ruleUnifier); Set vN = new LinkedHashSet<>(x.getComplementSubstitutions()); for (Unifier sigmaN : vN) { @@ -130,15 +139,15 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment log("Adapting N to N'. Original N is {}", vN); log("Adapted N' is {}", vNp); log("Searching for falsified negated literals in the body: {}", bodyR); - for (CoreLiteral lit : bodyR) { + for (Literal lit : bodyR) { if (!lit.isNegated()) { continue; } - CoreAtom lb = lit.getAtom().substitute(sigma); + Atom lb = lit.getAtom().substitute(sigma); log("Found: {}, searching falsifying ground instances of {} (with unifier from the head) now.", lit, lb); AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(lb.getPredicate()); while (assignedAtomsOverPredicate.hasNext()) { - CoreAtom lg = assignedAtomsOverPredicate.next(); + Atom lg = assignedAtomsOverPredicate.next(); log("Considering: {}", lg); if (atomStore.contains(lg)) { int atomId = atomStore.get(lg); @@ -172,8 +181,8 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment } } - List bodyPos = new ArrayList<>(); - for (CoreLiteral literal : bodyR) { + List bodyPos = new ArrayList<>(); + for (Literal literal : bodyR) { if (!literal.isNegated()) { bodyPos.add(literal); } @@ -186,7 +195,7 @@ private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment return ret; } - private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { + private Set unjustCover(List vB, Set vY, Set vN, Assignment currentAssignment) { padDepth += 2; log("Begin UnjustCoverFixed()"); log("Finding unjustified body literals in: {} / {} excluded {}", vB, vY, vN); @@ -204,10 +213,10 @@ private Set unjustCover(List vB, Set vY, Set vYp = new LinkedHashSet<>(); @@ -215,7 +224,7 @@ private Set unjustCover(List vB, Set vY, Set unjustCover(List vB, Set vY, Set variablesOccurringInSigma = sigma.getMappedVariables(); + Set variablesOccurringInSigma = sigma.getMappedVariables(); if (Unification.instantiate(bSigmaY, bSigma) != null) { for (Unifier sigmaN : vN) { - ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); + ArrayList occurringVariables = new ArrayList<>(variablesOccurringInSigma); occurringVariables.addAll(sigmaN.getMappedVariables()); BasicAtom genericAtom = new BasicAtom(CorePredicate.getInstance("_", occurringVariables.size(), true), occurringVariables); - CoreAtom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); + Atom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest"); if (Unification.instantiate(genericSubstituted, genericAtom.substitute(sigma)) != null) { log("Atom {} is excluded by: {} via {}", genericSubstituted, sigmaN, sigma); continue atomLoop; @@ -264,7 +273,7 @@ private Set unjustCover(List vB, Set vY, Set newB = new ArrayList<>(vB); + ArrayList newB = new ArrayList<>(vB); newB.remove(chosenLiteralPos); ret.addAll(unjustCover(newB, vYp, vN, currentAssignment)); log("Literal set(s) to treat: {}", ret); @@ -283,20 +292,20 @@ private String pad(String string) { return sb.toString(); } - private AssignedAtomsIterator getAssignedAtomsOverPredicate(CorePredicate predicate) { + private AssignedAtomsIterator getAssignedAtomsOverPredicate(Predicate predicate) { // Find more substitutions, consider currentAssignment. - List assignedAtoms = this.assignedAtoms.get(predicate); + List assignedAtoms = this.assignedAtoms.get(predicate); // Consider instances from facts. LinkedHashSet factsOverPredicate = factsFromProgram.get(predicate); return new AssignedAtomsIterator(predicate, assignedAtoms, factsOverPredicate); } - private static class AssignedAtomsIterator implements Iterator { - private final CorePredicate predicate; - private final Iterator assignedAtomsIterator; + private static class AssignedAtomsIterator implements Iterator { + private final Predicate predicate; + private final Iterator assignedAtomsIterator; private final Iterator factsIterator; - public AssignedAtomsIterator(CorePredicate predicate, List assignedAtoms, Set facts) { + public AssignedAtomsIterator(Predicate predicate, List assignedAtoms, Set facts) { this.predicate = predicate; this.assignedAtomsIterator = assignedAtoms == null ? Collections.emptyIterator() : assignedAtoms.iterator(); this.factsIterator = facts == null ? Collections.emptyIterator() : facts.iterator(); @@ -308,7 +317,7 @@ public boolean hasNext() { } @Override - public CoreAtom next() { + public Atom next() { if (assignedAtomsIterator.hasNext()) { return assignedAtomsIterator.next(); } @@ -319,10 +328,10 @@ public CoreAtom next() { } } - private List rulesHeadUnifyingWith(CoreAtom p) { + private List rulesHeadUnifyingWith(Atom p) { List rulesWithUnifier = new ArrayList<>(); - CorePredicate predicate = p.getPredicate(); + Predicate predicate = p.getPredicate(); ArrayList definingRulesAndFacts = new ArrayList<>(); // Get facts over the same predicate. @@ -341,8 +350,8 @@ private List rulesHeadUnifyingWith(CoreAtom p) { } for (FactOrNonGroundRule factOrNonGroundRule : definingRulesAndFacts) { boolean isNonGroundRule = factOrNonGroundRule.nonGroundRule != null; - Set renamedBody; - CoreAtom headAtom; + Set renamedBody; + Atom headAtom; if (isNonGroundRule) { // First rename all variables in the rule. InternalRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++); @@ -370,7 +379,7 @@ private void log(String msg, Object... refs) { } private static class ReturnExplainUnjust { - Set vL; + Set vL; Set vToDo; ReturnExplainUnjust() { @@ -380,11 +389,11 @@ private static class ReturnExplainUnjust { } private static class RuleAndUnifier { - final Set ruleBody; + final Set ruleBody; final Unifier unifier; - final CoreAtom originalHead; + final Atom originalHead; - private RuleAndUnifier(Set ruleBody, Unifier unifier, CoreAtom originalHead) { + private RuleAndUnifier(Set ruleBody, Unifier unifier, Atom originalHead) { this.ruleBody = ruleBody; this.unifier = unifier; this.originalHead = originalHead; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java index daa3eb128..af6924874 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java @@ -7,7 +7,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.core.atoms.VariableNormalizableAtom; import at.ac.tuwien.kr.alpha.core.grounder.Unification; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; @@ -16,14 +16,14 @@ * Copyright (c) 2018, the Alpha Team. */ public class LitSet { - private final CoreAtom atom; + private final Atom atom; private final Set complementSubstitutions; private final int hashCode; - private final CoreAtom normalizedLiteral; + private final Atom normalizedLiteral; private final Set normalizedSubstitutions; private static int litSetCounter = 1; - LitSet(CoreAtom atom, Set complementSubstitutions) { + LitSet(Atom atom, Set complementSubstitutions) { this.atom = atom.renameVariables("_AS" + litSetCounter++); this.complementSubstitutions = new HashSet<>(); for (Unifier complementSubstitution : complementSubstitutions) { @@ -48,8 +48,8 @@ public class LitSet { * @param normalizedAtom * @return */ - private Unifier normalizeSubstitution(CoreAtom originalAtom, Unifier substitution, CoreAtom normalizedAtom) { - CoreAtom substitutedLiteral = originalAtom.substitute(substitution); + private Unifier normalizeSubstitution(Atom originalAtom, Unifier substitution, Atom normalizedAtom) { + Atom substitutedLiteral = originalAtom.substitute(substitution); return Unification.instantiate(normalizedAtom, substitutedLiteral); } @@ -66,7 +66,7 @@ public boolean coversNothing() { return false; } - public CoreAtom getAtom() { + public Atom getAtom() { return atom; } @@ -118,7 +118,7 @@ private int computeHashCode() { return result; } - private CoreAtom computeNormalized(CoreAtom atom, String prefix) { + private Atom computeNormalized(Atom atom, String prefix) { if (atom instanceof VariableNormalizableAtom) { return ((VariableNormalizableAtom) atom).normalizeVariables(prefix, 0); } else { @@ -131,9 +131,9 @@ private Set computeNormalizedSubstitutions() { for (Unifier substitution : complementSubstitutions) { Unifier preNormalizedSubstitution = normalizeSubstitution(atom, substitution, normalizedLiteral); // Unifier may still contain variables in the right-hand side, those have to be normalized, too. - CoreAtom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); + Atom appliedSub = normalizedLiteral.substitute(preNormalizedSubstitution); // Apply substitution and normalize all remaining variables, i.e., those appearing at the right-hand side of the substitution. - CoreAtom normalized = computeNormalized(appliedSub, "_X"); + Atom normalized = computeNormalized(appliedSub, "_X"); // Compute final substitution from normalized atom to the one where also variables are normalized. Unifier normalizedSubstitution = new Unifier(Unification.instantiate(normalizedLiteral, normalized)); ret.add(normalizedSubstitution); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectivesImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectivesImpl.java index 534b1874f..8a5b67cf0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectivesImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/InlineDirectivesImpl.java @@ -11,10 +11,6 @@ */ public class InlineDirectivesImpl implements InlineDirectives { - public enum DIRECTIVE { - enum_predicate_is - } - private final LinkedHashMap directives = new LinkedHashMap<>(); public String getDirectiveValue(DIRECTIVE directive) { @@ -28,9 +24,13 @@ public void addDirective(DIRECTIVE directive, String value) { directives.put(directive, value); } - public void accumulate(InlineDirectivesImpl other) { - for (Map.Entry directiveEntry : other.directives.entrySet()) { + public void accumulate(InlineDirectives other) { + for (Map.Entry directiveEntry : other.getDirectives().entrySet()) { addDirective(directiveEntry.getKey(), directiveEntry.getValue()); } } + + public LinkedHashMap getDirectives() { + return this.directives; + } } 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 c1693a012..aec271c87 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 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016-2021, the Alpha Team. + * Copyright (c) 2016-2018, the Alpha Team. * All rights reserved. *

      * Additional changes made by Siemens. @@ -46,8 +46,15 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead.ChoiceElement; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +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.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; @@ -56,7 +63,6 @@ import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; @@ -70,19 +76,21 @@ import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; -import at.ac.tuwien.kr.alpha.core.rules.Rules; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHeadImpl; +import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHeadImpl.ChoiceElementImpl; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** - * Copyright (c) 2016-2021, the Alpha Team. + * Copyright (c) 2016-2018, the Alpha Team. */ public class ParseTreeVisitor extends ASPCore2BaseVisitor { private final Map externals; private final boolean acceptVariables; - private InputProgramImpl.Builder programBuilder; - private InlineDirectivesImpl inlineDirectives; + private InputProgram.Builder programBuilder; + private InlineDirectives inlineDirectives; public ParseTreeVisitor(Map externals) { this(externals, true); @@ -100,7 +108,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 InputProgramImpl translate(ASPCore2Parser.ProgramContext input) { + public InputProgram translate(ASPCore2Parser.ProgramContext input) { return visitProgram(input); } @@ -124,11 +132,11 @@ public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx @Override public CoreAnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { - SortedSet predicates = new TreeSet<>(); - Map> predicateInstances = new TreeMap<>(); + SortedSet predicates = new TreeSet<>(); + Map> predicateInstances = new TreeMap<>(); for (ASPCore2Parser.Classical_literalContext classicalLiteralContext : ctx.classical_literal()) { - CoreAtom atom = visitClassical_literal(classicalLiteralContext); + Atom atom = visitClassical_literal(classicalLiteralContext); predicates.add(atom.getPredicate()); predicateInstances.compute(atom.getPredicate(), (k, v) -> { @@ -150,19 +158,19 @@ public String visitTerminal(TerminalNode node) { } @Override - public InputProgramImpl visitProgram(ASPCore2Parser.ProgramContext ctx) { + public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { // program : statements? query?; if (ctx.query() != null) { throw notSupported(ctx.query()); } if (ctx.statements() == null) { - return InputProgramImpl.EMPTY; + return InputProgram.EMPTY; } inlineDirectives = new InlineDirectivesImpl(); - programBuilder = InputProgramImpl.builder(); + programBuilder = InputProgram.builder(); visitStatements(ctx.statements()); - programBuilder.addInlineDirectives(inlineDirectives); // TODO inline directives + programBuilder.addInlineDirectives(inlineDirectives); return programBuilder.build(); } @@ -178,52 +186,27 @@ public Object visitStatements(ASPCore2Parser.StatementsContext ctx) { @Override public Object visitStatement_fact(ASPCore2Parser.Statement_factContext ctx) { // head DOT - if (ctx.head().disjunction() != null) { - if (ctx.head().disjunction().disjunction() != null) { - // more than one disjunctive element - notSupported(ctx); - } else { - programBuilder.addFact(visitClassical_literal(ctx.head().disjunction().classical_literal())); - } + Head head = visitHead(ctx.head()); + if (head instanceof NormalHead) { + programBuilder.addFact(((NormalHead) head).getAtom()); } else { - handleRule(ctx.head(), null); + // Treat facts with choice or disjunction in the head like a rule. + programBuilder.addRule(new BasicRule(head, emptyList())); } return null; } - private void handleRule(ASPCore2Parser.HeadContext headCtx, ASPCore2Parser.BodyContext bodyCtx) { - List body = null; // TODO - if (headCtx == null) { - // constraint - programBuilder.addNormalRule(Rules.newConstraint(body)); - } else if (headCtx.disjunction() != null) { - // normal or disjunctive rule - if (headCtx.disjunction().disjunction() != null) { - // more than one disjunctive element - notSupported(headCtx); - } else { - programBuilder.addNormalRule(Rules.newNormalRule(visitClassical_literal(headCtx.disjunction().classical_literal()), body)); - } - } else if (headCtx.choice() != null) { - // choice rule - ChoiceHead head = visitChoice(headCtx.choice()); - programBuilder.addChoiceRule(Rules.newChoiceRule(head, body)); - } else { - notSupported(headCtx); - } - } - @Override public Object visitStatement_constraint(ASPCore2Parser.Statement_constraintContext ctx) { // CONS body DOT - handleRule(null, ctx.body()); + programBuilder.addRule(new BasicRule(null, visitBody(ctx.body()))); return null; } @Override public Object visitStatement_rule(ASPCore2Parser.Statement_ruleContext ctx) { // head CONS body DOT - handleRule(ctx.head(), ctx.body()); + programBuilder.addRule(new BasicRule(visitHead(ctx.head()), visitBody(ctx.body()))); return null; } @@ -242,27 +225,45 @@ public Object visitStatement_directive(ASPCore2Parser.Statement_directiveContext } @Override - public ChoiceHead visitChoice(ASPCore2Parser.ChoiceContext ctx) { + public Head visitDisjunction(ASPCore2Parser.DisjunctionContext ctx) { + // disjunction : classical_literal (OR disjunction)?; + if (ctx.disjunction() != null) { + throw notSupported(ctx); + } + return new NormalHeadImpl(visitClassical_literal(ctx.classical_literal())); + } + + @Override + public Head visitHead(ASPCore2Parser.HeadContext ctx) { + // head : disjunction | choice; + if (ctx.choice() != null) { + return visitChoice(ctx.choice()); + } + return visitDisjunction(ctx.disjunction()); + } + + @Override + public Head visitChoice(ASPCore2Parser.ChoiceContext ctx) { // choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; - CoreTerm lt = null; + Term lt = null; ComparisonOperator lop = null; - CoreTerm ut = null; + Term ut = null; ComparisonOperator uop = null; if (ctx.lt != null) { - lt = (CoreTerm) visit(ctx.lt); + lt = (Term) visit(ctx.lt); lop = visitBinop(ctx.lop); } if (ctx.ut != null) { - ut = (CoreTerm) visit(ctx.ut); + ut = (Term) visit(ctx.ut); uop = visitBinop(ctx.uop); } return new ChoiceHeadImpl(visitChoice_elements(ctx.choice_elements()), lt, lop, ut, uop); } @Override - public List visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { + public List visitChoice_elements(ASPCore2Parser.Choice_elementsContext ctx) { // choice_elements : choice_element (SEMICOLON choice_elements)?; - List choiceElements; + List choiceElements; if (ctx.choice_elements() != null) { choiceElements = visitChoice_elements(ctx.choice_elements()); } else { @@ -273,20 +274,20 @@ public List visitChoice_elements(ASPCore2Parser.Ch } @Override - public ChoiceHeadImpl.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { + public ChoiceHead.ChoiceElement visitChoice_element(ASPCore2Parser.Choice_elementContext ctx) { // choice_element : classical_literal (COLON naf_literals?)?; BasicAtom atom = (BasicAtom) visitClassical_literal(ctx.classical_literal()); if (ctx.naf_literals() != null) { - return new ChoiceHeadImpl.ChoiceElement(atom, visitNaf_literals(ctx.naf_literals())); + return new ChoiceElementImpl(atom, visitNaf_literals(ctx.naf_literals())); } else { - return new ChoiceHeadImpl.ChoiceElement(atom, Collections.emptyList()); + return new ChoiceElementImpl(atom, Collections.emptyList()); } } @Override - public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { + public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ctx) { // naf_literals : naf_literal (COMMA naf_literals)?; - List literals; + List literals; if (ctx.naf_literals() != null) { literals = visitNaf_literals(ctx.naf_literals()); } else { @@ -299,18 +300,18 @@ public List visitNaf_literals(ASPCore2Parser.Naf_literalsContext ct @Override public Object visitDirective_enumeration(ASPCore2Parser.Directive_enumerationContext ctx) { // directive_enumeration : SHARP 'enum_predicate_is' ID DOT; - inlineDirectives.addDirective(InlineDirectivesImpl.DIRECTIVE.enum_predicate_is, ctx.ID().getText()); + inlineDirectives.addDirective(InlineDirectives.DIRECTIVE.enum_predicate_is, ctx.ID().getText()); return null; } @Override - public List visitBody(ASPCore2Parser.BodyContext ctx) { + public List visitBody(ASPCore2Parser.BodyContext ctx) { // body : ( naf_literal | aggregate ) (COMMA body)?; if (ctx == null) { return emptyList(); } - final List literals = new ArrayList<>(); + final List literals = new ArrayList<>(); do { if (ctx.naf_literal() != null) { literals.add(visitNaf_literal(ctx.naf_literal())); @@ -327,16 +328,16 @@ public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { // aggregate : NAF? (lt=term lop=binop)? aggregate_function CURLY_OPEN aggregate_elements CURLY_CLOSE (uop=binop ut=term)?; boolean isPositive = ctx.NAF() == null; - CoreTerm lt = null; + Term lt = null; ComparisonOperator lop = null; - CoreTerm ut = null; + Term ut = null; ComparisonOperator uop = null; if (ctx.lt != null) { lt = (CoreTerm) visit(ctx.lt); lop = visitBinop(ctx.lop); } if (ctx.ut != null) { - ut = (CoreTerm) visit(ctx.ut); + ut = (Term) visit(ctx.ut); uop = visitBinop(ctx.uop); } AggregateAtom.AGGREGATEFUNCTION aggregateFunction = visitAggregate_function(ctx.aggregate_function()); @@ -358,7 +359,7 @@ public List visitAggregate_elements(ASPCore2Pars @Override public AggregateAtom.AggregateElement visitAggregate_element(ASPCore2Parser.Aggregate_elementContext ctx) { // aggregate_element : basic_terms? (COLON naf_literals?)?; - List basicTerms = ctx.basic_terms() != null ? visitBasic_terms(ctx.basic_terms()) : null; + List basicTerms = ctx.basic_terms() != null ? visitBasic_terms(ctx.basic_terms()) : null; if (ctx.naf_literals() != null) { return new AggregateAtom.AggregateElement(basicTerms, visitNaf_literals(ctx.naf_literals())); } @@ -366,9 +367,9 @@ public AggregateAtom.AggregateElement visitAggregate_element(ASPCore2Parser.Aggr } @Override - public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { + public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { // basic_terms : basic_term (COMMA basic_terms)? ; - List termList = new ArrayList<>(); + List termList = new ArrayList<>(); do { termList.add(visitBasic_term(ctx.basic_term())); } while ((ctx = ctx.basic_terms()) != null); @@ -376,7 +377,7 @@ public List visitBasic_terms(ASPCore2Parser.Basic_termsContext ctx) { } @Override - public CoreTerm visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { + public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { // basic_term : ground_term | variable_term; if (ctx.ground_term() != null) { return visitGround_term(ctx.ground_term()); @@ -386,7 +387,7 @@ public CoreTerm visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { } @Override - public CoreTerm visitGround_term(ASPCore2Parser.Ground_termContext ctx) { + public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { // ground_term : ID | QUOTED_STRING | MINUS? NUMBER; if (ctx.ID() != null) { return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); @@ -403,8 +404,7 @@ public CoreTerm visitGround_term(ASPCore2Parser.Ground_termContext ctx) { } @Override - // TODO proper "core" type - public CoreTerm visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { + public Term visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { // variable_term : VARIABLE | ANONYMOUS_VARIABLE; if (ctx.VARIABLE() != null) { return VariableTermImpl.getInstance(ctx.VARIABLE().getText()); @@ -453,9 +453,10 @@ public ComparisonOperator visitBinop(ASPCore2Parser.BinopContext ctx) { public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { // builtin_atom : term binop term; return new ComparisonAtom( - (CoreTerm) visit(ctx.term(0)), - (CoreTerm) visit(ctx.term(1)), - visitBinop(ctx.binop())); + (CoreTerm) visit(ctx.term(0)), + (CoreTerm) visit(ctx.term(1)), + visitBinop(ctx.binop()) + ); } @Override @@ -479,38 +480,38 @@ public BasicAtom visitClassical_literal(ASPCore2Parser.Classical_literalContext throw notSupported(ctx); } - final List terms = visitTerms(ctx.terms()); + final List terms = visitTerms(ctx.terms()); return new BasicAtom(CorePredicate.getInstance(ctx.ID().getText(), terms.size()), terms); } @Override - public List visitTerms(ASPCore2Parser.TermsContext ctx) { + public List visitTerms(ASPCore2Parser.TermsContext ctx) { // terms : term (COMMA terms)?; if (ctx == null) { return emptyList(); } - final List terms = new ArrayList<>(); + final List terms = new ArrayList<>(); do { ASPCore2Parser.TermContext term = ctx.term(); - terms.add((CoreTerm) visit(term)); + terms.add((Term) visit(term)); } while ((ctx = ctx.terms()) != null); return terms; } @Override - public CoreConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { + public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { return CoreConstantTerm.getInstance(Integer.parseInt(ctx.NUMBER().getText())); } @Override - public CoreConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { + public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); } @Override - public CoreConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { + public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { String quotedString = ctx.QUOTED_STRING().getText().replace("\\\"", "\""); return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); } @@ -521,7 +522,6 @@ public FunctionTerm visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { } @Override - // TODO proper "core" type public VariableTerm visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVariableContext ctx) { if (!acceptVariables) { throw notSupported(ctx); @@ -531,7 +531,6 @@ public VariableTerm visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVar } @Override - // TODO proper "core" type public VariableTerm visitTerm_variable(ASPCore2Parser.Term_variableContext ctx) { if (!acceptVariables) { throw notSupported(ctx); @@ -560,26 +559,24 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) throw new IllegalArgumentException("Unknown interpretation name encountered: " + predicateName); } - List outputTerms = visitTerms(ctx.output); + List outputTerms = visitTerms(ctx.output); return new ExternalAtom( - CorePredicate.getInstance(predicateName, outputTerms.size()), - interpretation, - visitTerms(ctx.input), - outputTerms); + CorePredicate.getInstance(predicateName, outputTerms.size()), + interpretation, + visitTerms(ctx.input), + outputTerms + ); } @Override - // TODO proper "core" type public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) { // interval : lower = (NUMBER | VARIABLE) DOT DOT upper = (NUMBER | VARIABLE); ASPCore2Parser.IntervalContext ictx = ctx.interval(); String lowerText = ictx.lower.getText(); String upperText = ictx.upper.getText(); - CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) - : VariableTermImpl.getInstance(lowerText); - CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) - : VariableTermImpl.getInstance(upperText); + CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) : VariableTermImpl.getInstance(lowerText); + CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) : VariableTermImpl.getInstance(upperText); return IntervalTerm.getInstance(lower, upper); } @@ -593,7 +590,7 @@ public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { // | term (TIMES | DIV | MODULO) term ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES - : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; + : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java index c36820296..bad967791 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java @@ -1,45 +1,52 @@ package at.ac.tuwien.kr.alpha.core.programs; import java.util.Collections; -import java.util.Set; +import java.util.List; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; -import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.core.rules.AbstractRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.Head; import at.ac.tuwien.kr.alpha.core.util.Util; /** * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives) * - * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an - * implementation permits - * Copyright (c) 2019-2021, the Alpha Team. + * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an implementation permits + * Copyright (c) 2019, the Alpha Team. */ -public abstract class AbstractProgram> implements Program { +public abstract class AbstractProgram> { - private final Set facts; + private final List rules; + private final List facts; private final InlineDirectives inlineDirectives; - protected AbstractProgram(Set facts, InlineDirectives inlineDirectives) { - this.facts = Collections.unmodifiableSet(facts); + public AbstractProgram(List rules, List facts, InlineDirectives inlineDirectives) { + this.rules = rules; + this.facts = facts; this.inlineDirectives = inlineDirectives; } - @Override - public Set getFacts() { - return this.facts; + public List getRules() { + return Collections.unmodifiableList(rules); + } + + public List getFacts() { + return Collections.unmodifiableList(facts); + } + + public InlineDirectives getInlineDirectives() { + return inlineDirectives; } @Override public String toString() { final String ls = System.lineSeparator(); - final String result = this.getFacts().isEmpty() ? "" : Util.join("", this.getFacts(), "." + ls, "." + ls); - if (this.getRules().isEmpty()) { + final String result = facts.isEmpty() ? "" : Util.join("", facts, "." + ls, "." + ls); + if (rules.isEmpty()) { return result; } - return Util.join(result, this.getRules(), ls, ls); + return Util.join(result, rules, ls, ls); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java index d9f4a1205..f86f2ed63 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java @@ -4,7 +4,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; import at.ac.tuwien.kr.alpha.core.depgraph.StronglyConnectedComponentsAlgorithm; @@ -21,14 +21,14 @@ public class AnalyzedProgram extends InternalProgram { private final DependencyGraph dependencyGraph; private final ComponentGraph componentGraph; - public AnalyzedProgram(List rules, List facts) { + public AnalyzedProgram(List rules, List facts) { super(rules, facts); dependencyGraph = DependencyGraph.buildDependencyGraph(getRulesById()); componentGraph = buildComponentGraph(dependencyGraph); } public static AnalyzedProgram analyzeNormalProgram(NormalProgram prog) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); return new AnalyzedProgram(rulesAndFacts.left, rulesAndFacts.right); } 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/InputProgram.java new file mode 100644 index 000000000..7cf8985bf --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 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.programs; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; +import at.ac.tuwien.kr.alpha.core.rules.BasicRule; + +/** + * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. + *

      + * Copyright (c) 2017-2019, the Alpha Team. + */ +public class InputProgram extends AbstractProgram { + + public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl()); + + public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { + super(rules, facts, inlineDirectives); + } + + public InputProgram() { + super(new ArrayList<>(), new ArrayList<>(), new InlineDirectivesImpl()); + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(InputProgram prog) { + return new Builder(prog); + } + + /** + * Builder for more complex program construction scenarios, ensuring that an {@link InputProgram} is immutable + */ + public static class Builder { + + private List rules = new ArrayList<>(); + private List facts = new ArrayList<>(); + private InlineDirectives inlineDirectives = new InlineDirectivesImpl(); + + public Builder(InputProgram prog) { + this.addRules(prog.getRules()); + this.addFacts(prog.getFacts()); + this.addInlineDirectives(prog.getInlineDirectives()); + } + + public Builder() { + + } + + public Builder addRules(List rules) { + this.rules.addAll(rules); + return this; + } + + public Builder addRule(BasicRule r) { + this.rules.add(r); + return this; + } + + public Builder addFacts(List facts) { + this.facts.addAll(facts); + return this; + } + + public Builder addFact(Atom fact) { + this.facts.add(fact); + return this; + } + + public Builder addInlineDirectives(InlineDirectives inlineDirectives) { + this.inlineDirectives.accumulate(inlineDirectives); + return this; + } + + 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); + } + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java deleted file mode 100644 index 4e0d14fcc..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Copyright (c) 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.programs; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.apache.commons.collections4.SetUtils; - -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; -import at.ac.tuwien.kr.alpha.api.program.InputProgram; -import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; -import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; -import at.ac.tuwien.kr.alpha.api.rules.Head; -import at.ac.tuwien.kr.alpha.api.rules.NormalHead; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; - -/** - * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. - *

      - * Copyright (c) 2017-2021, the Alpha Team. - */ -public class InputProgramImpl extends AbstractProgram implements InputProgram { - - public static final InputProgramImpl EMPTY = null; // TODO - - private final Set> disjunctiveRules; - private final Set> choiceRules; - private final Set> normalRules; - - public InputProgramImpl(Set facts, Set> disjunctiveRules, Set> choiceRules, Set> normalRules, - InlineDirectives inlineDirectives) { - super(facts, inlineDirectives); - this.disjunctiveRules = Collections.unmodifiableSet(disjunctiveRules); - this.choiceRules = Collections.unmodifiableSet(choiceRules); - this.normalRules = Collections.unmodifiableSet(normalRules); - } - - public static Builder builder() { - return new Builder(); - } - - public static Builder builder(InputProgramImpl prog) { - return new Builder(prog); - } - - /** - * Builder for more complex program construction scenarios, ensuring that an {@link InputProgramImpl} is immutable - */ - public static class Builder { - - private Set> disjunctiveRules = new LinkedHashSet<>(); - private Set> choiceRules = new LinkedHashSet<>(); - private Set> normalRules = new LinkedHashSet<>(); - private Set facts = new LinkedHashSet<>(); - private InlineDirectives inlineDirectives = null; // TODO do inline directives properly - - public Builder(InputProgramImpl prog) { - this.addDisjunctiveRules(prog.getDisjunctiveRules()); - this.addChoiceRules(prog.getChoiceRules()); - this.addNormalRules(prog.getNormalRules()); - this.addFacts(prog.getFacts()); - this.addInlineDirectives(prog.getInlineDirectives()); - } - - public Builder() { - - } - - public Builder addDisjunctiveRules(Set> rules) { - this.disjunctiveRules.addAll(rules); - return this; - } - - public Builder addChoiceRules(Set> rules) { - this.choiceRules.addAll(rules); - return this; - } - - public Builder addNormalRules(Set> rules) { - this.normalRules.addAll(rules); - return this; - } - - public Builder addDisjunctiveRule(Rule r) { - this.disjunctiveRules.add(r); - return this; - } - - public Builder addChoiceRule(Rule r) { - this.choiceRules.add(r); - return this; - } - - public Builder addNormalRule(Rule r) { - this.normalRules.add(r); - return this; - } - - public Builder addFacts(Set facts) { - this.facts.addAll(facts); - return this; - } - - public Builder addFact(CoreAtom fact) { - this.facts.add(fact); - return this; - } - - public Builder addInlineDirectives(InlineDirectives inlineDirectives) { - // this.inlineDirectives.accumulate(inlineDirectives); TODO - return this; - } - - public Builder accumulate(InputProgramImpl prog) { - this.addDisjunctiveRules(prog.getDisjunctiveRules()); - this.addChoiceRules(prog.getChoiceRules()); - this.addNormalRules(prog.getNormalRules()); - this.addFacts(prog.getFacts()); - this.addInlineDirectives(prog.getInlineDirectives()); - return this; - } - - public InputProgramImpl build() { - return new InputProgramImpl(this.facts, this.disjunctiveRules, this.choiceRules, this.normalRules, this.inlineDirectives); - } - } - - @Override - public Set> getRules() { - return SetUtils.union(SetUtils.union(this.disjunctiveRules, this.choiceRules), this.normalRules); - } - - @Override - public at.ac.tuwien.kr.alpha.api.program.InlineDirectives getInlineDirectives() { - return this.getInlineDirectives(); - } - - @Override - public Set> getChoiceRules() { - return this.getChoiceRules(); - } - - @Override - public Set> getDisjunctiveRules() { - return this.getDisjunctiveRules(); - } - - @Override - public Set> getNormalRules() { - return this.getNormalRules(); - } - -} 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 3fa131b22..5fc98b304 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 @@ -9,8 +9,8 @@ import org.apache.commons.lang3.tuple.ImmutablePair; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.grounder.FactIntervalEvaluator; import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; @@ -25,19 +25,19 @@ */ public class InternalProgram extends AbstractProgram { - private final Map> predicateDefiningRules = new LinkedHashMap<>(); - private final Map> factsByPredicate = new LinkedHashMap<>(); + private final Map> predicateDefiningRules = new LinkedHashMap<>(); + private final Map> factsByPredicate = new LinkedHashMap<>(); private final Map rulesById = new LinkedHashMap<>(); - public InternalProgram(List rules, List facts) { + public InternalProgram(List rules, List facts) { super(rules, facts, null); recordFacts(facts); recordRules(rules); } - static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { + static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { List internalRules = new ArrayList<>(); - List facts = new ArrayList<>(normalProgram.getFacts()); + List facts = new ArrayList<>(normalProgram.getFacts()); for (NormalRule r : normalProgram.getRules()) { if (r.getBody().isEmpty()) { if (!r.getHead().isGround()) { @@ -52,14 +52,14 @@ static ImmutablePair, List> internalizeRulesAndFact } public static InternalProgram fromNormalProgram(NormalProgram normalProgram) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); return new InternalProgram(rulesAndFacts.left, rulesAndFacts.right); } - private void recordFacts(List facts) { - for (CoreAtom fact : facts) { + private void recordFacts(List facts) { + for (Atom fact : facts) { List tmpInstances = FactIntervalEvaluator.constructFactInstances(fact); - CorePredicate tmpPredicate = fact.getPredicate(); + Predicate tmpPredicate = fact.getPredicate(); factsByPredicate.putIfAbsent(tmpPredicate, new LinkedHashSet<>()); factsByPredicate.get(tmpPredicate).addAll(tmpInstances); } @@ -74,16 +74,16 @@ private void recordRules(List rules) { } } - private void recordDefiningRule(CorePredicate headPredicate, InternalRule rule) { + private void recordDefiningRule(Predicate headPredicate, InternalRule rule) { predicateDefiningRules.putIfAbsent(headPredicate, new LinkedHashSet<>()); predicateDefiningRules.get(headPredicate).add(rule); } - public Map> getPredicateDefiningRules() { + public Map> getPredicateDefiningRules() { return Collections.unmodifiableMap(predicateDefiningRules); } - public Map> getFactsByPredicate() { + public Map> getFactsByPredicate() { return Collections.unmodifiableMap(factsByPredicate); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java index 72bbc2d8b..6a39329a3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; @@ -15,11 +15,11 @@ */ public class NormalProgram extends AbstractProgram { - public NormalProgram(List rules, List facts, InlineDirectivesImpl inlineDirectives) { + public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } - public static NormalProgram fromInputProgram(InputProgramImpl inputProgram) { + public static NormalProgram fromInputProgram(InputProgram inputProgram) { List normalRules = new ArrayList<>(); for (BasicRule r : inputProgram.getRules()) { normalRules.add(NormalRule.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 e5d7d3329..995a99c04 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 @@ -1,11 +1,11 @@ package at.ac.tuwien.kr.alpha.core.programs; -import org.antlr.v4.runtime.CharStreams; - 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.core.parser.ProgramParserImpl; @@ -15,7 +15,7 @@ private Programs() { throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); } - public static InputProgramImpl fromInputStream(InputStream is, Map externals) throws IOException { + public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { ProgramParserImpl parser = new ProgramParserImpl(externals); return parser.parse(CharStreams.fromStream(is)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index f19cc317c..537353027 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -7,26 +7,26 @@ import java.util.LinkedHashSet; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; 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.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Copyright (c) 2017-2020, the Alpha Team. */ -public class CardinalityNormalization extends ProgramTransformation { +public class CardinalityNormalization extends ProgramTransformation { private int aggregateCount; private ProgramParserImpl parser = new ProgramParserImpl(); @@ -40,16 +40,16 @@ public CardinalityNormalization(boolean useSortingCircuitEncoding) { this.useSortingCircuitEncoding = useSortingCircuitEncoding; } - private InputProgramImpl parse(String program) { + private InputProgram parse(String program) { return parser.parse(program); } @Override - public InputProgramImpl apply(InputProgramImpl inputProgram) { + public InputProgram apply(InputProgram inputProgram) { if (!this.rewritingNecessary(inputProgram)) { return inputProgram; } - InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); + InputProgram.Builder programBuilder = InputProgram.builder(); programBuilder.addFacts(inputProgram.getFacts()); programBuilder.addInlineDirectives(inputProgram.getInlineDirectives()); //@formatter:off @@ -92,7 +92,7 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { List rewrittenRules = rewriteAggregates(inputProgram.getRules()); String usedCardinalityEncoding = useSortingCircuitEncoding ? cardinalitySortingCircuit : cardinalityCountingGrid; - InputProgramImpl cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParserImpl().parse(usedCardinalityEncoding)); + InputProgram cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParserImpl().parse(usedCardinalityEncoding)); programBuilder.addRules(rewrittenRules); // Add enumeration rule that uses the special EnumerationAtom. @@ -101,7 +101,7 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { BasicRule tmpEnumRule = PredicateInternalizer.makePredicatesInternal(parse( "sorting_network_input_number(A, I) :- sorting_network_input(A, X).")).getRules().get(0); EnumerationAtom enumerationAtom = new EnumerationAtom(parse("sorting_network_index(A, X, I).").getFacts().get(0).getTerms()); - List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); + List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); enumerationRuleBody.add(enumerationAtom.toLiteral()); BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); programBuilder.addRule(enumerationRule); @@ -117,9 +117,9 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { * @param program the program. * @return true if count aggregates occur, false otherwise. */ - private boolean rewritingNecessary(InputProgramImpl program) { + private boolean rewritingNecessary(InputProgram program) { for (BasicRule rule : program.getRules()) { - for (CoreLiteral lit : rule.getBody()) { + for (Literal lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.COUNT) { @@ -155,14 +155,14 @@ private List rewriteAggregatesInRule(BasicRule rule) { final BasicAtom lowerBoundAtom = (BasicAtom) PredicateInternalizer .makePredicatesInternal(parse("sorting_network_bound(aggregate_arguments(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - ArrayList aggregateOutputAtoms = new ArrayList<>(); + ArrayList aggregateOutputAtoms = new ArrayList<>(); int aggregatesInRule = 0; // Only needed for limited rewriting. ArrayList additionalRules = new ArrayList<>(); - List rewrittenBody = new ArrayList<>(rule.getBody()); + List rewrittenBody = new ArrayList<>(rule.getBody()); - for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { - CoreLiteral bodyElement = iterator.next(); + for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { + Literal bodyElement = iterator.next(); // Skip non-aggregates. if (!(bodyElement instanceof AggregateLiteral)) { continue; @@ -189,12 +189,12 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Prepare aggregate parameters. aggregateCount++; Substitution aggregateSubstitution = new Unifier(); - Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); + Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier - ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); + ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); } @@ -206,14 +206,14 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create input to sorting network from aggregate elements. for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. - List elementTerms = aggregateElement.getElementTerms(); + List elementTerms = aggregateElement.getElementTerms(); FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); Substitution elementSubstitution = new Unifier(aggregateSubstitution); elementSubstitution.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementSubstitution); - List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); + List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); // If there are global variables used inside the aggregate, add original rule body // (minus the aggregate itself) to input rule. @@ -226,7 +226,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create lower bound for the aggregate. BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateSubstitution); - List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. + List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. additionalRules.add(new BasicRule(new NormalHeadImpl(lowerBoundHeadAtom), lowerBoundBody)); } @@ -236,19 +236,19 @@ private List rewriteAggregatesInRule(BasicRule rule) { return additionalRules; } - static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { + static Collection getGlobalVariables(List ruleBody, AggregateAtom aggregateAtom) { // Hacky way to get all global variables: take all variables inside the aggregate that occur also in the // rest of the rule. - HashSet occurringVariables = new LinkedHashSet<>(); - for (CoreLiteral element : ruleBody) { + HashSet occurringVariables = new LinkedHashSet<>(); + for (Literal element : ruleBody) { if (element instanceof AggregateLiteral) { continue; } occurringVariables.addAll(element.getBindingVariables()); occurringVariables.addAll(element.getNonBindingVariables()); } - LinkedHashSet globalVariables = new LinkedHashSet<>(); - for (CoreTerm aggVariable : aggregateAtom.getAggregateVariables()) { + LinkedHashSet globalVariables = new LinkedHashSet<>(); + for (Term aggVariable : aggregateAtom.getAggregateVariables()) { if (occurringVariables.contains(aggVariable)) { globalVariables.add(aggVariable); } 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 f11a094e4..e17790a49 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,34 +27,34 @@ */ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.api.program.*; -import at.ac.tuwien.kr.alpha.api.terms.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHeadImpl; -import at.ac.tuwien.kr.alpha.core.rules.heads.Head; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - /** * Copyright (c) 2017-2020, the Alpha Team. */ -public class ChoiceHeadToNormal extends ProgramTransformation { +public class ChoiceHeadToNormal extends ProgramTransformation { private final static String PREDICATE_NEGATION_PREFIX = "_n"; @Override - public InputProgramImpl apply(InputProgramImpl inputProgram) { - InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); + public InputProgram apply(InputProgram inputProgram) { + InputProgram.Builder programBuilder = InputProgram.builder(); List additionalRules = new ArrayList<>(); List srcRules = new ArrayList<>(inputProgram.getRules()); @@ -82,29 +82,29 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { // Create two guessing rules for each choiceElement. // Construct common body to both rules. - CoreAtom head = choiceElement.choiceAtom; - List ruleBody = new ArrayList<>(rule.getBody()); - ruleBody.addAll(choiceElement.conditionLiterals); + Atom head = choiceElement.getChoiceAtom(); + List ruleBody = new ArrayList<>(rule.getBody()); + ruleBody.addAll(choiceElement.getConditionLiterals()); if (containsIntervalTerms(head)) { throw new RuntimeException("Program contains a choice rule with interval terms in its head. This is not supported (yet)."); } // Construct head atom for the choice. - CorePredicate headPredicate = head.getPredicate(); + Predicate headPredicate = head.getPredicate(); - CorePredicate negPredicate = CorePredicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); - List headTerms = new ArrayList<>(head.getTerms()); + Predicate negPredicate = CorePredicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); + List headTerms = new ArrayList<>(head.getTerms()); headTerms.add(0, CoreConstantTerm.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for // classical negative atoms. CoreAtom negHead = new BasicAtom(negPredicate, headTerms); // Construct two guessing rules. - List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); + List guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody); guessingRuleBodyWithNegHead.add(new BasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false)); additionalRules.add(new BasicRule(new NormalHeadImpl(negHead), guessingRuleBodyWithNegHead)); - List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); + List guessingRuleBodyWithHead = new ArrayList<>(ruleBody); guessingRuleBodyWithHead.add(new BasicAtom(negPredicate, headTerms).toLiteral(false)); additionalRules.add(new BasicRule(new NormalHeadImpl(head), guessingRuleBodyWithHead)); @@ -115,8 +115,8 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { .addInlineDirectives(inputProgram.getInlineDirectives()).build(); } - private static boolean containsIntervalTerms(CoreAtom atom) { - for (CoreTerm term : atom.getTerms()) { + private static boolean containsIntervalTerms(Atom atom) { + for (Term term : atom.getTerms()) { if (IntervalTerm.termContainsIntervalTerm(term)) { return true; } 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 7e50d11e5..51d5bc0b0 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,13 +7,14 @@ import java.util.LinkedList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; 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.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; @@ -23,10 +24,10 @@ * * Copyright (c) 2017-2020, the Alpha Team. */ -public class EnumerationRewriting extends ProgramTransformation { +public class EnumerationRewriting extends ProgramTransformation { @Override - public InputProgramImpl apply(InputProgramImpl inputProgram) { + public InputProgram apply(InputProgram inputProgram) { // Read enumeration predicate from directive. String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectivesImpl.DIRECTIVE.enum_predicate_is); if (enumDirective == null) { @@ -35,7 +36,7 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { } CorePredicate enumPredicate = CorePredicate.getInstance(enumDirective, 3); - InputProgramImpl.Builder programBuilder = InputProgramImpl.builder().addInlineDirectives(inputProgram.getInlineDirectives()); + InputProgram.Builder programBuilder = InputProgram.builder().addInlineDirectives(inputProgram.getInlineDirectives()); checkFactsAreEnumerationFree(inputProgram.getFacts(), enumPredicate); programBuilder.addFacts(inputProgram.getFacts()); @@ -45,8 +46,8 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { return programBuilder.build(); } - private void checkFactsAreEnumerationFree(List srcFacts, CorePredicate enumPredicate) { - for (CoreAtom fact : srcFacts) { + private void checkFactsAreEnumerationFree(List srcFacts, Predicate enumPredicate) { + for (Atom fact : srcFacts) { if (fact.getPredicate().equals(enumPredicate)) { throw oops("Atom declared as enumeration atom by directive occurs in a fact: " + fact); } @@ -62,11 +63,11 @@ private List rewriteRules(List srcRules, CorePredicate enu if (rule.getHead() != null && ((NormalHeadImpl) 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()); - Iterator rit = modifiedBodyLiterals.iterator(); - LinkedList rewrittenLiterals = new LinkedList<>(); + List modifiedBodyLiterals = new ArrayList<>(rule.getBody()); + Iterator rit = modifiedBodyLiterals.iterator(); + LinkedList rewrittenLiterals = new LinkedList<>(); while (rit.hasNext()) { - CoreLiteral literal = rit.next(); + Literal literal = rit.next(); if (!(literal instanceof BasicLiteral)) { continue; } 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 b445c1537..0aa0ed37c 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 @@ -32,10 +32,12 @@ import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.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.core.atoms.IntervalAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; @@ -58,14 +60,14 @@ public class IntervalTermToIntervalAtom extends ProgramTransformation intervalReplacements = new LinkedHashMap<>(); + Map intervalReplacements = new LinkedHashMap<>(); - List rewrittenBody = new ArrayList<>(); + List rewrittenBody = new ArrayList<>(); - for (CoreLiteral literal : rule.getBody()) { + for (Literal literal : rule.getBody()) { rewrittenBody.add(rewriteLiteral(literal, intervalReplacements)); } - NormalHeadImpl rewrittenHead = rule.isConstraint() ? null : + NormalHead rewrittenHead = rule.isConstraint() ? null : new NormalHeadImpl(rewriteLiteral(rule.getHeadAtom().toLiteral(), intervalReplacements).getAtom()); // If intervalReplacements is empty, no IntervalTerms have been found, keep rule as is. @@ -74,7 +76,7 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { } // Add new IntervalAtoms representing the interval specifications. - for (Map.Entry interval : intervalReplacements.entrySet()) { + for (Map.Entry interval : intervalReplacements.entrySet()) { rewrittenBody.add(new IntervalAtom(interval.getValue(), interval.getKey()).toLiteral()); } return new NormalRule(rewrittenHead, rewrittenBody); @@ -83,12 +85,12 @@ private static NormalRule rewriteIntervalSpecifications(NormalRule rule) { /** * Replaces every IntervalTerm by a new variable and returns a mapping of the replaced VariableTerm -> IntervalTerm. */ - private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { - CoreAtom atom = lit.getAtom(); - List termList = new ArrayList<>(atom.getTerms()); + private static Literal rewriteLiteral(Literal lit, Map intervalReplacement) { + Atom atom = lit.getAtom(); + List termList = new ArrayList<>(atom.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { - CoreTerm term = termList.get(i); + Term term = termList.get(i); if (term instanceof IntervalTerm) { VariableTermImpl replacementVariable = VariableTermImpl.getInstance(INTERVAL_VARIABLE_PREFIX + intervalReplacement.size()); intervalReplacement.put(replacementVariable, (IntervalTerm) term); @@ -103,17 +105,17 @@ private static CoreLiteral rewriteLiteral(CoreLiteral lit, Map intervalReplacement) { - List termList = new ArrayList<>(functionTerm.getTerms()); + private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map intervalReplacement) { + List termList = new ArrayList<>(functionTerm.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { - CoreTerm term = termList.get(i); + Term term = termList.get(i); if (term instanceof IntervalTerm) { VariableTermImpl replacementVariable = VariableTermImpl.getInstance("_Interval" + intervalReplacement.size()); intervalReplacement.put(replacementVariable, (IntervalTerm) term); 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 2b4bc7576..534247068 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.core.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; /** @@ -9,7 +9,7 @@ * * Copyright (c) 2019-2020, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformation { +public class NormalizeProgramTransformation extends ProgramTransformation { private boolean useNormalizationGrid; @@ -18,8 +18,8 @@ public NormalizeProgramTransformation(boolean useNormalizationGrid) { } @Override - public NormalProgram apply(InputProgramImpl inputProgram) { - InputProgramImpl tmpPrg; + public NormalProgram apply(InputProgram inputProgram) { + InputProgram tmpPrg; // Transform choice rules. tmpPrg = new ChoiceHeadToNormal().apply(inputProgram); // Transform cardinality aggregates. 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 c72179f9b..1f10c3d1d 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,14 +3,16 @@ import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.Head; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** @@ -21,9 +23,9 @@ */ public class PredicateInternalizer { - static InputProgramImpl makePredicatesInternal(InputProgramImpl program) { - InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); - for (CoreAtom atom : program.getFacts()) { + static InputProgram makePredicatesInternal(InputProgram program) { + InputProgram.Builder prgBuilder = InputProgram.builder(); + for (Atom atom : program.getFacts()) { prgBuilder.addFact(PredicateInternalizer.makePredicateInternal(atom)); } for (BasicRule rule : program.getRules()) { @@ -39,10 +41,10 @@ private static BasicRule makePredicateInternal(BasicRule rule) { if (!(rule.getHead() instanceof NormalHeadImpl)) { throw new UnsupportedOperationException("Cannot make predicates in rules internal whose head is not normal."); } - newHead = new NormalHeadImpl(makePredicateInternal(((NormalHeadImpl) rule.getHead()).getAtom())); + newHead = new NormalHeadImpl(makePredicateInternal(((NormalHead) rule.getHead()).getAtom())); } - List newBody = new ArrayList<>(); - for (CoreLiteral bodyElement : rule.getBody()) { + List newBody = new ArrayList<>(); + for (Literal bodyElement : rule.getBody()) { // Only rewrite BasicAtoms. if (bodyElement instanceof BasicLiteral) { newBody.add(makePredicateInternal(bodyElement.getAtom()).toLiteral()); @@ -54,7 +56,7 @@ private static BasicRule makePredicateInternal(BasicRule rule) { return new BasicRule(newHead, newBody); } - private static CoreAtom makePredicateInternal(CoreAtom atom) { + private static CoreAtom makePredicateInternal(Atom atom) { CorePredicate newInternalPredicate = CorePredicate.getInstance(atom.getPredicate().getName(), atom.getPredicate().getArity(), true); return new BasicAtom(newInternalPredicate, atom.getTerms()); } 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 7e8bd71e6..459e7065b 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 @@ -16,19 +16,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph.SCComponent; import at.ac.tuwien.kr.alpha.core.depgraph.Node; import at.ac.tuwien.kr.alpha.core.depgraph.StratificationAlgorithm; -import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph.SCComponent; import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrder; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationResult; @@ -48,11 +49,11 @@ public class StratifiedEvaluation extends ProgramTransformation> predicateDefiningRules; + private Map> predicateDefiningRules; - private Map> modifiedInLastEvaluationRun = new HashMap<>(); + private Map> modifiedInLastEvaluationRun = new HashMap<>(); - private List additionalFacts = new ArrayList<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. + private List additionalFacts = new ArrayList<>(); // 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; @@ -67,15 +68,15 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { predicateDefiningRules = inputProgram.getPredicateDefiningRules(); // Set up list of atoms which are known to be true - these will be expand by the evaluation. - Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); - for (Map.Entry> entry : knownFacts.entrySet()) { + Map> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate()); + for (Map.Entry> entry : knownFacts.entrySet()) { workingMemory.initialize(entry.getKey()); workingMemory.addInstances(entry.getKey(), true, entry.getValue()); } // Create working memories for all predicates occurring in each rule. for (InternalRule nonGroundRule : inputProgram.getRulesById().values()) { - for (CorePredicate predicate : nonGroundRule.getOccurringPredicates()) { + for (Predicate predicate : nonGroundRule.getOccurringPredicates()) { workingMemory.initialize(predicate); } } @@ -166,15 +167,15 @@ private void prepareInitialEvaluation(Set rulesToEvaluate) { modifiedInLastEvaluationRun = new HashMap<>(); for (InternalRule rule : rulesToEvaluate) { // Register rule head instances. - CorePredicate headPredicate = rule.getHeadAtom().getPredicate(); + Predicate headPredicate = rule.getHeadAtom().getPredicate(); IndexedInstanceStorage headInstances = workingMemory.get(headPredicate, true); modifiedInLastEvaluationRun.putIfAbsent(headPredicate, new LinkedHashSet<>()); if (headInstances != null) { modifiedInLastEvaluationRun.get(headPredicate).addAll(headInstances.getAllInstances()); } // Register positive body literal instances. - for (CoreLiteral lit : rule.getPositiveBody()) { - CorePredicate bodyPredicate = lit.getPredicate(); + for (Literal lit : rule.getPositiveBody()) { + Predicate bodyPredicate = lit.getPredicate(); IndexedInstanceStorage bodyInstances = workingMemory.get(bodyPredicate, true); modifiedInLastEvaluationRun.putIfAbsent(bodyPredicate, new LinkedHashSet<>()); if (bodyInstances != null) { @@ -200,20 +201,20 @@ private List calculateSatisfyingSubstitutionsForRule(InternalRule LOGGER.debug("Is fixed rule? {}", rule.getGroundingOrders().fixedInstantiation()); if (groundingOrders.fixedInstantiation()) { RuleGroundingOrder fixedGroundingOrder = groundingOrders.getFixedGroundingOrder(); - return calcSubstitutionsWithGroundingOrder(fixedGroundingOrder, Collections.singletonList(new Substitution())); + return calcSubstitutionsWithGroundingOrder(fixedGroundingOrder, Collections.singletonList(new SubstitutionImpl())); } - List startingLiterals = groundingOrders.getStartingLiterals(); + List startingLiterals = groundingOrders.getStartingLiterals(); // Check only one starting literal if indicated by the parameter. if (!checkAllStartingLiterals) { // If this is the first evaluation run, it suffices to start from the first starting literal only. - CoreLiteral lit = startingLiterals.get(0); + Literal lit = startingLiterals.get(0); return calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), substituteFromRecentlyAddedInstances(lit)); } // Ground from all starting literals. List groundSubstitutions = new ArrayList<>(); // Collection of full ground substitutions for the given rule. - for (CoreLiteral lit : startingLiterals) { + for (Literal lit : startingLiterals) { List substitutionsForStartingLiteral = calcSubstitutionsWithGroundingOrder(groundingOrders.orderStartingFrom(lit), substituteFromRecentlyAddedInstances(lit)); groundSubstitutions.addAll(substitutionsForStartingLiteral); @@ -230,14 +231,14 @@ private List calculateSatisfyingSubstitutionsForRule(InternalRule * @return valid ground substitutions for the literal based on the recently added instances (i.e. instances derived in * the last evaluation run). */ - private List substituteFromRecentlyAddedInstances(CoreLiteral lit) { + private List substituteFromRecentlyAddedInstances(Literal lit) { List retVal = new ArrayList<>(); Set instances = modifiedInLastEvaluationRun.get(lit.getPredicate()); if (instances == null) { return Collections.emptyList(); } for (Instance instance : instances) { - Substitution unifyingSubstitution = Substitution.specializeSubstitution(lit, instance, Substitution.EMPTY_SUBSTITUTION); + Substitution unifyingSubstitution = SubstitutionImpl.specializeSubstitution(lit, instance, SubstitutionImpl.EMPTY_SUBSTITUTION); if (unifyingSubstitution != null) { retVal.add(unifyingSubstitution); } @@ -269,7 +270,7 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde } // In case the full grounding order has been worked on, all current substitutions are full substitutions, add them to // result. - CoreLiteral currentLiteral = groundingOrder.getLiteralAtOrderPosition(currentOrderPosition); + Literal currentLiteral = groundingOrder.getLiteralAtOrderPosition(currentOrderPosition); if (currentLiteral == null) { fullSubstitutions.addAll(currentSubstitutions); currentSubstitutions.clear(); @@ -297,7 +298,7 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde } private void fireRule(InternalRule rule, Substitution substitution) { - CoreAtom newAtom = rule.getHeadAtom().substitute(substitution); + Atom newAtom = rule.getHeadAtom().substitute(substitution); if (!newAtom.isGround()) { throw new IllegalStateException("Trying to fire rule " + rule.toString() + " with incompatible substitution " + substitution.toString()); } @@ -310,13 +311,13 @@ private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { Set recursiveRules = new HashSet<>(); // Collect all predicates occurring in heads of rules of the given component. - Set headPredicates = new HashSet<>(); + Set headPredicates = new HashSet<>(); for (Node node : comp.getNodes()) { headPredicates.add(node.getPredicate()); } // Check each predicate whether its defining rules depend on some of the head predicates, i.e., whether there is a // cycle. - for (CorePredicate headPredicate : headPredicates) { + for (Predicate headPredicate : headPredicates) { HashSet definingRules = predicateDefiningRules.get(headPredicate); if (definingRules == null) { // Predicate only occurs in facts, skip. @@ -325,7 +326,7 @@ private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { // Note: here we assume that all rules defining a predicate belong to the same SC component. for (InternalRule rule : definingRules) { boolean isRuleRecursive = false; - for (CoreLiteral lit : rule.getPositiveBody()) { + for (Literal lit : rule.getPositiveBody()) { if (headPredicates.contains(lit.getPredicate())) { // The rule body contains a predicate that is defined in the same // component, the rule is therefore part of a cyclic dependency within diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index d46f694f9..bd0ecde0e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -7,18 +7,18 @@ import java.util.Iterator; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; 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.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; @@ -28,17 +28,17 @@ * * Copyright (c) 2018-2020, the Alpha Team. */ -public class SumNormalization extends ProgramTransformation { +public class SumNormalization extends ProgramTransformation { private int aggregateCount; private ProgramParserImpl parser = new ProgramParserImpl(); - private InputProgramImpl parse(String program) { + private InputProgram parse(String program) { return parser.parse(program); } @Override - public InputProgramImpl apply(InputProgramImpl inputProgram) { + public InputProgram apply(InputProgram inputProgram) { if (!rewritingNecessary(inputProgram)) { return inputProgram; } @@ -52,9 +52,9 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { // Connect/Rewrite every aggregate in each rule. List rewrittenRules = rewriteAggregates(inputProgram.getRules()); - InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); + InputProgram.Builder prgBuilder = InputProgram.builder(); prgBuilder.addFacts(inputProgram.getFacts()); - InputProgramImpl summationEncoding = makePredicatesInternal(new ProgramParserImpl().parse(summationSubprogram)); + InputProgram summationEncoding = makePredicatesInternal(new ProgramParserImpl().parse(summationSubprogram)); prgBuilder.accumulate(summationEncoding); prgBuilder.addRules(rewrittenRules); @@ -62,7 +62,7 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { // The enumeration rule is: "input_number_with_first(A, I, F) :- input_with_first(A, X, F), _index(A, X, I)." BasicRule tmpEnumRule = makePredicatesInternal(parse("input_number_with_first(A, I, F) :- input_with_first(A, X, F).")).getRules().get(0); EnumerationAtom enumerationAtom = new EnumerationAtom(parse("index(A, X, I).").getFacts().get(0).getTerms()); - List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); + List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); enumerationRuleBody.add(enumerationAtom.toLiteral()); BasicRule enumerationRule = new BasicRule(tmpEnumRule.getHead(), enumerationRuleBody); prgBuilder.addRule(enumerationRule); @@ -76,9 +76,9 @@ public InputProgramImpl apply(InputProgramImpl inputProgram) { * @param program the program. * @return true if sum aggregates occur, false otherwise. */ - private boolean rewritingNecessary(InputProgramImpl program) { + private boolean rewritingNecessary(InputProgram program) { for (BasicRule rule : program.getRules()) { - for (CoreLiteral lit : rule.getBody()) { + for (Literal lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); if (aggregateAtom.getAggregatefunction() == AggregateAtom.AGGREGATEFUNCTION.SUM) { @@ -117,13 +117,13 @@ private List rewriteAggregatesInRule(BasicRule rule) { final BasicAtom lowerBoundAtom = (BasicAtom) makePredicatesInternal(parse( "bound(aggregate(AGGREGATE_ID), LOWER_BOUND).")).getFacts().get(0); - ArrayList aggregateOutputAtoms = new ArrayList<>(); + ArrayList aggregateOutputAtoms = new ArrayList<>(); int aggregatesInRule = 0; // Only needed for limited rewriting. ArrayList additionalRules = new ArrayList<>(); - List rewrittenBody = new ArrayList<>(rule.getBody()); - for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { - CoreLiteral bodyElement = iterator.next(); + List rewrittenBody = new ArrayList<>(rule.getBody()); + for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { + Literal bodyElement = iterator.next(); // Skip non-aggregates. if (!(bodyElement instanceof AggregateLiteral)) { continue; @@ -149,12 +149,12 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Prepare aggregate parameters. aggregateCount++; Unifier aggregateUnifier = new Unifier(); - Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); + Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier - ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); + ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); } @@ -166,7 +166,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create input to sorting network from aggregate elements. for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. - List elementTerms = aggregateElement.getElementTerms(); + List elementTerms = aggregateElement.getElementTerms(); FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); Unifier elementUnifier = new Unifier(aggregateUnifier); elementUnifier.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); @@ -174,7 +174,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementUnifier); - List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); + List elementLiterals = new ArrayList<>(aggregateElement.getElementLiterals()); // If there are global variables used inside the aggregate, add original rule body (minus the aggregate itself) to input rule. if (!globalVariables.isEmpty()) { @@ -186,7 +186,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { // Create lower bound for the aggregate. BasicAtom lowerBoundHeadAtom = lowerBoundAtom.substitute(aggregateUnifier); - List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. + List lowerBoundBody = rewrittenBody; // Note: this is only correct if no other aggregate occurs in the rule. additionalRules.add(new BasicRule(new NormalHeadImpl(lowerBoundHeadAtom), lowerBoundBody)); } if (aggregatesInRule > 0) { 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 b70dde6cf..82a1c1bcd 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,11 +37,12 @@ import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.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.core.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; @@ -65,9 +66,9 @@ public NormalProgram apply(NormalProgram inputProgram) { private NormalRule findAndReplaceVariableEquality(NormalRule rule) { // Collect all equal variables. - HashMap> variableToEqualVariables = new LinkedHashMap<>(); - HashSet equalitiesToRemove = new HashSet<>(); - for (CoreLiteral bodyElement : rule.getBody()) { + HashMap> variableToEqualVariables = new LinkedHashMap<>(); + HashSet equalitiesToRemove = new HashSet<>(); + for (Literal bodyElement : rule.getBody()) { if (!(bodyElement instanceof ComparisonLiteral)) { continue; } @@ -75,13 +76,13 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { if (!comparisonLiteral.isNormalizedEquality()) { continue; } - if (comparisonLiteral.getTerms().get(0) instanceof VariableTermImpl && comparisonLiteral.getTerms().get(1) instanceof VariableTermImpl) { - VariableTermImpl leftVariable = (VariableTermImpl) comparisonLiteral.getTerms().get(0); - VariableTermImpl rightVariable = (VariableTermImpl) comparisonLiteral.getTerms().get(1); - HashSet leftEqualVariables = variableToEqualVariables.get(leftVariable); - HashSet rightEqualVariables = variableToEqualVariables.get(rightVariable); + if (comparisonLiteral.getTerms().get(0) instanceof VariableTerm && comparisonLiteral.getTerms().get(1) instanceof VariableTerm) { + VariableTerm leftVariable = (VariableTerm) comparisonLiteral.getTerms().get(0); + VariableTerm rightVariable = (VariableTerm) comparisonLiteral.getTerms().get(1); + HashSet leftEqualVariables = variableToEqualVariables.get(leftVariable); + HashSet rightEqualVariables = variableToEqualVariables.get(rightVariable); if (leftEqualVariables == null && rightEqualVariables == null) { - HashSet equalVariables = new LinkedHashSet<>(Arrays.asList(leftVariable, rightVariable)); + HashSet equalVariables = new LinkedHashSet<>(Arrays.asList(leftVariable, rightVariable)); variableToEqualVariables.put(leftVariable, equalVariables); variableToEqualVariables.put(rightVariable, equalVariables); } @@ -95,7 +96,7 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { } if (leftEqualVariables != null && rightEqualVariables != null) { leftEqualVariables.addAll(rightEqualVariables); - for (VariableTermImpl rightEqualVariable : rightEqualVariables) { + for (VariableTerm rightEqualVariable : rightEqualVariables) { variableToEqualVariables.put(rightEqualVariable, leftEqualVariables); } } @@ -107,37 +108,37 @@ private NormalRule findAndReplaceVariableEquality(NormalRule rule) { return rule; } - List rewrittenBody = new ArrayList<>(rule.getBody()); - NormalHeadImpl rewrittenHead = rule.isConstraint() ? null : new NormalHeadImpl(rule.getHeadAtom()); + List rewrittenBody = new ArrayList<>(rule.getBody()); + NormalHead rewrittenHead = rule.isConstraint() ? null : new NormalHeadImpl(rule.getHeadAtom()); // Use substitution for actual replacement. Unifier replacementSubstitution = new Unifier(); // For each set of equal variables, take the first variable and replace all others by it. - for (Map.Entry> variableEqualityEntry : variableToEqualVariables.entrySet()) { - VariableTermImpl variableToReplace = variableEqualityEntry.getKey(); - VariableTermImpl replacementVariable = variableEqualityEntry.getValue().iterator().next(); + for (Map.Entry> variableEqualityEntry : variableToEqualVariables.entrySet()) { + VariableTerm variableToReplace = variableEqualityEntry.getKey(); + VariableTerm replacementVariable = variableEqualityEntry.getValue().iterator().next(); if (variableToReplace == replacementVariable) { continue; } replacementSubstitution.put(variableToReplace, replacementVariable); } // Replace/Substitute in each literal every term where one of the common variables occurs. - Iterator bodyIterator = rewrittenBody.iterator(); + Iterator bodyIterator = rewrittenBody.iterator(); while (bodyIterator.hasNext()) { - CoreLiteral literal = bodyIterator.next(); + Literal literal = bodyIterator.next(); if (equalitiesToRemove.contains(literal)) { bodyIterator.remove(); } for (int i = 0; i < literal.getTerms().size(); i++) { - CoreTerm replaced = literal.getTerms().get(i).substitute(replacementSubstitution); + Term replaced = literal.getTerms().get(i).substitute(replacementSubstitution); literal.getTerms().set(i, replaced); } } // Replace variables in head. if (rewrittenHead != null) { - CoreAtom headAtom = rewrittenHead.getAtom(); + Atom headAtom = rewrittenHead.getAtom(); for (int i = 0; i < headAtom.getTerms().size(); i++) { - CoreTerm replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); + Term replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution); headAtom.getTerms().set(i, replaced); } } 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 71c6e61c8..dd428172a 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 @@ -8,8 +8,8 @@ import org.apache.commons.collections4.SetUtils; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.core.util.Util; /** @@ -22,14 +22,14 @@ public abstract class AbstractRule { private final H head; - private final Set bodyLiteralsPositive; - private final Set bodyLiteralsNegative; + private final Set bodyLiteralsPositive; + private final Set bodyLiteralsNegative; - public AbstractRule(H head, List body) { + public AbstractRule(H head, List body) { this.head = head; - Set positiveBody = new LinkedHashSet<>(); - Set negativeBody = new LinkedHashSet<>(); - for (CoreLiteral bodyLiteral : body) { + Set positiveBody = new LinkedHashSet<>(); + Set negativeBody = new LinkedHashSet<>(); + for (Literal bodyLiteral : body) { if (bodyLiteral.isNegated()) { negativeBody.add(bodyLiteral); } else { @@ -94,15 +94,15 @@ public H getHead() { return head; } - public Set getBody() { + public Set getBody() { return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); } - public Set getPositiveBody() { + public Set getPositiveBody() { return this.bodyLiteralsPositive; } - public Set getNegativeBody() { + public Set getNegativeBody() { return this.bodyLiteralsNegative; } 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 9a6a47bd2..e55d23647 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 @@ -29,8 +29,8 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.rules.heads.Head; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.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. @@ -38,7 +38,7 @@ */ public class BasicRule extends AbstractRule { - public BasicRule(Head head, List body) { + 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 13499b968..c6dbe7e34 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 @@ -32,10 +32,12 @@ import com.google.common.annotations.VisibleForTesting; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; @@ -52,11 +54,11 @@ public class InternalRule extends NormalRule { private final int ruleId; - private final List occurringPredicates; + private final List occurringPredicates; private final RuleGroundingOrders groundingOrders; - public InternalRule(NormalHeadImpl head, List body) { + public InternalRule(NormalHead head, List body) { super(head, body); if (body.isEmpty()) { throw new IllegalArgumentException( @@ -69,7 +71,7 @@ public InternalRule(NormalHeadImpl head, List body) { this.occurringPredicates.add(this.getHeadAtom().getPredicate()); } - for (CoreLiteral literal : body) { + for (Literal literal : body) { if (literal instanceof AggregateLiteral) { throw new IllegalArgumentException("AggregateLiterals aren't supported in InternalRules! (lit: " + literal.toString() + ")"); } @@ -101,20 +103,20 @@ public static InternalRule fromNormalRule(NormalRule rule) { * @return */ public InternalRule renameVariables(String newVariablePostfix) { - List occurringVariables = new ArrayList<>(); - CoreAtom headAtom = this.getHeadAtom(); + List occurringVariables = new ArrayList<>(); + Atom headAtom = this.getHeadAtom(); occurringVariables.addAll(headAtom.getOccurringVariables()); - for (CoreLiteral literal : this.getBody()) { + for (Literal literal : this.getBody()) { occurringVariables.addAll(literal.getOccurringVariables()); } Unifier variableReplacement = new Unifier(); - for (VariableTermImpl occurringVariable : occurringVariables) { + for (VariableTerm occurringVariable : occurringVariables) { final String newVariableName = occurringVariable.toString() + newVariablePostfix; variableReplacement.put(occurringVariable, VariableTermImpl.getInstance(newVariableName)); } - CoreAtom renamedHeadAtom = headAtom.substitute(variableReplacement); - ArrayList renamedBody = new ArrayList<>(this.getBody().size()); - for (CoreLiteral literal : this.getBody()) { + Atom renamedHeadAtom = headAtom.substitute(variableReplacement); + ArrayList renamedBody = new ArrayList<>(this.getBody().size()); + for (Literal literal : this.getBody()) { renamedBody.add(literal.substitute(variableReplacement)); } return new InternalRule(new NormalHeadImpl(renamedHeadAtom), renamedBody); @@ -124,7 +126,7 @@ public InternalRule renameVariables(String newVariablePostfix) { * Returns the predicates occurring in this rule. * @return a list of all predicates occurring in the rule (may contain duplicates and builtin atoms). */ - public List getOccurringPredicates() { + public List getOccurringPredicates() { return this.occurringPredicates; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java index 5eadce6c0..c0db947be 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java @@ -3,8 +3,9 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; import at.ac.tuwien.kr.alpha.core.util.Util; @@ -14,19 +15,19 @@ * * Copyright (c) 2019, the Alpha Team. */ -public class NormalRule extends AbstractRule { +public class NormalRule extends AbstractRule { - public NormalRule(NormalHeadImpl head, List body) { + public NormalRule(NormalHead head, List body) { super(head, body); } public static NormalRule fromBasicRule(BasicRule rule) { - CoreAtom headAtom = null; + Atom headAtom = null; if (!rule.isConstraint()) { if (!(rule.getHead() instanceof NormalHeadImpl)) { throw Util.oops("Trying to construct a NormalRule from rule with non-normal head! Head type is: " + rule.getHead().getClass().getSimpleName()); } - headAtom = ((NormalHeadImpl) rule.getHead()).getAtom(); + headAtom = ((NormalHead) rule.getHead()).getAtom(); } return new NormalRule(headAtom != null ? new NormalHeadImpl(headAtom) : null, new ArrayList<>(rule.getBody())); } @@ -35,7 +36,7 @@ public boolean isGround() { if (!isConstraint() && !this.getHead().isGround()) { return false; } - for (CoreLiteral bodyElement : this.getBody()) { + for (Literal bodyElement : this.getBody()) { if (!bodyElement.isGround()) { return false; } @@ -43,7 +44,7 @@ public boolean isGround() { return true; } - public CoreAtom getHeadAtom() { + public Atom getHeadAtom() { return this.isConstraint() ? null : this.getHead().getAtom(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java new file mode 100644 index 000000000..4b7aab7c9 --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java @@ -0,0 +1,129 @@ +package at.ac.tuwien.kr.alpha.core.rules; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; + +import org.apache.commons.collections4.SetUtils; + +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.core.util.Util; + +/** + * TODO update javadoc + * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) + * + * @param the type of head for this rule + * + * Copyright (c) 2017-2021, the Alpha Team. + */ +public class RuleImpl implements Rule { + + private final H head; + private final Set bodyLiteralsPositive; + private final Set bodyLiteralsNegative; + + public RuleImpl(H head, Set body) { + this.head = head; + Set positiveBody = new LinkedHashSet<>(); + Set negativeBody = new LinkedHashSet<>(); + for (Literal bodyLiteral : body) { + if (bodyLiteral.isNegated()) { + negativeBody.add(bodyLiteral); + } else { + positiveBody.add(bodyLiteral); + } + } + this.bodyLiteralsPositive = Collections.unmodifiableSet(positiveBody); + this.bodyLiteralsNegative = Collections.unmodifiableSet(negativeBody); + + if (!this.isSafe()) { + // TODO: safety check needs to be adapted to solver what the solver actually understands. Will change in the future, + // adapt exception message accordingly. + throw new RuntimeException("Encountered unsafe rule: " + toString() + System.lineSeparator() + + "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."); + } + } + + /** + * Checks whether a rule is safe. The actual safety condition may vary over the next improvements. Currently, a rule is + * safe iff all negated variables and + * all variables occurring in the head also occur in the positive body). + * + * @return true if this rule is safe. + */ + private boolean isSafe() { + // TODO: do the real check. + // Note that - once a proper safety check is implemented - that check should probably be specific for each rule + // implementation, therefore this method should be "protected abstract" here and implemented in each subclass. + return true; + /* + * Set positiveVariables = new HashSet<>(); Set builtinVariables = new HashSet<>(); + * + * // Check that all negative variables occur in the positive body. for (Literal literal : body) { // FIXME: The + * following five lines depend on concrete + * // implementations of the Atom interface. Not nice. if (literal instanceof BasicAtom) { + * positiveVariables.addAll(literal.getOccurringVariables()); } + * else if (literal instanceof BuiltinAtom) { builtinVariables.addAll(literal.getOccurringVariables()); } } + * + * for (Atom negAtom : bodyAtomsNegative) { for (VariableTerm term : negAtom.getOccurringVariables()) { if + * (!positiveVariables.contains(term)) { return + * false; } } } for (VariableTerm builtinVariable : builtinVariables) { if + * (!positiveVariables.contains(builtinVariable)) { return false; } } + * + * // Constraint are safe at this point if (isConstraint()) { return true; } + * + * // Check that all variables of the head occur in the positive body. List headVariables = + * head.getOccurringVariables(); + * headVariables.removeAll(positiveVariables); return headVariables.isEmpty(); + */ + } + + public boolean isConstraint() { + return head == null; + } + + @Override + public String toString() { + return Util.join((isConstraint() ? "" : head.toString() + " ") + ":- ", getBody(), "."); + } + + public H getHead() { + return head; + } + + public Set getBody() { + return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); + } + + public Set getPositiveBody() { + return this.bodyLiteralsPositive; + } + + public Set getNegativeBody() { + return this.bodyLiteralsNegative; + } + + @Override + public int hashCode() { + return Objects.hash(bodyLiteralsNegative, bodyLiteralsPositive, head); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof RuleImpl)) { + return false; + } + RuleImpl other = (RuleImpl) obj; + return Objects.equals(this.bodyLiteralsNegative, other.bodyLiteralsNegative) + && Objects.equals(this.bodyLiteralsPositive, other.bodyLiteralsPositive) + && Objects.equals(this.head, other.head); + } + +} 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 index 150711de3..ee991439b 100644 --- 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 @@ -1,6 +1,8 @@ package at.ac.tuwien.kr.alpha.core.rules; import java.util.List; +import java.util.Optional; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; @@ -8,23 +10,26 @@ import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.core.rules.heads.DisjunctiveHeadImpl; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; public class Rules { - public static Rule newDisjunctiveRule(List disjunctiveAtoms, List body) { - return null; // TODO + public static Rule newDisjunctiveRule(List disjunctiveAtoms, Set body) { + return new RuleImpl<>(new DisjunctiveHeadImpl(disjunctiveAtoms), body); } - public static Rule newChoiceRule(ChoiceHead head, List body) { - return null; // TODO (also better params) + // TODO factory method for choice heads + public static Rule newChoiceRule(ChoiceHead head, Set body) { + return new RuleImpl<>(head, body); } - public static Rule newNormalRule(Atom headAtom, List body) { - return null; // TODO + public static Rule newNormalRule(Atom headAtom, Set body) { + return new RuleImpl<>(new NormalHeadImpl(Optional.of(headAtom)), body); } - public static Rule newConstraint(List body) { - return null; // TODO + public static Rule newConstraint(Set body) { + return new RuleImpl<>(new NormalHeadImpl(Optional.empty()), body); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java index b3dfc2ebb..ed2900325 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java @@ -4,11 +4,11 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; +import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; /** * Represents the head of a choice rule. @@ -18,17 +18,17 @@ public class ChoiceHeadImpl implements ChoiceHead { private final List choiceElements; - private final CoreTerm lowerBound; + private final Term lowerBound; private final ComparisonOperator lowerOp; - private final CoreTerm upperBound; + private final Term upperBound; private final ComparisonOperator upperOp; - public static class ChoiceElement { - public final CoreAtom choiceAtom; - public final List conditionLiterals; + public static class ChoiceElementImpl implements ChoiceElement { + public final Atom choiceAtom; + public final List conditionLiterals; - public ChoiceElement(CoreAtom choiceAtom, List conditionLiterals) { + public ChoiceElementImpl(Atom choiceAtom, List conditionLiterals) { this.choiceAtom = choiceAtom; this.conditionLiterals = conditionLiterals; } @@ -43,6 +43,16 @@ public String toString() { return join(result + " : ", conditionLiterals, ""); } + + @Override + public Atom getChoiceAtom() { + return choiceAtom; + } + + @Override + public List getConditionLiterals() { + return conditionLiterals; + } } public ComparisonOperator getLowerOperator() { @@ -53,19 +63,23 @@ public ComparisonOperator getUpperOperator() { return upperOp; } + @Override public List getChoiceElements() { return choiceElements; } - public CoreTerm getLowerBound() { + @Override + public Term getLowerBound() { return lowerBound; } - public CoreTerm getUpperBound() { + @Override + public Term getUpperBound() { return upperBound; } - public ChoiceHeadImpl(List choiceElements, CoreTerm lowerBound, ComparisonOperator lowerOp, CoreTerm upperBound, ComparisonOperator upperOp) { + public ChoiceHeadImpl(List choiceElements, Term lowerBound, ComparisonOperator lowerOp, Term upperBound, + ComparisonOperator upperOp) { this.choiceElements = choiceElements; this.lowerBound = lowerBound; this.lowerOp = lowerOp; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHead.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHeadImpl.java similarity index 73% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHead.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHeadImpl.java index 6de31830a..5c86bb9a1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHead.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHeadImpl.java @@ -4,15 +4,16 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; /** * Copyright (c) 2017, the Alpha Team. */ -public class DisjunctiveHead extends Head { - public final List disjunctiveAtoms; +public class DisjunctiveHeadImpl implements DisjunctiveHead { + public final List disjunctiveAtoms; - public DisjunctiveHead(List disjunctiveAtoms) { + public DisjunctiveHeadImpl(List disjunctiveAtoms) { this.disjunctiveAtoms = disjunctiveAtoms; if (disjunctiveAtoms != null && disjunctiveAtoms.size() > 1) { throw new UnsupportedOperationException("Disjunction in rule heads is not yet supported"); @@ -25,7 +26,7 @@ public String toString() { } public boolean isGround() { - for (CoreAtom atom : disjunctiveAtoms) { + for (Atom atom : disjunctiveAtoms) { if (!atom.isGround()) { return false; } @@ -49,10 +50,10 @@ public boolean equals(Object obj) { if (obj == null) { return false; } - if (!(obj instanceof DisjunctiveHead)) { + if (!(obj instanceof DisjunctiveHeadImpl)) { return false; } - DisjunctiveHead other = (DisjunctiveHead) obj; + DisjunctiveHeadImpl other = (DisjunctiveHeadImpl) obj; if (this.disjunctiveAtoms == null) { if (other.disjunctiveAtoms != null) { return false; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/Head.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/HeadImpl.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/Head.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/HeadImpl.java index 3b813f89d..1cb9c1c4e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/Head.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/HeadImpl.java @@ -5,7 +5,7 @@ * * Copyright (c) 2017-2019, the Alpha Team. */ -public abstract class Head { +public abstract class HeadImpl { @Override public abstract String toString(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java index 8d5c00802..ba6492305 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java @@ -1,9 +1,7 @@ package at.ac.tuwien.kr.alpha.core.rules.heads; -import java.util.Optional; - +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; /** * Represents a normal head, i.e., a head that is an Atom. @@ -11,9 +9,9 @@ */ public class NormalHeadImpl implements NormalHead { - private final Optional atom; + private final Atom atom; - public NormalHeadImpl(Optional atom) { + public NormalHeadImpl(Atom atom) { this.atom = atom; } @@ -23,7 +21,7 @@ public boolean isGround() { return false; } - public Optional getAtom() { + public Atom getAtom() { return atom; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounter.java index 8504ec567..1e30b7f79 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounter.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; /** @@ -40,9 +41,9 @@ */ public class AtomCounter { - private final Map, Integer> countByType = new HashMap<>(); + private final Map, Integer> countByType = new HashMap<>(); - public void add(CoreAtom atom) { + public void add(Atom atom) { countByType.compute(atom.getClass(), (k, v) -> (v == null) ? 1 : v + 1); } @@ -50,7 +51,7 @@ public void add(CoreAtom atom) { * @param type the class of atoms to count * @return the number of atoms of the given type */ - public int getNumberOfAtoms(Class type) { + public int getNumberOfAtoms(Class type) { return countByType.getOrDefault(type, 0); } @@ -59,7 +60,7 @@ public int getNumberOfAtoms(Class type) { */ public String getStatsByType() { List statsList = new ArrayList<>(); - for (Map.Entry, Integer> entry : countByType.entrySet()) { + for (Map.Entry, Integer> entry : countByType.entrySet()) { statsList.add(entry.getKey().getSimpleName() + ": " + entry.getValue()); } Collections.sort(statsList); 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 90971d645..ff18aec00 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,10 +51,10 @@ import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.AtomStore; @@ -63,7 +63,7 @@ import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.ProgramAnalyzingGrounder; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristic; import at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristicFactory; @@ -304,7 +304,7 @@ private boolean justifyMbtAndBacktrack() { LOGGER.debug("Searching for justification of {} / {}", atomToJustify, atomStore.atomToString(atomToJustify)); LOGGER.debug("Assignment is (TRUE part only): {}", translate(assignment.getTrueAssignments())); } - Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomToJustify, assignment); + Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomToJustify, assignment); NoGood noGood = noGoodFromJustificationReasons(atomToJustify, reasonsForUnjustified); @@ -320,12 +320,12 @@ private boolean justifyMbtAndBacktrack() { return true; } - private NoGood noGoodFromJustificationReasons(int atomToJustify, Set reasonsForUnjustified) { + private NoGood noGoodFromJustificationReasons(int atomToJustify, Set reasonsForUnjustified) { // Turn the justification into a NoGood. int[] reasons = new int[reasonsForUnjustified.size() + 1]; reasons[0] = atomToLiteral(atomToJustify); int arrpos = 1; - for (CoreLiteral literal : reasonsForUnjustified) { + for (Literal literal : reasonsForUnjustified) { reasons[arrpos++] = atomToLiteral(atomStore.get(literal.getAtom()), !literal.isNegated()); } return NoGood.learnt(reasons); @@ -356,7 +356,7 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { ArrayList ruleAtomReplacements = new ArrayList<>(); while (toJustifyIterator.hasNext()) { Integer literal = toJustifyIterator.next(); - CoreAtom atom = atomStore.get(atomOf(literal)); + Atom atom = atomStore.get(atomOf(literal)); if (atom instanceof BasicAtom) { continue; } @@ -370,10 +370,10 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { String ruleId = (String) ((CoreConstantTerm)atom.getTerms().get(0)).getObject(); InternalRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); String substitution = (String) ((CoreConstantTerm)atom.getTerms().get(1)).getObject(); - Substitution groundingSubstitution = Substitution.fromString(substitution); + SubstitutionImpl groundingSubstitution = SubstitutionImpl.fromString(substitution); // Find ground literals in the body that have been assigned false and justify those. - for (CoreLiteral bodyLiteral : nonGroundRule.getBody()) { - CoreAtom groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); + for (Literal bodyLiteral : nonGroundRule.getBody()) { + Atom groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution); if (groundAtom instanceof ComparisonAtom || analyzingGrounder.isFact(groundAtom)) { // Facts and ComparisonAtoms are always true, no justification needed. continue; @@ -390,7 +390,7 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { toJustify.addAll(ruleAtomReplacements); for (Integer literalToJustify : toJustify) { LOGGER.debug("Searching for justification(s) of {} / {}", toJustify, atomStore.atomToString(atomOf(literalToJustify))); - Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomOf(literalToJustify), assignment); + Set reasonsForUnjustified = analyzingGrounder.justifyAtom(atomOf(literalToJustify), assignment); NoGood noGood = noGoodFromJustificationReasons(atomOf(literalToJustify), reasonsForUnjustified); int noGoodID = grounder.register(noGood); obtained.put(noGoodID, noGood); From 848ad7c728a655129ea6ed7f1cf667bb8bbde17e Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 29 Jan 2021 13:37:39 +0100 Subject: [PATCH 016/111] extract all interfaces, make it compile --- .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 29 ++-- .../at/ac/tuwien/kr/alpha/api/AnswerSet.java | 3 +- .../at/ac/tuwien/kr/alpha/api}/Solver.java | 12 +- .../java/at/ac/tuwien/kr/alpha/api}/Util.java | 3 +- .../kr/alpha/api}/grounder/Instance.java | 7 +- .../alpha/api/grounder/RuleGroundingInfo.java | 18 +++ .../api/grounder/RuleGroundingOrder.java | 16 +++ .../kr/alpha/api/grounder/Substitution.java | 2 +- .../kr/alpha/api/program/ASPCore2Program.java | 8 ++ .../kr/alpha/api/program/CompiledProgram.java | 18 +++ .../tuwien/kr/alpha/api/program/Program.java | 10 +- .../kr/alpha/api/program/ProgramParser.java | 20 +-- .../kr/alpha/api/rules/CompiledRule.java | 24 ++++ .../at/ac/tuwien/kr/alpha/api/rules/Rule.java | 10 +- .../kr/alpha/AnswerSetToXlsxWriter.java | 6 +- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 29 ++-- .../kr/alpha/core/atoms/AggregateAtom.java | 4 +- .../tuwien/kr/alpha/core/atoms/BasicAtom.java | 7 +- .../kr/alpha/core/atoms/ChoiceAtom.java | 5 +- .../kr/alpha/core/atoms/EnumerationAtom.java | 5 +- .../kr/alpha/core/atoms/ExternalAtom.java | 6 +- .../kr/alpha/core/atoms/IntervalAtom.java | 8 +- .../tuwien/kr/alpha/core/atoms/RuleAtom.java | 4 +- .../alpha/core/common/AnswerSetFormatter.java | 4 +- .../kr/alpha/core/common/AtomStoreImpl.java | 6 +- .../kr/alpha/core/common/BasicAnswerSet.java | 7 +- .../alpha/core/common/ComparisonOperator.java | 4 +- .../tuwien/kr/alpha/core/common/NoGood.java | 17 ++- .../core/common/SimpleAnswerSetFormatter.java | 3 +- .../alpha/core/common/terms/FunctionTerm.java | 5 +- .../alpha/core/common/terms/IntervalTerm.java | 7 +- .../alpha/core/depgraph/DependencyGraph.java | 11 +- .../core/grounder/FactIntervalEvaluator.java | 1 + .../kr/alpha/core/grounder/Grounder.java | 4 +- .../alpha/core/grounder/GrounderFactory.java | 8 +- .../core/grounder/IndexedInstanceStorage.java | 1 + .../alpha/core/grounder/IntIdGenerator.java | 2 +- .../kr/alpha/core/grounder/NaiveGrounder.java | 68 ++++----- .../alpha/core/grounder/NoGoodGenerator.java | 17 ++- .../grounder/ProgramAnalyzingGrounder.java | 4 +- ...Orders.java => RuleGroundingInfoImpl.java} | 21 +-- ...Order.java => RuleGroundingOrderImpl.java} | 13 +- .../alpha/core/grounder/SubstitutionImpl.java | 3 +- .../kr/alpha/core/grounder/Unification.java | 2 +- .../kr/alpha/core/grounder/Unifier.java | 2 +- .../kr/alpha/core/grounder/WorkingMemory.java | 1 + .../AbstractLiteralInstantiationStrategy.java | 2 +- ...ultLazyGroundingInstantiationStrategy.java | 6 +- ...rkingMemoryBasedInstantiationStrategy.java | 2 +- .../structure/AnalyzeUnjustified.java | 21 +-- .../alpha/core/grounder/structure/LitSet.java | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 10 +- .../alpha/core/parser/ProgramParserImpl.java | 8 +- .../alpha/core/programs/AbstractProgram.java | 10 +- .../alpha/core/programs/AnalyzedProgram.java | 11 +- .../kr/alpha/core/programs/InputProgram.java | 16 ++- .../alpha/core/programs/InternalProgram.java | 37 ++--- .../kr/alpha/core/programs/NormalProgram.java | 16 ++- .../CardinalityNormalization.java | 33 +++-- .../transformation/ChoiceHeadToNormal.java | 18 ++- .../transformation/EnumerationRewriting.java | 24 ++-- .../IntervalTermToIntervalAtom.java | 9 +- .../NormalizeProgramTransformation.java | 8 +- .../transformation/PredicateInternalizer.java | 8 +- .../transformation/ProgramTransformation.java | 5 +- .../transformation/StratifiedEvaluation.java | 48 +++---- .../transformation/SumNormalization.java | 29 ++-- .../VariableEqualityRemoval.java | 7 +- .../kr/alpha/core/rules/AbstractRule.java | 7 +- .../tuwien/kr/alpha/core/rules/BasicRule.java | 16 ++- .../kr/alpha/core/rules/InternalRule.java | 15 +- .../kr/alpha/core/rules/NormalRule.java | 6 +- .../tuwien/kr/alpha/core/rules/RuleImpl.java | 129 ------------------ .../ac/tuwien/kr/alpha/core/rules/Rules.java | 35 ----- .../core/rules/heads/ChoiceHeadImpl.java | 2 +- .../core/rules/heads/DisjunctiveHeadImpl.java | 2 +- .../kr/alpha/core/solver/AbstractSolver.java | 20 +-- .../core/solver/ChoiceInfluenceManager.java | 18 ++- .../kr/alpha/core/solver/ChoiceManager.java | 2 +- .../kr/alpha/core/solver/DefaultSolver.java | 12 +- .../kr/alpha/core/solver/NaiveSolver.java | 34 +++-- .../core/solver/NoGoodStoreAlphaRoaming.java | 4 +- .../alpha/core/solver/ShallowAntecedent.java | 2 +- .../kr/alpha/core/solver/SolverFactory.java | 1 + .../kr/alpha/core/solver/TrailAssignment.java | 4 +- .../kr/alpha/core/solver/WatchedNoGood.java | 2 +- .../ChainedBranchingHeuristics.java | 2 +- .../heuristics/HeapOfActiveChoicePoints.java | 2 +- .../alpha/core/solver/heuristics/VSIDS.java | 2 +- .../learning/GroundConflictNoGoodLearner.java | 2 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 55 ++++---- 91 files changed, 603 insertions(+), 566 deletions(-) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver => alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api}/Solver.java (59%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util => alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api}/Util.java (98%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core => alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api}/grounder/Instance.java (85%) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ASPCore2Program.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/CompiledProgram.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/{RuleGroundingOrders.java => RuleGroundingInfoImpl.java} (92%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/{RuleGroundingOrder.java => RuleGroundingOrderImpl.java} (88%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.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 a54275099..febda8b7c 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,23 +8,36 @@ 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.program.InputProgram; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; public interface Alpha { - InputProgram readProgram(InputConfig cfg) throws IOException; + ASPCore2Program readProgram(InputConfig cfg) throws IOException; - InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException; + ASPCore2Program readProgramFiles(boolean literate, Map externals, List paths) throws IOException; - InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; + ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; - InputProgram readProgramString(String aspString, Map externals); + ASPCore2Program readProgramString(String aspString, Map externals); - InputProgram readProgramString(String aspString); + ASPCore2Program readProgramString(String aspString); - Stream solve(InputProgram program); + Stream solve(ASPCore2Program program); - Stream solve(InputProgram program, java.util.function.Predicate filter); + Stream solve(ASPCore2Program program, java.util.function.Predicate filter); + Program> normalizeProgram(ASPCore2Program program); + + SystemConfig getConfig(); + + CompiledProgram performProgramPreprocessing(CompiledProgram prog); + + Solver prepareSolverFor(CompiledProgram program, java.util.function.Predicate filter); + } 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 63e9baefc..10dfa6693 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 @@ -6,7 +6,8 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; public interface AnswerSet extends Comparable { - SortedSet getPredicates(); + + SortedSet getPredicates(); SortedSet getPredicateInstances(Predicate predicate); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Solver.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Solver.java similarity index 59% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Solver.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Solver.java index 396c72f22..74b7d7820 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/Solver.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Solver.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.api; import java.util.List; import java.util.Set; @@ -7,21 +7,19 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; - @FunctionalInterface public interface Solver { - Spliterator spliterator(); + Spliterator spliterator(); - default Stream stream() { + default Stream stream() { return StreamSupport.stream(spliterator(), false); } - default Set collectSet() { + default Set collectSet() { return stream().collect(Collectors.toSet()); } - default List collectList() { + default List collectList() { return stream().collect(Collectors.toList()); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Util.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Util.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Util.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Util.java index 16da43143..81df8ead3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Util.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Util.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.util; +package at.ac.tuwien.kr.alpha.api; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -41,6 +41,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +// TODO shouldn't be public API public class Util { private static final String LITERATE_INDENT = " "; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Instance.java similarity index 85% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Instance.java index 8841bd6ba..aaa0c6a85 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Instance.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Instance.java @@ -1,19 +1,20 @@ -package at.ac.tuwien.kr.alpha.core.grounder; +package at.ac.tuwien.kr.alpha.api.grounder; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; +import static at.ac.tuwien.kr.alpha.api.Util.join; import java.util.Arrays; import java.util.List; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.core.util.Util; /** * An instance is a positional association of terms, e.g., representing a variable substitution, or a ground instance of * a predicate. * Copyright (c) 2016, the Alpha Team. */ +// TODO probably shouldn't be published API public class Instance { public final List terms; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java new file mode 100644 index 000000000..30881011c --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java @@ -0,0 +1,18 @@ +package at.ac.tuwien.kr.alpha.api.grounder; + +import java.util.List; + +import at.ac.tuwien.kr.alpha.api.program.Literal; + +public interface RuleGroundingInfo { + + boolean hasFixedInstantiation(); + + // TODO this should be an Optional + RuleGroundingOrder getFixedGroundingOrder(); + + List getStartingLiterals(); + + RuleGroundingOrder orderStartingFrom(Literal startingLiteral); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java new file mode 100644 index 000000000..a55a00c57 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java @@ -0,0 +1,16 @@ +package at.ac.tuwien.kr.alpha.api.grounder; + +import at.ac.tuwien.kr.alpha.api.program.Literal; + +// TODO should we really expose this?? pretty specific to how our grounder works +public interface RuleGroundingOrder { + + Literal getStartingLiteral(); + + Literal getLiteralAtOrderPosition(int pos); + + RuleGroundingOrder pushBack(int pos); + + void considerUntilCurrentEnd(); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java index faafc3660..4d008e1ee 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java @@ -11,6 +11,6 @@ public interface Substitution { TreeMap getSubstitution(); - > Term put(VariableTerm variableTerm, Term groundTerm); + > Term put(VariableTerm variableTerm, Term groundTerm); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ASPCore2Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ASPCore2Program.java new file mode 100644 index 000000000..822b4c046 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ASPCore2Program.java @@ -0,0 +1,8 @@ +package at.ac.tuwien.kr.alpha.api.program; + +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; + +public interface ASPCore2Program extends Program> { + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/CompiledProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/CompiledProgram.java new file mode 100644 index 000000000..24d882b63 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/CompiledProgram.java @@ -0,0 +1,18 @@ +package at.ac.tuwien.kr.alpha.api.program; + +import java.util.LinkedHashSet; +import java.util.Map; + +import at.ac.tuwien.kr.alpha.api.grounder.Instance; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; + +public interface CompiledProgram extends Program { + + Map> getPredicateDefiningRules(); + + Map> getFactsByPredicate(); + + Map getRulesById(); + + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java index 859899561..6feaacc8f 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java @@ -1,14 +1,16 @@ package at.ac.tuwien.kr.alpha.api.program; -import java.util.Set; +import java.util.List; import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; -public interface Program { +public interface Program> { - Set getFacts(); + List getFacts(); - Set> getRules(); + InlineDirectives getInlineDirectives(); + + List getRules(); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java index d2fe80171..84a793086 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java @@ -9,34 +9,34 @@ public interface ProgramParser { - default InputProgram parse(String programString) { + default ASPCore2Program parse(String programString) { return parse(programString, Collections.emptyMap()); } - default InputProgram parse(InputStream programSource) { + default ASPCore2Program parse(InputStream programSource) { return parse(programSource, Collections.emptyMap()); } - default InputProgram parse(Path programPath) { + default ASPCore2Program parse(Path programPath) { return parse(programPath, Collections.emptyMap()); } - default InputProgram parse(Path... programSources) { + default ASPCore2Program parse(Path... programSources) { return parse(Collections.emptyMap(), programSources); } - default InputProgram parse(Iterable programSources) { + default ASPCore2Program parse(Iterable programSources) { return parse(programSources, Collections.emptyMap()); } - InputProgram parse(String programString, Map externalPredicateDefinitions); + ASPCore2Program parse(String programString, Map externalPredicateDefinitions); - InputProgram parse(InputStream programSource, Map externalPredicateDefinitions); + ASPCore2Program parse(InputStream programSource, Map externalPredicateDefinitions); - InputProgram parse(Path programPath, Map externalPredicateDefinitions); + ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions); - InputProgram parse(Map externalPredicateDefinitions, Path... programSources); + ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources); - InputProgram parse(Iterable programSources, Map externalPredicateDefinitions); + ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java new file mode 100644 index 000000000..a0758a515 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java @@ -0,0 +1,24 @@ +package at.ac.tuwien.kr.alpha.api.rules; + +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; + +public interface CompiledRule extends Rule { + + int getRuleId(); + + List getOccurringPredicates(); + + Set getPositiveBody(); + + Set getNegativeBody(); + + RuleGroundingInfo getGroundingInfo(); + + CompiledRule renameVariables(String str); + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java index 315d769bd..a8de0452c 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java @@ -2,11 +2,17 @@ import java.util.Set; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; public interface Rule { - + H getHead(); - + Set getBody(); + + boolean isConstraint(); + + // TODO clean up programs/rules mess + Atom getHeadAtom(); } diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java index 6041f05af..add725e9d 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java @@ -14,11 +14,11 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToObjectMapper; import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToWorkbookMapper; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; -public class AnswerSetToXlsxWriter implements BiConsumer { +public class AnswerSetToXlsxWriter implements BiConsumer { private String targetBasePath; private AnswerSetToObjectMapper answerSetMapper; @@ -29,7 +29,7 @@ public AnswerSetToXlsxWriter(String targetBasePath) { } @Override - public void accept(Integer num, CoreAnswerSet as) { + public void accept(Integer num, AnswerSet as) { try { Path outputPath = Paths.get(this.targetBasePath + "." + num + ".xlsx"); OutputStream os = Files.newOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); 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 a943c0588..c95b77155 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 @@ -44,22 +44,25 @@ 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.Solver; 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.impl.AlphaImpl; -import at.ac.tuwien.kr.alpha.api.program.InputProgram; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.app.ComponentGraphWriter; import at.ac.tuwien.kr.alpha.app.DependencyGraphWriter; import at.ac.tuwien.kr.alpha.config.CommandLineParser; import at.ac.tuwien.kr.alpha.core.common.AnswerSetFormatter; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.SimpleAnswerSetFormatter; import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; 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.NormalProgram; -import at.ac.tuwien.kr.alpha.core.solver.Solver; import at.ac.tuwien.kr.alpha.core.solver.SolverMaintainingStatistics; /** @@ -83,7 +86,7 @@ public static void main(String[] args) { Alpha alpha = new AlphaImpl(cfg.getSystemConfig()); - InputProgram program = null; + ASPCore2Program program = null; try { program = alpha.readProgram(cfg.getInputConfig()); } catch (RecognitionException e) { @@ -97,8 +100,8 @@ public static void main(String[] args) { Main.bailOut("Failed to parse program.", e); } - NormalProgram normalized = alpha.normalizeProgram(program); - InternalProgram preprocessed; + Program> normalized = alpha.normalizeProgram(program); + CompiledProgram preprocessed; InputConfig inputCfg = cfg.getInputConfig(); if (!(inputCfg.isWriteDependencyGraph() || inputCfg.isWriteComponentGraph())) { LOGGER.debug("Not writing dependency or component graphs, starting preprocessing..."); @@ -157,7 +160,7 @@ private static void writeComponentGraph(ComponentGraph cg, String path) { * @param prg the program to write * @param path the path to write the program to */ - private static void writeInternalProgram(InternalProgram prg, String path) { + private static void writeInternalProgram(CompiledProgram prg, String path) { LOGGER.debug("Writing preprocessed program to {}", path); PrintStream ps; try { @@ -173,9 +176,9 @@ private static void writeInternalProgram(InternalProgram prg, String path) { } } - private static void computeAndConsumeAnswerSets(AlphaImpl alpha, InputConfig inputCfg, InternalProgram program) { + private static void computeAndConsumeAnswerSets(Alpha alpha, InputConfig inputCfg, CompiledProgram program) { Solver solver = alpha.prepareSolverFor(program, inputCfg.getFilter()); - Stream stream = solver.stream(); + Stream stream = solver.stream(); if (alpha.getConfig().isSortAnswerSets()) { stream = stream.sorted(); } @@ -187,13 +190,13 @@ private static void computeAndConsumeAnswerSets(AlphaImpl alpha, InputConfig inp if (!alpha.getConfig().isQuiet()) { AtomicInteger counter = new AtomicInteger(0); - final BiConsumer answerSetHandler; + final BiConsumer answerSetHandler; final AnswerSetFormatter fmt = new SimpleAnswerSetFormatter(alpha.getConfig().getAtomSeparator()); - BiConsumer stdoutPrinter = (n, as) -> { + BiConsumer stdoutPrinter = (n, as) -> { System.out.println("Answer set " + Integer.toString(n) + ":" + System.lineSeparator() + fmt.format(as)); }; if (inputCfg.isWriteAnswerSetsAsXlsx()) { - BiConsumer xlsxWriter = new AnswerSetToXlsxWriter(inputCfg.getAnswerSetFileOutputPath()); + BiConsumer xlsxWriter = new AnswerSetToXlsxWriter(inputCfg.getAnswerSetFileOutputPath()); answerSetHandler = stdoutPrinter.andThen(xlsxWriter); } else { answerSetHandler = stdoutPrinter; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index ef195b9f1..e03befacb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -27,8 +27,8 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.join; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.Collections; import java.util.LinkedList; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java index 45c512f4d..f1c56e698 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java @@ -27,19 +27,16 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; - import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** @@ -119,7 +116,7 @@ public String toString() { return prefix; } - return join(prefix + "(", terms, ")"); + return Util.join(prefix + "(", terms, ")"); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java index b8df895cb..fe615fc46 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java @@ -27,11 +27,10 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; - import java.util.Collections; import java.util.List; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; @@ -92,7 +91,7 @@ public CoreAtom substitute(Substitution substitution) { @Override public String toString() { - return join(predicate.getName() + "(", terms, ")"); + return Util.join(predicate.getName() + "(", terms, ")"); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 6cab45522..86b911072 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -1,10 +1,9 @@ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; - import java.util.HashMap; import java.util.List; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -84,7 +83,7 @@ public EnumerationAtom substitute(Substitution substitution) { @Override public EnumerationLiteral toLiteral(boolean positive) { if (!positive) { - throw oops("IntervalLiteral cannot be negated"); + throw Util.oops("IntervalLiteral cannot be negated"); } return new EnumerationLiteral(this); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index 1eaaf3151..6ba7a3b35 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -27,12 +27,12 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; @@ -124,10 +124,10 @@ public ExternalLiteral toLiteral(boolean positive) { public String toString() { String result = "&" + predicate.getName(); if (!input.isEmpty()) { - result += join("[", input, "]"); + result += Util.join("[", input, "]"); } if (!output.isEmpty()) { - result += join("(", output, ")"); + result += Util.join("(", output, ")"); } return result; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java index bf6706157..6cb15d9ab 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java @@ -27,12 +27,10 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; - import java.util.Arrays; import java.util.List; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; @@ -85,7 +83,7 @@ public boolean isGround() { @Override public IntervalLiteral toLiteral(boolean positive) { if (!positive) { - throw oops("IntervalLiteral cannot be negated"); + throw Util.oops("IntervalLiteral cannot be negated"); } return new IntervalLiteral(this); } @@ -97,7 +95,7 @@ public IntervalLiteral toLiteral() { @Override public String toString() { - return join(PREDICATE.getName() + "(", terms, ")"); + return Util.join(PREDICATE.getName() + "(", terms, ")"); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java index 3bf3a0512..a72a57813 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java @@ -35,10 +35,10 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Atoms corresponding to rule bodies use this predicate, first term is rule number, @@ -57,7 +57,7 @@ private RuleAtom(List> terms) { this.terms = terms; } - public RuleAtom(InternalRule nonGroundRule, Substitution substitution) { + public RuleAtom(CompiledRule nonGroundRule, Substitution substitution) { this(Arrays.asList( getInstance(Integer.toString(nonGroundRule.getRuleId())), getInstance(substitution.toString()) diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java index 6f58ff695..021918c07 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetFormatter.java @@ -1,6 +1,8 @@ package at.ac.tuwien.kr.alpha.core.common; +import at.ac.tuwien.kr.alpha.api.AnswerSet; + @FunctionalInterface public interface AnswerSetFormatter { - T format(CoreAnswerSet answerSet); + T format(AnswerSet answerSet); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java index ce41da6cd..6d97681fe 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java @@ -27,15 +27,15 @@ */ package at.ac.tuwien.kr.alpha.core.common; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; @@ -116,7 +116,7 @@ public Atom get(int atom) { try { return atomIdsToInternalBasicAtoms.get(atom); } catch (IndexOutOfBoundsException e) { - throw oops("Unknown atom ID encountered: " + atom, e); + throw Util.oops("Unknown atom ID encountered: " + atom, e); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java index be25f35b3..52ca5c093 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java @@ -8,15 +8,16 @@ import java.util.Set; import java.util.SortedSet; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.core.util.Util; /** * Copyright (c) 2016, the Alpha Team. */ // TODO bring this into public non-core API by using something like an "answer-set-view" -public class BasicAnswerSet implements CoreAnswerSet { +public class BasicAnswerSet implements AnswerSet { public static final BasicAnswerSet EMPTY = new BasicAnswerSet(emptySortedSet(), emptyMap()); private final SortedSet predicates; @@ -97,7 +98,7 @@ public int hashCode() { } @Override - public int compareTo(CoreAnswerSet other) { + public int compareTo(AnswerSet other) { final SortedSet predicates = this.getPredicates(); int result = Util.compareSortedSets(predicates, other.getPredicates()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java index 5ae12a8c0..77bb458ce 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.common; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import at.ac.tuwien.kr.alpha.api.Util; public enum ComparisonOperator { EQ("="), @@ -30,7 +30,7 @@ public ComparisonOperator getNegation() { case LE: return GT; case GE: return LT; } - throw oops("Unknown binary operator encountered, cannot negate it"); + throw Util.oops("Unknown binary operator encountered, cannot negate it"); } public CorePredicate predicate() { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java index 367df5dc0..9b780b1d6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java @@ -27,17 +27,24 @@ */ package at.ac.tuwien.kr.alpha.core.common; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; +import static at.ac.tuwien.kr.alpha.core.common.Literals.negateLiteral; +import static at.ac.tuwien.kr.alpha.core.common.Literals.positiveLiteral; +import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.INTERNAL; +import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.LEARNT; +import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.STATIC; +import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.SUPPORT; + import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.IntStream; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.core.solver.Antecedent; -import static at.ac.tuwien.kr.alpha.core.common.Literals.*; -import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.*; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; - public class NoGood implements NoGoodInterface, Comparable { public static final int HEAD = 0; public static final NoGood UNSAT = new NoGood(); @@ -58,7 +65,7 @@ private NoGood(Type type, int[] literals, boolean head) { this.type = type; this.head = head; if (head && !isNegated(literals[0])) { - throw oops("Head is not negative"); + throw Util.oops("Head is not negative"); } // HINT: this might decrease performance if NoGoods are mostly small. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java index e45ee03e9..1c9d50a27 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java @@ -5,6 +5,7 @@ import java.util.SortedSet; import java.util.stream.Collectors; +import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; @@ -17,7 +18,7 @@ public SimpleAnswerSetFormatter(String atomSeparator) { } @Override - public String format(CoreAnswerSet answerSet) { + public String format(AnswerSet answerSet) { List predicateInstanceStrings = new ArrayList<>(); for (Predicate p : answerSet.getPredicates()) { SortedSet instances; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java index 194f02239..713bad3c5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java @@ -1,7 +1,5 @@ package at.ac.tuwien.kr.alpha.core.common.terms; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -9,6 +7,7 @@ import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.Util; 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.terms.VariableTerm; @@ -87,7 +86,7 @@ public String toString() { return symbol; } - return join(symbol + "(", terms, ")"); + return Util.join(symbol + "(", terms, ")"); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java index e0dbd225e..5936b764a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java @@ -1,10 +1,9 @@ package at.ac.tuwien.kr.alpha.core.common.terms; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; - import java.util.LinkedHashSet; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.Util; 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.terms.VariableTerm; @@ -55,14 +54,14 @@ public boolean isGround() { public int getLowerBound() { if (!isGround()) { - throw oops("Cannot get the lower bound of non-ground interval"); + throw Util.oops("Cannot get the lower bound of non-ground interval"); } return this.lowerBound; } public int getUpperBound() { if (!isGround()) { - throw oops("Cannot get the upper bound of non-ground interval"); + throw Util.oops("Cannot get the upper bound of non-ground interval"); } return this.upperBound; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java index 7474add51..04e402173 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java @@ -38,6 +38,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; @@ -71,7 +72,7 @@ private DependencyGraph(Map> adjacencyMap, Map this.nodesByPredicate = nodesByPredicate; } - public static DependencyGraph buildDependencyGraph(Map nonGroundRules) { + public static DependencyGraph buildDependencyGraph(Map nonGroundRules) { return new DependencyGraph.Builder(nonGroundRules.values()).build(); } @@ -88,18 +89,18 @@ private static class Builder { private static final String CONSTRAINT_PREDICATE_FORMAT = "[constr_%d]"; private int constraintNumber; - private Collection rules; + private Collection rules; private Map> adjacentNodesMap = new HashMap<>(); private Map nodesByPredicate = new HashMap<>(); - private Builder(Collection rules) { + private Builder(Collection rules) { this.rules = rules; this.constraintNumber = 0; } private DependencyGraph build() { - for (InternalRule rule : rules) { + for (CompiledRule rule : rules) { LOGGER.debug("Processing rule: {}", rule); Node headNode = handleRuleHead(rule); for (Literal literal : rule.getBody()) { @@ -114,7 +115,7 @@ private DependencyGraph build() { return new DependencyGraph(adjacentNodesMap, nodesByPredicate); } - private Node handleRuleHead(InternalRule rule) { + private Node handleRuleHead(CompiledRule rule) { LOGGER.trace("Processing head of rule: {}", rule); Node headNode; if (rule.isConstraint()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index 4a4ce5f6f..4f11a409f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Grounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Grounder.java index e9958dcde..2c697f955 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Grounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Grounder.java @@ -32,9 +32,9 @@ import org.apache.commons.lang3.tuple.Pair; +import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.common.Assignment; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.IntIterator; import at.ac.tuwien.kr.alpha.core.common.NoGood; @@ -44,7 +44,7 @@ public interface Grounder { * @param trueAtoms * @return */ - CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms); + AnswerSet assignmentToAnswerSet(Iterable trueAtoms); /** * Applies lazy grounding and returns all newly derived (fully ground) NoGoods. 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 99172fd66..039a4265c 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 @@ -29,13 +29,13 @@ import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.programs.InternalProgram; public final class GrounderFactory { - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + 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": @@ -44,12 +44,12 @@ public static Grounder getInstance(String name, InternalProgram program, AtomSto throw new IllegalArgumentException("Unknown grounder requested."); } - public static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + 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 static Grounder getInstance(String name, InternalProgram program, AtomStore atomStore, boolean debugInternalChecks) { + public static Grounder getInstance(String name, CompiledProgram program, AtomStore atomStore, boolean debugInternalChecks) { return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, new GrounderHeuristicsConfiguration(), debugInternalChecks); } 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 ff8c7c317..f9748a0c5 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 @@ -36,6 +36,7 @@ import java.util.Map; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java index 3b9c09691..278268bb0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; /** * Generates unique, sequential integers starting at 0, i.e., it maintains a counter that is incremented for each getNextId(). 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 327dab730..4e0ae6320 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 @@ -27,8 +27,8 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; import java.util.ArrayList; import java.util.Collection; @@ -48,11 +48,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Util; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; @@ -60,7 +66,6 @@ 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.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.IntIterator; import at.ac.tuwien.kr.alpha.core.common.NoGood; @@ -72,9 +77,6 @@ import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationResult; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiator; import at.ac.tuwien.kr.alpha.core.grounder.structure.AnalyzeUnjustified; -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.util.Util; /** * A semi-naive grounder. @@ -89,14 +91,14 @@ public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGr private final NogoodRegistry registry = new NogoodRegistry(); final NoGoodGenerator noGoodGenerator; private final ChoiceRecorder choiceRecorder; - private final InternalProgram program; + private final CompiledProgram program; private final AnalyzeUnjustified analyzeUnjustified; private final Map> factsFromProgram; private final Map> rulesUsingPredicateWorkingMemory = new HashMap<>(); - private final Map knownNonGroundRules; + private final Map knownNonGroundRules; - private ArrayList fixedRules = new ArrayList<>(); + private ArrayList fixedRules = new ArrayList<>(); private LinkedHashSet removeAfterObtainingNewNoGoods = new LinkedHashSet<>(); private final boolean debugInternalChecks; @@ -107,16 +109,16 @@ public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGr private final LiteralInstantiator ruleInstantiator; private final DefaultLazyGroundingInstantiationStrategy instantiationStrategy; - public NaiveGrounder(InternalProgram program, AtomStore atomStore, boolean debugInternalChecks, Bridge... bridges) { + public NaiveGrounder(CompiledProgram program, AtomStore atomStore, boolean debugInternalChecks, Bridge... bridges) { this(program, atomStore, new GrounderHeuristicsConfiguration(), debugInternalChecks, bridges); } - private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, + private NaiveGrounder(CompiledProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, bridges); } - NaiveGrounder(InternalProgram program, AtomStore atomStore, java.util.function.Predicate filter, + NaiveGrounder(CompiledProgram program, AtomStore atomStore, java.util.function.Predicate filter, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { super(filter, bridges); this.atomStore = atomStore; @@ -132,7 +134,7 @@ private NaiveGrounder(InternalProgram program, AtomStore atomStore, GrounderHeur this.initializeFactsAndRules(); - final Set uniqueGroundRulePerGroundHead = getRulesWithUniqueHead(); + final Set uniqueGroundRulePerGroundHead = getRulesWithUniqueHead(); choiceRecorder = new ChoiceRecorder(atomStore); noGoodGenerator = new NoGoodGenerator(atomStore, choiceRecorder, factsFromProgram, this.program, uniqueGroundRulePerGroundHead); @@ -160,7 +162,7 @@ private void initializeFactsAndRules() { workingMemory.initialize(ChoiceAtom.ON); // Initialize rules and constraints in working memory. - for (InternalRule nonGroundRule : program.getRulesById().values()) { + for (CompiledRule nonGroundRule : program.getRulesById().values()) { // Create working memories for all predicates occurring in the rule. for (Predicate predicate : nonGroundRule.getOccurringPredicates()) { // FIXME: this also contains interval/builtin predicates that are not needed. @@ -168,30 +170,30 @@ private void initializeFactsAndRules() { } // If the rule has fixed ground instantiations, it is not registered but grounded once like facts. - if (nonGroundRule.getGroundingOrders().fixedInstantiation()) { + if (nonGroundRule.getGroundingInfo().hasFixedInstantiation()) { fixedRules.add(nonGroundRule); continue; } // Register each starting literal at the corresponding working memory. - for (Literal literal : nonGroundRule.getGroundingOrders().getStartingLiterals()) { + for (Literal literal : nonGroundRule.getGroundingInfo().getStartingLiterals()) { registerLiteralAtWorkingMemory(literal, nonGroundRule); } } } - private Set getRulesWithUniqueHead() { + private Set getRulesWithUniqueHead() { // FIXME: below optimisation (adding support nogoods if there is only one rule instantiation per unique atom over the interpretation) could // be done as a transformation (adding a non-ground constraint corresponding to the nogood that is generated by the grounder). // Record all unique rule heads. - final Set uniqueGroundRulePerGroundHead = new HashSet<>(); + final Set uniqueGroundRulePerGroundHead = new HashSet<>(); - for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { + for (Map.Entry> headDefiningRules : program.getPredicateDefiningRules().entrySet()) { if (headDefiningRules.getValue().size() != 1) { continue; } - InternalRule nonGroundRule = headDefiningRules.getValue().iterator().next(); + CompiledRule nonGroundRule = headDefiningRules.getValue().iterator().next(); // Check that all variables of the body also occur in the head (otherwise grounding is not unique). Atom headAtom = nonGroundRule.getHeadAtom(); @@ -222,7 +224,7 @@ private Set getRulesWithUniqueHead() { * * @param nonGroundRule the rule in which the literal occurs. */ - private void registerLiteralAtWorkingMemory(Literal literal, InternalRule nonGroundRule) { + private void registerLiteralAtWorkingMemory(Literal literal, CompiledRule nonGroundRule) { if (literal.isNegated()) { throw new RuntimeException("Literal to register is negated. Should not happen."); } @@ -232,7 +234,7 @@ private void registerLiteralAtWorkingMemory(Literal literal, InternalRule nonGro } @Override - public CoreAnswerSet assignmentToAnswerSet(Iterable trueAtoms) { + public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { Map> predicateInstances = new LinkedHashMap<>(); SortedSet knownPredicates = new TreeSet<>(); @@ -300,9 +302,9 @@ protected HashMap bootstrap() { workingMemory.addInstances(predicate, true, factsFromProgram.get(predicate)); } - for (InternalRule nonGroundRule : fixedRules) { + for (CompiledRule nonGroundRule : fixedRules) { // Generate NoGoods for all rules that have a fixed grounding. - RuleGroundingOrder groundingOrder = nonGroundRule.getGroundingOrders().getFixedGroundingOrder(); + RuleGroundingOrder groundingOrder = nonGroundRule.getGroundingInfo().getFixedGroundingOrder(); BindingResult bindingResult = getGroundInstantiations(nonGroundRule, groundingOrder, new SubstitutionImpl(), null); groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), groundNogoods); } @@ -335,7 +337,7 @@ public Map getNoGoods(Assignment currentAssignment) { for (FirstBindingAtom firstBindingAtom : firstBindingAtoms) { // Use the recently added instances from the modified working memory to construct an initial substitution - InternalRule nonGroundRule = firstBindingAtom.rule; + CompiledRule nonGroundRule = firstBindingAtom.rule; // Generate substitutions from each recent instance. for (Instance instance : modifiedWorkingMemory.getRecentlyAddedInstances()) { @@ -350,7 +352,7 @@ public Map getNoGoods(Assignment currentAssignment) { final BindingResult bindingResult = getGroundInstantiations( nonGroundRule, - nonGroundRule.getGroundingOrders().orderStartingFrom(firstBindingAtom.startingLiteral), + nonGroundRule.getGroundingInfo().orderStartingFrom(firstBindingAtom.startingLiteral), unifier, currentAssignment); @@ -398,7 +400,7 @@ public Map getNoGoods(Assignment currentAssignment) { * @param substitutions the substitutions to be applied. * @param newNoGoods a set of nogoods to which newly generated nogoods will be added. */ - private void groundAndRegister(final InternalRule nonGroundRule, final List substitutions, final Map newNoGoods) { + private void groundAndRegister(final CompiledRule nonGroundRule, final List substitutions, final Map newNoGoods) { for (Substitution substitution : substitutions) { List generatedNoGoods = noGoodGenerator.generateNoGoodsFromGroundSubstitution(nonGroundRule, substitution); registry.register(generatedNoGoods, newNoGoods); @@ -411,7 +413,7 @@ public int register(NoGood noGood) { } // Ideally, this method should be private. It's only visible because NaiveGrounderTest needs to access it. - BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder groundingOrder, Substitution partialSubstitution, + BindingResult getGroundInstantiations(CompiledRule rule, RuleGroundingOrder groundingOrder, Substitution partialSubstitution, Assignment currentAssignment) { int tolerance = heuristicsConfiguration.getTolerance(rule.isConstraint()); if (tolerance < 0) { @@ -436,7 +438,7 @@ BindingResult getGroundInstantiations(InternalRule rule, RuleGroundingOrder grou } /** - * Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrder, int, int, int, SubstitutionImpl)}. + * Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrderImpl, int, int, int, SubstitutionImpl)}. * * Takes an ImmutablePair of a {@link SubstitutionImpl} and an accompanying {@link AssignmentStatus} and calls * bindNextAtomInRule for the next literal in the grounding order. @@ -493,12 +495,12 @@ private BindingResult pushBackAndBindNextAtomInRule(RuleGroundingOrder grounding //@formatter:off /** - * Computes ground substitutions for a literal based on a {@link RuleGroundingOrder} and a {@link SubstitutionImpl}. + * Computes ground substitutions for a literal based on a {@link RuleGroundingOrderImpl} and a {@link SubstitutionImpl}. * * Computes ground substitutions for the literal at position orderPosition of groundingOrder * Actual substitutions are computed by this grounder's {@link LiteralInstantiator}. * - * @param groundingOrder a {@link RuleGroundingOrder} representing the body literals of a rule in the + * @param groundingOrder a {@link RuleGroundingOrderImpl} representing the body literals of a rule in the * sequence in which the should be bound during grounding. * @param orderPosition the current position within groundingOrder, indicates which literal should be bound * @param originalTolerance the original tolerance of the used grounding heuristic @@ -587,7 +589,7 @@ public void forgetAssignment(int[] atomIds) { } @Override - public InternalRule getNonGroundRule(Integer ruleId) { + public CompiledRule getNonGroundRule(Integer ruleId) { return knownNonGroundRules.get(ruleId); } @@ -637,10 +639,10 @@ private void checkTypesOfNoGoods(Collection newNoGoods) { } private static class FirstBindingAtom { - final InternalRule rule; + final CompiledRule rule; final Literal startingLiteral; - FirstBindingAtom(InternalRule rule, Literal startingLiteral) { + FirstBindingAtom(CompiledRule rule, Literal startingLiteral) { this.rule = rule; this.startingLiteral = startingLiteral; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java index 456897772..5333787b1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java @@ -40,10 +40,13 @@ import java.util.Map; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; @@ -60,10 +63,10 @@ public class NoGoodGenerator { private final AtomStore atomStore; private final ChoiceRecorder choiceRecorder; private final Map> factsFromProgram; - private final InternalProgram programAnalysis; - private final Set uniqueGroundRulePerGroundHead; + private final CompiledProgram programAnalysis; + private final Set uniqueGroundRulePerGroundHead; - NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, InternalProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { + NoGoodGenerator(AtomStore atomStore, ChoiceRecorder recorder, Map> factsFromProgram, CompiledProgram programAnalysis, Set uniqueGroundRulePerGroundHead) { this.atomStore = atomStore; this.choiceRecorder = recorder; this.factsFromProgram = factsFromProgram; @@ -81,7 +84,7 @@ public class NoGoodGenerator { * Assumption: atoms with fixed interpretation evaluate to true under the substitution. * @return a list of the NoGoods corresponding to the ground rule. */ - List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundRule, final Substitution substitution) { + List generateNoGoodsFromGroundSubstitution(final CompiledRule nonGroundRule, final Substitution substitution) { final List posLiterals = collectPosLiterals(nonGroundRule, substitution); final List negLiterals = collectNegLiterals(nonGroundRule, substitution); @@ -139,7 +142,7 @@ List generateNoGoodsFromGroundSubstitution(final InternalRule nonGroundR return result; } - List collectNegLiterals(final InternalRule nonGroundRule, final Substitution substitution) { + List collectNegLiterals(final CompiledRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsNegative = new ArrayList<>(); for (Literal lit : nonGroundRule.getNegativeBody()) { Atom groundAtom = lit.getAtom().substitute(substitution); @@ -161,7 +164,7 @@ List collectNegLiterals(final InternalRule nonGroundRule, final Substit return bodyLiteralsNegative; } - private List collectPosLiterals(final InternalRule nonGroundRule, final Substitution substitution) { + private List collectPosLiterals(final CompiledRule nonGroundRule, final Substitution substitution) { final List bodyLiteralsPositive = new ArrayList<>(); for (Literal lit : nonGroundRule.getPositiveBody()) { if (lit instanceof FixedInterpretationLiteral) { @@ -198,7 +201,7 @@ private List collectPosLiterals(final InternalRule nonGroundRule, final } private boolean existsRuleWithPredicateInHead(final Predicate predicate) { - final HashSet definingRules = programAnalysis.getPredicateDefiningRules().get(predicate); + final HashSet definingRules = programAnalysis.getPredicateDefiningRules().get(predicate); return definingRules != null && !definingRules.isEmpty(); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java index 85b9377ce..a76ab3202 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java @@ -4,8 +4,8 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.common.Assignment; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Copyright (c) 2017, the Alpha Team. @@ -32,5 +32,5 @@ public interface ProgramAnalyzingGrounder extends Grounder { * @param ruleId the id of the rule. * @return the corresponding NonGroundRule. */ - InternalRule getNonGroundRule(Integer ruleId); + CompiledRule getNonGroundRule(Integer ruleId); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java index 0c8b9adcd..d50c333ab 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrders.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java @@ -37,10 +37,11 @@ import java.util.List; import java.util.Set; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreLiteral; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** @@ -61,16 +62,16 @@ * Note that rules with self-joins (rules with p(X,Y), p(A,B) in their body) make it necessary that every positive * literal (whose interpretation is not fixed) is a starting literal, at least for the current grounding procedure. */ -public class RuleGroundingOrders { +public class RuleGroundingInfoImpl implements RuleGroundingInfo { private final InternalRule internalRule; - HashMap groundingOrders; + HashMap groundingOrders; private HashMap literalSelectivity; private List startingLiterals; private final boolean fixedGroundingInstantiation; - private RuleGroundingOrder fixedGroundingOrder; + private RuleGroundingOrderImpl fixedGroundingOrder; - public RuleGroundingOrders(InternalRule internalRule) { + public RuleGroundingInfoImpl(InternalRule internalRule) { this.internalRule = internalRule; this.literalSelectivity = new HashMap<>(); resetLiteralSelectivity(); @@ -137,10 +138,11 @@ public void updateLiteralSelectivity(Literal literal, int numGivenTuples, int nu // TODO: add old selectivity (with a decay factor) and new selectivity. } - public RuleGroundingOrder orderStartingFrom(Literal startingLiteral) { + public RuleGroundingOrderImpl orderStartingFrom(Literal startingLiteral) { return groundingOrders.get(startingLiteral); } + @Override public RuleGroundingOrder getFixedGroundingOrder() { return fixedGroundingOrder; } @@ -150,7 +152,8 @@ public RuleGroundingOrder getFixedGroundingOrder() { * * @return true if the rule has a (limited number of) fixed grounding instantiation(s). */ - public boolean fixedInstantiation() { + @Override + public boolean hasFixedInstantiation() { return fixedGroundingInstantiation; } @@ -197,9 +200,9 @@ private void computeGroundingOrder(Literal startingLiteral) { position++; } if (fixedGroundingInstantiation) { - fixedGroundingOrder = new RuleGroundingOrder(null, literalsOrder, positionLastVarBound, internalRule.isGround()); + fixedGroundingOrder = new RuleGroundingOrderImpl(null, literalsOrder, positionLastVarBound, internalRule.isGround()); } - groundingOrders.put(startingLiteral, new RuleGroundingOrder(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); + groundingOrders.put(startingLiteral, new RuleGroundingOrderImpl(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround())); } private Literal selectNextGroundingLiteral(LinkedHashSet remainingLiterals, Set boundVariables) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderImpl.java similarity index 88% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderImpl.java index 6a09549a8..b0d1320b7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderImpl.java @@ -28,13 +28,14 @@ import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** - * A grounding order computed by {@link RuleGroundingOrders} for a specific {@link InternalRule} and a specific starting literal. + * A grounding order computed by {@link RuleGroundingInfoImpl} for a specific {@link InternalRule} and a specific starting literal. */ -public class RuleGroundingOrder { +public class RuleGroundingOrderImpl implements RuleGroundingOrder{ private Literal startingLiteral; private List otherLiterals; @@ -42,7 +43,7 @@ public class RuleGroundingOrder { private int stopBindingAtOrderPosition; private final boolean ground; - RuleGroundingOrder(Literal startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { + RuleGroundingOrderImpl(Literal startingLiteral, List otherLiterals, int positionLastVarBound, boolean isGround) { super(); this.startingLiteral = startingLiteral; this.otherLiterals = otherLiterals; @@ -51,7 +52,7 @@ public class RuleGroundingOrder { this.ground = isGround; } - private RuleGroundingOrder(RuleGroundingOrder otherRuleGroundingOrder) { + private RuleGroundingOrderImpl(RuleGroundingOrderImpl otherRuleGroundingOrder) { this(otherRuleGroundingOrder.startingLiteral, new ArrayList<>(otherRuleGroundingOrder.otherLiterals), otherRuleGroundingOrder.positionLastVarBound, otherRuleGroundingOrder.ground); this.stopBindingAtOrderPosition = otherRuleGroundingOrder.stopBindingAtOrderPosition; } @@ -112,11 +113,11 @@ public String toString() { * @return a new grounding order in which the atom is pushed back, * or {@code null} if the position of the grounding order after which no new bindings can be found has been reached. */ - public RuleGroundingOrder pushBack(int orderPosition) { + public RuleGroundingOrderImpl pushBack(int orderPosition) { if (orderPosition >= stopBindingAtOrderPosition - 1) { return null; } - RuleGroundingOrder reorderedGroundingOrder = new RuleGroundingOrder(this); + RuleGroundingOrderImpl reorderedGroundingOrder = new RuleGroundingOrderImpl(this); reorderedGroundingOrder.otherLiterals.add(otherLiterals.get(orderPosition)); return reorderedGroundingOrder; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java index 2aaa0b90a..2814670c2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java @@ -33,6 +33,8 @@ import java.util.Set; import java.util.TreeMap; +import at.ac.tuwien.kr.alpha.api.Util; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; @@ -43,7 +45,6 @@ import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; -import at.ac.tuwien.kr.alpha.core.util.Util; public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Substitution { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index 129e93af2..cf19df43c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.Set; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java index 8e3b7158d..757e1040e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.ArrayList; import java.util.HashSet; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java index 63ab287e9..51d4a4e3e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java @@ -34,6 +34,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java index ec05f3465..2b19d2adf 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -30,11 +30,11 @@ import org.apache.commons.lang3.tuple.ImmutablePair; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java index 58d72f7f6..13ed4511b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java @@ -28,6 +28,9 @@ import java.util.LinkedHashSet; import java.util.Map; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.Util; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; @@ -35,12 +38,9 @@ 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.IndexedInstanceStorage; -import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.core.solver.Solver; import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.core.util.Util; /** * Implementation of {@link AbstractLiteralInstantiationStrategy} designed for use in {@link NaiveGrounder}. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java index f69d5f0c7..5e88bcfa9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/WorkingMemoryBasedInstantiationStrategy.java @@ -25,9 +25,9 @@ */ package at.ac.tuwien.kr.alpha.core.grounder.instantiation; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java index b1fba7404..974c19a57 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.grounder.structure; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.ArrayList; import java.util.Collections; @@ -16,9 +16,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; @@ -26,10 +29,8 @@ 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.CorePredicate; -import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.grounder.Unification; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; -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.solver.ThriceTruth; @@ -38,13 +39,13 @@ */ public class AnalyzeUnjustified { private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeUnjustified.class); - private final InternalProgram programAnalysis; + private final CompiledProgram programAnalysis; private final AtomStore atomStore; private final Map> factsFromProgram; private int renamingCounter; private int padDepth; - public AnalyzeUnjustified(InternalProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { + public AnalyzeUnjustified(CompiledProgram programAnalysis, AtomStore atomStore, Map> factsFromProgram) { this.programAnalysis = programAnalysis; this.atomStore = atomStore; this.factsFromProgram = factsFromProgram; @@ -342,9 +343,9 @@ private List rulesHeadUnifyingWith(Atom p) { } } - HashSet rulesDefiningPredicate = programAnalysis.getPredicateDefiningRules().get(predicate); + HashSet rulesDefiningPredicate = programAnalysis.getPredicateDefiningRules().get(predicate); if (rulesDefiningPredicate != null) { - for (InternalRule nonGroundRule : rulesDefiningPredicate) { + for (CompiledRule nonGroundRule : rulesDefiningPredicate) { definingRulesAndFacts.add(new FactOrNonGroundRule(nonGroundRule)); } } @@ -354,7 +355,7 @@ private List rulesHeadUnifyingWith(Atom p) { Atom headAtom; if (isNonGroundRule) { // First rename all variables in the rule. - InternalRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++); + CompiledRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++); renamedBody = rule.getBody(); headAtom = rule.getHeadAtom(); } else { @@ -407,14 +408,14 @@ public String toString() { private static class FactOrNonGroundRule { final Instance factInstance; - final InternalRule nonGroundRule; + final CompiledRule nonGroundRule; private FactOrNonGroundRule(Instance factInstance) { this.factInstance = factInstance; this.nonGroundRule = null; } - private FactOrNonGroundRule(InternalRule nonGroundRule) { + private FactOrNonGroundRule(CompiledRule nonGroundRule) { this.nonGroundRule = nonGroundRule; this.factInstance = null; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java index af6924874..8c39ce9e7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/LitSet.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.grounder.structure; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.Collections; import java.util.HashSet; 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 aec271c87..0ecdcdcfd 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 @@ -45,6 +45,7 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2BaseVisitor; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; +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.program.Atom; import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; @@ -68,7 +69,6 @@ import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; import at.ac.tuwien.kr.alpha.core.common.BasicAnswerSet; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; @@ -115,13 +115,13 @@ public InputProgram translate(ASPCore2Parser.ProgramContext input) { /** * Translates a context for answer sets (referring to a node in an ATN specific to ANTLR) to the representation that Alpha uses. */ - public Set translate(ASPCore2Parser.Answer_setsContext input) { + public Set translate(ASPCore2Parser.Answer_setsContext input) { return visitAnswer_sets(input); } @Override - public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { - Set result = new TreeSet<>(); + public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx) { + Set result = new TreeSet<>(); for (ASPCore2Parser.Answer_setContext answerSetContext : ctx.answer_set()) { result.add(visitAnswer_set(answerSetContext)); @@ -131,7 +131,7 @@ public Set visitAnswer_sets(ASPCore2Parser.Answer_setsContext ctx } @Override - public CoreAnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { + public AnswerSet visitAnswer_set(ASPCore2Parser.Answer_setContext ctx) { SortedSet predicates = new TreeSet<>(); Map> predicateInstances = new TreeMap<>(); 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 7a4f49ab7..6d399c310 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 @@ -18,9 +18,9 @@ import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.program.InputProgram; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; -import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; public class ProgramParserImpl implements ProgramParser { private final Map externals; @@ -33,7 +33,7 @@ public ProgramParserImpl() { this(Collections.emptyMap()); } - public InputProgramImpl parse(String s) { + public ASPCore2Program parse(String s) { try { return parse(CharStreams.fromString(s)); } catch (IOException e) { @@ -49,7 +49,7 @@ public InputProgramImpl parse(String s) { } } - public InputProgramImpl parse(CharStream stream) throws IOException { + public InputProgram parse(CharStream stream) throws IOException { //@formatter:off /* * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java index bad967791..8fc003c81 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java @@ -3,11 +3,12 @@ import java.util.Collections; import java.util.List; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.program.Program; import at.ac.tuwien.kr.alpha.api.rules.Head; -import at.ac.tuwien.kr.alpha.core.rules.AbstractRule; -import at.ac.tuwien.kr.alpha.core.util.Util; +import at.ac.tuwien.kr.alpha.api.rules.Rule; /** * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives) @@ -15,7 +16,7 @@ * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an implementation permits * Copyright (c) 2019, the Alpha Team. */ -public abstract class AbstractProgram> { +public abstract class AbstractProgram> implements Program{ private final List rules; private final List facts; @@ -27,14 +28,17 @@ public AbstractProgram(List rules, List facts, InlineDirectives inlineD this.inlineDirectives = inlineDirectives; } + @Override public List getRules() { return Collections.unmodifiableList(rules); } + @Override public List getFacts() { return Collections.unmodifiableList(facts); } + @Override public InlineDirectives getInlineDirectives() { return inlineDirectives; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java index f86f2ed63..4a3f003ab 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AnalyzedProgram.java @@ -5,10 +5,13 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; import at.ac.tuwien.kr.alpha.core.depgraph.StronglyConnectedComponentsAlgorithm; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** @@ -21,14 +24,14 @@ public class AnalyzedProgram extends InternalProgram { private final DependencyGraph dependencyGraph; private final ComponentGraph componentGraph; - public AnalyzedProgram(List rules, List facts) { + public AnalyzedProgram(List rules, List facts) { super(rules, facts); dependencyGraph = DependencyGraph.buildDependencyGraph(getRulesById()); componentGraph = buildComponentGraph(dependencyGraph); } - public static AnalyzedProgram analyzeNormalProgram(NormalProgram prog) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); + public static AnalyzedProgram analyzeNormalProgram(Program> prog) { + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(prog); return new AnalyzedProgram(rulesAndFacts.left, rulesAndFacts.right); } 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/InputProgram.java index 7cf8985bf..f17c52f9f 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/InputProgram.java @@ -31,21 +31,23 @@ import java.util.Collections; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Alpha-internal representation of an ASP program, i.e., a set of ASP rules. *

      * Copyright (c) 2017-2019, the Alpha Team. */ -public class InputProgram extends AbstractProgram { +public class InputProgram extends AbstractProgram> implements ASPCore2Program{ public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl()); - public InputProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public InputProgram(List> rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } @@ -66,7 +68,7 @@ public static Builder builder(InputProgram prog) { */ public static class Builder { - private List rules = new ArrayList<>(); + private List> rules = new ArrayList<>(); private List facts = new ArrayList<>(); private InlineDirectives inlineDirectives = new InlineDirectivesImpl(); @@ -80,12 +82,12 @@ public Builder() { } - public Builder addRules(List rules) { + public Builder addRules(List> rules) { this.rules.addAll(rules); return this; } - public Builder addRule(BasicRule r) { + public Builder addRule(Rule r) { this.rules.add(r); return this; } @@ -105,7 +107,7 @@ public Builder addInlineDirectives(InlineDirectives inlineDirectives) { return this; } - public Builder accumulate(InputProgram prog) { + public Builder accumulate(ASPCore2Program prog) { return this.addRules(prog.getRules()).addFacts(prog.getFacts()).addInlineDirectives(prog.getInlineDirectives()); } 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 5fc98b304..f29369bb9 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 @@ -9,12 +9,16 @@ import org.apache.commons.lang3.tuple.ImmutablePair; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.grounder.FactIntervalEvaluator; -import at.ac.tuwien.kr.alpha.core.grounder.Instance; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; -import at.ac.tuwien.kr.alpha.core.rules.NormalRule; /** * A program in the internal representation needed for grounder and solver, i.e.: rules must have normal heads, all @@ -23,22 +27,23 @@ *

      * Copyright (c) 2017-2020, the Alpha Team. */ -public class InternalProgram extends AbstractProgram { +public class InternalProgram extends AbstractProgram implements CompiledProgram{ - private final Map> predicateDefiningRules = new LinkedHashMap<>(); + private final Map> predicateDefiningRules = new LinkedHashMap<>(); private final Map> factsByPredicate = new LinkedHashMap<>(); - private final Map rulesById = new LinkedHashMap<>(); + private final Map rulesById = new LinkedHashMap<>(); - public InternalProgram(List rules, List facts) { + // TODO constructor param internal rule + public InternalProgram(List rules, List facts) { super(rules, facts, null); recordFacts(facts); recordRules(rules); } - static ImmutablePair, List> internalizeRulesAndFacts(NormalProgram normalProgram) { - List internalRules = new ArrayList<>(); + static ImmutablePair, List> internalizeRulesAndFacts(Program> normalProgram) { + List internalRules = new ArrayList<>(); List facts = new ArrayList<>(normalProgram.getFacts()); - for (NormalRule r : normalProgram.getRules()) { + for (Rule r : normalProgram.getRules()) { if (r.getBody().isEmpty()) { if (!r.getHead().isGround()) { throw new IllegalArgumentException("InternalProgram does not support non-ground rules with empty bodies! (Head = " + r.getHead().toString() + ")"); @@ -51,8 +56,8 @@ static ImmutablePair, List> internalizeRulesAndFacts(No return new ImmutablePair<>(internalRules, facts); } - public static InternalProgram fromNormalProgram(NormalProgram normalProgram) { - ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); + public static CompiledProgram fromNormalProgram(Program> normalProgram) { + ImmutablePair, List> rulesAndFacts = InternalProgram.internalizeRulesAndFacts(normalProgram); return new InternalProgram(rulesAndFacts.left, rulesAndFacts.right); } @@ -65,8 +70,8 @@ private void recordFacts(List facts) { } } - private void recordRules(List rules) { - for (InternalRule rule : rules) { + private void recordRules(List rules) { + for (CompiledRule rule : rules) { rulesById.put(rule.getRuleId(), rule); if (!rule.isConstraint()) { recordDefiningRule(rule.getHeadAtom().getPredicate(), rule); @@ -74,12 +79,12 @@ private void recordRules(List rules) { } } - private void recordDefiningRule(Predicate headPredicate, InternalRule rule) { + private void recordDefiningRule(Predicate headPredicate, CompiledRule rule) { predicateDefiningRules.putIfAbsent(headPredicate, new LinkedHashSet<>()); predicateDefiningRules.get(headPredicate).add(rule); } - public Map> getPredicateDefiningRules() { + public Map> getPredicateDefiningRules() { return Collections.unmodifiableMap(predicateDefiningRules); } @@ -87,7 +92,7 @@ public Map> getFactsByPredicate() { return Collections.unmodifiableMap(factsByPredicate); } - public Map getRulesById() { + public Map getRulesById() { return Collections.unmodifiableMap(rulesById); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java index 6a39329a3..331058673 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java @@ -3,9 +3,13 @@ import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; -import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; /** @@ -13,15 +17,15 @@ * * Copyright (c) 2019, the Alpha Team. */ -public class NormalProgram extends AbstractProgram { +public class NormalProgram extends AbstractProgram> implements Program>{ - public NormalProgram(List rules, List facts, InlineDirectives inlineDirectives) { + public NormalProgram(List> rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } - public static NormalProgram fromInputProgram(InputProgram inputProgram) { - List normalRules = new ArrayList<>(); - for (BasicRule r : inputProgram.getRules()) { + public static NormalProgram fromInputProgram(ASPCore2Program inputProgram) { + List> normalRules = new ArrayList<>(); + for (Rule r : inputProgram.getRules()) { normalRules.add(NormalRule.fromBasicRule(r)); } return new NormalProgram(normalRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index 537353027..345dd1048 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -8,7 +8,10 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; @@ -26,7 +29,7 @@ /** * Copyright (c) 2017-2020, the Alpha Team. */ -public class CardinalityNormalization extends ProgramTransformation { +public class CardinalityNormalization extends ProgramTransformation { private int aggregateCount; private ProgramParserImpl parser = new ProgramParserImpl(); @@ -40,12 +43,12 @@ public CardinalityNormalization(boolean useSortingCircuitEncoding) { this.useSortingCircuitEncoding = useSortingCircuitEncoding; } - private InputProgram parse(String program) { + private ASPCore2Program parse(String program) { return parser.parse(program); } @Override - public InputProgram apply(InputProgram inputProgram) { + public ASPCore2Program apply(ASPCore2Program inputProgram) { if (!this.rewritingNecessary(inputProgram)) { return inputProgram; } @@ -89,17 +92,17 @@ public InputProgram apply(InputProgram inputProgram) { //@formatter:on // Connect/Rewrite every aggregate in each rule. - List rewrittenRules = rewriteAggregates(inputProgram.getRules()); + List> rewrittenRules = rewriteAggregates(inputProgram.getRules()); String usedCardinalityEncoding = useSortingCircuitEncoding ? cardinalitySortingCircuit : cardinalityCountingGrid; - InputProgram cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParserImpl().parse(usedCardinalityEncoding)); + ASPCore2Program cardinalityEncoding = PredicateInternalizer.makePredicatesInternal(new ProgramParserImpl().parse(usedCardinalityEncoding)); programBuilder.addRules(rewrittenRules); // Add enumeration rule that uses the special EnumerationAtom. // The enumeration rule is: "sorting_network_input_number(A, I) :- sorting_network_input(A, X), // sorting_network_index(A, X, I)." - BasicRule tmpEnumRule = PredicateInternalizer.makePredicatesInternal(parse( - "sorting_network_input_number(A, I) :- sorting_network_input(A, X).")).getRules().get(0); + Rule tmpEnumRule = PredicateInternalizer.makePredicatesInternal(parse( + "sorting_network_input_number(A, I) :- sorting_network_input(A, X).")).getRules().get(0); EnumerationAtom enumerationAtom = new EnumerationAtom(parse("sorting_network_index(A, X, I).").getFacts().get(0).getTerms()); List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); enumerationRuleBody.add(enumerationAtom.toLiteral()); @@ -117,8 +120,8 @@ public InputProgram apply(InputProgram inputProgram) { * @param program the program. * @return true if count aggregates occur, false otherwise. */ - private boolean rewritingNecessary(InputProgram program) { - for (BasicRule rule : program.getRules()) { + private boolean rewritingNecessary(ASPCore2Program program) { + for (Rule rule : program.getRules()) { for (Literal lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); @@ -131,15 +134,15 @@ private boolean rewritingNecessary(InputProgram program) { return false; } - private List rewriteAggregates(List srcRules) { - List retVal = new ArrayList<>(); - for (BasicRule rule : srcRules) { + private List> rewriteAggregates(List> srcRules) { + List> retVal = new ArrayList<>(); + for (Rule rule : srcRules) { retVal.addAll(rewriteAggregatesInRule(rule)); } return retVal; } - private List rewriteAggregatesInRule(BasicRule rule) { + private List> rewriteAggregatesInRule(Rule rule) { // Example rewriting/connection: // num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K). // is rewritten into: @@ -157,7 +160,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { ArrayList aggregateOutputAtoms = new ArrayList<>(); int aggregatesInRule = 0; // Only needed for limited rewriting. - ArrayList additionalRules = new ArrayList<>(); + ArrayList> additionalRules = new ArrayList<>(); List rewrittenBody = new ArrayList<>(rule.getBody()); @@ -231,7 +234,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { } rewrittenBody.addAll(aggregateOutputAtoms); - BasicRule rewrittenSrcRule = new BasicRule(rule.getHead(), rewrittenBody); + Rule rewrittenSrcRule = new BasicRule(rule.getHead(), rewrittenBody); additionalRules.add(rewrittenSrcRule); return additionalRules; } 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 e17790a49..a9cbde0f3 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,10 +31,13 @@ import java.util.Iterator; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; @@ -49,21 +52,22 @@ /** * Copyright (c) 2017-2020, the Alpha Team. */ -public class ChoiceHeadToNormal extends ProgramTransformation { +// TODO this could already give NormalProgram as result type +public class ChoiceHeadToNormal extends ProgramTransformation { private final static String PREDICATE_NEGATION_PREFIX = "_n"; @Override - public InputProgram apply(InputProgram inputProgram) { + public ASPCore2Program apply(ASPCore2Program inputProgram) { InputProgram.Builder programBuilder = InputProgram.builder(); - List additionalRules = new ArrayList<>(); + List> additionalRules = new ArrayList<>(); - List srcRules = new ArrayList<>(inputProgram.getRules()); - Iterator ruleIterator = srcRules.iterator(); + List> srcRules = new ArrayList<>(inputProgram.getRules()); + Iterator> ruleIterator = srcRules.iterator(); while (ruleIterator.hasNext()) { - BasicRule rule = ruleIterator.next(); + Rule rule = ruleIterator.next(); Head ruleHead = rule.getHead(); - if (!(ruleHead instanceof ChoiceHeadImpl)) { + if (!(ruleHead instanceof ChoiceHead)) { // Rule is constraint or without choice in the head. Leave as is. continue; } 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 51d5bc0b0..e527a13cb 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 @@ -1,22 +1,25 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; 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.rules.BasicRule; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; /** * Rewrites the ordinary atom whose name is given in the input program by the enumeration directive #enum_atom_is into @@ -24,10 +27,11 @@ * * Copyright (c) 2017-2020, the Alpha Team. */ -public class EnumerationRewriting extends ProgramTransformation { +// TODO this should happen during/after internalization +public class EnumerationRewriting extends ProgramTransformation { @Override - public InputProgram apply(InputProgram inputProgram) { + public ASPCore2Program apply(ASPCore2Program inputProgram) { // Read enumeration predicate from directive. String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectivesImpl.DIRECTIVE.enum_predicate_is); if (enumDirective == null) { @@ -41,7 +45,7 @@ public InputProgram apply(InputProgram inputProgram) { checkFactsAreEnumerationFree(inputProgram.getFacts(), enumPredicate); programBuilder.addFacts(inputProgram.getFacts()); - List srcRules = new ArrayList<>(inputProgram.getRules()); + List> srcRules = new ArrayList<>(inputProgram.getRules()); programBuilder.addRules(rewriteRules(srcRules, enumPredicate)); return programBuilder.build(); } @@ -54,13 +58,13 @@ private void checkFactsAreEnumerationFree(List srcFacts, Predicate enumPre } } - private List rewriteRules(List srcRules, CorePredicate enumPredicate) { - List rewrittenRules = new ArrayList<>(); - for (BasicRule rule : srcRules) { - if (rule.getHead() != null && !(rule.getHead() instanceof NormalHeadImpl)) { + private List> rewriteRules(List> srcRules, Predicate enumPredicate) { + List> rewrittenRules = new ArrayList<>(); + for (Rule rule : srcRules) { + if (rule.getHead() != null && !(rule.getHead() instanceof NormalHead)) { throw oops("Encountered rule whose head is not normal: " + rule); } - if (rule.getHead() != null && ((NormalHeadImpl) rule.getHead()).getAtom().getPredicate().equals(enumPredicate)) { + 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()); 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 0aa0ed37c..f9379007a 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 @@ -35,6 +35,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom; @@ -58,7 +59,7 @@ public class IntervalTermToIntervalAtom extends ProgramTransformation rewriteIntervalSpecifications(Rule rule) { // Collect all intervals and replace them with variables. Map intervalReplacements = new LinkedHashMap<>(); @@ -140,9 +141,9 @@ private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map rewrittenRules = new ArrayList<>(); - for (NormalRule rule : inputProgram.getRules()) { - NormalRule rewrittenRule = rewriteIntervalSpecifications(rule); + List> rewrittenRules = new ArrayList<>(); + for (Rule rule : inputProgram.getRules()) { + Rule rewrittenRule = rewriteIntervalSpecifications(rule); rewrittenRules.add(rewrittenRule); // If no rewriting occurred, the output rule is the same as the input to the rewriting. 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 534247068..3fc7fbc3b 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.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; /** @@ -9,7 +9,7 @@ * * Copyright (c) 2019-2020, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformation { +public class NormalizeProgramTransformation extends ProgramTransformation { private boolean useNormalizationGrid; @@ -18,8 +18,8 @@ public NormalizeProgramTransformation(boolean useNormalizationGrid) { } @Override - public NormalProgram apply(InputProgram inputProgram) { - InputProgram tmpPrg; + public NormalProgram apply(ASPCore2Program inputProgram) { + ASPCore2Program tmpPrg; // Transform choice rules. tmpPrg = new ChoiceHeadToNormal().apply(inputProgram); // Transform cardinality aggregates. 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 1f10c3d1d..153476289 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,10 +3,12 @@ import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; @@ -23,19 +25,19 @@ */ public class PredicateInternalizer { - static InputProgram makePredicatesInternal(InputProgram program) { + static ASPCore2Program makePredicatesInternal(ASPCore2Program program) { InputProgram.Builder prgBuilder = InputProgram.builder(); for (Atom atom : program.getFacts()) { prgBuilder.addFact(PredicateInternalizer.makePredicateInternal(atom)); } - for (BasicRule rule : program.getRules()) { + for (Rule rule : program.getRules()) { prgBuilder.addRule(PredicateInternalizer.makePredicateInternal(rule)); } prgBuilder.addInlineDirectives(program.getInlineDirectives()); return prgBuilder.build(); } - private static BasicRule makePredicateInternal(BasicRule rule) { + private static Rule makePredicateInternal(Rule rule) { Head newHead = null; if (rule.getHead() != null) { if (!(rule.getHead() instanceof NormalHeadImpl)) { 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/ProgramTransformation.java index 3d6e87eec..71f5285dd 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/ProgramTransformation.java @@ -1,11 +1,12 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.core.programs.AbstractProgram; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.Rule; /** * Copyright (c) 2017-2019, the Alpha Team. */ -public abstract class ProgramTransformation, O extends AbstractProgram> { +public abstract class ProgramTransformation>, O extends Program>> { 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 459e7065b..da322dd06 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 @@ -16,19 +16,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph.SCComponent; import at.ac.tuwien.kr.alpha.core.depgraph.Node; 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.Instance; -import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrder; -import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; @@ -37,7 +38,6 @@ 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.rules.InternalRule; /** * Evaluates the stratifiable part of a given (analyzed) ASP program. @@ -49,7 +49,7 @@ public class StratifiedEvaluation extends ProgramTransformation> predicateDefiningRules; + private Map> predicateDefiningRules; private Map> modifiedInLastEvaluationRun = new HashMap<>(); @@ -75,7 +75,7 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { } // Create working memories for all predicates occurring in each rule. - for (InternalRule nonGroundRule : inputProgram.getRulesById().values()) { + for (CompiledRule nonGroundRule : inputProgram.getRulesById().values()) { for (Predicate predicate : nonGroundRule.getOccurringPredicates()) { workingMemory.initialize(predicate); } @@ -93,7 +93,7 @@ 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<>(); + List outputRules = new ArrayList<>(); inputProgram.getRulesById().entrySet().stream().filter((entry) -> !solvedRuleIds.contains(entry.getKey())) .forEach((entry) -> outputRules.add(entry.getValue())); @@ -150,10 +150,10 @@ private void evaluateComponent(SCComponent comp) { .forEach((rule) -> solvedRuleIds.add(rule.getRuleId())); } - private void evaluateRules(Set rules, boolean isInitialRun) { + private void evaluateRules(Set rules, boolean isInitialRun) { workingMemory.reset(); LOGGER.debug("Starting component evaluation run..."); - for (InternalRule r : rules) { + for (CompiledRule r : rules) { evaluateRule(r, !isInitialRun); } } @@ -163,9 +163,9 @@ private void evaluateRules(Set rules, boolean isInitialRun) { * of rules to the "modifiedInLastEvaluationRun" map in order to "bootstrap" incremental grounding, i.e. making sure * that those instances are taken into account for ground substitutions by evaluateRule. */ - private void prepareInitialEvaluation(Set rulesToEvaluate) { + private void prepareInitialEvaluation(Set rulesToEvaluate) { modifiedInLastEvaluationRun = new HashMap<>(); - for (InternalRule rule : rulesToEvaluate) { + for (CompiledRule rule : rulesToEvaluate) { // Register rule head instances. Predicate headPredicate = rule.getHeadAtom().getPredicate(); IndexedInstanceStorage headInstances = workingMemory.get(headPredicate, true); @@ -185,7 +185,7 @@ private void prepareInitialEvaluation(Set rulesToEvaluate) { } } - private void evaluateRule(InternalRule rule, boolean checkAllStartingLiterals) { + private void evaluateRule(CompiledRule rule, boolean checkAllStartingLiterals) { LOGGER.debug("Evaluating rule {}", rule); List satisfyingSubstitutions = calculateSatisfyingSubstitutionsForRule(rule, checkAllStartingLiterals); for (Substitution subst : satisfyingSubstitutions) { @@ -193,13 +193,13 @@ private void evaluateRule(InternalRule rule, boolean checkAllStartingLiterals) { } } - private List calculateSatisfyingSubstitutionsForRule(InternalRule rule, boolean checkAllStartingLiterals) { + private List calculateSatisfyingSubstitutionsForRule(CompiledRule rule, boolean checkAllStartingLiterals) { LOGGER.debug("Grounding rule {}", rule); - RuleGroundingOrders groundingOrders = rule.getGroundingOrders(); + RuleGroundingInfo groundingOrders = rule.getGroundingInfo(); // Treat rules with fixed instantiation first. - LOGGER.debug("Is fixed rule? {}", rule.getGroundingOrders().fixedInstantiation()); - if (groundingOrders.fixedInstantiation()) { + LOGGER.debug("Is fixed rule? {}", rule.getGroundingInfo().hasFixedInstantiation()); + if (groundingOrders.hasFixedInstantiation()) { RuleGroundingOrder fixedGroundingOrder = groundingOrders.getFixedGroundingOrder(); return calcSubstitutionsWithGroundingOrder(fixedGroundingOrder, Collections.singletonList(new SubstitutionImpl())); } @@ -297,7 +297,7 @@ private List calcSubstitutionsWithGroundingOrder(RuleGroundingOrde return fullSubstitutions; } - private void fireRule(InternalRule rule, Substitution substitution) { + private void fireRule(CompiledRule rule, Substitution substitution) { Atom newAtom = rule.getHeadAtom().substitute(substitution); if (!newAtom.isGround()) { throw new IllegalStateException("Trying to fire rule " + rule.toString() + " with incompatible substitution " + substitution.toString()); @@ -307,8 +307,8 @@ private void fireRule(InternalRule rule, Substitution substitution) { } private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { - Set nonRecursiveRules = new HashSet<>(); - Set recursiveRules = new HashSet<>(); + Set nonRecursiveRules = new HashSet<>(); + Set recursiveRules = new HashSet<>(); // Collect all predicates occurring in heads of rules of the given component. Set headPredicates = new HashSet<>(); @@ -318,13 +318,13 @@ private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { // Check each predicate whether its defining rules depend on some of the head predicates, i.e., whether there is a // cycle. for (Predicate headPredicate : headPredicates) { - HashSet definingRules = predicateDefiningRules.get(headPredicate); + HashSet definingRules = predicateDefiningRules.get(headPredicate); if (definingRules == null) { // Predicate only occurs in facts, skip. continue; } // Note: here we assume that all rules defining a predicate belong to the same SC component. - for (InternalRule rule : definingRules) { + for (CompiledRule rule : definingRules) { boolean isRuleRecursive = false; for (Literal lit : rule.getPositiveBody()) { if (headPredicates.contains(lit.getPredicate())) { @@ -353,10 +353,10 @@ private ComponentEvaluationInfo getRulesToEvaluate(SCComponent comp) { * Copyright (c) 2020, the Alpha Team. */ private class ComponentEvaluationInfo { - final Set nonRecursiveRules; - final Set recursiveRules; + final Set nonRecursiveRules; + final Set recursiveRules; - ComponentEvaluationInfo(Set nonRecursive, Set recursive) { + ComponentEvaluationInfo(Set nonRecursive, Set recursive) { nonRecursiveRules = Collections.unmodifiableSet(nonRecursive); recursiveRules = Collections.unmodifiableSet(recursive); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index bd0ecde0e..d0aac5547 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -7,7 +7,10 @@ import java.util.Iterator; import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; @@ -28,17 +31,17 @@ * * Copyright (c) 2018-2020, the Alpha Team. */ -public class SumNormalization extends ProgramTransformation { +public class SumNormalization extends ProgramTransformation { private int aggregateCount; private ProgramParserImpl parser = new ProgramParserImpl(); - private InputProgram parse(String program) { + private ASPCore2Program parse(String program) { return parser.parse(program); } @Override - public InputProgram apply(InputProgram inputProgram) { + public ASPCore2Program apply(ASPCore2Program inputProgram) { if (!rewritingNecessary(inputProgram)) { return inputProgram; } @@ -50,17 +53,17 @@ public InputProgram apply(InputProgram inputProgram) { + "output(R, K) :- prefix_subset_sum(R, I1, S), I1 = I - 1, input_number_with_first(R, I, F), bound(R, K), K <= S + F."; // Connect/Rewrite every aggregate in each rule. - List rewrittenRules = rewriteAggregates(inputProgram.getRules()); + List> rewrittenRules = rewriteAggregates(inputProgram.getRules()); InputProgram.Builder prgBuilder = InputProgram.builder(); prgBuilder.addFacts(inputProgram.getFacts()); - InputProgram summationEncoding = makePredicatesInternal(new ProgramParserImpl().parse(summationSubprogram)); + ASPCore2Program summationEncoding = makePredicatesInternal(new ProgramParserImpl().parse(summationSubprogram)); prgBuilder.accumulate(summationEncoding); prgBuilder.addRules(rewrittenRules); // Add enumeration rule that uses the special EnumerationAtom. // The enumeration rule is: "input_number_with_first(A, I, F) :- input_with_first(A, X, F), _index(A, X, I)." - BasicRule tmpEnumRule = makePredicatesInternal(parse("input_number_with_first(A, I, F) :- input_with_first(A, X, F).")).getRules().get(0); + Rule tmpEnumRule = makePredicatesInternal(parse("input_number_with_first(A, I, F) :- input_with_first(A, X, F).")).getRules().get(0); EnumerationAtom enumerationAtom = new EnumerationAtom(parse("index(A, X, I).").getFacts().get(0).getTerms()); List enumerationRuleBody = new ArrayList<>(tmpEnumRule.getBody()); enumerationRuleBody.add(enumerationAtom.toLiteral()); @@ -76,8 +79,8 @@ public InputProgram apply(InputProgram inputProgram) { * @param program the program. * @return true if sum aggregates occur, false otherwise. */ - private boolean rewritingNecessary(InputProgram program) { - for (BasicRule rule : program.getRules()) { + private boolean rewritingNecessary(ASPCore2Program program) { + for (Rule rule : program.getRules()) { for (Literal lit : rule.getBody()) { if (lit instanceof AggregateLiteral) { AggregateAtom aggregateAtom = ((AggregateLiteral) lit).getAtom(); @@ -90,15 +93,15 @@ private boolean rewritingNecessary(InputProgram program) { return false; } - private List rewriteAggregates(List srcRules) { - List rewrittenRules = new ArrayList<>(); - for (BasicRule rule : srcRules) { + private List> rewriteAggregates(List> srcRules) { + List> rewrittenRules = new ArrayList<>(); + for (Rule rule : srcRules) { rewrittenRules.addAll(rewriteAggregatesInRule(rule)); } return rewrittenRules; } - private List rewriteAggregatesInRule(BasicRule rule) { + private List> rewriteAggregatesInRule(Rule rule) { // Example rewriting/connection: // x :- 6 <= #sum {3,a:a; 4,b:b; 5,c:c}. @@ -119,7 +122,7 @@ private List rewriteAggregatesInRule(BasicRule rule) { ArrayList aggregateOutputAtoms = new ArrayList<>(); int aggregatesInRule = 0; // Only needed for limited rewriting. - ArrayList additionalRules = new ArrayList<>(); + ArrayList> additionalRules = new ArrayList<>(); List rewrittenBody = new ArrayList<>(rule.getBody()); for (Iterator iterator = rewrittenBody.iterator(); iterator.hasNext();) { 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 82a1c1bcd..ebc778a6f 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 @@ -40,6 +40,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; @@ -57,14 +58,14 @@ public class VariableEqualityRemoval extends ProgramTransformation rewrittenRules = new ArrayList<>(); - for (NormalRule rule : inputProgram.getRules()) { + List> rewrittenRules = new ArrayList<>(); + for (Rule rule : inputProgram.getRules()) { rewrittenRules.add(findAndReplaceVariableEquality(rule)); } return new NormalProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); } - private NormalRule findAndReplaceVariableEquality(NormalRule rule) { + private Rule findAndReplaceVariableEquality(Rule rule) { // Collect all equal variables. HashMap> variableToEqualVariables = new LinkedHashMap<>(); HashSet equalitiesToRemove = new HashSet<>(); 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 dd428172a..4ed4ee9a4 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 @@ -8,9 +8,10 @@ import org.apache.commons.collections4.SetUtils; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.Head; -import at.ac.tuwien.kr.alpha.core.util.Util; +import at.ac.tuwien.kr.alpha.api.rules.Rule; /** * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) @@ -19,7 +20,7 @@ * * Copyright (c) 2017-2019, the Alpha Team. */ -public abstract class AbstractRule { +public abstract class AbstractRule implements Rule{ private final H head; private final Set bodyLiteralsPositive; @@ -90,10 +91,12 @@ public String toString() { return Util.join((isConstraint() ? "" : head.toString() + " ") + ":- ", getBody(), "."); } + @Override public H getHead() { return head; } + @Override public Set getBody() { return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); } 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 e55d23647..8c506e4f7 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 @@ -29,17 +29,27 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; /** - * 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 NormalRule}. + * 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 NormalRule}. */ -public class BasicRule extends AbstractRule { +public class BasicRule extends AbstractRule implements Rule { public BasicRule(Head head, List body) { super(head, body); } + @Override + public Atom getHeadAtom() { + // TODO this only makes sense for NormalRule + throw new UnsupportedOperationException("Only here for compatibility, this will be removed!"); + } + } 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 c6dbe7e34..cecb63498 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 @@ -35,12 +35,14 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; -import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrders; +import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfoImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; @@ -48,7 +50,7 @@ * 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 NormalRule { +public class InternalRule extends NormalRule implements CompiledRule { private static final IntIdGenerator ID_GENERATOR = new IntIdGenerator(); @@ -56,7 +58,7 @@ public class InternalRule extends NormalRule { private final List occurringPredicates; - private final RuleGroundingOrders groundingOrders; + private final RuleGroundingInfoImpl groundingOrders; public InternalRule(NormalHead head, List body) { super(head, body); @@ -82,7 +84,7 @@ public InternalRule(NormalHead head, List body) { // proper place to put it // this.checkSafety(); - this.groundingOrders = new RuleGroundingOrders(this); + this.groundingOrders = new RuleGroundingInfoImpl(this); this.groundingOrders.computeGroundingOrders(); } @@ -91,7 +93,7 @@ public static void resetIdGenerator() { InternalRule.ID_GENERATOR.resetGenerator(); } - public static InternalRule fromNormalRule(NormalRule rule) { + public static CompiledRule fromNormalRule(Rule rule) { return new InternalRule(rule.isConstraint() ? null : new NormalHeadImpl(rule.getHeadAtom()), new ArrayList<>(rule.getBody())); } @@ -130,10 +132,11 @@ public List getOccurringPredicates() { return this.occurringPredicates; } - public RuleGroundingOrders getGroundingOrders() { + public RuleGroundingInfoImpl getGroundingInfo() { return this.groundingOrders; } + @Override public int getRuleId() { return this.ruleId; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java index c0db947be..4b795c96b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRule.java @@ -3,11 +3,13 @@ import java.util.ArrayList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; -import at.ac.tuwien.kr.alpha.core.util.Util; /** * A rule that has a normal head, i.e. just one head atom, no disjunction or choice heads allowed. @@ -21,7 +23,7 @@ public NormalRule(NormalHead head, List body) { super(head, body); } - public static NormalRule fromBasicRule(BasicRule rule) { + public static NormalRule fromBasicRule(Rule rule) { Atom headAtom = null; if (!rule.isConstraint()) { if (!(rule.getHead() instanceof NormalHeadImpl)) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java deleted file mode 100644 index 4b7aab7c9..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/RuleImpl.java +++ /dev/null @@ -1,129 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.rules; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; - -import org.apache.commons.collections4.SetUtils; - -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.rules.Head; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.core.util.Util; - -/** - * TODO update javadoc - * An abstract representation of a rule with a specific type of @{link Head} (type parameter H) - * - * @param the type of head for this rule - * - * Copyright (c) 2017-2021, the Alpha Team. - */ -public class RuleImpl implements Rule { - - private final H head; - private final Set bodyLiteralsPositive; - private final Set bodyLiteralsNegative; - - public RuleImpl(H head, Set body) { - this.head = head; - Set positiveBody = new LinkedHashSet<>(); - Set negativeBody = new LinkedHashSet<>(); - for (Literal bodyLiteral : body) { - if (bodyLiteral.isNegated()) { - negativeBody.add(bodyLiteral); - } else { - positiveBody.add(bodyLiteral); - } - } - this.bodyLiteralsPositive = Collections.unmodifiableSet(positiveBody); - this.bodyLiteralsNegative = Collections.unmodifiableSet(negativeBody); - - if (!this.isSafe()) { - // TODO: safety check needs to be adapted to solver what the solver actually understands. Will change in the future, - // adapt exception message accordingly. - throw new RuntimeException("Encountered unsafe rule: " + toString() + System.lineSeparator() - + "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."); - } - } - - /** - * Checks whether a rule is safe. The actual safety condition may vary over the next improvements. Currently, a rule is - * safe iff all negated variables and - * all variables occurring in the head also occur in the positive body). - * - * @return true if this rule is safe. - */ - private boolean isSafe() { - // TODO: do the real check. - // Note that - once a proper safety check is implemented - that check should probably be specific for each rule - // implementation, therefore this method should be "protected abstract" here and implemented in each subclass. - return true; - /* - * Set positiveVariables = new HashSet<>(); Set builtinVariables = new HashSet<>(); - * - * // Check that all negative variables occur in the positive body. for (Literal literal : body) { // FIXME: The - * following five lines depend on concrete - * // implementations of the Atom interface. Not nice. if (literal instanceof BasicAtom) { - * positiveVariables.addAll(literal.getOccurringVariables()); } - * else if (literal instanceof BuiltinAtom) { builtinVariables.addAll(literal.getOccurringVariables()); } } - * - * for (Atom negAtom : bodyAtomsNegative) { for (VariableTerm term : negAtom.getOccurringVariables()) { if - * (!positiveVariables.contains(term)) { return - * false; } } } for (VariableTerm builtinVariable : builtinVariables) { if - * (!positiveVariables.contains(builtinVariable)) { return false; } } - * - * // Constraint are safe at this point if (isConstraint()) { return true; } - * - * // Check that all variables of the head occur in the positive body. List headVariables = - * head.getOccurringVariables(); - * headVariables.removeAll(positiveVariables); return headVariables.isEmpty(); - */ - } - - public boolean isConstraint() { - return head == null; - } - - @Override - public String toString() { - return Util.join((isConstraint() ? "" : head.toString() + " ") + ":- ", getBody(), "."); - } - - public H getHead() { - return head; - } - - public Set getBody() { - return SetUtils.union(this.bodyLiteralsPositive, this.bodyLiteralsNegative); - } - - public Set getPositiveBody() { - return this.bodyLiteralsPositive; - } - - public Set getNegativeBody() { - return this.bodyLiteralsNegative; - } - - @Override - public int hashCode() { - return Objects.hash(bodyLiteralsNegative, bodyLiteralsPositive, head); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof RuleImpl)) { - return false; - } - RuleImpl other = (RuleImpl) obj; - return Objects.equals(this.bodyLiteralsNegative, other.bodyLiteralsNegative) - && Objects.equals(this.bodyLiteralsPositive, other.bodyLiteralsPositive) - && Objects.equals(this.head, other.head); - } - -} 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 ee991439b..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/Rules.java +++ /dev/null @@ -1,35 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.rules; - -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; -import at.ac.tuwien.kr.alpha.api.rules.DisjunctiveHead; -import at.ac.tuwien.kr.alpha.api.rules.NormalHead; -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.core.rules.heads.DisjunctiveHeadImpl; -import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; - -public class Rules { - - public static Rule newDisjunctiveRule(List disjunctiveAtoms, Set body) { - return new RuleImpl<>(new DisjunctiveHeadImpl(disjunctiveAtoms), body); - } - - // TODO factory method for choice heads - public static Rule newChoiceRule(ChoiceHead head, Set body) { - return new RuleImpl<>(head, body); - } - - public static Rule newNormalRule(Atom headAtom, Set body) { - return new RuleImpl<>(new NormalHeadImpl(Optional.of(headAtom)), body); - } - - public static Rule newConstraint(Set body) { - return new RuleImpl<>(new NormalHeadImpl(Optional.empty()), body); - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java index ed2900325..a5e226e35 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.rules.heads; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; +import static at.ac.tuwien.kr.alpha.api.Util.join; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHeadImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHeadImpl.java index 5c86bb9a1..1fadabad0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHeadImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/DisjunctiveHeadImpl.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.rules.heads; -import static at.ac.tuwien.kr.alpha.core.util.Util.join; +import static at.ac.tuwien.kr.alpha.api.Util.join; import java.util.List; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java index f1fa10674..3692a2264 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java @@ -1,13 +1,15 @@ package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; - import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; +import at.ac.tuwien.kr.alpha.core.grounder.Grounder; + /** * Copyright (c) 2016, the Alpha Team. */ @@ -20,17 +22,17 @@ protected AbstractSolver(AtomStore atomStore, Grounder grounder) { this.grounder = grounder; } - protected CoreAnswerSet translate(Iterable assignment) { + protected AnswerSet translate(Iterable assignment) { return grounder.assignmentToAnswerSet(assignment); } - protected abstract boolean tryAdvance(Consumer action); + protected abstract boolean tryAdvance(Consumer action); @Override - public Spliterator spliterator() { - return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 0) { + public Spliterator spliterator() { + return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 0) { @Override - public boolean tryAdvance(Consumer action) { + public boolean tryAdvance(Consumer action) { return AbstractSolver.this.tryAdvance(action); } }; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceInfluenceManager.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceInfluenceManager.java index 500413366..45ed07e08 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceInfluenceManager.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceInfluenceManager.java @@ -27,17 +27,21 @@ */ package at.ac.tuwien.kr.alpha.core.solver; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; +import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; +import static at.ac.tuwien.kr.alpha.api.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.api.Util.oops; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; - -import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.TRUE; -import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; - /** * Manages influence of atoms on the activity of certain other atoms. Can be used for either choice points or heuristic atoms. * 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 2519fc29c..351718646 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 @@ -39,7 +39,7 @@ import java.util.stream.Collectors; import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; /** * This class provides functionality for choice point management, detection of active choice points, etc. 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 ff18aec00..55c7e7ace 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 @@ -34,7 +34,7 @@ import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; import static at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; import static at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.ArrayList; import java.util.Iterator; @@ -50,21 +50,21 @@ 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.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; 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.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.common.NoGood; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.ProgramAnalyzingGrounder; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristic; import at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristicFactory; import at.ac.tuwien.kr.alpha.core.solver.heuristics.ChainedBranchingHeuristics; @@ -122,7 +122,7 @@ private BranchingHeuristic chainFallbackHeuristic(Grounder grounder, WritableAss } @Override - protected boolean tryAdvance(Consumer action) { + protected boolean tryAdvance(Consumer action) { boolean didChange = false; // Initially, get NoGoods from grounder. @@ -210,7 +210,7 @@ protected boolean tryAdvance(Consumer action) { afterAllAtomsAssigned = true; } else if (assignment.getMBTCount() == 0) { // NOTE: If we would do optimization, we would now have a guaranteed upper bound. - CoreAnswerSet as = translate(assignment.getTrueAssignments()); + AnswerSet as = translate(assignment.getTrueAssignments()); LOGGER.debug("Answer-Set found: {}", as); action.accept(as); logStats(); @@ -368,7 +368,7 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { // For RuleAtoms in toJustify the corresponding ground body contains BasicAtoms that have been assigned FALSE in the closing. // First, translate RuleAtom back to NonGroundRule + Substitution. String ruleId = (String) ((CoreConstantTerm)atom.getTerms().get(0)).getObject(); - InternalRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); + CompiledRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); String substitution = (String) ((CoreConstantTerm)atom.getTerms().get(1)).getObject(); SubstitutionImpl groundingSubstitution = SubstitutionImpl.fromString(substitution); // Find ground literals in the body that have been assigned false and justify those. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveSolver.java index de4d82a36..4bee6e06d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NaiveSolver.java @@ -27,21 +27,29 @@ */ package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; -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.grounder.Grounder; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; +import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; +import static java.lang.Math.abs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.function.Consumer; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; -import java.util.function.Consumer; - -import static at.ac.tuwien.kr.alpha.core.common.Literals.*; -import static java.lang.Math.abs; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +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.grounder.Grounder; /** * Copyright (c) 2016-2020, the Alpha Team. @@ -78,7 +86,7 @@ public class NaiveSolver extends AbstractSolver { } @Override - protected boolean tryAdvance(Consumer action) { + protected boolean tryAdvance(Consumer action) { // Get basic rules and facts from grounder if (doInit) { obtainNoGoodsFromGrounder(); @@ -114,7 +122,7 @@ protected boolean tryAdvance(Consumer action) { assignUnassignedToFalse(); didChange = true; } else if (noMBTValuesReamining()) { - CoreAnswerSet as = getAnswerSetFromAssignment(); + AnswerSet as = getAnswerSetFromAssignment(); LOGGER.debug("Answer-Set found: {}", as); LOGGER.trace("Choice stack: {}", choiceStack); action.accept(as); @@ -193,7 +201,7 @@ private boolean propagationFixpointReached() { return !changeCopy; } - private CoreAnswerSet getAnswerSetFromAssignment() { + private AnswerSet getAnswerSetFromAssignment() { ArrayList trueAtoms = new ArrayList<>(); for (Map.Entry atomAssignment : truthAssignments.entrySet()) { if (atomAssignment.getValue()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java index cc7af5db8..f8d1228ec 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoaming.java @@ -51,8 +51,8 @@ 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; -import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.api.Util.oops; /** * NoGoodStore using for each NoGood three watches, two ordinary ones and an alpha watch. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ShallowAntecedent.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ShallowAntecedent.java index 595804f21..1af25c83c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ShallowAntecedent.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/ShallowAntecedent.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.solver; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; /** * Represents a shallow {@link Antecedent} that must be instantiated before use. 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 a89f1cc06..dd01471b0 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 @@ -27,6 +27,7 @@ */ 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; 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 edeace8db..4fd0b0eef 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 @@ -40,8 +40,8 @@ import static at.ac.tuwien.kr.alpha.core.common.Literals.*; import static at.ac.tuwien.kr.alpha.core.solver.Atoms.isAtom; import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.*; -import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.api.Util.oops; /** * An implementation of Assignment using a trail (of literals) and arrays as underlying structures for storing diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WatchedNoGood.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WatchedNoGood.java index b4346a2ee..82e46af99 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WatchedNoGood.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/WatchedNoGood.java @@ -33,7 +33,7 @@ import at.ac.tuwien.kr.alpha.core.common.NoGoodInterface; import static at.ac.tuwien.kr.alpha.core.common.Literals.literalToString; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; public final class WatchedNoGood implements NoGoodInterface, Antecedent { private int activity; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ChainedBranchingHeuristics.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ChainedBranchingHeuristics.java index eac27790d..9739feb0f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ChainedBranchingHeuristics.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ChainedBranchingHeuristics.java @@ -28,7 +28,7 @@ import at.ac.tuwien.kr.alpha.core.common.NoGood; import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.*; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveChoicePoints.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveChoicePoints.java index 7a0174238..126d0ec20 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveChoicePoints.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveChoicePoints.java @@ -35,7 +35,7 @@ import java.util.Set; import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; /** * Extends {@code HeapOfActiveAtoms} by a mechanism that, diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java index cf67f4f32..dced64b2d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDS.java @@ -28,7 +28,7 @@ import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; -import static at.ac.tuwien.kr.alpha.core.util.Util.arrayGrowthSize; +import static at.ac.tuwien.kr.alpha.api.Util.arrayGrowthSize; import java.util.ArrayList; import java.util.Arrays; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearner.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearner.java index 85fb5affa..abd2ac73c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearner.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/learning/GroundConflictNoGoodLearner.java @@ -42,7 +42,7 @@ import static at.ac.tuwien.kr.alpha.core.common.Literals.*; import static at.ac.tuwien.kr.alpha.core.solver.NoGoodStore.LBD_NO_VALUE; -import static at.ac.tuwien.kr.alpha.core.util.Util.oops; +import static at.ac.tuwien.kr.alpha.api.Util.oops; /** * Conflict-driven learning on ground clauses. 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 029df5b12..b89a4a286 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 @@ -45,26 +45,29 @@ 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.Util; 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.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.rules.Rule; 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.CoreAnswerSet; 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.InputProgramImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; 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.Solver; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; -import at.ac.tuwien.kr.alpha.core.util.Util; public class AlphaImpl implements Alpha { @@ -80,9 +83,9 @@ public AlphaImpl() { } @Override - public InputProgramImpl readProgram(InputConfig cfg) throws IOException { - InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); - InputProgramImpl tmpProg; + public ASPCore2Program readProgram(InputConfig cfg) throws IOException { + InputProgram.Builder prgBuilder = InputProgram.builder(); + ASPCore2Program tmpProg; if (!cfg.getFiles().isEmpty()) { tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); prgBuilder.accumulate(tmpProg); @@ -95,15 +98,15 @@ public InputProgramImpl readProgram(InputConfig cfg) throws IOException { } @Override - public InputProgramImpl readProgramFiles(boolean literate, Map externals, List paths) throws IOException { + public ASPCore2Program 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 InputProgramImpl readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { + public ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { ProgramParserImpl parser = new ProgramParserImpl(externals); - InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); - InputProgramImpl tmpProg; + InputProgram.Builder prgBuilder = InputProgram.builder(); + InputProgram tmpProg; for (Path path : paths) { CharStream stream; if (!literate) { @@ -118,25 +121,25 @@ public InputProgramImpl readProgramFiles(boolean literate, Map externals) { + public ASPCore2Program readProgramString(String aspString, Map externals) { ProgramParserImpl parser = new ProgramParserImpl(externals); return parser.parse(aspString); } @Override - public InputProgramImpl readProgramString(String aspString) { + public ASPCore2Program readProgramString(String aspString) { return readProgramString(aspString, null); } // TODO make sure to adapt this without exposing internal imnplementation types - public NormalProgram normalizeProgram(InputProgramImpl program) { + public Program> normalizeProgram(ASPCore2Program program) { return new NormalizeProgramTransformation(config.isUseNormalizationGrid()).apply(program); } // TODO make sure to adapt this without exposing internal imnplementation types - public InternalProgram performProgramPreprocessing(InternalProgram program) { + public CompiledProgram performProgramPreprocessing(CompiledProgram program) { LOGGER.debug("Preprocessing InternalProgram!"); - InternalProgram retVal = program; + CompiledProgram retVal = program; if (config.isEvaluateStratifiedPart()) { AnalyzedProgram analyzed = new AnalyzedProgram(program.getRules(), program.getFacts()); retVal = new StratifiedEvaluation().apply(analyzed); @@ -158,7 +161,8 @@ public InternalProgram performProgramPreprocessing(AnalyzedProgram program) { * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the * program analysis and normalization aren't of interest. */ - public Stream solve(InputProgramImpl program) { + @Override + public Stream solve(ASPCore2Program program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -166,8 +170,9 @@ public Stream solve(InputProgramImpl program) { * Convenience method - overloaded version of solve({@link InternalProgram}, {@link Predicate}) for cases where * details of the program analysis and normalization aren't of interest. */ - public Stream solve(InputProgramImpl program, java.util.function.Predicate filter) { - NormalProgram normalized = normalizeProgram(program); + @Override + public Stream solve(ASPCore2Program program, java.util.function.Predicate filter) { + Program> normalized = normalizeProgram(program); return solve(normalized, filter); } @@ -175,8 +180,8 @@ public Stream solve(InputProgramImpl program, java.util.function.Pred * Convenience method - overloaded version of solve({@link InternalProgram}) for cases where details of the * program analysis aren't of interest. */ - public Stream solve(NormalProgram program, java.util.function.Predicate filter) { - InternalProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); + public Stream solve(Program> program, java.util.function.Predicate filter) { + CompiledProgram preprocessed = performProgramPreprocessing(InternalProgram.fromNormalProgram(program)); return solve(preprocessed, filter); } @@ -187,7 +192,7 @@ public Stream solve(NormalProgram program, java.util.function.Predica * @param program the program to solve * @return a stream of answer sets */ - public Stream solve(InternalProgram program) { + public Stream solve(CompiledProgram program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -198,7 +203,7 @@ public Stream solve(InternalProgram program) { * @param filter {@link Predicate} filtering {@at.ac.tuwien.kr.alpha.common.Predicate}s in the returned answer sets * @return a Stream of answer sets representing stable models of the given program */ - public Stream solve(InternalProgram program, java.util.function.Predicate filter) { + public Stream solve(CompiledProgram program, java.util.function.Predicate filter) { Stream retVal = prepareSolverFor(program, filter).stream(); return config.isSortAnswerSets() ? retVal.sorted() : retVal; } @@ -212,7 +217,7 @@ public Stream solve(InternalProgram program, java.util.function.Predi * set stream from the solver. * @return a solver (and accompanying grounder) instance pre-loaded with the given program. */ - public Solver prepareSolverFor(InternalProgram program, java.util.function.Predicate filter) { + public Solver prepareSolverFor(CompiledProgram program, java.util.function.Predicate filter) { String grounderName = config.getGrounderName(); boolean doDebugChecks = config.isDebugInternalChecks(); From 131a5c825d77ea2e143537d3a3052558e4c07d0d Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 29 Jan 2021 13:56:41 +0100 Subject: [PATCH 017/111] fix build errors --- alpha-api/build.gradle | 2 +- alpha-cli-app/build.gradle | 3 +++ .../ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java | 1 - .../at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java | 1 - .../ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java | 1 - .../at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java | 2 +- .../ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java | 1 - .../ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java | 2 -- .../alpha/core/grounder/structure/AnalyzeUnjustified.java | 1 - .../ac/tuwien/kr/alpha/core/programs/AbstractProgram.java | 5 +++-- .../ac/tuwien/kr/alpha/core/programs/InternalProgram.java | 2 +- .../ac/tuwien/kr/alpha/core/programs/NormalProgram.java | 2 +- .../at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java | 2 +- .../at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java | 1 - .../core/solver/heuristics/BranchingHeuristicFactory.java | 8 +++----- 15 files changed, 14 insertions(+), 20 deletions(-) diff --git a/alpha-api/build.gradle b/alpha-api/build.gradle index 105ea638a..219c5ce0f 100644 --- a/alpha-api/build.gradle +++ b/alpha-api/build.gradle @@ -3,8 +3,8 @@ plugins { } dependencies { + // TODO this should be slf4j, not full logback! implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7' - implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' } diff --git a/alpha-cli-app/build.gradle b/alpha-cli-app/build.gradle index 026138ba4..4f06690f6 100644 --- a/alpha-cli-app/build.gradle +++ b/alpha-cli-app/build.gradle @@ -4,8 +4,11 @@ plugins { dependencies { implementation project(':alpha-solver') + implementation project(':alpha-core') implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' + implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' + implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' } def mainClassName = 'at.ac.tuwien.kr.alpha.Main' diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index 19166fb46..cb1468b2c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -8,7 +8,6 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Copyright (c) 2018, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java index 68b2b706e..c42969a8d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java @@ -35,7 +35,6 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Contains a potentially negated {@link BasicAtom}. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java index efb690392..6d7a146dc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java @@ -14,7 +14,6 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; public class AnswerSetBuilder { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java index bb040beef..d0439bb31 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java @@ -85,7 +85,7 @@ public RenameCounter(int startingValue) { renamedVariables = new HashMap<>(); } - public Map getRenamedVariables(){ + public Map getRenamedVariables() { return renamedVariables; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java index 04e402173..b672f2a01 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java @@ -41,7 +41,6 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Internal representation of an {@link at.ac.tuwien.kr.alpha.core.programs.InternalProgram}'s dependency graph. The dependency graph tracks dependencies diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java index 5333787b1..a4ef6675a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java @@ -52,8 +52,6 @@ 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.NoGood; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Class to generate ground NoGoods out of non-ground rules and grounding substitutions. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java index 974c19a57..d3c2e822c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/structure/AnalyzeUnjustified.java @@ -31,7 +31,6 @@ import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.grounder.Unification; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java index 8fc003c81..ec345bf93 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/AbstractProgram.java @@ -13,10 +13,11 @@ /** * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives) * - * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an implementation permits + * @param the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an + * implementation permits * Copyright (c) 2019, the Alpha Team. */ -public abstract class AbstractProgram> implements Program{ +public abstract class AbstractProgram> implements Program { private final List rules; private final List facts; 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 f29369bb9..1986471d3 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 @@ -27,7 +27,7 @@ *

      * Copyright (c) 2017-2020, the Alpha Team. */ -public class InternalProgram extends AbstractProgram implements CompiledProgram{ +public class InternalProgram extends AbstractProgram implements CompiledProgram { private final Map> predicateDefiningRules = new LinkedHashMap<>(); private final Map> factsByPredicate = new LinkedHashMap<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java index 331058673..4115b2cf9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgram.java @@ -17,7 +17,7 @@ * * Copyright (c) 2019, the Alpha Team. */ -public class NormalProgram extends AbstractProgram> implements Program>{ +public class NormalProgram extends AbstractProgram> implements Program> { public NormalProgram(List> rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); 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 4ed4ee9a4..4a325ec19 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 @@ -20,7 +20,7 @@ * * Copyright (c) 2017-2019, the Alpha Team. */ -public abstract class AbstractRule implements Rule{ +public abstract class AbstractRule implements Rule { private final H head; private final Set bodyLiteralsPositive; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java index 3692a2264..9cbc497e5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolver.java @@ -7,7 +7,6 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.CoreAnswerSet; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactory.java index 4ca447bcf..29f995071 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactory.java @@ -25,16 +25,14 @@ */ package at.ac.tuwien.kr.alpha.core.solver.heuristics; +import java.util.List; +import java.util.Random; + import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; import at.ac.tuwien.kr.alpha.core.solver.heuristics.activity.BodyActivityProviderFactory.BodyActivityType; -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; - public final class BranchingHeuristicFactory { public static BranchingHeuristic getInstance(HeuristicsConfiguration heuristicsConfiguration, Grounder grounder, WritableAssignment assignment, ChoiceManager choiceManager, Random random) { From 84f537c718ff5a39e8271620c6c76b7ba4470fae Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 29 Jan 2021 22:46:03 +0100 Subject: [PATCH 018/111] WIP: fix tests --- alpha-api/build.gradle | 2 + .../kr/alpha/api/ComparisonOperator.java | 5 + .../tuwien/kr/alpha/api/rules/ChoiceHead.java | 5 + .../kr/alpha/api/rules/CompiledRule.java | 6 - .../at/ac/tuwien/kr/alpha/api/rules/Rule.java | 4 + .../at/ac/tuwien/kr/alpha/api/UtilTest.java | 20 + alpha-cli-app/build.gradle | 2 + .../kr/alpha/AnswerSetToXlsxWriter.java | 2 +- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 2 +- .../{ => app}/config/CliOptionHandler.java | 2 +- .../{ => app}/config/CommandLineParser.java | 2 +- .../mappers}/AnswerSetToWorkbookMapper.java | 3 +- .../kr/alpha/AnswerSetToXlsxWriterTest.java | 114 +++ .../java/at/ac/tuwien/kr/alpha/MainTest.java | 87 ++ .../alpha/app/ComponentGraphWriterTest.java | 67 ++ .../alpha/app/DependencyGraphWriterTest.java | 63 ++ .../app/config/CommandLineParserTest.java | 175 ++++ .../AnswerSetToWorkbookMapperTest.java | 99 +++ .../kr/alpha/core/atoms/AggregateAtom.java | 14 +- .../kr/alpha/core/atoms/AggregateLiteral.java | 6 +- .../kr/alpha/core/atoms/ComparisonAtom.java | 8 +- .../alpha/core/atoms/ComparisonLiteral.java | 10 +- ...rator.java => ComparisonOperatorImpl.java} | 10 +- .../kr/alpha/core/common/terms/CoreTerm.java | 4 +- .../kr/alpha/core/common/terms/Terms.java | 2 +- .../alpha/core/grounder/SubstitutionImpl.java | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 24 +- .../core/rules/heads/ChoiceHeadImpl.java | 13 +- .../kr/alpha/core/util/AnswerSetsParser.java | 49 ++ .../java/at/ac/tuwien/kr/alpha/TestUtil.java | 75 ++ .../ac/tuwien/kr/alpha/antlr/ParserTest.java | 226 +++++ .../stdlib/AspStandardLibraryTest.java | 105 +++ .../tuwien/kr/alpha/common/AtomStoreTest.java | 21 + .../kr/alpha/common/BasicAnswerSetTest.java | 88 ++ .../ac/tuwien/kr/alpha/common/NoGoodTest.java | 112 +++ .../tuwien/kr/alpha/common/ProgramTest.java | 49 ++ .../ac/tuwien/kr/alpha/common/RuleTest.java | 53 ++ .../common/SimpleAnswerSetFormatterTest.java | 21 + .../ac/tuwien/kr/alpha/common/TermTest.java | 95 ++ .../kr/alpha/common/atoms/AtomsTest.java | 144 ++++ ...LiteralBindingNonBindingVariablesTest.java | 207 +++++ .../kr/alpha/common/terms/TermsTest.java | 34 + .../kr/alpha/common/terms/TestMinusTerm.java | 60 ++ .../core/depgraph/DependencyGraphTest.java | 269 ++++++ .../depgraph/StratificationAlgorithmTest.java | 239 ++++++ .../alpha/core/grounder/ChoiceGrounder.java | 214 +++++ .../kr/alpha/core/grounder/DummyGrounder.java | 193 +++++ .../grounder/IndexedInstanceStorageTest.java | 101 +++ .../core/grounder/NaiveGrounderTest.java | 447 ++++++++++ .../core/grounder/NoGoodGeneratorTest.java | 91 ++ .../grounder/ProgramTransformationTest.java | 73 ++ .../core/grounder/RuleGroundingOrderTest.java | 161 ++++ .../alpha/core/grounder/RuleToStringTest.java | 102 +++ .../alpha/core/grounder/SubstitutionTest.java | 169 ++++ .../kr/alpha/core/grounder/UnifierTest.java | 82 ++ .../GrounderHeuristicConfigurationTest.java | 95 ++ .../LiteralInstantiationStrategyTest.java | 368 ++++++++ .../LiteralInstantiatorTest.java | 153 ++++ .../structure/AnalyzeUnjustifiedTest.java | 218 +++++ .../StratifiedEvaluationRegressionTest.java | 260 ++++++ .../StratifiedEvaluationTest.java | 276 ++++++ .../kr/alpha/solver/AbstractSolverTests.java | 266 ++++++ ...AggregatesCardinalityCountingGridTest.java | 38 + ...gregatesCardinalitySortingCircuitTest.java | 38 + .../kr/alpha/solver/AggregatesTest.java | 182 ++++ .../kr/alpha/solver/AntecedentTest.java | 32 + .../kr/alpha/solver/AtomCounterTests.java | 134 +++ .../kr/alpha/solver/ChoiceManagerTests.java | 85 ++ .../alpha/solver/HanoiTowerDetailedTest.java | 44 + .../kr/alpha/solver/HanoiTowerTest.java | 135 +++ .../solver/HeadBodyTransformationTests.java | 319 +++++++ .../solver/LearnedNoGoodDeletionTest.java | 149 ++++ .../kr/alpha/solver/NaiveNoGoodStoreTest.java | 588 +++++++++++++ .../solver/NoGoodStoreAlphaRoamingTest.java | 615 +++++++++++++ .../kr/alpha/solver/OmigaBenchmarksTest.java | 100 +++ .../solver/PartSubpartConfigurationTest.java | 116 +++ .../kr/alpha/solver/PigeonHoleTest.java | 180 ++++ .../ac/tuwien/kr/alpha/solver/RacksTest.java | 58 ++ .../alpha/solver/SolverStatisticsTests.java | 103 +++ .../tuwien/kr/alpha/solver/SolverTests.java | 808 ++++++++++++++++++ .../alpha/solver/TestableChoiceManager.java | 50 ++ .../solver/ThreeColouringRandomGraphTest.java | 149 ++++ .../solver/ThreeColouringTestWithRandom.java | 229 +++++ .../alpha/solver/ThreeColouringWheelTest.java | 152 ++++ .../kr/alpha/solver/TrailAssignmentTest.java | 260 ++++++ .../AlphaHeuristicTestAssumptions.java | 170 ++++ .../alpha/solver/heuristics/BerkMinTest.java | 193 +++++ .../BranchingHeuristicFactoryTest.java | 72 ++ .../heuristics/HeapOfActiveAtomsTest.java | 99 +++ .../solver/heuristics/HeuristicTestUtils.java | 56 ++ .../heuristics/PseudoChoiceManager.java | 51 ++ .../heuristics/ReplayHeuristicTest.java | 74 ++ .../kr/alpha/solver/heuristics/VSIDSTest.java | 141 +++ .../GroundConflictNoGoodLearnerTest.java | 91 ++ .../alpha/test/util/DependencyGraphUtils.java | 91 ++ .../alpha/test/util/SubstitutionTestUtil.java | 58 ++ .../tuwien/kr/alpha/test/util/TestUtils.java | 99 +++ .../src/test/resources/HanoiTower_Alpha.asp | 98 +++ .../test/resources/HanoiTower_instances/1.asp | 85 ++ .../test/resources/HanoiTower_instances/2.asp | 91 ++ .../test/resources/HanoiTower_instances/3.asp | 89 ++ .../test/resources/HanoiTower_instances/4.asp | 95 ++ .../HanoiTower_instances/instances.txt | 4 + .../resources/HanoiTower_instances/simple.asp | 24 + .../PreviouslyProblematic/3col-20-38.txt | 67 ++ .../vehicle_normal_small.asp | 86 ++ .../src/test/resources/escaped_quotes.asp | 1 + alpha-core/src/test/resources/logback.xml | 24 + .../partial-eval/pup_topological_order.asp | 34 + .../recursive_w_negated_condition.asp | 34 + alpha-core/src/test/resources/show.asp | 1 + .../transform-test/choice-to-normal.1.in | 1 + .../transform-test/choice-to-normal.1.out | 6 + .../resources/transform-test/interval.1.in | 6 + .../resources/transform-test/interval.1.out | 4 + alpha-solver/build.gradle | 3 + .../tuwien/kr/alpha/impl/AlphaImplTest.java | 593 +++++++++++++ .../impl/FixedInterpretationLiteralsTest.java | 195 +++++ .../tuwien/kr/alpha/test/util/TestUtils.java | 100 +++ build.gradle | 1 + 120 files changed, 13215 insertions(+), 55 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java create mode 100644 alpha-api/src/test/java/at/ac/tuwien/kr/alpha/api/UtilTest.java rename alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/{ => app}/config/CliOptionHandler.java (83%) rename alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/{ => app}/config/CommandLineParser.java (99%) rename {alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper => alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers}/AnswerSetToWorkbookMapper.java (98%) create mode 100644 alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java create mode 100644 alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java create mode 100644 alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java create mode 100644 alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java create mode 100644 alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParserTest.java create mode 100644 alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/{ComparisonOperator.java => ComparisonOperatorImpl.java} (65%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/AnswerSetsParser.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatterTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithmTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceGrounder.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/DummyGrounder.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java create 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/ProgramTransformationTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java create mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java create mode 100644 alpha-core/src/test/resources/HanoiTower_Alpha.asp create mode 100644 alpha-core/src/test/resources/HanoiTower_instances/1.asp create mode 100644 alpha-core/src/test/resources/HanoiTower_instances/2.asp create mode 100644 alpha-core/src/test/resources/HanoiTower_instances/3.asp create mode 100644 alpha-core/src/test/resources/HanoiTower_instances/4.asp create mode 100644 alpha-core/src/test/resources/HanoiTower_instances/instances.txt create mode 100644 alpha-core/src/test/resources/HanoiTower_instances/simple.asp create mode 100644 alpha-core/src/test/resources/PreviouslyProblematic/3col-20-38.txt create mode 100644 alpha-core/src/test/resources/PreviouslyProblematic/vehicle_normal_small.asp create mode 100644 alpha-core/src/test/resources/escaped_quotes.asp create mode 100644 alpha-core/src/test/resources/logback.xml create mode 100644 alpha-core/src/test/resources/partial-eval/pup_topological_order.asp create mode 100644 alpha-core/src/test/resources/partial-eval/recursive_w_negated_condition.asp create mode 100644 alpha-core/src/test/resources/show.asp create mode 100644 alpha-core/src/test/resources/transform-test/choice-to-normal.1.in create mode 100644 alpha-core/src/test/resources/transform-test/choice-to-normal.1.out create mode 100644 alpha-core/src/test/resources/transform-test/interval.1.in create mode 100644 alpha-core/src/test/resources/transform-test/interval.1.out create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java create mode 100644 alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java diff --git a/alpha-api/build.gradle b/alpha-api/build.gradle index 219c5ce0f..130db84b2 100644 --- a/alpha-api/build.gradle +++ b/alpha-api/build.gradle @@ -7,5 +7,7 @@ dependencies { implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7' implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' + + testImplementation group: 'junit', name: 'junit', version: '4.12' } 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 new file mode 100644 index 000000000..404920530 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.api; + +public interface ComparisonOperator { + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java index 3e68c1704..54a2b06d9 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java @@ -2,6 +2,7 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -11,6 +12,10 @@ public interface ChoiceHead extends Head { Term getLowerBound(); Term getUpperBound(); + + ComparisonOperator getLowerOperator(); + + ComparisonOperator getUpperOperator(); List getChoiceElements(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java index a0758a515..2eeb6dbbd 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java @@ -1,10 +1,8 @@ package at.ac.tuwien.kr.alpha.api.rules; import java.util.List; -import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; -import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; public interface CompiledRule extends Rule { @@ -13,10 +11,6 @@ public interface CompiledRule extends Rule { List getOccurringPredicates(); - Set getPositiveBody(); - - Set getNegativeBody(); - RuleGroundingInfo getGroundingInfo(); CompiledRule renameVariables(String str); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java index a8de0452c..572495d34 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java @@ -15,4 +15,8 @@ public interface Rule { // TODO clean up programs/rules mess Atom getHeadAtom(); + + Set getPositiveBody(); + + Set getNegativeBody(); } diff --git a/alpha-api/src/test/java/at/ac/tuwien/kr/alpha/api/UtilTest.java b/alpha-api/src/test/java/at/ac/tuwien/kr/alpha/api/UtilTest.java new file mode 100644 index 000000000..4b4e298a1 --- /dev/null +++ b/alpha-api/src/test/java/at/ac/tuwien/kr/alpha/api/UtilTest.java @@ -0,0 +1,20 @@ +package at.ac.tuwien.kr.alpha.api; + +import org.junit.Test; + +public class UtilTest { + @Test(expected = RuntimeException.class) + public void oops() throws Exception { + throw Util.oops("Ha", new UnsupportedOperationException("Ho")); + } + + @Test(expected = RuntimeException.class) + public void oops1() throws Exception { + throw Util.oops("Ha"); + } + + @Test(expected = RuntimeException.class) + public void oops2() throws Exception { + throw Util.oops(); + } +} \ No newline at end of file diff --git a/alpha-cli-app/build.gradle b/alpha-cli-app/build.gradle index 4f06690f6..19907f7ce 100644 --- a/alpha-cli-app/build.gradle +++ b/alpha-cli-app/build.gradle @@ -9,6 +9,8 @@ dependencies { implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1' implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1' implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1' + + testImplementation group: 'junit', name: 'junit', version: '4.12' } def mainClassName = 'at.ac.tuwien.kr.alpha.Main' diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java index add725e9d..ee9a3bad2 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriter.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToObjectMapper; -import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToWorkbookMapper; +import at.ac.tuwien.kr.alpha.app.mappers.AnswerSetToWorkbookMapper; public class AnswerSetToXlsxWriter implements BiConsumer { 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 c95b77155..c84b01383 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 @@ -56,7 +56,7 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.app.ComponentGraphWriter; import at.ac.tuwien.kr.alpha.app.DependencyGraphWriter; -import at.ac.tuwien.kr.alpha.config.CommandLineParser; +import at.ac.tuwien.kr.alpha.app.config.CommandLineParser; import at.ac.tuwien.kr.alpha.core.common.AnswerSetFormatter; import at.ac.tuwien.kr.alpha.core.common.SimpleAnswerSetFormatter; import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CliOptionHandler.java similarity index 83% rename from alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java rename to alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CliOptionHandler.java index 054f01654..adc671dc2 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CliOptionHandler.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CliOptionHandler.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.config; +package at.ac.tuwien.kr.alpha.app.config; import org.apache.commons.cli.Option; import org.apache.commons.cli.ParseException; diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java similarity index 99% rename from alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java rename to alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java index 100ceb974..8d06e2263 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.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.config; +package at.ac.tuwien.kr.alpha.app.config; import at.ac.tuwien.kr.alpha.api.config.AlphaConfig; import at.ac.tuwien.kr.alpha.api.config.InputConfig; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapper.java similarity index 98% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java rename to alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapper.java index 840d51243..3102e58a3 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapper.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapper.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.mapper; +package at.ac.tuwien.kr.alpha.app.mappers; import java.util.List; @@ -40,6 +40,7 @@ import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToObjectMapper; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; 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 new file mode 100644 index 000000000..ccd013ef3 --- /dev/null +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java @@ -0,0 +1,114 @@ +package at.ac.tuwien.kr.alpha; + + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; + +public class AnswerSetToXlsxWriterTest { + + @Test + public void writeAnswerSetFilesTest() throws IOException { + AnswerSet as = new AnswerSetBuilder().predicate("bla").instance("blubb", "blubb").instance("foo", "bar").predicate("foo").instance("bar") + .instance("baz").predicate("complex").instance(Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)).build(); + Path tmpDir = Files.createTempDirectory("alpha-test-xlsx-output"); + AnswerSetToXlsxWriter writer = new AnswerSetToXlsxWriter(tmpDir.toString() + "/alphaAnswerSet"); + writer.accept(0, as); + File tmpDirFile = tmpDir.toFile(); + File[] generatedFiles = tmpDirFile.listFiles(); + Assert.assertEquals(generatedFiles.length, 1); + File answerSetFile = generatedFiles[0]; + Assert.assertEquals("alphaAnswerSet.0.xlsx", answerSetFile.getName()); + Workbook wb = WorkbookFactory.create(answerSetFile); + assertWorkbookMatchesAnswerSet(wb, as); + wb.close(); + // clean up + answerSetFile.delete(); + tmpDirFile.delete(); + } + + @Test + public void writeUnsatTest() throws IOException { + Path tmpDir = Files.createTempDirectory("alpha-test-xlsx-unsat"); + AnswerSetToXlsxWriter.writeUnsatInfo(Paths.get(tmpDir.toString() + "/alphaAnswerSet.UNSAT.xlsx")); + File tmpDirFile = tmpDir.toFile(); + File[] generatedFiles = tmpDirFile.listFiles(); + Assert.assertEquals(generatedFiles.length, 1); + File unsatFile = generatedFiles[0]; + Assert.assertEquals("alphaAnswerSet.UNSAT.xlsx", unsatFile.getName()); + Workbook wb = WorkbookFactory.create(unsatFile); + Sheet unsatSheet = wb.getSheet("Unsatisfiable"); + Assert.assertNotNull(unsatSheet); + Cell cell = unsatSheet.getRow(0).getCell(0); + Assert.assertNotNull(cell); + String cellValue = cell.getStringCellValue(); + Assert.assertEquals("Input is unsatisfiable - No answer sets!", cellValue); + wb.close(); + // clean up + unsatFile.delete(); + tmpDirFile.delete(); + } + + private static void assertWorkbookMatchesAnswerSet(Workbook wb, AnswerSet as) { + for (Predicate pred : as.getPredicates()) { + if (pred.getArity() == 0) { + boolean flagFound = false; + Sheet flagsSheet = wb.getSheet("Flags"); + Assert.assertNotNull(flagsSheet); + for (Row row : flagsSheet) { + if (row.getCell(0).getStringCellValue().equals(pred.getName())) { + flagFound = true; + break; + } + } + Assert.assertTrue("0-arity predicate " + pred.getName() + " not found in workbook!", flagFound); + } else { + Sheet predicateSheet = wb.getSheet(pred.getName() + "_" + pred.getArity()); + for (Atom atom : as.getPredicateInstances(pred)) { + boolean atomFound = false; + Assert.assertNotNull(predicateSheet); + for (Row row : predicateSheet) { + if (rowMatchesAtom(row, atom)) { + atomFound = true; + break; + } + } + Assert.assertTrue("Atom " + atom.toString() + " not found in workbook!", atomFound); + } + } + } + } + + private static boolean rowMatchesAtom(Row row, Atom atom) { + List terms = atom.getTerms(); + Cell cell; + for (int i = 0; i < terms.size(); i++) { + cell = row.getCell(i); + if (cell == null) { + return false; + } + if (!(cell.getStringCellValue().equals(terms.get(i).toString()))) { + return false; + } + } + return true; + } + +} 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 new file mode 100644 index 000000000..186779999 --- /dev/null +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2016-2018, 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; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Arrays; + +import static at.ac.tuwien.kr.alpha.Main.main; +import static org.junit.Assert.assertTrue; + +@RunWith(Parameterized.class) +public class MainTest { + private static final String INPUT = "p(a). " + System.lineSeparator() + " b :- p(X)." + System.lineSeparator(); + + @Parameters + public static Iterable data() { + return Arrays.asList( + new String[][][] {{{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-e", "1119654162577372", "-n", "20", "-str", INPUT }}, + {{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "0", "-str", INPUT }}, + {{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "1", "-str", INPUT }}, + {{"-g", "naive", "-s", "default", "-r", "naive", "-e", "1119654162577372", "--numAS", "1", "-str", INPUT }}}); + } + + @Parameter + public String[] argv; + + /** + * Temporarily redirects System.err and System.out while running the solver from the main entry point with the + * given parameters. + * Warning: this test is fragile and may require adaptions if printing is changed anywhere in Alpha. + */ + @Test + public void test() { + PrintStream sysOut = System.out; + ByteArrayOutputStream newOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(newOut)); + main(argv); + System.setOut(sysOut); + assertTrue(newOut.toString().contains("{ b, p(a) }")); + } + + @Test + public void filterTest() { + PrintStream sysOut = System.out; + ByteArrayOutputStream newOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(newOut)); + String[] args = Arrays.copyOf(argv, argv.length + 2); + args[args.length - 2] = "-f"; + args[args.length - 1] = "b"; + main(args); + System.setOut(sysOut); + assertTrue(newOut.toString().contains("{ b }")); + } + +} \ No newline at end of file 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 new file mode 100644 index 000000000..b258a35c0 --- /dev/null +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java @@ -0,0 +1,67 @@ +package at.ac.tuwien.kr.alpha.app; + +import java.io.ByteArrayOutputStream; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph; +import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; + +public class ComponentGraphWriterTest { + private static final String LS = System.lineSeparator(); + + @Test + public void smokeTest() { + // Note: rather than testing correct implementation of dot file format, + // (which would be a lot of work), just test correct dot code generation + // for one component graph that has all possible "special" node constellations, + // i.e. positive and negative dependencies, cycle through negation, constraints. + String asp = "p(X) :- q(X), r(X)." + LS + + "s(X) :- p(X), q(X), not r(X)." + LS + + "t(X) :- p(X), not u(X)." + LS + + "u(X) :- p(X), not t(X)." + LS + + ":- p(X), not q(X), not r(X)."; + String expectedGraph = "digraph componentGraph" + LS + + "{" + LS + + "splines=false;" + LS + + "ranksep=4.0;" + LS + + "label = <" + LS + + " " + LS + + " " + LS + + " " + LS + + + "
      Component Id012345
      Predicatesq/1
      r/1
      p/1
      [constr_1]/0
      t/1
      u/1
      s/1
      " + LS + + ">" + LS + + "" + LS + + "n0 [label = C0]" + LS + + "n1 [label = C1]" + LS + + "n2 [label = C2]" + LS + + "n0 -> n2 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n1 -> n2 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n3 [label = C3]" + LS + + "n0 -> n3 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n1 -> n3 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n2 -> n3 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n4 [label = C4]" + LS + + "n2 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n5 [label = C5]" + LS + + "n0 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n2 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + + "}" + LS; + Alpha alpha = new AlphaImpl(); + AnalyzedProgram prog = AnalyzedProgram.analyzeNormalProgram( + alpha.normalizeProgram(alpha.readProgramString(asp))); + ComponentGraph compgraph = prog.getComponentGraph(); + ComponentGraphWriter writer = new ComponentGraphWriter(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + writer.writeAsDot(compgraph, out); + String actualGraph = out.toString(); + System.out.println(actualGraph); + Assert.assertEquals(expectedGraph, actualGraph); + } + +} 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 new file mode 100644 index 000000000..c043eff8c --- /dev/null +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java @@ -0,0 +1,63 @@ +package at.ac.tuwien.kr.alpha.app; + +import java.io.ByteArrayOutputStream; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; + +public class DependencyGraphWriterTest { + private static final String LS = System.lineSeparator(); + + @Test + public void smokeTest() { + // Note: rather than testing correct implementation of dot file format, + // (which would be a lot of work), just test correct dot code generation + // for one dependency graph that has all possible "special" node constellations, + // i.e. positive and negative dependencies, cycle through negation, constraints. + String asp = "p(X) :- q(X), r(X)." + LS + + "s(X) :- p(X), q(X), not r(X)." + LS + + "t(X) :- p(X), not u(X)." + LS + + "u(X) :- p(X), not t(X)." + LS + + ":- p(X), not q(X), not r(X)."; + String expectedGraph = "digraph dependencyGraph" + LS + + "{" + LS + + "splines=false;" + LS + + "ranksep=4.0;" + LS + + "n0 [label = \"r/1\"]" + LS + + "n1 [label = \"q/1\"]" + LS + + "n2 [label = \"t/1\"]" + LS + + "n3 [label = \"s/1\"]" + LS + + "n4 [label = \"u/1\"]" + LS + + "n5 [label = \"[constr_1]/0\"]" + LS + + "n6 [label = \"p/1\"]" + LS + + "n0 -> n6 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n0 -> n3 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n0 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n1 -> n6 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n1 -> n3 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n2 -> n4 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n4 -> n2 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n5 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + + "n6 -> n3 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n6 -> n2 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n6 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + + "n6 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + + "}" + LS; + Alpha alpha = new AlphaImpl(); + AnalyzedProgram prog = AnalyzedProgram.analyzeNormalProgram( + alpha.normalizeProgram(alpha.readProgramString(asp))); + DependencyGraph depgraph = prog.getDependencyGraph(); + DependencyGraphWriter writer = new DependencyGraphWriter(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + writer.writeAsDot(depgraph, out); + String actualGraph = out.toString(); + Assert.assertEquals(expectedGraph, actualGraph); + } + +} 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 new file mode 100644 index 000000000..a3dc9c71f --- /dev/null +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParserTest.java @@ -0,0 +1,175 @@ +/** + * Copyright (c) 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.app.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.function.Consumer; + +import org.apache.commons.cli.ParseException; +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.config.AlphaConfig; + +public class CommandLineParserTest { + + private static final String DEFAULT_COMMAND_LINE = "java -jar Alpha-bundled.jar"; + private static final Consumer DEFAULT_ABORT_ACTION = (msg) -> { }; + + /** + * Tests that a help message is written to the consumer configured in the + * parser. + * + * @throws ParseException shouldn't happen + */ + @Test + public void help() throws ParseException { + StringBuilder bld = new StringBuilder(); + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, (msg) -> bld.append(msg)); + parser.parseCommandLine(new String[] {"-h"}); + assertTrue(!(bld.toString().isEmpty())); + } + + @Test + public void basicUsageWithFile() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig ctx = parser.parseCommandLine(new String[] {"-i", "someFile.asp", "-i", "someOtherFile.asp"}); + assertEquals(Arrays.asList(new String[] {"someFile.asp", "someOtherFile.asp"}), ctx.getInputConfig().getFiles()); + } + + @Test + public void basicUsageWithString() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig ctx = parser.parseCommandLine(new String[] {"-str", "b :- a.", "-str", "c :- a, b."}); + assertEquals(Arrays.asList(new String[] {"b :- a.", "c :- a, b."}), ctx.getInputConfig().getAspStrings()); + } + + @Test(expected = ParseException.class) + public void invalidUsageNoInput() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + parser.parseCommandLine(new String[] {}); + } + + @Test + public void moreThanOneInputSource() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + parser.parseCommandLine(new String[] {"-i", "a.b", "-i", "b.c", "-str", "aString."}); + } + + @Test(expected = ParseException.class) + public void invalidUsageMissingInputFlag() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + parser.parseCommandLine(new String[] {"-i", "a.b", "b.c"}); + } + + @Test + public void numAnswerSets() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig ctx = parser.parseCommandLine(new String[] {"-str", "aString.", "-n", "00435"}); + assertEquals(435, ctx.getInputConfig().getNumAnswerSets()); + } + + @Test(expected = ParseException.class) + public void noInputGiven() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + parser.parseCommandLine(new String[] {}); + } + + @Test + public void replay() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-rc", "\"1,2, 3\""}); + assertEquals(Arrays.asList(1, 2, 3), alphaConfig.getSystemConfig().getReplayChoices()); + } + + @Test(expected = ParseException.class) + public void replayWithNonNumericLiteral() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + parser.parseCommandLine(new String[]{"-str", "aString.", "-rc", "\"1, 2, x\""}); + } + + @Test + public void grounderToleranceConstraints_numeric() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtc", "-1"}); + assertEquals("-1", alphaConfig.getSystemConfig().getGrounderToleranceConstraints()); + } + + @Test + public void grounderToleranceConstraints_string() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtc", "strict"}); + assertEquals("strict", alphaConfig.getSystemConfig().getGrounderToleranceConstraints()); + } + + @Test + public void grounderToleranceRules_numeric() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtr", "1"}); + assertEquals("1", alphaConfig.getSystemConfig().getGrounderToleranceRules()); + } + + @Test + public void grounderToleranceRules_string() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtr", "permissive"}); + assertEquals("permissive", alphaConfig.getSystemConfig().getGrounderToleranceRules()); + } + + @Test + public void noInstanceRemoval() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-acc"}); + 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"}); + Assert.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"}); + Assert.assertFalse(ctx.getSystemConfig().isEvaluateStratifiedPart()); + } + + @Test + public void atomSeparator() throws ParseException { + CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); + AlphaConfig cfg = parser.parseCommandLine(new String[]{"-str", "aString.", "-sep", "some-string"}); + assertEquals("some-string", cfg.getSystemConfig().getAtomSeparator()); + } + +} 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 new file mode 100644 index 000000000..0c5a69b67 --- /dev/null +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java @@ -0,0 +1,99 @@ +package at.ac.tuwien.kr.alpha.app.mappers; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.junit.Assert; +import org.junit.Test; + +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.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; + +public class AnswerSetToWorkbookMapperTest { + + private AnswerSetToWorkbookMapper mapper = new AnswerSetToWorkbookMapper(); + + @Test + public void smokeTest() throws IOException { + AnswerSet as = new AnswerSetBuilder().predicate("bla").instance("blubb", "blubb").instance("foo", "bar").predicate("foo").instance("bar") + .instance("baz").predicate("complex").instance(Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)).build(); + Workbook wb = this.mapper.mapFromAnswerSet(as); + Assert.assertNotNull(wb.getSheet("Flags")); + Assert.assertNotNull(wb.getSheet("bla_2")); + Assert.assertNotNull(wb.getSheet("foo_1")); + Assert.assertNotNull(wb.getSheet("complex_3")); + wb.close(); + } + + @Test + public void solveAndWriteWorkbookTest() { + //@formatter:off + String progstr = "aFlag. oneMoreFlag. yetAnotherFlag. createPs. maxP(5). r(s(1, 2, 3), 4). r(bla, blubb). r(foo, bar(baaz))." + + "p(0) :- createPs. " + + "p(N) :- p(I), N = I + 1, N <= MX, maxP(MX)." + + "q(A, B) :- p(A), p(B)."; + //@formatter:on + Alpha alpha = new AlphaImpl(); + List answerSets = alpha.solve(alpha.readProgramString(progstr, null)).collect(Collectors.toList()); + Assert.assertEquals(1, answerSets.size()); + AnswerSet as = answerSets.get(0); + Workbook answerSetWorkbook = this.mapper.mapFromAnswerSet(as); + AnswerSetToWorkbookMapperTest.assertWorkbookMatchesAnswerSet(answerSetWorkbook, as); + } + + public static void assertWorkbookMatchesAnswerSet(Workbook wb, AnswerSet as) { + for (Predicate pred : as.getPredicates()) { + if (pred.getArity() == 0) { + boolean flagFound = false; + Sheet flagsSheet = wb.getSheet("Flags"); + Assert.assertNotNull(flagsSheet); + for (Row row : flagsSheet) { + if (row.getCell(0).getStringCellValue().equals(pred.getName())) { + flagFound = true; + break; + } + } + Assert.assertTrue("0-arity predicate " + pred.getName() + " not found in workbook!", flagFound); + } else { + Sheet predicateSheet = wb.getSheet(pred.getName() + "_" + pred.getArity()); + for (Atom atom : as.getPredicateInstances(pred)) { + boolean atomFound = false; + Assert.assertNotNull(predicateSheet); + for (Row row : predicateSheet) { + if (AnswerSetToWorkbookMapperTest.rowMatchesAtom(row, atom)) { + atomFound = true; + break; + } + } + Assert.assertTrue("Atom " + atom.toString() + " not found in workbook!", atomFound); + } + } + } + } + + private static boolean rowMatchesAtom(Row row, Atom atom) { + List terms = atom.getTerms(); + Cell cell; + for (int i = 0; i < terms.size(); i++) { + cell = row.getCell(i); + if (cell == null) { + return false; + } + if (!(cell.getStringCellValue().equals(terms.get(i).toString()))) { + return false; + } + } + return true; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index e03befacb..736f6c366 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -39,20 +39,20 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; public class AggregateAtom extends CoreAtom { - private final ComparisonOperator lowerBoundOperator; + private final ComparisonOperatorImpl lowerBoundOperator; private final Term lowerBoundTerm; - private final ComparisonOperator upperBoundOperator; + private final ComparisonOperatorImpl upperBoundOperator; private final Term upperBoundTerm; private final AGGREGATEFUNCTION aggregatefunction; private final List aggregateElements; - public AggregateAtom(ComparisonOperator lowerBoundOperator, Term lowerBoundTerm, ComparisonOperator upperBoundOperator, Term upperBoundTerm, + public AggregateAtom(ComparisonOperatorImpl lowerBoundOperator, Term lowerBoundTerm, ComparisonOperatorImpl upperBoundOperator, Term upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { this.lowerBoundOperator = lowerBoundOperator; this.lowerBoundTerm = lowerBoundTerm; @@ -60,7 +60,7 @@ public AggregateAtom(ComparisonOperator lowerBoundOperator, Term lowerBoundTerm, this.upperBoundTerm = upperBoundTerm; this.aggregatefunction = aggregatefunction; this.aggregateElements = aggregateElements; - if (upperBoundOperator != null || lowerBoundOperator != ComparisonOperator.LE || lowerBoundTerm == null) { + if (upperBoundOperator != null || lowerBoundOperator != ComparisonOperatorImpl.LE || lowerBoundTerm == null) { throw new UnsupportedOperationException("Aggregate construct not yet supported: " + this); } } @@ -164,7 +164,7 @@ public int hashCode() { return result; } - public ComparisonOperator getLowerBoundOperator() { + public ComparisonOperatorImpl getLowerBoundOperator() { return lowerBoundOperator; } @@ -172,7 +172,7 @@ public Term getLowerBoundTerm() { return lowerBoundTerm; } - public ComparisonOperator getUpperBoundOperator() { + public ComparisonOperatorImpl getUpperBoundOperator() { return upperBoundOperator; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index cb1468b2c..74f8d48cb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -6,7 +6,7 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; /** @@ -54,8 +54,8 @@ public Set getNonBindingVariables() { throw new UnsupportedOperationException(); } - private static VariableTerm boundBindingVariable(ComparisonOperator op, Term bound, boolean positive) { - boolean isNormalizedEquality = op == ComparisonOperator.EQ && positive || op == ComparisonOperator.NE && !positive; + private static VariableTerm boundBindingVariable(ComparisonOperatorImpl op, Term bound, boolean positive) { + boolean isNormalizedEquality = op == ComparisonOperatorImpl.EQ && positive || op == ComparisonOperatorImpl.NE && !positive; if (isNormalizedEquality && bound instanceof VariableTermImpl) { return (VariableTermImpl) bound; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java index c29d36267..0a773777c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java @@ -35,7 +35,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** @@ -43,16 +43,16 @@ */ public class ComparisonAtom extends CoreAtom implements VariableNormalizableAtom { private final Predicate predicate; - final ComparisonOperator operator; + final ComparisonOperatorImpl operator; private final List terms; - private ComparisonAtom(List terms, ComparisonOperator operator) { + private ComparisonAtom(List terms, ComparisonOperatorImpl operator) { this.terms = terms; this.operator = operator; this.predicate = operator.predicate(); } - public ComparisonAtom(Term term1, Term term2, ComparisonOperator operator) { + public ComparisonAtom(Term term1, Term term2, ComparisonOperatorImpl operator) { this(Arrays.asList(term1, term2), operator); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index f8e1460cd..48854da29 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; @@ -53,9 +53,9 @@ public class ComparisonLiteral extends FixedInterpretationLiteral { public ComparisonLiteral(ComparisonAtom atom, boolean positive) { super(atom, positive); - final ComparisonOperator operator = getAtom().operator; - isNormalizedEquality = (positive && operator == ComparisonOperator.EQ) - || (!positive && operator == ComparisonOperator.NE); + final ComparisonOperatorImpl operator = getAtom().operator; + isNormalizedEquality = (positive && operator == ComparisonOperatorImpl.EQ) + || (!positive && operator == ComparisonOperatorImpl.NE); } @Override @@ -199,7 +199,7 @@ private Term evaluateTerm(Term term) { private boolean compare(Term x, Term y) { final int comparisonResult = x.compareTo(y); - ComparisonOperator operator = isNegated() ? getAtom().operator.getNegation() : getAtom().operator; + ComparisonOperatorImpl operator = isNegated() ? getAtom().operator.getNegation() : getAtom().operator; switch (operator) { case EQ: return comparisonResult == 0; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperatorImpl.java similarity index 65% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperatorImpl.java index 77bb458ce..5b739d0a5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperatorImpl.java @@ -1,8 +1,10 @@ package at.ac.tuwien.kr.alpha.core.common; +import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.Util; +import at.ac.tuwien.kr.alpha.api.program.Predicate; -public enum ComparisonOperator { +public enum ComparisonOperatorImpl implements ComparisonOperator { EQ("="), NE("!="), LT("<"), @@ -12,7 +14,7 @@ public enum ComparisonOperator { private String asString; - ComparisonOperator(String asString) { + ComparisonOperatorImpl(String asString) { this.asString = asString; } @@ -21,7 +23,7 @@ public String toString() { return asString; } - public ComparisonOperator getNegation() { + public ComparisonOperatorImpl getNegation() { switch (this) { case EQ: return NE; case NE: return EQ; @@ -33,7 +35,7 @@ public ComparisonOperator getNegation() { throw Util.oops("Unknown binary operator encountered, cannot negate it"); } - public CorePredicate predicate() { + public Predicate predicate() { return CorePredicate.getInstance(this.asString, 2); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java index d0439bb31..440a0fa21 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java @@ -76,11 +76,11 @@ public int compareTo(Term o) { public abstract Term normalizeVariables(String renamePrefix, Term.RenameCounter counter); - public static class RenameCounter implements Term.RenameCounter { + public static class RenameCounterImpl implements Term.RenameCounter { int counter; final HashMap renamedVariables; - public RenameCounter(int startingValue) { + public RenameCounterImpl(int startingValue) { counter = startingValue; renamedVariables = new HashMap<>(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java index 79cc47eb6..6ad916486 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java @@ -35,7 +35,7 @@ public static > List> asTermList(T... va public static List renameTerms(List terms, String prefix, int counterStartingValue) { List renamedTerms = new ArrayList<>(terms.size()); - CoreTerm.RenameCounter renameCounter = new CoreTerm.RenameCounter(counterStartingValue); + CoreTerm.RenameCounterImpl renameCounter = new CoreTerm.RenameCounterImpl(counterStartingValue); for (Term term : terms) { renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java index 2814670c2..76f2cd19b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java @@ -49,7 +49,7 @@ public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Substitution { private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); - public static final SubstitutionImpl EMPTY_SUBSTITUTION = new SubstitutionImpl() { + public static final Substitution EMPTY_SUBSTITUTION = new SubstitutionImpl() { @Override public > CoreTerm put(VariableTerm variableTerm, Term groundTerm) { throw Util.oops("Should not be called on EMPTY_SUBSTITUTION"); 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 0ecdcdcfd..8283ed3ba 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 @@ -68,7 +68,7 @@ import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; import at.ac.tuwien.kr.alpha.core.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; @@ -246,9 +246,9 @@ public Head visitHead(ASPCore2Parser.HeadContext ctx) { public Head visitChoice(ASPCore2Parser.ChoiceContext ctx) { // choice : (lt=term lop=binop)? CURLY_OPEN choice_elements? CURLY_CLOSE (uop=binop ut=term)?; Term lt = null; - ComparisonOperator lop = null; + ComparisonOperatorImpl lop = null; Term ut = null; - ComparisonOperator uop = null; + ComparisonOperatorImpl uop = null; if (ctx.lt != null) { lt = (Term) visit(ctx.lt); lop = visitBinop(ctx.lop); @@ -329,9 +329,9 @@ public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { // 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; + ComparisonOperatorImpl lop = null; Term ut = null; - ComparisonOperator uop = null; + ComparisonOperatorImpl uop = null; if (ctx.lt != null) { lt = (CoreTerm) visit(ctx.lt); lop = visitBinop(ctx.lop); @@ -430,20 +430,20 @@ public AggregateAtom.AGGREGATEFUNCTION visitAggregate_function(ASPCore2Parser.Ag } @Override - public ComparisonOperator visitBinop(ASPCore2Parser.BinopContext ctx) { + public ComparisonOperatorImpl visitBinop(ASPCore2Parser.BinopContext ctx) { // binop : EQUAL | UNEQUAL | LESS | GREATER | LESS_OR_EQ | GREATER_OR_EQ; if (ctx.EQUAL() != null) { - return ComparisonOperator.EQ; + return ComparisonOperatorImpl.EQ; } else if (ctx.UNEQUAL() != null) { - return ComparisonOperator.NE; + return ComparisonOperatorImpl.NE; } else if (ctx.LESS() != null) { - return ComparisonOperator.LT; + return ComparisonOperatorImpl.LT; } else if (ctx.LESS_OR_EQ() != null) { - return ComparisonOperator.LE; + return ComparisonOperatorImpl.LE; } else if (ctx.GREATER() != null) { - return ComparisonOperator.GT; + return ComparisonOperatorImpl.GT; } else if (ctx.GREATER_OR_EQ() != null) { - return ComparisonOperator.GE; + return ComparisonOperatorImpl.GE; } else { throw notSupported(ctx); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java index a5e226e35..e0f9987c2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/ChoiceHeadImpl.java @@ -4,11 +4,12 @@ import java.util.List; +import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.core.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; /** * Represents the head of a choice rule. @@ -19,10 +20,10 @@ public class ChoiceHeadImpl implements ChoiceHead { private final List choiceElements; private final Term lowerBound; - private final ComparisonOperator lowerOp; + private final ComparisonOperatorImpl lowerOp; private final Term upperBound; - private final ComparisonOperator upperOp; + private final ComparisonOperatorImpl upperOp; public static class ChoiceElementImpl implements ChoiceElement { public final Atom choiceAtom; @@ -55,10 +56,12 @@ public List getConditionLiterals() { } } + @Override public ComparisonOperator getLowerOperator() { return lowerOp; } + @Override public ComparisonOperator getUpperOperator() { return upperOp; } @@ -78,8 +81,8 @@ public Term getUpperBound() { return upperBound; } - public ChoiceHeadImpl(List choiceElements, Term lowerBound, ComparisonOperator lowerOp, Term upperBound, - ComparisonOperator upperOp) { + public ChoiceHeadImpl(List choiceElements, Term lowerBound, ComparisonOperatorImpl lowerOp, Term upperBound, + ComparisonOperatorImpl upperOp) { this.choiceElements = choiceElements; this.lowerBound = lowerBound; this.lowerOp = lowerOp; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/AnswerSetsParser.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/AnswerSetsParser.java new file mode 100644 index 000000000..ed9426bdb --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/AnswerSetsParser.java @@ -0,0 +1,49 @@ +package at.ac.tuwien.kr.alpha.core.util; + +import java.io.IOException; +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.antlr.ASPCore2Lexer; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.core.parser.ParseTreeVisitor; + +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 (IOException e) { + // In this case we assume that something went fundamentally + // wrong when using a String as input. The caller probably + // assumes that I/O on a String should always be fine. + throw new RuntimeException("Encountered I/O-related exception while parsing a String.", e); + } 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) throws IOException { + 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-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java new file mode 100644 index 000000000..21a3616f9 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019-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; + +import java.util.Collection; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; + +/** + * Provides utility methods for test cases + * + */ +// TODO TestUtil/TestUtils?? Also, TestUtils duplicated +// maybe introduce module "test-support" or smth +public class TestUtil { + + 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] = VariableTermImpl.getInstance(termString); + } else { + terms[i] = CoreConstantTerm.getInstance(termString); + } + } + return new BasicAtom(CorePredicate.getInstance(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] = CoreConstantTerm.getInstance(termInts[i]); + } + return new BasicAtom(CorePredicate.getInstance(predicateName, terms.length), terms); + } + + public static void printNoGoods(AtomStore atomStore, Collection noGoods) { + System.out.println(noGoods.stream().map(atomStore::noGoodToString).collect(Collectors.toSet())); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java new file mode 100644 index 000000000..789658c0c --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java @@ -0,0 +1,226 @@ +/** + * Copyright (c) 2016-2017, 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.antlr; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.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.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.Util; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public class ParserTest { + private final ProgramParserImpl parser = new ProgramParserImpl(); + + @Test + public void parseFact() throws IOException { + ASPCore2Program parsedProgram = parser.parse("p(a,b)."); + + assertEquals("Program contains one fact.", 1, parsedProgram.getFacts().size()); + assertEquals("Predicate name of fact is p.", "p", parsedProgram.getFacts().get(0).getPredicate().getName()); + assertEquals("Fact has two terms.", 2, parsedProgram.getFacts().get(0).getPredicate().getArity()); + assertEquals("First term is a.", "a", (parsedProgram.getFacts().get(0).getTerms().get(0)).toString()); + assertEquals("Second term is b.", "b", (parsedProgram.getFacts().get(0).getTerms().get(1)).toString()); + } + + @Test + public void parseFactWithFunctionTerms() throws IOException { + ASPCore2Program parsedProgram = parser.parse("p(f(a),g(h(Y)))."); + + assertEquals("Program contains one fact.", 1, parsedProgram.getFacts().size()); + assertEquals("Predicate name of fact is p.", "p", parsedProgram.getFacts().get(0).getPredicate().getName()); + assertEquals("Fact has two terms.", 2, parsedProgram.getFacts().get(0).getPredicate().getArity()); + assertEquals("First term is function term f.", "f", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(0)).getSymbol()); + assertEquals("Second term is function term g.", "g", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(1)).getSymbol()); + } + + @Test + public void parseSmallProgram() throws IOException { + ASPCore2Program parsedProgram = parser.parse( + "a :- b, not d." + System.lineSeparator() + + "c(X) :- p(X,a,_), q(Xaa,xaa)." + System.lineSeparator() + + ":- f(Y)."); + + assertEquals("Program contains three rules.", 3, parsedProgram.getRules().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseBadSyntax() throws IOException { + parser.parse("Wrong Syntax."); + } + + @Test + public void parseBuiltinAtom() throws IOException { + ASPCore2Program parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); + assertEquals(1, parsedProgram.getRules().size()); + assertEquals(3, parsedProgram.getRules().get(0).getBody().size()); + } + + @Test(expected = UnsupportedOperationException.class) + // Change expected after Alpha can deal with disjunction. + public void parseProgramWithDisjunctionInHead() throws IOException { + parser.parse("r(X) | q(X) :- q(X)." + System.lineSeparator() + "q(a)." + System.lineSeparator()); + } + + @Test + public void parseInterval() throws IOException { + 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(CoreConstantTerm.getInstance(2), CoreConstantTerm.getInstance(5)))); + IntervalTerm bodyInterval = (IntervalTerm) ((Literal) parsedProgram.getRules().get(0).getBody().stream().findFirst().get()).getTerms().get(1); + assertTrue(bodyInterval.equals(IntervalTerm.getInstance(CoreConstantTerm.getInstance(3), CoreConstantTerm.getInstance("X")))); + } + + @Test + public void parseChoiceRule() throws IOException { + ASPCore2Program 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()); + } + + @Test + public void parseChoiceRuleBounded() throws IOException { + ASPCore2Program 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")); + List conditionalLiterals = choiceHead.getChoiceElements().get(0).getConditionLiterals(); + assertEquals(2, conditionalLiterals.size()); + assertFalse(conditionalLiterals.get(0).isNegated()); + assertTrue(conditionalLiterals.get(1).isNegated()); + assertEquals(CoreConstantTerm.getInstance(1), choiceHead.getLowerBound()); + assertEquals(ComparisonOperatorImpl.LT, choiceHead.getLowerOperator()); + assertEquals(CoreConstantTerm.getInstance(13), choiceHead.getUpperBound()); + assertEquals(ComparisonOperatorImpl.LE, choiceHead.getUpperOperator()); + } + + @Test + public void literate() throws IOException { + final ReadableByteChannel input = Util.streamToChannel(Util.literate(Stream.of( + "This is some description.", + "", + " p(a).", + "", + "Test!"))); + + final String actual = new ProgramParserImpl().parse(CharStreams.fromChannel(input)).toString(); + final String expected = "p(a)." + System.lineSeparator(); + + assertEquals(expected, actual); + } + + @Test(expected = IllegalArgumentException.class) + public void testMalformedInputNotIgnored() { + String program = "foo(a) :- p(b).\n" + + "// rule :- q.\n" + + "r(1).\n" + + "r(2).\n"; + parser.parse(program); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingDotNotIgnored() { + parser.parse("p(X,Y) :- q(X), r(Y) p(a). q(b)."); + } + + @Test + public void parseEnumerationDirective() throws IOException { + ASPCore2Program parsedProgram = parser.parse("p(a,1)." + + "# enumeration_predicate_is mune." + + "r(X) :- p(X), mune(X)." + + "p(b,2)."); + String directive = parsedProgram.getInlineDirectives().getDirectiveValue(InlineDirectives.DIRECTIVE.enum_predicate_is); + assertEquals("mune", directive); + } + + @Test + public void cardinalityAggregate() throws IOException { + ASPCore2Program 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(); + AggregateLiteral parsedAggregate = (AggregateLiteral) bodyElement; + VariableTerm x = VariableTermImpl.getInstance("X"); + VariableTerm y = VariableTermImpl.getInstance("Y"); + VariableTerm z = VariableTermImpl.getInstance("Z"); + List basicTerms = Arrays.asList(x, y, z); + AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, + Collections.singletonList(new BasicAtom(CorePredicate.getInstance("p", 3), x, y, z).toLiteral())); + AggregateAtom expectedAggregate = new AggregateAtom(ComparisonOperatorImpl.LE, VariableTermImpl.getInstance("K"), null, null, + AggregateAtom.AGGREGATEFUNCTION.COUNT, Collections.singletonList(aggregateElement)); + assertEquals(expectedAggregate, parsedAggregate.getAtom()); + } + + @Test + public void stringWithEscapedQuotes() throws IOException { + CharStream stream = CharStreams.fromStream(ParserTest.class.getResourceAsStream("/escaped_quotes.asp")); + ASPCore2Program prog = parser.parse(stream); + Assert.assertEquals(1, prog.getFacts().size()); + Atom stringAtom = prog.getFacts().get(0); + String stringWithQuotes = stringAtom.getTerms().get(0).toString(); + Assert.assertEquals("\"a string with \"quotes\"\"", stringWithQuotes); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java new file mode 100644 index 000000000..cdde34fd1 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java @@ -0,0 +1,105 @@ +package at.ac.tuwien.kr.alpha.api.externals.stdlib; + +import java.util.List; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; + +public class AspStandardLibraryTest { + + @Test + public void parseDateTime1() { + Set>> dtSubstitution = AspStandardLibrary.datetimeParse("20.05.2020 01:19:13", "dd.MM.yyyy HH:mm:ss"); + Assert.assertEquals(1, dtSubstitution.size()); + List> dtTerms = dtSubstitution.stream().findFirst().get(); + Assert.assertEquals(6, dtTerms.size()); + Assert.assertEquals(CoreConstantTerm.getInstance(2020), dtTerms.get(0)); + Assert.assertEquals(CoreConstantTerm.getInstance(5), dtTerms.get(1)); + Assert.assertEquals(CoreConstantTerm.getInstance(20), dtTerms.get(2)); + Assert.assertEquals(CoreConstantTerm.getInstance(1), dtTerms.get(3)); + Assert.assertEquals(CoreConstantTerm.getInstance(19), dtTerms.get(4)); + Assert.assertEquals(CoreConstantTerm.getInstance(13), dtTerms.get(5)); + } + + @Test + public void parseDateTime2() { + Set>> dtSubstitution = AspStandardLibrary.datetimeParse("07/2123/18 22/37/01", "MM/yyyy/dd HH/mm/ss"); + Assert.assertEquals(1, dtSubstitution.size()); + List> dtTerms = dtSubstitution.stream().findFirst().get(); + Assert.assertEquals(6, dtTerms.size()); + Assert.assertEquals(CoreConstantTerm.getInstance(2123), dtTerms.get(0)); + Assert.assertEquals(CoreConstantTerm.getInstance(7), dtTerms.get(1)); + Assert.assertEquals(CoreConstantTerm.getInstance(18), dtTerms.get(2)); + Assert.assertEquals(CoreConstantTerm.getInstance(22), dtTerms.get(3)); + Assert.assertEquals(CoreConstantTerm.getInstance(37), dtTerms.get(4)); + Assert.assertEquals(CoreConstantTerm.getInstance(1), dtTerms.get(5)); + } + + @Test + public void parseDateTime3() { + Set>> dtSubstitution = AspStandardLibrary.datetimeParse("\"03,12,2019\", \"11:00:00\"", + "\"dd,MM,yyyy\", \"HH:mm:ss\""); + Assert.assertEquals(1, dtSubstitution.size()); + List> dtTerms = dtSubstitution.stream().findFirst().get(); + Assert.assertEquals(6, dtTerms.size()); + Assert.assertEquals(CoreConstantTerm.getInstance(2019), dtTerms.get(0)); + Assert.assertEquals(CoreConstantTerm.getInstance(12), dtTerms.get(1)); + Assert.assertEquals(CoreConstantTerm.getInstance(3), dtTerms.get(2)); + Assert.assertEquals(CoreConstantTerm.getInstance(11), dtTerms.get(3)); + Assert.assertEquals(CoreConstantTerm.getInstance(0), dtTerms.get(4)); + Assert.assertEquals(CoreConstantTerm.getInstance(0), dtTerms.get(5)); + } + + @Test + public void datetimeBefore() { + Assert.assertTrue(AspStandardLibrary.datetimeIsBefore(1990, 2, 14, 15, 16, 17, 1990, 3, 1, 0, 59, 1)); + Assert.assertFalse(AspStandardLibrary.datetimeIsBefore(2015, 5, 13, 12, 1, 33, 2003, 1, 1, 0, 0, 1)); + Assert.assertFalse(AspStandardLibrary.datetimeIsBefore(2022, 2, 22, 22, 22, 22, 2022, 2, 22, 22, 22, 22)); + } + + @Test + public void datetimeEqual() { + Assert.assertTrue(AspStandardLibrary.datetimeIsEqual(1990, 2, 14, 15, 16, 17, 1990, 2, 14, 15, 16, 17)); + Assert.assertFalse(AspStandardLibrary.datetimeIsEqual(2015, 5, 13, 12, 1, 33, 2003, 1, 1, 0, 0, 1)); + } + + @Test + public void datetimeBeforeOrEqual() { + Assert.assertTrue(AspStandardLibrary.datetimeIsBeforeOrEqual(1990, 2, 14, 15, 16, 17, 1990, 3, 1, 0, 59, 1)); + Assert.assertFalse(AspStandardLibrary.datetimeIsBeforeOrEqual(2015, 5, 13, 12, 1, 33, 2003, 1, 1, 0, 0, 1)); + Assert.assertTrue(AspStandardLibrary.datetimeIsBeforeOrEqual(2022, 2, 22, 22, 22, 22, 2022, 2, 22, 22, 22, 22)); + + } + + @Test + public void matchesRegex() { + Assert.assertTrue(AspStandardLibrary.stringMatchesRegex("Blaaaaa Blubbb!!", "Bla+ Blub+!!")); + Assert.assertFalse(AspStandardLibrary.stringMatchesRegex("Foobar", "Bla+ Blub+!!")); + } + + @Test + public void stringLength() { + Set>> result = AspStandardLibrary.stringLength("A String of length 21"); + Assert.assertEquals(1, result.size()); + List> lengthTerms = result.stream().findFirst().get(); + Assert.assertEquals(1, lengthTerms.size()); + ConstantTerm lenTerm = lengthTerms.get(0); + Assert.assertEquals(CoreConstantTerm.getInstance(21), lenTerm); + } + + @Test + public void stringConcat() { + Set>> result = AspStandardLibrary.stringConcat("Foo", "bar"); + Assert.assertEquals(1, result.size()); + List> concatTerms = result.stream().findFirst().get(); + Assert.assertEquals(1, concatTerms.size()); + ConstantTerm concat = concatTerms.get(0); + Assert.assertEquals(CoreConstantTerm.getInstance("Foobar"), concat); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java new file mode 100644 index 000000000..92cb6dfbf --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java @@ -0,0 +1,21 @@ +package at.ac.tuwien.kr.alpha.common; + +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; + +/** + * Copyright (c) 2018, the Alpha Team. + */ +// TODO (what is this? where is this used?) +public class AtomStoreTest { + + public static void fillAtomStore(AtomStore atomStore, int numberOfAtomsToFill) { + Predicate predA = CorePredicate.getInstance("a", 1); + for (int i = 0; i < numberOfAtomsToFill; i++) { + atomStore.putIfAbsent(new BasicAtom(predA, CoreConstantTerm.getInstance(i))); + } + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java new file mode 100644 index 000000000..80f27f8fb --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java @@ -0,0 +1,88 @@ +package at.ac.tuwien.kr.alpha.common; + +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public class BasicAnswerSetTest { + @Test + public void areAnswerSetsEqual() throws Exception { + Predicate a = CorePredicate.getInstance("a", 0); + Predicate foo = CorePredicate.getInstance("foo", 1); + SortedSet fooAndA = new TreeSet<>(asList(foo, a)); + + Predicate q = CorePredicate.getInstance("q", 0); + Predicate p = CorePredicate.getInstance("p", 1); + SortedSet qAndP = new TreeSet<>(asList(q, p)); + + ConstantTerm bar = CoreConstantTerm.getInstance("bar"); + ConstantTerm baz = CoreConstantTerm.getInstance("baz"); + + Map> inst1 = new HashMap<>(); + inst1.put(a, new TreeSet<>(singleton(new BasicAtom(a)))); + inst1.put(foo, new TreeSet<>(asList( + new BasicAtom(foo, bar), + new BasicAtom(foo, baz) + ))); + // as1 = { a, foo(bar), foo(baz) } + + Map> inst2 = new HashMap<>(); + inst2.put(a, new TreeSet<>(singleton(new BasicAtom(a)))); + inst2.put(foo, new TreeSet<>(asList( + new BasicAtom(foo, baz), + new BasicAtom(foo, bar) + ))); + // as1 = { a, foo(baz), foo(bar) } + + Map> inst3 = new HashMap<>(); + inst3.put(q, new TreeSet<>(singleton(new BasicAtom(q)))); + inst3.put(p, new TreeSet<>(asList( + new BasicAtom(p, bar), + new BasicAtom(p, baz) + ))); + // as3 = { q, p(bar), p(baz) } + + Map> inst4 = new HashMap<>(); + inst4.put(a, new TreeSet<>(singleton(new BasicAtom(a)))); + inst4.put(foo, new TreeSet<>(asList( + new BasicAtom(foo, bar), + new BasicAtom(foo, baz), + new BasicAtom(foo, CoreConstantTerm.getInstance("batsinga")) + ))); + // as4 = { a, foo(bar), foo(baz), foo(batsinga) } + + final List answerSets = asList( + new BasicAnswerSet(fooAndA, inst1), + new BasicAnswerSet(fooAndA, inst2), + new BasicAnswerSet(qAndP, inst3), + new BasicAnswerSet(fooAndA, inst4) + ); + + assertEquals(answerSets.get(0), answerSets.get(1)); + assertEquals(answerSets.get(1), answerSets.get(0)); + + assertNotEquals(answerSets.get(0), answerSets.get(2)); + assertNotEquals(answerSets.get(0), answerSets.get(3)); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java new file mode 100644 index 000000000..c5654c846 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java @@ -0,0 +1,112 @@ +package at.ac.tuwien.kr.alpha.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.core.common.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; + +public class NoGoodTest { + /** + * Constructs an array of literals with the new representation (least-significant bit is polarity, other bits + * are atom id) from an array of literals from the old representation (positive literal is atom id, negative + * literal is negated atom id). + * @param literals + * @return + */ + public static int[] fromOldLiterals(int... literals) { + int[] newLiterals = new int[literals.length]; + for (int i = 0; i < literals.length; i++) { + newLiterals[i] = literals[i] >= 0 ? Literals.atomToLiteral(literals[i]) : Literals.atomToNegatedLiteral(-literals[i]); + } + return newLiterals; + } + + public static int fromOldLiterals(int literal) { + return literal >= 0 ? Literals.atomToLiteral(literal) : Literals.atomToNegatedLiteral(-literal); + } + + @Test + public void iteration() throws Exception { + Iterator i = new NoGood(1).iterator(); + assertEquals(1, (int)i.next()); + assertFalse(i.hasNext()); + } + + @Test(expected = NullPointerException.class) + public void compareToNull() throws Exception { + new NoGood().compareTo(null); + } + + @Test + public void compareToSame() throws Exception { + assertEquals(0, new NoGood(1).compareTo(new NoGood(1))); + } + + @Test + public void compareToLengthShort() throws Exception { + assertEquals(-1, new NoGood(1).compareTo(new NoGood(1, 2))); + } + + @Test + public void compareToLengthLong() throws Exception { + assertEquals(+1, new NoGood(1, 2).compareTo(new NoGood(1))); + } + + @Test + public void compareToLexicographicSmall() throws Exception { + assertEquals(-1, new NoGood(1, 2).compareTo(new NoGood(2, 3))); + } + + @Test + public void compareToLexicographicBig() throws Exception { + assertEquals(+1, new NoGood(2, 3).compareTo(new NoGood(1, 2))); + } + + @Test + public void deleteDuplicates() { + NoGood ng = NoGood.headFirst(fromOldLiterals(-3, 1, -2, -2)); + assertEquals("Duplicate entry must be removed.", 3, ng.size()); + assertEquals(fromOldLiterals(-3), ng.getLiteral(0)); + assertEquals(fromOldLiterals(1), ng.getLiteral(1)); + assertEquals(fromOldLiterals(-2), ng.getLiteral(2)); + + NoGood ng2 = NoGood.headFirst(fromOldLiterals(-2, 3, 3, -6, -1, 5, 5, -6, 7)); + assertEquals("Duplicate entries must be removed.", 6, ng2.size()); + assertEquals(fromOldLiterals(-2), ng2.getLiteral(0)); + assertEquals(fromOldLiterals(-1), ng2.getLiteral(1)); + assertEquals(fromOldLiterals(3), ng2.getLiteral(2)); + assertEquals(fromOldLiterals(5), ng2.getLiteral(3)); + assertEquals(fromOldLiterals(-6), ng2.getLiteral(4)); + assertEquals(fromOldLiterals(7), ng2.getLiteral(5)); + + NoGood ng3 = NoGood.headFirst(fromOldLiterals(-1, 2, -3, -4)); + assertEquals("NoGood contains no duplicates, size must stay the same.", 4, ng3.size()); + assertEquals(fromOldLiterals(-1), ng3.getLiteral(0)); + assertEquals(fromOldLiterals(2), ng3.getLiteral(1)); + assertEquals(fromOldLiterals(-3), ng3.getLiteral(2)); + assertEquals(fromOldLiterals(-4), ng3.getLiteral(3)); + + } + + @Test + public void noGoodsInHashMap() { + NoGood ng1 = NoGood.headFirst(-1, 2, -3, -4); + NoGood ng2 = NoGood.headFirst(-1, 2, -4); + NoGood ng3 = NoGood.headFirst(-1, 2, -3, -4); + Map noGoodIdentifiers = new LinkedHashMap<>(); + noGoodIdentifiers.put(ng1, 1); + noGoodIdentifiers.put(ng1, 2); + noGoodIdentifiers.put(ng2, 4); + assertTrue(noGoodIdentifiers.containsKey(ng3)); + noGoodIdentifiers.put(ng3, 5); + assertEquals(2, noGoodIdentifiers.size()); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java new file mode 100644 index 000000000..886947876 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2017 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.common; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; + +public class ProgramTest { + + @Test + public void testToString() { + ASPCore2Program 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(), + parsedProgram.toString()); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java new file mode 100644 index 000000000..9e2da1271 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java @@ -0,0 +1,53 @@ +package at.ac.tuwien.kr.alpha.common; + +import static org.junit.Assert.assertEquals; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.NormalRule; + +/** + * Copyright (c) 2018, 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(NormalRule.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(NormalRule.fromBasicRule(expectedRenamedRule)); + assertEquals(expectedRenamedNormalRule.toString(), renamedRule.toString()); + } + + @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); + Assert.assertTrue(r1.equals(r2)); + Assert.assertTrue(r2.equals(r1)); + Assert.assertTrue(r1.hashCode() == r2.hashCode()); + Assert.assertFalse(r1.equals(r3)); + Assert.assertFalse(r3.equals(r1)); + Assert.assertTrue(r1.hashCode() != r3.hashCode()); + Assert.assertFalse(r2.equals(r3)); + Assert.assertFalse(r3.equals(r2)); + Assert.assertTrue(r2.hashCode() != r3.hashCode()); + } + +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatterTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatterTest.java new file mode 100644 index 000000000..ca008e8f5 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/SimpleAnswerSetFormatterTest.java @@ -0,0 +1,21 @@ +package at.ac.tuwien.kr.alpha.common; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetFormatter; +import at.ac.tuwien.kr.alpha.core.common.SimpleAnswerSetFormatter; + +public class SimpleAnswerSetFormatterTest { + + @Test + public void basicFormatterWithSeparator() { + AnswerSetFormatter fmt = new SimpleAnswerSetFormatter(" bla "); + AnswerSet as = new AnswerSetBuilder().predicate("p").instance("a").predicate("q").instance("b").build(); + String formatted = fmt.format(as); + Assert.assertEquals("{ p(\"a\") bla q(\"b\") }", formatted); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java new file mode 100644 index 000000000..380fb1995 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java @@ -0,0 +1,95 @@ +package at.ac.tuwien.kr.alpha.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; + +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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public class TermTest { + + @Test + public void testTermReferenceEquality() { + // Terms must have a unique representation so that reference comparison is + // sufficient to check + // whether two terms are equal. + ConstantTerm ta1 = CoreConstantTerm.getInstance("a"); + ConstantTerm ta2 = CoreConstantTerm.getInstance("a"); + assertTrue("Two instances of ConstantTerms for the same term symbol must be the same object", ta1 == ta2); + + List termList = new LinkedList<>(); + termList.add(ta1); + termList.add(ta2); + FunctionTerm ft1 = FunctionTerm.getInstance("f", termList); + List termList2 = new LinkedList<>(); + termList2.add(ta1); + termList2.add(ta2); + FunctionTerm ft2 = FunctionTerm.getInstance("f", termList2); + assertTrue("Two instances of FunctionTerms for the same term symbol and equal term lists must be the same object", ft1 == ft2); + } + + @Test + public void testTermVariableOccurrences() { + ConstantTerm ta = CoreConstantTerm.getInstance("a"); + VariableTerm tx = VariableTermImpl.getInstance("X"); + FunctionTerm tf = FunctionTerm.getInstance("f", ta, tx); + Set occurringVariables = tf.getOccurringVariables(); + + assertEquals("Variable occurring as subterm must be reported as occurring variable.", new ArrayList<>(occurringVariables).get(0), tx); + } + + @Test + public void testTermOrdering() throws Exception { + Term cts = CoreConstantTerm.getInstance("abc"); + Term cti = CoreConstantTerm.getInstance(2); + Term cto = CoreConstantTerm.getInstance(new UUID(0, 0)); + Term ft = FunctionTerm.getInstance("f", CoreConstantTerm.getInstance("a")); + + assertTrue(cts.compareTo(cti) > 0); + assertTrue(cti.compareTo(cts) < 0); + + assertTrue(cts.compareTo(cto) < 0); + assertTrue(cto.compareTo(cts) > 0); + + assertTrue(cts.compareTo(ft) < 0); + assertTrue(ft.compareTo(cts) > 0); + + assertTrue(cto.compareTo(ft) < 0); + assertTrue(ft.compareTo(cto) > 0); + } + + @Test + public void testStringVsConstantSymbolEquality() { + String theString = "string"; + ConstantTerm stringConstant = CoreConstantTerm.getInstance(theString); + ConstantTerm constantSymbol = CoreConstantTerm.getSymbolicInstance(theString); + // Reference equality must hold for both the string constant and the constant + // symbol. + Assert.assertTrue(stringConstant == CoreConstantTerm.getInstance(theString)); + ConstantTerm sameConstantSymbol = CoreConstantTerm.getSymbolicInstance(theString); + Assert.assertTrue(constantSymbol == sameConstantSymbol); + // Make sure both hashCode and equals understand that stringConstant and + // constantSymbol are NOT the same thing! + Assert.assertNotEquals(stringConstant.hashCode(), constantSymbol.hashCode()); + Assert.assertNotEquals(stringConstant, constantSymbol); + // This also applies to compareTo - it must behave in sync with equals and + // hashCode, i.e. return a non-zero result for non-equal objects + Assert.assertNotEquals(0, stringConstant.compareTo(constantSymbol)); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java new file mode 100644 index 000000000..b861d8e6d --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java @@ -0,0 +1,144 @@ +package at.ac.tuwien.kr.alpha.common.atoms; + +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.Assert; +import org.junit.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.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +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; + + public AtomsTest() throws NoSuchMethodException, SecurityException { + Map 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(externals); + } + + @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(CoreConstantTerm.getSymbolicInstance(Integer.toString(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); + Assert.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); + Assert.assertEquals(a3, a4); + ASPCore2Program p3 = parser.parse("foo(BAR). foo(BAR)."); + Atom a5 = p3.getFacts().get(0); + Atom a6 = p3.getFacts().get(1); + Assert.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); + Assert.assertEquals(a7, a8); + + Assert.assertFalse(a1.equals(a3)); + Assert.assertFalse(a3.equals(a1)); + Assert.assertFalse(a1.equals(a5)); + Assert.assertFalse(a5.equals(a1)); + Assert.assertFalse(a1.equals(a7)); + Assert.assertFalse(a7.equals(a1)); + } + + @Test + public void testIsExternalAtomGround() { + ASPCore2Program p1 = parser.parse("a :- &isFoo[1]."); + Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); + assertExternalAtomGround(ext1, true); + ASPCore2Program p2 = parser.parse("a :- &isFoo[bar(1)]."); + Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); + assertExternalAtomGround(ext2, true); + ASPCore2Program p3 = parser.parse("a :- &isFoo[BLA]."); + 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]."); + Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); + ASPCore2Program p2 = parser.parse("a :- &isFoo[1]."); + Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); + Assert.assertEquals(ext1, ext2); + Assert.assertEquals(ext2, ext1); + + Assert.assertFalse(ext1.equals(null)); + Assert.assertFalse(ext1.equals("bla")); + Assert.assertTrue(ext1.hashCode() == ext2.hashCode()); + } + + @Test + public void testExternalHasOutput() { + ASPCore2Program p = parser.parse("a:- &extWithOutput[1](OUT)."); + Atom ext = p.getRules().get(0).getBody().stream().findFirst().get().getAtom(); + assertExternalAtomGround(ext, false); + Assert.assertTrue(((ExternalAtom) ext).hasOutput()); + } + + private void assertBasicAtomGround(Atom a, boolean expectedGround) { + Assert.assertTrue(a instanceof BasicAtom); + Assert.assertEquals(expectedGround, a.isGround()); + } + + private void assertExternalAtomGround(Atom a, boolean expectedGround) { + Assert.assertTrue(a instanceof ExternalAtom); + Assert.assertEquals(expectedGround, a.isGround()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java new file mode 100644 index 000000000..464eafca6 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java @@ -0,0 +1,207 @@ +/** + * 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.common.atoms; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; +import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.IntPredicateInterpretation; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; + +/** + * Tests the behaviour of {@link Literal#getBindingVariables()} and {@link Literal#getNonBindingVariables()} + * on classes implementing {@link Atom}. + * + */ +public class LiteralBindingNonBindingVariablesTest { + + private final Map externals = new HashMap<>(); + private final ProgramParser parser = new ProgramParserImpl(externals); + + @Test + public void testPositiveBasicLiteral() { + Literal literal = parser.parse("p(X,Y) :- q(X,Y).").getRules().get(0).getBody().stream().findFirst().get(); + assertEquals(false, literal.isNegated()); + expectVariables(literal.getBindingVariables(), "X", "Y"); + expectVariables(literal.getNonBindingVariables()); + } + + @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(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "X", "Y"); + } + + @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() == ComparisonOperatorImpl.EQ.predicate()).findFirst().get(); + assertEquals(false, literal.isNegated()); + expectVariables(literal.getBindingVariables(), "Y"); + expectVariables(literal.getNonBindingVariables()); + } + + @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(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "Y"); + } + + @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() == ComparisonOperatorImpl.EQ.predicate()).findFirst().get(); + assertEquals(false, literal.isNegated()); + expectVariables(literal.getBindingVariables(), "Y"); + expectVariables(literal.getNonBindingVariables()); + } + + @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(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "Y"); + } + + @Test + @Ignore("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() == ComparisonOperatorImpl.EQ.predicate()).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(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "X", "Y"); + } + + @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() == ComparisonOperatorImpl.NE.predicate()).findFirst().get(); + assertEquals(false, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "Y"); + } + + @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(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables(), "Y"); + expectVariables(literal.getNonBindingVariables()); + } + + @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() == ComparisonOperatorImpl.NE.predicate()).findFirst().get(); + assertEquals(false, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "Y"); + } + + @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(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables(), "Y"); + expectVariables(literal.getNonBindingVariables()); + } + + @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() == ComparisonOperatorImpl.NE.predicate()).findFirst().get(); + assertEquals(false, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "X", "Y"); + } + + @Test + @Ignore("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(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables(), "X", "Y"); + expectVariables(literal.getNonBindingVariables()); + } + + @Test + public void testPositiveExternalLiteral() { + externals.put("ext", new IntPredicateInterpretation(i -> i > 0)); + Rule rule = parser.parse("p(X) :- q(Y), &ext[Y](X).").getRules().get(0); + Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate().getName().equals("ext")).findFirst().get(); + assertEquals(false, literal.isNegated()); + expectVariables(literal.getBindingVariables(), "X"); + expectVariables(literal.getNonBindingVariables(), "Y"); + } + + @Test + public void testNegativeExternalLiteral() { + externals.put("ext", new IntPredicateInterpretation(i -> i > 0)); + Literal literal = parser.parse("p(X) :- q(Y), not &ext[Y](X).").getRules().get(0).getNegativeBody().stream().findFirst().get(); + assertEquals(true, literal.isNegated()); + expectVariables(literal.getBindingVariables()); + expectVariables(literal.getNonBindingVariables(), "X", "Y"); + } + + private void expectVariables(Collection variables, String... expectedVariableNames) { + Set setActualVariableNames = variables.stream().map(VariableTerm::toString).collect(Collectors.toSet()); + Set setExpectedVariableNames = Arrays.stream(expectedVariableNames).collect(Collectors.toSet()); + assertEquals(setExpectedVariableNames, setActualVariableNames); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java new file mode 100644 index 000000000..ba36bbde1 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.kr.alpha.common.terms; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.Terms; + +public class TermsTest { + + @Test + public void integersAsTermList() { + List> intTerms = Terms.asTermList(1, 2, 3, 4, 5, 6); + Assert.assertEquals(6, intTerms.size()); + Assert.assertEquals(CoreConstantTerm.getInstance(1), intTerms.get(0)); + Assert.assertEquals(CoreConstantTerm.getInstance(2), intTerms.get(1)); + Assert.assertEquals(CoreConstantTerm.getInstance(3), intTerms.get(2)); + Assert.assertEquals(CoreConstantTerm.getInstance(4), intTerms.get(3)); + Assert.assertEquals(CoreConstantTerm.getInstance(5), intTerms.get(4)); + Assert.assertEquals(CoreConstantTerm.getInstance(6), intTerms.get(5)); + } + + @Test + public void stringsAsTermList() { + List> terms = Terms.asTermList("bla", "blubb"); + Assert.assertEquals(2, terms.size()); + Assert.assertEquals("\"bla\"", terms.get(0).toString()); + Assert.assertEquals("\"blubb\"", terms.get(1).toString()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java new file mode 100644 index 000000000..f3ac4b9ad --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2019 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.common.terms; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.Term.RenameCounter; +import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm.MinusTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm.RenameCounterImpl; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; + +/** + * Tests {@link MinusTerm} + */ +public class TestMinusTerm { + + private final String renamePrefix = "Renamed"; + private final RenameCounter counter = new RenameCounterImpl(0); + + @Test + public void testNormalizeVariablesNoVariable() { + Term m2 = MinusTerm.getInstance(CoreConstantTerm.getInstance(2)); + assertEquals(m2, m2.normalizeVariables(renamePrefix, counter)); + } + + @Test + public void testNormalizeVariablesWithVariable() { + Term mX = MinusTerm.getInstance(VariableTermImpl.getInstance("X")); + Term expected = MinusTerm.getInstance(VariableTermImpl.getInstance(renamePrefix + 0)); + assertEquals(expected, mX.normalizeVariables(renamePrefix, counter)); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java new file mode 100644 index 000000000..303c45bd5 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java @@ -0,0 +1,269 @@ +package at.ac.tuwien.kr.alpha.core.depgraph; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +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.NormalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.test.util.DependencyGraphUtils; + +public class DependencyGraphTest { + + private ProgramParser parser = new ProgramParserImpl(); + private NormalizeProgramTransformation normalizeTransform = new NormalizeProgramTransformation(false); + + // 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 = CorePredicate.getInstance("test", 2, false, false); + Edge e1 = new Edge(new Node(testPredicate), true); + Edge e2 = new Edge(new Node(testPredicate), true); + Assert.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(CorePredicate.getInstance("a", 0)); + Node b = dg.getNodeForPredicate(CorePredicate.getInstance("b", 0)); + + Node nonExistent = new Node(CorePredicate.getInstance("notHere", 0)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); + Assert.assertFalse(DependencyGraphUtils.isReachableFrom(a, b, dg)); + Assert.assertFalse(DependencyGraphUtils.isReachableFrom(nonExistent, a, dg)); + Assert.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(CorePredicate.getInstance("a", 0)); + Node b = dg.getNodeForPredicate(CorePredicate.getInstance("b", 0)); + Node c = dg.getNodeForPredicate(CorePredicate.getInstance("c", 0)); + Node d = dg.getNodeForPredicate(CorePredicate.getInstance("d", 0)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, a, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, a, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, b, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, b, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, b, dg)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, c, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, c, dg)); + + Assert.assertFalse(DependencyGraphUtils.isReachableFrom(a, d, dg)); + Assert.assertFalse(DependencyGraphUtils.isReachableFrom(a, c, dg)); + Assert.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(CorePredicate.getInstance("a", 0)); + Node b = dg.getNodeForPredicate(CorePredicate.getInstance("b", 0)); + Node c = dg.getNodeForPredicate(CorePredicate.getInstance("c", 0)); + Node d = dg.getNodeForPredicate(CorePredicate.getInstance("d", 0)); + Node f1 = dg.getNodeForPredicate(CorePredicate.getInstance("f1", 0)); + Node x = dg.getNodeForPredicate(CorePredicate.getInstance("x", 0)); + Node notInGraph = new Node(CorePredicate.getInstance("notInGraph", 0)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, a, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, a, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, b, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, b, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, b, dg)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, c, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, c, dg)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, d, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, c, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, b, dg)); + + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(x, f1, dg)); + Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, f1, dg)); + + Assert.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(), null); + NormalProgram normalProg = normalizeTransform.apply(prog); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); + DependencyGraph dg = analyzed.getDependencyGraph(); + Node a = dg.getNodeForPredicate(CorePredicate.getInstance("a", 0)); + Node b = dg.getNodeForPredicate(CorePredicate.getInstance("b", 0)); + + List componentA = new ArrayList<>(); + componentA.add(a); + Assert.assertTrue(DependencyGraphUtils.areStronglyConnected(componentA, dg)); + Assert.assertFalse(DependencyGraphUtils.isStronglyConnectedComponent(componentA, dg)); + + List componentB = new ArrayList<>(); + componentB.add(b); + Assert.assertTrue(DependencyGraphUtils.areStronglyConnected(componentB, dg)); + Assert.assertFalse(DependencyGraphUtils.isStronglyConnectedComponent(componentB, dg)); + + List componentAll = new ArrayList<>(); + componentAll.add(a); + componentAll.add(b); + Assert.assertTrue(DependencyGraphUtils.areStronglyConnected(componentAll, dg)); + Assert.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(CorePredicate.getInstance("f0", 0)); + Node f1 = dg.getNodeForPredicate(CorePredicate.getInstance("f1", 0)); + Node f2 = dg.getNodeForPredicate(CorePredicate.getInstance("f2", 0)); + Node f3 = dg.getNodeForPredicate(CorePredicate.getInstance("f3", 0)); + Node a = dg.getNodeForPredicate(CorePredicate.getInstance("a", 0)); + Node b = dg.getNodeForPredicate(CorePredicate.getInstance("b", 0)); + Node c = dg.getNodeForPredicate(CorePredicate.getInstance("c", 0)); + Node d = dg.getNodeForPredicate(CorePredicate.getInstance("d", 0)); + Node x = dg.getNodeForPredicate(CorePredicate.getInstance("x", 0)); + Node y = dg.getNodeForPredicate(CorePredicate.getInstance("y", 0)); + Node z = dg.getNodeForPredicate(CorePredicate.getInstance("z", 0)); + + StronglyConnectedComponentsAlgorithm.SccResult sccResult = StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg); + Map nodesByComponent = sccResult.nodesByComponentId; + List> stronglyConnectedComponents = sccResult.stronglyConnectedComponents; + Assert.assertEquals(8, stronglyConnectedComponents.size()); + + for (int i = 0; i < stronglyConnectedComponents.size(); i++) { + List stronglyConnectedComponent = stronglyConnectedComponents.get(i); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(stronglyConnectedComponent, dg)); + for (Node node : stronglyConnectedComponent) { + Assert.assertEquals(Integer.valueOf(i), nodesByComponent.get(node)); + } + } + + List c1 = new ArrayList<>(); + c1.add(a); + c1.add(b); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c1, dg)); + Assert.assertEquals(nodesByComponent.get(a), nodesByComponent.get(b)); + + List c2 = new ArrayList<>(); + c2.add(c); + c2.add(d); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c2, dg)); + Assert.assertEquals(nodesByComponent.get(c), nodesByComponent.get(d)); + + List c3 = new ArrayList<>(); + c3.add(x); + c3.add(y); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c3, dg)); + Assert.assertEquals(nodesByComponent.get(x), nodesByComponent.get(y)); + + List c4 = new ArrayList<>(); + c4.add(z); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c4, dg)); + + List c5 = new ArrayList<>(); + c5.add(f0); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c5, dg)); + + List c6 = new ArrayList<>(); + c6.add(f1); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c6, dg)); + + List c7 = new ArrayList<>(); + c7.add(f2); + Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c7, dg)); + + List c8 = new ArrayList<>(); + c8.add(f3); + Assert.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 new file mode 100644 index 000000000..709c5b904 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/StratificationAlgorithmTest.java @@ -0,0 +1,239 @@ +package at.ac.tuwien.kr.alpha.core.depgraph; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.depgraph.ComponentGraph.SCComponent; +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.NormalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; + +public class StratificationAlgorithmTest { + + private ProgramParser parser = new ProgramParserImpl(); + private NormalizeProgramTransformation normalizeTransform = new NormalizeProgramTransformation(false); + + 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.", null); + NormalProgram normalProg = normalizeTransform.apply(prog); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); + DependencyGraph dg = analyzed.getDependencyGraph(); + ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); + List strata = StratificationAlgorithm.calculateStratification(cg); + + Predicate a = CorePredicate.getInstance("a", 0); + Predicate b = CorePredicate.getInstance("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 = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); + List strata = StratificationAlgorithm.calculateStratification(cg); + + Predicate a = CorePredicate.getInstance("a", 0); + Predicate b = CorePredicate.getInstance("b", 0); + Predicate c = CorePredicate.getInstance("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() throws IOException { + 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 = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); + List strata = StratificationAlgorithm.calculateStratification(cg); + + Predicate a = CorePredicate.getInstance("a", 0); + Predicate b = CorePredicate.getInstance("b", 0); + Predicate c = CorePredicate.getInstance("c", 0); + Predicate d = CorePredicate.getInstance("d", 0); + Predicate e = CorePredicate.getInstance("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 = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); + List strata = StratificationAlgorithm.calculateStratification(cg); + + Predicate ancestorOf = CorePredicate.getInstance("ancestor_of", 2); + Predicate parentOf = CorePredicate.getInstance("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 = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); + List strata = StratificationAlgorithm.calculateStratification(cg); + + Predicate a = CorePredicate.getInstance("a", 0); + Predicate b = CorePredicate.getInstance("b", 0); + Predicate c = CorePredicate.getInstance("c", 0); + Predicate d = CorePredicate.getInstance("d", 0); + Predicate e = CorePredicate.getInstance("e", 0); + Predicate f = CorePredicate.getInstance("f", 0); + Predicate h = CorePredicate.getInstance("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 = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); + List strata = StratificationAlgorithm.calculateStratification(cg); + + Predicate a = CorePredicate.getInstance("a", 0); + Predicate b = CorePredicate.getInstance("b", 0); + Predicate c = CorePredicate.getInstance("c", 0); + Predicate d = CorePredicate.getInstance("d", 0); + Predicate e = CorePredicate.getInstance("e", 0); + Predicate f = CorePredicate.getInstance("f", 0); + Predicate h = CorePredicate.getInstance("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 = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); + List strata = StratificationAlgorithm.calculateStratification(cg); + + Predicate a = CorePredicate.getInstance("a", 0); + Predicate b = CorePredicate.getInstance("b", 0); + Predicate c = CorePredicate.getInstance("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/ChoiceGrounder.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceGrounder.java new file mode 100644 index 000000000..9ca9430d0 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceGrounder.java @@ -0,0 +1,214 @@ +/** + * 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 + * 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.api.Util.entriesToMap; +import static at.ac.tuwien.kr.alpha.api.Util.entry; +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static at.ac.tuwien.kr.alpha.core.common.NoGood.headFirst; +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Stream; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; +import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; +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.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +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.grounder.Grounder; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; +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.NormalRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; + +/** + * Represents a small ASP program with choices {@code { aa :- not bb. bb :- not aa. }}. + */ +public class ChoiceGrounder implements Grounder { + public static final Set EXPECTED = new HashSet<>(asList( + new AnswerSetBuilder() + .predicate("aa") + .build(), + new AnswerSetBuilder() + .predicate("bb") + .build() + )); + + private static final int ATOM_AA = 1; + private static final int ATOM_BB = 2; + private static final int ATOM_BR1 = 3; + private static final int ATOM_BR2 = 4; + private static final int ATOM_EN_BR1 = 5; + private static final int ATOM_EN_BR2 = 6; + private static final int ATOM_DIS_BR1 = 7; + private static final int ATOM_DIS_BR2 = 8; + private static final int RULE_AA = 11; // { -aa, _br1 } + private static final int BRULE_AA = 12; // { -_br1, -bb } + private static final int RULE_BB = 13; // { -bb, _br2 } + 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_BR2 = 18; // { -dis_br2, aa } + private static final Map NOGOODS = Stream.of( + entry(RULE_AA, headFirst(fromOldLiterals(-ATOM_AA, ATOM_BR1))), + entry(BRULE_AA, headFirst(fromOldLiterals(-ATOM_BR1, -ATOM_BB))), + entry(RULE_BB, headFirst(fromOldLiterals(-ATOM_BB, ATOM_BR2))), + entry(BRULE_BB, headFirst(fromOldLiterals(-ATOM_BR2, -ATOM_AA))), + 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()); + private static final Map CHOICE_ENABLE = Stream.of( + entry(ATOM_BR1, ATOM_EN_BR1), + 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()); + private static Atom atomAA = new BasicAtom(CorePredicate.getInstance("aa", 0)); + private static Atom atomBB = new BasicAtom(CorePredicate.getInstance("bb", 0)); + private static BasicRule ruleAA = new BasicRule(new NormalHeadImpl(atomAA), Collections.singletonList(new BasicAtom(CorePredicate.getInstance("bb", 0)).toLiteral(false))); + private static BasicRule ruleBB = new BasicRule(new NormalHeadImpl(atomBB), Collections.singletonList(new BasicAtom(CorePredicate.getInstance("aa", 0)).toLiteral(false))); + private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(NormalRule.fromBasicRule(ruleAA)), new SubstitutionImpl()); + private static Atom rule2 = new RuleAtom(InternalRule.fromNormalRule(NormalRule.fromBasicRule(ruleBB)), new SubstitutionImpl()); + private static Atom atomEnBR1 = ChoiceAtom.on(1); + private static Atom atomEnBR2 = ChoiceAtom.on(2); + private static Atom atomDisBR1 = ChoiceAtom.off(3); + private static Atom atomDisBR2 = ChoiceAtom.off(4); + private final AtomStore atomStore; + private boolean returnedAllNogoods; + + private final java.util.function.Predicate filter; + + public ChoiceGrounder(AtomStore atomStore) { + this(atomStore, p -> true); + } + + public ChoiceGrounder(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); + } + + @Override + public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { + SortedSet trueAtomPredicates = new TreeSet<>(); + for (int trueAtom : trueAtoms) { + Predicate atomPredicate = atomStore.get(trueAtom).getPredicate(); + if (!filter.test(atomPredicate)) { + continue; + } + if (atomPredicate.isInternal()) { + continue; + } + trueAtomPredicates.add(atomPredicate); + } + + // Add the atom instances + Map> predicateInstances = new HashMap<>(); + for (Predicate trueAtomPredicate : trueAtomPredicates) { + BasicAtom basicAtom = new BasicAtom(trueAtomPredicate); + 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. + return new BasicAnswerSet(trueAtomPredicates, predicateInstances); + } + + @Override + public Map getNoGoods(Assignment assignment) { + if (!returnedAllNogoods) { + returnedAllNogoods = true; + return NOGOODS; + } else { + return new HashMap<>(); + } + } + + private boolean isFirst = true; + + @Override + public Pair, Map> getChoiceAtoms() { + if (isFirst) { + isFirst = false; + return new ImmutablePair<>(CHOICE_ENABLE, CHOICE_DISABLE); + } else { + return new ImmutablePair<>(new HashMap<>(), new HashMap<>()); + } + } + + @Override + public Map> getHeadsToBodies() { + return Collections.emptyMap(); + } + + @Override + public void updateAssignment(IntIterator it) { + // This test grounder reports all NoGoods immediately, irrespective of any assignment. + } + + @Override + public void forgetAssignment(int[] atomIds) { + } + + private int solverDerivedNoGoodIdCounter = 20; + private Map solverDerivedNoGoods = new HashMap<>(); + + @Override + public int register(NoGood noGood) { + if (!solverDerivedNoGoods.containsKey(noGood)) { + solverDerivedNoGoods.put(noGood, solverDerivedNoGoodIdCounter++); + } + return solverDerivedNoGoods.get(noGood); + } +} 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/DummyGrounder.java new file mode 100644 index 000000000..4c9b79ef1 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/DummyGrounder.java @@ -0,0 +1,193 @@ +/** + * 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 + * 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.api.Util.entriesToMap; +import static at.ac.tuwien.kr.alpha.api.Util.entry; +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static at.ac.tuwien.kr.alpha.core.common.NoGood.headFirst; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Stream; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; +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.BasicAnswerSet; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +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.grounder.Grounder; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; +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.NormalRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; + +/** + * Represents a small ASP program {@code { c :- a, b. a. b. }}. + * + * Copyright (c) 2016, the Alpha Team. + */ +public class DummyGrounder implements Grounder { + public static final Set EXPECTED = new HashSet<>(singletonList(new AnswerSetBuilder() + .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))) + ).collect(entriesToMap()); + private final AtomStore atomStore; + private final java.util.function.Predicate filter; + private byte[] currentTruthValues = new byte[]{-2, -1, -1, -1, -1}; + private static Atom atomAA = new BasicAtom(CorePredicate.getInstance("a", 0)); + private static Atom atomBB = new BasicAtom(CorePredicate.getInstance("b", 0)); + private static Atom atomCC = new BasicAtom(CorePredicate.getInstance("c", 0)); + private static BasicRule ruleABC = new BasicRule(new NormalHeadImpl(atomCC), Arrays.asList(atomAA.toLiteral(), atomBB.toLiteral())); + private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(NormalRule.fromBasicRule(ruleABC)), new SubstitutionImpl()); + private Set returnedNogoods = new HashSet<>(); + + public DummyGrounder(AtomStore atomStore) { + this(atomStore, p -> true); + } + + public DummyGrounder(AtomStore atomStore, java.util.function.Predicate filter) { + this.atomStore = atomStore; + this.filter = filter; + Arrays.asList(atomAA, atomBB, rule1, atomCC).forEach(atomStore::putIfAbsent); + } + + @Override + public void forgetAssignment(int[] atomIds) { + for (int atomId : atomIds) { + currentTruthValues[atomId] = -1; + } + } + + private int solverDerivedNoGoodIdCounter = 20; + private Map solverDerivedNoGoods = new HashMap<>(); + + @Override + public int register(NoGood noGood) { + if (!solverDerivedNoGoods.containsKey(noGood)) { + solverDerivedNoGoods.put(noGood, solverDerivedNoGoodIdCounter++); + } + return solverDerivedNoGoods.get(noGood); + } + + @Override + public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { + // 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. + + SortedSet trueAtomPredicates = new TreeSet<>(); + for (int trueAtom : trueAtoms) { + Predicate atomPredicate = atomStore.get(trueAtom).getPredicate(); + if (!filter.test(atomPredicate)) { + continue; + } + if (atomPredicate.isInternal()) { + continue; + } + trueAtomPredicates.add(atomPredicate); + } + + // Add the atom instances + Map> predicateInstances = new HashMap<>(); + for (Predicate trueAtomPredicate : trueAtomPredicates) { + BasicAtom internalBasicAtom = new BasicAtom(trueAtomPredicate); + predicateInstances.put(trueAtomPredicate, new TreeSet<>(singleton(internalBasicAtom))); + } + + return new BasicAnswerSet(trueAtomPredicates, predicateInstances); + } + + @Override + public Map getNoGoods(Assignment assignment) { + // Return NoGoods depending on current assignment. + HashMap returnNoGoods = new HashMap<>(); + if (currentTruthValues[1] == 1 && currentTruthValues[2] == 1) { + addNoGoodIfNotAlreadyReturned(returnNoGoods, RULE_B); + addNoGoodIfNotAlreadyReturned(returnNoGoods, RULE_H); + } else { + addNoGoodIfNotAlreadyReturned(returnNoGoods, FACT_A); + addNoGoodIfNotAlreadyReturned(returnNoGoods, FACT_B); + } + return returnNoGoods; + } + + @Override + public Pair, Map> getChoiceAtoms() { + return new ImmutablePair<>(new HashMap<>(), new HashMap<>()); + } + + @Override + public Map> getHeadsToBodies() { + return Collections.emptyMap(); + } + + @Override + public void updateAssignment(IntIterator it) { + while (it.hasNext()) { + currentTruthValues[it.next()] = 1; + } + } + + private void addNoGoodIfNotAlreadyReturned(Map integerNoGoodMap, Integer idNoGood) { + if (!returnedNogoods.contains(idNoGood)) { + integerNoGoodMap.put(idNoGood, NOGOODS.get(idNoGood)); + returnedNogoods.add(idNoGood); + } + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java new file mode 100644 index 000000000..59f131e1c --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2016-2018, 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.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.grounder.Instance; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; + +/** + * Copyright (c) 2016, the Alpha Team. + */ +public class IndexedInstanceStorageTest { + @Test + public void testIndexedInstanceStorage() { + IndexedInstanceStorage storage = new IndexedInstanceStorage(CorePredicate.getInstance("p", 4), true); + storage.addIndexPosition(0); + storage.addIndexPosition(2); + ConstantTerm t0 = CoreConstantTerm.getInstance("0"); + ConstantTerm t1 = CoreConstantTerm.getInstance("1"); + ConstantTerm t2 = CoreConstantTerm.getInstance("2"); + ConstantTerm t3 = CoreConstantTerm.getInstance("3"); + ConstantTerm t4 = CoreConstantTerm.getInstance("4"); + ConstantTerm t5 = CoreConstantTerm.getInstance("5"); + + Instance badInst1 = new Instance(t1, t1, t0); + Instance badInst2 = new Instance(t5, t5, t5, t5, t5); + + try { + storage.addInstance(badInst1); + fail(); + } catch (Exception e) { + assertTrue(e.getMessage().startsWith("Instance length does not match arity of IndexedInstanceStorage")); + } + + try { + storage.addInstance(badInst2); + fail(); + } catch (Exception e) { + assertTrue(e.getMessage().startsWith("Instance length does not match arity of IndexedInstanceStorage")); + } + + Instance inst1 = new Instance(t1, t1, t1, t1); + Instance inst2 = new Instance(t1, t2, t3, t4); + Instance inst3 = new Instance(t4, t3, t3, t5); + Instance inst4 = new Instance(t1, t2, t1, t1); + Instance inst5 = new Instance(t5, t4, t3, t2); + + storage.addInstance(inst1); + storage.addInstance(inst2); + storage.addInstance(inst3); + storage.addInstance(inst4); + storage.addInstance(inst5); + + List matching3 = storage.getInstancesMatchingAtPosition(t3, 2); + assertEquals(matching3.size(), 3); + assertTrue(matching3.contains(new Instance(t1, t2, t3, t4))); + assertTrue(matching3.contains(new Instance(t4, t3, t3, t5))); + assertTrue(matching3.contains(new Instance(t5, t4, t3, t2))); + assertFalse(matching3.contains(new Instance(t1, t1, t1, t1))); + + List matching1 = storage.getInstancesMatchingAtPosition(t2, 0); + assertEquals(matching1.size(), 0); + } + +} \ 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 new file mode 100644 index 000000000..5c97e1d00 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java @@ -0,0 +1,447 @@ +/* + * 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.TestUtil.atom; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.grounder.Instance; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +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.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +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.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +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.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(false); + + 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)"); + + @Before + 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 = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(CoreConstantTerm.getInstance(1)), SubstitutionImpl.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 + @Ignore("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 = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(CoreConstantTerm.getInstance(startingInstance)), SubstitutionImpl.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 = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(CoreConstantTerm.getInstance(startingInstance)), SubstitutionImpl.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 new file mode 100644 index 000000000..16473387d --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGeneratorTest.java @@ -0,0 +1,91 @@ +/** + * 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.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +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.Literals; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +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(false); + + private static final ConstantTerm A = CoreConstantTerm.getSymbolicInstance("a"); + private static final ConstantTerm B = CoreConstantTerm.getSymbolicInstance("b"); + + private static final VariableTerm X = VariableTermImpl.getInstance("X"); + private static final VariableTerm Y = VariableTermImpl.getInstance("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 SubstitutionImpl(); + 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/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramTransformationTest.java new file mode 100644 index 000000000..6ebf3aa9a --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramTransformationTest.java @@ -0,0 +1,73 @@ +package at.ac.tuwien.kr.alpha.core.grounder; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.function.Function; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ChoiceHeadToNormal; +import at.ac.tuwien.kr.alpha.core.programs.transformation.IntervalTermToIntervalAtom; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; + +public class ProgramTransformationTest { + + private static final ProgramParser PARSER = new ProgramParserImpl(); + + private static final Logger LOGGER = LoggerFactory.getLogger(ProgramTransformationTest.class); + + private static final String TESTFILES_PATH = "/transform-test/"; + + private ChoiceHeadToNormal choiceToNormal = new ChoiceHeadToNormal(); + private IntervalTermToIntervalAtom intervalRewriting = new IntervalTermToIntervalAtom(); + + private static String readTestResource(String resource) throws IOException { + InputStream is = ProgramTransformationTest.class.getResourceAsStream(TESTFILES_PATH + resource); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + StringBuilder bld = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + bld.append(line).append(System.lineSeparator()); + } + br.close(); + return bld.toString(); + } + + private , O extends Program> void genericTransformationTest(ProgramTransformation transform, + Function prepareFunc, String resourceSet) { + try { + String inputCode = ProgramTransformationTest.readTestResource(resourceSet + ".in"); + String expectedResult = ProgramTransformationTest.readTestResource(resourceSet + ".out"); + ASPCore2Program inputProg = PARSER.parse(inputCode); + I transformInput = prepareFunc.apply(inputProg); + String beforeTransformProg = transformInput.toString(); + O transformedProg = transform.apply(transformInput); + Assert.assertEquals("Transformation result doesn't match expected result", expectedResult, transformedProg.toString()); + Assert.assertEquals("Transformation modified source program (breaks immutability!)", beforeTransformProg, transformInput.toString()); + } catch (Exception ex) { + LOGGER.error("Exception in test, nested exception: " + ex.getMessage(), ex); + throw new RuntimeException(ex); + } + } + + @Test + public void choiceHeadToNormalSimpleTest() { + this.genericTransformationTest(this.choiceToNormal, Function.identity(), "choice-to-normal.1"); + } + + @Test + public void intervalTermToIntervalAtomSimpleTest() { + this.genericTransformationTest(this.intervalRewriting, NormalProgram::fromInputProgram, "interval.1"); + } + +} 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 new file mode 100644 index 000000000..2f69d8055 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingOrderTest.java @@ -0,0 +1,161 @@ +/* + * 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.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; + +/** + * Copyright (c) 2017-2019, the Alpha Team. + */ +public class RuleGroundingOrderTest { + + private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); + + + @Test + public void groundingOrder() throws IOException { + 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."; + Alpha system = new Alpha(); + system.getConfig().setEvaluateStratifiedPart(false); + InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); + InternalRule rule0 = internalPrg.getRules().get(0); + RuleGroundingOrders rgo0 = new RuleGroundingOrders(rule0); + rgo0.computeGroundingOrders(); + assertEquals(4, rgo0.getStartingLiterals().size()); + + InternalRule rule1 = internalPrg.getRules().get(1); + RuleGroundingOrders rgo1 = new RuleGroundingOrders(rule1); + rgo1.computeGroundingOrders(); + assertEquals(4, rgo1.getStartingLiterals().size()); + + InternalRule rule2 = internalPrg.getRules().get(2); + RuleGroundingOrders rgo2 = new RuleGroundingOrders(rule2); + rgo2.computeGroundingOrders(); + assertTrue(rgo2.fixedInstantiation()); + } + + @Test(expected = RuntimeException.class) + public void groundingOrderUnsafe() throws IOException { + String aspStr = "h(X,C) :- X = Y, Y = C .. 3, C = X."; + Alpha system = new Alpha(); + system.getConfig().setEvaluateStratifiedPart(false); + InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); + computeGroundingOrdersForRule(internalPrg, 0); + } + + @Test + public void testPositionFromWhichAllVarsAreBound_ground() { + String aspStr = "a :- b, not c."; + Alpha system = new Alpha(); + system.getConfig().setEvaluateStratifiedPart(false); + InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); + RuleGroundingOrders rgo0 = computeGroundingOrdersForRule(internalPrg, 0); + assertEquals(0, rgo0.getFixedGroundingOrder().getPositionFromWhichAllVarsAreBound()); + } + + @Test + public void testPositionFromWhichAllVarsAreBound_simpleNonGround() { + String aspStr = "a(X) :- b(X), not c(X)."; + Alpha system = new Alpha(); + system.getConfig().setEvaluateStratifiedPart(false); + InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); + RuleGroundingOrders 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)."; + Alpha system = new Alpha(); + system.getConfig().setEvaluateStratifiedPart(false); + InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); + RuleGroundingOrders 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)."; + Alpha system = new Alpha(); + system.getConfig().setEvaluateStratifiedPart(false); + InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); + RuleGroundingOrders 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)."; + Alpha system = new Alpha(); + system.getConfig().setEvaluateStratifiedPart(false); + InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); + RuleGroundingOrders 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 RuleGroundingOrders computeGroundingOrdersForRule(InternalProgram program, int ruleIndex) { + InternalRule rule = program.getRules().get(ruleIndex); + RuleGroundingOrders rgo = new RuleGroundingOrders(rule); + rgo.computeGroundingOrders(); + return rgo; + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java new file mode 100644 index 000000000..54be5d18a --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java @@ -0,0 +1,102 @@ +/** + * 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.grounder; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.rule.NormalRule; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +/** + * Tests {@link BasicRule#toString()} and {@link InternalRule#toString()}. + */ +public class RuleToStringTest { + private final ProgramParser parser = new ProgramParser(); + + @Test + public void positiveRuleToString() { + parseSingleRuleAndCheckToString("a :- b1, b2."); + } + + @Test + public void ruleWithNegativeBodyToString() { + parseSingleRuleAndCheckToString("a :- b1, b2."); + } + + @Test + public void normalRuleToString() { + parseSingleRuleAndCheckToString("a :- b1, b2, not c1, not c2."); + } + + @Test + public void constraintToString() { + parseSingleRuleAndCheckToString(":- b1, b2, not c1, not c2."); + } + + @Test + public void nonGroundPositiveRuleToString() { + constructNonGroundRuleAndCheckToString("a :- b1, b2."); + } + + @Test + public void nonGroundRuleWithNegativeBodyToString() { + constructNonGroundRuleAndCheckToString("a :- b1, b2."); + } + + @Test + public void nonGroundRuleToString() { + constructNonGroundRuleAndCheckToString("a(X) :- b1(X), b2(X), not c1(X), not c2(X)."); + } + + @Test + public void nonGroundConstraintToString() { + constructNonGroundRuleAndCheckToString(":- b1(X), b2(X), not c1(X), not c2(X)."); + } + + private void parseSingleRuleAndCheckToString(String rule) { + BasicRule parsedRule = parseSingleRule(rule); + assertEquals(rule, parsedRule.toString()); + } + + private void constructNonGroundRuleAndCheckToString(String textualRule) { + InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(parseSingleRule(textualRule))); + assertEquals(textualRule, nonGroundRule.toString()); + } + + private BasicRule parseSingleRule(String rule) { + InputProgram program = parser.parse(rule); + List rules = program.getRules(); + assertEquals("Number of rules", 1, rules.size()); + return rules.get(0); + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..88dfcb9ec --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionTest.java @@ -0,0 +1,169 @@ +/** + * Copyright (c) 2016-2018, 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 at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.rule.BasicRule; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.rule.NormalRule; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.grounder.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.test.util.SubstitutionTestUtil; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +public class SubstitutionTest { + private static final ProgramParser PARSER = new ProgramParser(); + + private static final ConstantTerm A = ConstantTerm.getSymbolicInstance("a"); + private static final ConstantTerm B = ConstantTerm.getSymbolicInstance("b"); + private static final ConstantTerm C = ConstantTerm.getSymbolicInstance("c"); + + private static final VariableTerm X = VariableTerm.getInstance("X"); + private static final VariableTerm Y = VariableTerm.getInstance("Y"); + private static final BasicAtom PX = new BasicAtom(Predicate.getInstance("p", 1), X); + private static final BasicAtom PY = new BasicAtom(Predicate.getInstance("p", 1), Y); + private static final Instance PA = new Instance(A); + private static final Instance PB = new Instance(B); + + @Test + public void putSimpleBinding() { + Substitution substitution = new Substitution(); + substitution.put(Y, A); + assertEquals(A, substitution.eval(Y)); + } + + @Test + public void specializeTermsSimpleBinding() { + Substitution substitution = Substitution.specializeSubstitution(PY, PA, Substitution.EMPTY_SUBSTITUTION); + assertEquals(A, substitution.eval(Y)); + } + + @Test + public void specializeTermsFunctionTermBinding() { + Substitution substitution = new Substitution(); + substitution.put(Y, A); + + FunctionTerm groundFunctionTerm = FunctionTerm.getInstance("f", B, C); + Instance qfBC = new Instance(groundFunctionTerm); + Term nongroundFunctionTerm = FunctionTerm.getInstance("f", B, X); + BasicAtom qfBX = new BasicAtom(Predicate.getInstance("q", 2), nongroundFunctionTerm); + + Substitution substitution1 = Substitution.specializeSubstitution(qfBX, qfBC, substitution); + + assertEquals(C, substitution1.eval(X)); + assertEquals(A, substitution1.eval(Y)); + } + + @Test + public void substitutePositiveBasicAtom() { + substituteBasicAtomLiteral(false); + } + + @Test + public void substituteNegativeBasicAtom() { + substituteBasicAtomLiteral(true); + } + + @Test + public void groundAndPrintRule() { + BasicRule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); + InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); + Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); + Substitution substitution2 = Substitution.specializeSubstitution(PY, PB, substitution1); + String printedString = SubstitutionTestUtil.groundAndPrintRule(nonGroundRule, substitution2); + assertEquals("x :- p(a, b), not q(a, b).", printedString); + } + + @Test + public void specializeBasicAtom() { + Predicate p = Predicate.getInstance("p", 2); + BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); + Instance instance = new Instance(A, B); + Substitution substitution = Substitution.specializeSubstitution(atom, instance, Substitution.EMPTY_SUBSTITUTION); + BasicAtom substituted = atom.substitute(substitution); + assertEquals(p, substituted.getPredicate()); + assertEquals(A, substituted.getTerms().get(0)); + assertEquals(B, substituted.getTerms().get(1)); + } + + private void substituteBasicAtomLiteral(boolean negated) { + Predicate p = Predicate.getInstance("p", 2); + BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); + Literal literal = new BasicLiteral(atom, !negated); + Substitution substitution = new Substitution(); + substitution.put(X, A); + substitution.put(Y, B); + literal = literal.substitute(substitution); + assertEquals(p, literal.getPredicate()); + assertEquals(A, literal.getTerms().get(0)); + assertEquals(B, literal.getTerms().get(1)); + assertEquals(negated, literal.isNegated()); + } + + @Test + public void groundLiteralToString_PositiveBasicAtom() { + groundLiteralToString(false); + } + + @Test + public void groundLiteralToString_NegativeBasicAtom() { + groundLiteralToString(true); + } + + private void groundLiteralToString(boolean negated) { + Predicate p = Predicate.getInstance("p", 2); + BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); + Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); + Substitution substitution = Substitution.specializeSubstitution(PY, PB, substitution1); + String printedString = SubstitutionTestUtil.groundLiteralToString(atom.toLiteral(!negated), substitution, true); + assertEquals((negated ? "not " : "") + "p(a, b)", printedString); + } + + @Test + public void substitutionFromString() { + BasicRule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); + InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); + Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); + Substitution substitution = Substitution.specializeSubstitution(PY, PB, substitution1); + RuleAtom ruleAtom = new RuleAtom(nonGroundRule, substitution); + String substitutionString = (String) ((ConstantTerm) ruleAtom.getTerms().get(1)).getObject(); + Substitution fromString = Substitution.fromString(substitutionString); + assertEquals(substitution, fromString); + } +} 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 new file mode 100644 index 000000000..9031d619e --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java @@ -0,0 +1,82 @@ +/* + * 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 at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class UnifierTest extends SubstitutionTest { + + @Test + public void extendUnifier() { + VariableTerm varX = VariableTerm.getInstance("X"); + VariableTerm varY = VariableTerm.getInstance("Y"); + Unifier sub1 = new Unifier(); + sub1.put(varX, varY); + Unifier sub2 = new Unifier(); + sub2.put(varY, ConstantTerm.getInstance("a")); + + sub1.extendWith(sub2); + BasicAtom atom1 = parseAtom("p(X)"); + + Atom atomSubstituted = atom1.substitute(sub1); + assertEquals(ConstantTerm.getInstance("a"), atomSubstituted.getTerms().get(0)); + } + + @Test + public void mergeUnifierIntoLeft() { + VariableTerm varX = VariableTerm.getInstance("X"); + VariableTerm varY = VariableTerm.getInstance("Y"); + VariableTerm varZ = VariableTerm.getInstance("Z"); + Term constA = ConstantTerm.getInstance("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 ProgramParser(); + InputProgram program = programParser.parse(atom + "."); + return (BasicAtom) program.getFacts().get(0); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java new file mode 100644 index 000000000..bb57ea6c8 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2019 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.grounder.heuristics; + +import org.junit.Test; + +import static at.ac.tuwien.kr.alpha.core.grounder.heuristics.GrounderHeuristicsConfiguration.PERMISSIVE_STRING; +import static at.ac.tuwien.kr.alpha.core.grounder.heuristics.GrounderHeuristicsConfiguration.STRICT_STRING; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Tests {@link GrounderHeuristicsConfiguration} + */ +public class GrounderHeuristicConfigurationTest { + + @Test + public void testGetInstanceStrictStrict() { + GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(STRICT_STRING, STRICT_STRING); + assertFalse(grounderHeuristicsConfiguration.isPermissive(true)); + assertFalse(grounderHeuristicsConfiguration.isPermissive(false)); + assertEquals(0, grounderHeuristicsConfiguration.getToleranceConstraints()); + assertEquals(0, grounderHeuristicsConfiguration.getToleranceRules()); + } + + @Test + public void testGetInstanceStrictPermissive() { + GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(STRICT_STRING, PERMISSIVE_STRING); + assertFalse(grounderHeuristicsConfiguration.isPermissive(true)); + assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); + assertEquals(0, grounderHeuristicsConfiguration.getToleranceConstraints()); + assertEquals(-1, grounderHeuristicsConfiguration.getToleranceRules()); + } + + @Test + public void testGetInstancePermissiveStrict() { + GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(PERMISSIVE_STRING, STRICT_STRING); + assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); + assertFalse(grounderHeuristicsConfiguration.isPermissive(false)); + assertEquals(-1, grounderHeuristicsConfiguration.getToleranceConstraints()); + assertEquals(0, grounderHeuristicsConfiguration.getToleranceRules()); + } + + @Test + public void testGetInstancePermissivePermissive() { + GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(PERMISSIVE_STRING, PERMISSIVE_STRING); + assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); + assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); + assertEquals(-1, grounderHeuristicsConfiguration.getToleranceConstraints()); + assertEquals(-1, grounderHeuristicsConfiguration.getToleranceRules()); + } + + @Test + public void testGetInstanceIntInt() { + GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(5, 1); + assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); + assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); + assertEquals(5, grounderHeuristicsConfiguration.getToleranceConstraints()); + assertEquals(1, grounderHeuristicsConfiguration.getToleranceRules()); + } + + @Test + public void testGetInstanceStringIntStringInt() { + GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance("5", "1"); + assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); + assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); + assertEquals(5, grounderHeuristicsConfiguration.getToleranceConstraints()); + assertEquals(1, grounderHeuristicsConfiguration.getToleranceRules()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java new file mode 100644 index 000000000..2a7580ce2 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java @@ -0,0 +1,368 @@ +package at.ac.tuwien.kr.alpha.grounder.instantiation; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; + +public class LiteralInstantiationStrategyTest { + + @Test + public void workingMemoryBasedInstantiationAcceptLiteral() { + Predicate p = Predicate.getInstance("p", 1); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(p); + workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); + LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); + Literal positiveAcceptedLiteral = new BasicLiteral( + new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); + Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(positiveAcceptedLiteral)); + Literal negativeAcceptedLiteral = new BasicLiteral( + new BasicAtom(p, ConstantTerm.getSymbolicInstance("b")), false); + Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(negativeAcceptedLiteral)); + } + + @Test + public void workingMemoryBasedInstantiationRejectLiteral() { + Predicate p = Predicate.getInstance("p", 1); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(p); + workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); + LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); + Literal positiveRejectedLiteral = new BasicLiteral( + new BasicAtom(p, ConstantTerm.getSymbolicInstance("b")), true); + Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(positiveRejectedLiteral)); + Literal negativeRejectedLiteral = new BasicLiteral( + new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), false); + Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(negativeRejectedLiteral)); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth + * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". + * + * In this case, the instantiation strategy does not have an assignment set (as + * is the case when {@link NaiveGrounder} is in bootstrap), + * so we expect the instantiation strategy to determine that p(a) is TRUE. + * Furthermore, the stale atom set (used by {@link NaiveGrounder} to clean up + * atoms that should be deleted from working memory) must stay empty. + */ + @Test + public void defaultLazyGroundingNoAssignmentGroundLiteral() { + Predicate p = Predicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + WorkingMemory workingMemory = new WorkingMemory(); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(null); + + + AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); + Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); + Assert.assertTrue(staleSet.isEmpty()); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find ground + * instances for the partially ground positive literal "q(a, X)". + * + * In this case, the instantiation strategy does not have an assignment set (as + * is the case when {@link NaiveGrounder} is in bootstrap), so we expect the + * assignment status (i.e. assignment status of the found ground instance) + * passed back with the substitution to be TRUE. Furthermore, the stale atom set + * (used by {@link NaiveGrounder} to clean up atoms that should be deleted from + * working memory) must stay empty. + */ + @Test + public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { + Predicate q = Predicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(q); + workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(null); + + List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), + new Substitution()); + Assert.assertEquals(1, result.size()); + ImmutablePair substitutionInfo = result.get(0); + Substitution substitution = substitutionInfo.left; + AssignmentStatus assignmentStatus = substitutionInfo.right; + Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); + Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); + Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); + Assert.assertTrue(staleSet.isEmpty()); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth + * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". + * + * In this case, the instantiation strategy has an empty assignment, + * so we expect the instantiation strategy to determine that p(a) is UNASSIGNED. + * Since UNASSIGNED and FALSE atoms are (potentially) stale in working memory, + * we expect the atom "p(a)" to be added to the stale set by the instantiation + * strategy. + */ + @Test + public void defaultLazyGroundingCheckUnassignedGroundLiteral() { + Predicate p = Predicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + WorkingMemory workingMemory = new WorkingMemory(); + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(assignment); + + AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); + Assert.assertEquals(AssignmentStatus.UNASSIGNED, assignmentStatus); + + Assert.assertEquals(1, staleSet.size()); + Assert.assertTrue(staleSet.contains(pOfA)); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth + * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". + * + * In this case, the instantiation strategy has an assignment where the atom + * "p(a)" is assigned ThriceTruth.FALSE, so we expect the instantiation strategy + * to determine that p(a) is FALSE. Since UNASSIGNED and FALSE atoms are + * (potentially) stale in working memory, we expect the atom "p(a)" to be added + * to the stale set by the instantiation strategy. + */ + @Test + public void defaultLazyGroundingCheckFalseGroundLiteral() { + Predicate p = Predicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + WorkingMemory workingMemory = new WorkingMemory(); + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + atomStore.putIfAbsent(pOfA); + assignment.growForMaxAtomId(); + assignment.assign(atomStore.get(pOfA), ThriceTruth.FALSE); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(assignment); + + AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); + Assert.assertEquals(AssignmentStatus.FALSE, assignmentStatus); + + Assert.assertEquals(1, staleSet.size()); + Assert.assertTrue(staleSet.contains(pOfA)); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth + * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". + * + * In this case, the instantiation strategy has an assignment where the atom + * "p(a)" is assigned ThriceTruth.TRUE, so we expect the instantiation strategy + * to determine that p(a) is TRUE. Furthermore, the stale atom set + * (used by {@link NaiveGrounder} to clean up atoms that should be deleted from + * working memory) must stay empty. + */ + @Test + public void defaultLazyGroundingCheckTrueGroundLiteral() { + Predicate p = Predicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + WorkingMemory workingMemory = new WorkingMemory(); + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + atomStore.putIfAbsent(pOfA); + assignment.growForMaxAtomId(); + assignment.assign(atomStore.get(pOfA), ThriceTruth.TRUE); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(assignment); + + AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); + Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); + + Assert.assertTrue(staleSet.isEmpty()); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth + * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". + * + * In this case, the instantiation strategy has an assignment where the atom + * "p(a)" is assigned ThriceTruth.MBT, so we expect the instantiation strategy + * to determine that p(a) is TRUE. Furthermore, the stale atom set + * (used by {@link NaiveGrounder} to clean up atoms that should be deleted from + * working memory) must stay empty. + */ + @Test + public void defaultLazyGroundingCheckMustBeTrueGroundLiteral() { + Predicate p = Predicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + WorkingMemory workingMemory = new WorkingMemory(); + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + atomStore.putIfAbsent(pOfA); + assignment.growForMaxAtomId(); + assignment.assign(atomStore.get(pOfA), ThriceTruth.MBT); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(assignment); + + AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); + Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); + + Assert.assertTrue(staleSet.isEmpty()); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find the ground + * instance "q(a, b)" for the partially ground positive literal "q(a, X)". + * + * In this case, the instantiation strategy has an empty assignment, so we + * expect the assignment status (i.e. assignment status of the found ground + * instance) passed back with the substitution to be UNASSIGNED. Since + * UNASSIGNED and FALSE atoms are (potentially) stale in working memory, we + * expect the atom "q(a, b)" to be added to the stale set by the instantiation + * strategy. + */ + @Test + public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance() { + Predicate q = Predicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(q); + workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(assignment); + + List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), + new Substitution()); + Assert.assertEquals(1, result.size()); + ImmutablePair substitutionInfo = result.get(0); + Substitution substitution = substitutionInfo.left; + AssignmentStatus assignmentStatus = substitutionInfo.right; + Assert.assertEquals(AssignmentStatus.UNASSIGNED, assignmentStatus); + Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); + Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); + + Assert.assertEquals(1, staleSet.size()); + Assert.assertTrue(staleSet.contains(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")))); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find the ground + * instance "q(a, b)" for the partially ground positive literal "q(a, X)". + * + * In this case, the instantiation strategy has an assignment where q(a, b) is + * assigned ThriceTruth.TRUE, so we expect the assignment status (i.e. + * assignment status of the found ground instance) passed back with the + * substitution to be TRUE. Furthermore, we expect the stale atom set to stay + * empty. + */ + @Test + public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { + Predicate q = Predicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(q); + workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + BasicAtom groundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")); + atomStore.putIfAbsent(groundAtom); + assignment.growForMaxAtomId(); + assignment.assign(atomStore.get(groundAtom), ThriceTruth.TRUE); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(assignment); + + List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), + new Substitution()); + Assert.assertEquals(1, result.size()); + ImmutablePair substitutionInfo = result.get(0); + Substitution substitution = substitutionInfo.left; + AssignmentStatus assignmentStatus = substitutionInfo.right; + Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); + Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); + Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); + + Assert.assertTrue(staleSet.isEmpty()); + } + + /** + * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find the ground + * instance "q(a, b)" for the partially ground positive literal "q(a, X)". + * + * In this case, the instantiation strategy has an assignment where q(a, b) is + * assigned ThriceTruth.FALSE, so we expect an empty list from + * {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)}. + * Furthermore, we expect the atom q(a, b) to be added to the stale atom set. + */ + @Test + public void defaultLazyGroundingSubstituteNonGroundLiteralWithFalseInstance() { + Predicate q = Predicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(q); + workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + BasicAtom groundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")); + atomStore.putIfAbsent(groundAtom); + assignment.growForMaxAtomId(); + assignment.assign(atomStore.get(groundAtom), ThriceTruth.FALSE); + LinkedHashSet staleSet = new LinkedHashSet<>(); + DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, + Collections.emptyMap()); + strategy.setStaleWorkingMemoryEntries(staleSet); + strategy.setCurrentAssignment(assignment); + + List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), + new Substitution()); + Assert.assertTrue(result.isEmpty()); + + Assert.assertEquals(1, staleSet.size()); + Assert.assertTrue(staleSet.contains(groundAtom)); + } + +} + \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java new file mode 100644 index 000000000..1e160c184 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java @@ -0,0 +1,153 @@ +package at.ac.tuwien.kr.alpha.grounder.instantiation; + +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; +import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.core.grounder.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.grounder.atoms.EnumerationLiteral; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class LiteralInstantiatorTest { + + @Test + public void instantiateSatisfiedFixedInterpretationLiteral() { + ComparisonAtom equalsThree = new ComparisonAtom(ConstantTerm.getInstance(3), VariableTerm.getInstance("THREE"), ComparisonOperatorImpl.EQ); + Literal lit = new ComparisonLiteral(equalsThree, true); + Substitution substitution = new Substitution(); + LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); + LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); + Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); + List> resultSubstitutions = result.getSubstitutions(); + Assert.assertEquals(1, resultSubstitutions.size()); + Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitutions.get(0).right); + Substitution extendedSubstitution = resultSubstitutions.get(0).left; + Assert.assertTrue(extendedSubstitution.isVariableSet(VariableTerm.getInstance("THREE"))); + Assert.assertEquals(ConstantTerm.getInstance(3), extendedSubstitution.eval(VariableTerm.getInstance("THREE"))); + } + + @Test + public void instantiateUnsatisfiedFixedInterpretationLiteral() { + ComparisonAtom fiveEqualsThree = new ComparisonAtom(VariableTerm.getInstance("FIVE"), VariableTerm.getInstance("THREE"), ComparisonOperatorImpl.EQ); + Literal lit = new ComparisonLiteral(fiveEqualsThree, true); + Substitution substitution = new Substitution(); + substitution.put(VariableTerm.getInstance("FIVE"), ConstantTerm.getInstance(5)); + substitution.put(VariableTerm.getInstance("THREE"), ConstantTerm.getInstance(3)); + LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); + LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); + Assert.assertEquals(LiteralInstantiationResult.Type.STOP_BINDING, result.getType()); + } + + @Test + public void instantiateEnumLiteral() { + VariableTerm enumTerm = VariableTerm.getInstance("E"); + VariableTerm idTerm = VariableTerm.getInstance("X"); + VariableTerm indexTerm = VariableTerm.getInstance("I"); + List termList = new ArrayList<>(); + termList.add(enumTerm); + termList.add(idTerm); + termList.add(indexTerm); + EnumerationAtom enumAtom = new EnumerationAtom(termList); + EnumerationLiteral lit = new EnumerationLiteral(enumAtom); + Substitution substitution = new Substitution(); + substitution.put(enumTerm, ConstantTerm.getSymbolicInstance("enum1")); + substitution.put(idTerm, ConstantTerm.getSymbolicInstance("someElement")); + LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); + LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); + Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); + List> resultSubstitutions = result.getSubstitutions(); + Assert.assertEquals(1, resultSubstitutions.size()); + Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitutions.get(0).right); + Assert.assertTrue(resultSubstitutions.get(0).left.isVariableSet(indexTerm)); + } + + @Test + public void workingMemoryBasedVerifyPositiveGroundLiteralSatisfied() { + Predicate p = Predicate.getInstance("p", 2); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(p); + workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("y")), true); + VariableTerm x = VariableTerm.getInstance("X"); + VariableTerm y = VariableTerm.getInstance("Y"); + Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); + Substitution substitution = new Substitution(); + substitution.put(x, ConstantTerm.getSymbolicInstance("x")); + substitution.put(y, ConstantTerm.getSymbolicInstance("y")); + LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); + LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); + Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); + List> substitutions = result.getSubstitutions(); + Assert.assertEquals(1, substitutions.size()); + Assert.assertEquals(AssignmentStatus.TRUE, substitutions.get(0).right); + Substitution resultSubstitution = substitutions.get(0).left; + // With the given input substitution, lit is ground and satisfied - + // we expect the instantiator to verify that. + Assert.assertEquals(substitution, resultSubstitution); + } + + @Test + public void workingMemoryBasedVerifyPositiveGroundLiteralUnsatisfied() { + Predicate p = Predicate.getInstance("p", 2); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(p); + VariableTerm x = VariableTerm.getInstance("X"); + VariableTerm y = VariableTerm.getInstance("Y"); + Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); + Substitution substitution = new Substitution(); + substitution.put(x, ConstantTerm.getSymbolicInstance("x")); + substitution.put(y, ConstantTerm.getSymbolicInstance("y")); + LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); + LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); + // With the given input substitution, lit is ground, but not satisfied - + // we expect the instantiator to verify that and return an empty list of + // substitutions. + Assert.assertEquals(LiteralInstantiationResult.Type.STOP_BINDING, result.getType()); + } + + @Test + public void workingMemoryBasedInstantiatePositiveBasicLiteral() { + Predicate p = Predicate.getInstance("p", 2); + WorkingMemory workingMemory = new WorkingMemory(); + workingMemory.initialize(p); + workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("y")), true); + workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("z")), true); + VariableTerm x = VariableTerm.getInstance("X"); + VariableTerm y = VariableTerm.getInstance("Y"); + Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); + Substitution substitution = new Substitution(); + substitution.put(x, ConstantTerm.getSymbolicInstance("x")); + LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); + LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); + Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); + List> substitutions = result.getSubstitutions(); + Assert.assertEquals(2, substitutions.size()); + boolean ySubstituted = false; + boolean zSubstituted = false; + for (ImmutablePair resultSubstitution : substitutions) { + Assert.assertTrue(resultSubstitution.left.isVariableSet(y)); + Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitution.right); + if (resultSubstitution.left.eval(y).equals(ConstantTerm.getSymbolicInstance("y"))) { + ySubstituted = true; + } else if (resultSubstitution.left.eval(y).equals(ConstantTerm.getSymbolicInstance("z"))) { + zSubstituted = true; + } else { + Assert.fail("Invalid substitution for variable Y"); + } + } + Assert.assertTrue(ySubstituted && zSubstituted); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java new file mode 100644 index 000000000..4748e85ba --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java @@ -0,0 +1,218 @@ +/** + * 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.grounder.structure; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.solver.TrailAssignment; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertNotEquals; + +/** + * Copyright (c) 2018-2020, the Alpha Team. + */ +public class AnalyzeUnjustifiedTest { + + private final ProgramParser parser = new ProgramParser(); + + @Test + public void justifySimpleRules() { + Alpha system = new Alpha(); + String program = "p(X) :- q(X)." + + "q(X) :- p(X)." + + "q(5) :- r." + + "r :- not nr." + + "nr :- not r." + + ":- not p(5)."; + InputProgram parsedProgram = parser.parse(program); + NormalProgram normal = system.normalizeProgram(parsedProgram); + InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + AtomStore atomStore = new AtomStoreImpl(); + NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); + grounder.getNoGoods(null); + TrailAssignment assignment = new TrailAssignment(atomStore); + int rId = atomStore.get(new BasicAtom(Predicate.getInstance("r", 0))); + int nrId = atomStore.get(new BasicAtom(Predicate.getInstance("nr", 0))); + assignment.growForMaxAtomId(); + assignment.assign(rId, ThriceTruth.FALSE); + assignment.assign(nrId, ThriceTruth.TRUE); + BasicAtom p5 = new BasicAtom(Predicate.getInstance("p", 1), Collections.singletonList(ConstantTerm.getInstance(5))); + assignment.assign(atomStore.get(p5), ThriceTruth.MBT); + Set reasons = grounder.justifyAtom(atomStore.get(p5), assignment); + assertFalse(reasons.isEmpty()); + } + + @Test + public void justifyLargerRules() { + Alpha system = new Alpha(); + 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)."; + InputProgram parsedProgram = parser.parse(program); + NormalProgram normal = system.normalizeProgram(parsedProgram); + InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + 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() { + Alpha system = new Alpha(); + 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)."; + InputProgram parsedProgram = parser.parse(program); + NormalProgram normal = system.normalizeProgram(parsedProgram); + InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + 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 = Predicate.getInstance("_nq", 2, true); + Atom nqa = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("a"))); + Atom nqb = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("b"))); + Atom nqc = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("c"))); + Atom nqd = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("d"))); + Atom nqe = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("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() { + Alpha system = new Alpha(); + 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)."; + InputProgram parsedProgram = parser.parse(program); + NormalProgram normal = system.normalizeProgram(parsedProgram); + InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + AtomStore atomStore = new AtomStoreImpl(); + NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); + grounder.getNoGoods(null); + TrailAssignment assignment = new TrailAssignment(atomStore); + int rId = atomStore.get(new BasicAtom(Predicate.getInstance("r", 0))); + int nrId = atomStore.get(new BasicAtom(Predicate.getInstance("nr", 0))); + assignment.growForMaxAtomId(); + assignment.assign(rId, ThriceTruth.FALSE); + assignment.assign(nrId, ThriceTruth.TRUE); + BasicAtom p5 = new BasicAtom(Predicate.getInstance("p", 1), Collections.singletonList(ConstantTerm.getInstance(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(), Predicate.getInstance("forbidden", 2)); + } + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java new file mode 100644 index 000000000..b196005a4 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java @@ -0,0 +1,260 @@ +package at.ac.tuwien.kr.alpha.grounder.transformation; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.test.util.TestUtils; + +@RunWith(Parameterized.class) +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); + + @Parameters(name = "Run {index}: aspString={0}, programVerifier={1}, answerSetsVerifier={2}") + public static Iterable 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(new Object[] {pair.left, pair.right.left, pair.right.right })); + return paramList; + } + + private String aspString; + private Consumer programVerifier; + private Consumer> answerSetsVerifier; + + public StratifiedEvaluationRegressionTest(String aspString, Consumer programVerifier, Consumer> answerSetsVerifier) { + this.aspString = aspString; + this.programVerifier = programVerifier; + this.answerSetsVerifier = answerSetsVerifier; + } + + @Test + public void runTest() { + String aspStr = this.aspString; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(aspStr); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + this.programVerifier.accept(evaluated); + Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + this.answerSetsVerifier.accept(answerSets); + } + + private static void verifyProgramBasic(InternalProgram evaluated) { + TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("a"), TestUtils.basicAtomWithSymbolicTerms("b")); + Assert.assertEquals(2, evaluated.getFacts().size()); + Assert.assertTrue(evaluated.getRules().size() == 0); + } + + private static void verifyAnswerSetsBasic(Set answerSets) { + TestUtils.assertAnswerSetsEqual("a, b", answerSets); + } + + private static void verifyProgramBasicMultiInstance(InternalProgram evaluated) { + TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("q", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "b")); + Assert.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(InternalProgram evaluated) { + TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("s", "a", "b"), + TestUtils.basicAtomWithSymbolicTerms("s", "a", "d")); + Assert.assertEquals(7, evaluated.getFacts().size()); + Assert.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(InternalProgram 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()); + Assert.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(InternalProgram evaluated) { + Predicate num = Predicate.getInstance("num", 1); + TestUtils.assertFactsContainedInProgram(evaluated, new BasicAtom(Predicate.getInstance("max_num", 1), ConstantTerm.getInstance(10)), + new BasicAtom(num, ConstantTerm.getInstance(0)), + new BasicAtom(num, ConstantTerm.getInstance(1)), new BasicAtom(num, ConstantTerm.getInstance(2)), + new BasicAtom(num, ConstantTerm.getInstance(3)), new BasicAtom(num, ConstantTerm.getInstance(4)), + new BasicAtom(num, ConstantTerm.getInstance(5)), new BasicAtom(num, ConstantTerm.getInstance(6)), + new BasicAtom(num, ConstantTerm.getInstance(7)), new BasicAtom(num, ConstantTerm.getInstance(8)), + new BasicAtom(num, ConstantTerm.getInstance(9)), new BasicAtom(num, ConstantTerm.getInstance(10))); + LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); + Assert.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(InternalProgram evaluated) { + Assert.assertTrue(evaluated.getRules().isEmpty()); + Assert.assertTrue(evaluated.getRulesById().isEmpty()); + Assert.assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); + Assert.assertTrue(evaluated.getFacts().isEmpty()); + Assert.assertTrue(evaluated.getFactsByPredicate().isEmpty()); + } + + private static void verifyAnswerSetsEmptyProg(Set answerSets) { + Assert.assertEquals(1, answerSets.size()); + Assert.assertTrue(answerSets.iterator().next().isEmpty()); + } + + private static void verifyProgramFactsOnly(InternalProgram evaluated) { + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("a"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("b"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("c"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("p", "a"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "b", "c"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("r", "c", "c", "a"))); + Assert.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(InternalProgram evaluated) { + Assert.assertTrue(evaluated.getFacts().isEmpty()); + } + + private static void verifyAnswerSetsStratNoFacts(Set answerSets) { + Assert.assertEquals(1, answerSets.size()); + Assert.assertTrue(answerSets.iterator().next().isEmpty()); + } + + private static void verifyProgramStratWithFacts(InternalProgram evaluated) { + // rules should all be taken care of at this point + Assert.assertTrue(evaluated.getRules().isEmpty()); + Assert.assertTrue(evaluated.getRulesById().isEmpty()); + Assert.assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); + + // facts should be the full answer set + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "a"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "b"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("incomp", "b"))); + + // below facts from stratified evaluation + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("base", "a"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_base", "a", "a"))); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("dep_b_hlp", "a"))); + Assert.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(InternalProgram evaluated) { + Assert.assertEquals(0, evaluated.getRules().size()); + Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("equal"))); + } + + private static void verifyAnswerSetsEquality(Set answerSets) { + TestUtils.assertAnswerSetsEqual("equal", answerSets); + } + + private static void verifyProgramEqualityWithVar(InternalProgram evaluated) { + Assert.assertEquals(0, evaluated.getRules().size()); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("a", 1), ConstantTerm.getInstance(1)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("c", 1), ConstantTerm.getInstance(2)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("d", 1), ConstantTerm.getInstance(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/grounder/transformation/StratifiedEvaluationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java new file mode 100644 index 000000000..9bb9842be --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java @@ -0,0 +1,276 @@ +/** + * Copyright (c) 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.grounder.transformation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.antlr.v4.runtime.CharStreams; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.externals.Externals; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.common.program.Programs; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.config.InputConfig; +import at.ac.tuwien.kr.alpha.core.grounder.Instance; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.test.util.TestUtils; + +public class StratifiedEvaluationTest { + + @Test + public void testDuplicateFacts() { + String aspStr = "p(a). p(b). q(b). q(X) :- p(X)."; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(aspStr); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Instance qOfB = new Instance(TestUtils.basicAtomWithSymbolicTerms("q", "b").getTerms()); + Set facts = evaluated.getFactsByPredicate().get(at.ac.tuwien.kr.alpha.common.Predicate.getInstance("q", 1)); + int numQOfB = 0; + for (Instance at : facts) { + if (at.equals(qOfB)) { + numQOfB++; + } + } + assertEquals(1, numQOfB); + } + + @Test + public void testEqualityWithConstantTerms() { + String aspStr = "equal :- 1 = 1."; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(aspStr); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Atom equal = TestUtils.basicAtomWithSymbolicTerms("equal"); + 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)."; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(aspStr); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + TestUtils.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)."; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(asp); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + TestUtils.assertAnswerSetsEqual("p(a), q(a,b)", answerSets); + } + + @Test + public void testCountAggregate() { + String asp = "a. b :- 1 <= #count { 1 : a }."; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(asp); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + TestUtils.assertAnswerSetsEqual("a, b", answerSets); + } + + @Test + public void testIntervalFact() { + String asp = "a(1..3)."; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(asp); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); + } + + @Test + public void testAggregateSpecial() { + String asp = "thing(1..3).\n" + "% choose exactly one - since Alpha doesn't support bounds,\n" + "% this needs two constraints\n" + + "{ 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."; + Alpha system = new Alpha(); + // system.getConfig().setUseNormalizationGrid(true); + InputProgram prg = system.readProgramString(asp); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("allThings"))); + Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + TestUtils.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."; + Alpha system = new Alpha(); + InputProgram prg = system.readProgramString(asp); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + TestUtils.assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); + } + + @at.ac.tuwien.kr.alpha.api.externals.Predicate + 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]."; + Alpha alpha = new Alpha(); + InputConfig inputCfg = InputConfig.forString(asp); + inputCfg.addPredicateMethod("sayTrue", Externals.processPredicateMethod(this.getClass().getMethod("sayTrue", Object.class))); + InputProgram input = alpha.readProgram(inputCfg); + NormalProgram normal = alpha.normalizeProgram(input); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Set answerSets = alpha.solve(evaluated).collect(Collectors.toSet()); + TestUtils.assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); + } + + /** + * Tests an encoding associated with the partner units problem (PUP) that computes a topological order to be used by + * domain-specific heuristics. The entire program can be solved by stratified evaluation. + */ + @Test + public void testPartnerUnitsProblemTopologicalOrder() throws IOException { + Alpha system = new Alpha(); + InputProgram prg = new ProgramParser().parse(CharStreams.fromStream(this.getClass().getResourceAsStream("/partial-eval/pup_topological_order.asp"))); + NormalProgram normal = system.normalizeProgram(prg); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); + InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + assertTrue("Not all rules eliminated by stratified evaluation", evaluated.getRules().isEmpty()); + assertEquals(57, evaluated.getFacts().size()); + } + + /** + * 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 + String expectedAnswerSet = "basefact1(1), basefact2(1), max_value(10), min_value(1), " + + "basefact1(9), basefact2(9), base(1), base(9), " + + "inc_value(1), inc_value(2), inc_value(2), inc_value(3), " + + "inc_value(4), inc_value(5), inc_value(6), inc_value(7), " + + "inc_value(8)"; + //@formatter:on + InputProgram prog = Programs.fromInputStream( + StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), + new HashMap<>()); + Alpha systemStratified = new Alpha(); + systemStratified.getConfig().setEvaluateStratifiedPart(true); + Set asStrat = systemStratified.solve(prog).collect(Collectors.toSet()); + TestUtils.assertAnswerSetsEqual(expectedAnswerSet, asStrat); + Alpha systemNoStratEval = new Alpha(); + systemNoStratEval.getConfig().setEvaluateStratifiedPart(false); + Set as = systemNoStratEval.solve(prog).collect(Collectors.toSet()); + TestUtils.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" + + " R = K + 1."; + //@formatter:on + Alpha alpha = new Alpha(); + InputProgram prog = alpha.readProgramString(asp); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(alpha.normalizeProgram(prog)); + StratifiedEvaluation evaluation = new StratifiedEvaluation(); + InternalProgram evaluated = evaluation.apply(analyzed); + Predicate rank = Predicate.getInstance("thing_rank", 2); + BasicAtom rank1 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getInstance(1)); + BasicAtom rank2 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("b"), ConstantTerm.getInstance(2)); + BasicAtom rank3 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("c"), ConstantTerm.getInstance(3)); + List evaluatedFacts = evaluated.getFacts(); + Assert.assertTrue(evaluatedFacts.contains(rank1)); + Assert.assertTrue(evaluatedFacts.contains(rank2)); + Assert.assertTrue(evaluatedFacts.contains(rank3)); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java new file mode 100644 index 000000000..d237fb548 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java @@ -0,0 +1,266 @@ +/* + * 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.solver; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.config.SystemConfig; +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.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; +import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic; +import at.ac.tuwien.kr.alpha.test.util.TestUtils; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Random; +import java.util.Set; + +@RunWith(Parameterized.class) +public abstract class AbstractSolverTests { + + private static final String[] NON_DEPRECATED_HEURISTICS_NAMES; + static { + final List nonDeprecatedHeuristicsNames = new ArrayList<>(); + for (Field field : Heuristic.class.getFields()) { + if (field.getAnnotation(Deprecated.class) == null) { + nonDeprecatedHeuristicsNames.add(field.getName()); + } + } + NON_DEPRECATED_HEURISTICS_NAMES = nonDeprecatedHeuristicsNames.toArray(new String[]{}); + } + + private final ProgramParser parser = new ProgramParser(); + + /** + * Sets the logging level to TRACE. Useful for debugging; call at beginning of test case. + */ + protected static void enableTracing() { + Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + root.setLevel(ch.qos.logback.classic.Level.TRACE); + } + + protected static void enableDebugLog() { + Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + root.setLevel(Level.DEBUG); + } + + /** + * Calling this method in a test leads to the test being ignored for the naive solver. + * Note: use this sparingly and only on tests that require too much run time with the naive solver. + */ + void ignoreTestForNaiveSolver() { + org.junit.Assume.assumeFalse(solverName.equals("naive")); + } + + /** + * Calling this method in a test leads to the test being ignored for non-default domain-independent heuristics. + * Note: use this sparingly and only on tests that require too much run time with non-default heuristics + * (which are not tuned for good performance as well as VSIDS). + */ + void ignoreNonDefaultDomainIndependentHeuristics() { + org.junit.Assume.assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + } + + private static String[] getProperty(String subKey, String def) { + return System.getProperty("test." + subKey, def).split(","); + } + + @Parameters(name = "{0}/{1}/{2}/{3}/seed={4}/checks={5}/gtc={6}/gtr={7}/dir={8}") + public static Collection parameters() { + // Check whether we are running in a CI environment. + boolean ci = Boolean.valueOf(System.getenv("CI")); + + String[] solvers = getProperty("solvers", ci ? "default,naive" : "default"); + String[] grounders = getProperty("grounders", "naive"); + String[] stores = getProperty("stores", ci ? "alpharoaming,naive" : "alpharoaming"); + String[] heuristics = getProperty("heuristics", ci ? "NON_DEPRECATED" : "NAIVE,VSIDS"); + String[] gtcValues = getProperty("grounderToleranceConstraints", "strict,permissive"); + String[] gtrValues = getProperty("grounderToleranceRules", "strict"); + String[] dirValues = getProperty("disableInstanceRemoval", ci ? "false,true" : "false"); + + // "ALL" is a magic value that will be expanded to contain all heuristics. + if ("ALL".equals(heuristics[0])) { + BranchingHeuristicFactory.Heuristic[] values = BranchingHeuristicFactory.Heuristic.values(); + heuristics = new String[values.length]; + int i = 0; + for (BranchingHeuristicFactory.Heuristic heuristic : values) { + heuristics[i++] = heuristic.toString(); + } + } + // "NON_DEPRECATED" is a magic value that will be expanded to contain all non-deprecated heuristics. + if ("NON_DEPRECATED".equals(heuristics[0])) { + heuristics = NON_DEPRECATED_HEURISTICS_NAMES; + } + + // NOTE: + // It is handy to set the seed for reproducing bugs. However, the reverse is also sometimes needed: + // A test case fails, now what was the seed that "caused" it? To allow this, we need full control over + // the seed, so we generate one in any case. + // If your test case fails you can inspect the property called "seed" of AbstractSolverTests and extract + // its value. + String seedProperty = System.getProperty("seed", ci ? "0" : ""); + long seed = seedProperty.isEmpty() ? (new Random().nextLong()) : Long.valueOf(seedProperty); + + boolean checks = true; + + Collection factories = new ArrayList<>(); + + for (String solver : solvers) { + for (String grounder : grounders) { + for (String store : stores) { + for (String heuristic : heuristics) { + for (String gtc : gtcValues) { + for (String gtr : gtrValues) { + for (String dir : dirValues) { + factories.add(new Object[]{ + solver, grounder, store, BranchingHeuristicFactory.Heuristic.valueOf(heuristic), seed, checks, gtc, gtr, Boolean.valueOf(dir) + }); + } + } + } + } + } + } + } + + return factories; + } + + @Parameter(0) + public String solverName; + + @Parameter(1) + public String grounderName; + + @Parameter(2) + public String storeName; + + @Parameter(3) + public BranchingHeuristicFactory.Heuristic heuristic; + + @Parameter(4) + public long seed; + + @Parameter(5) + public boolean checks; + + @Parameter(6) + public String grounderToleranceConstraints; + + @Parameter(7) + public String grounderToleranceRules; + + @Parameter(8) + public boolean disableInstanceRemoval; + + protected Solver getInstance(AtomStore atomStore, Grounder grounder) { + return SolverFactory.getInstance(buildSystemConfig(), atomStore, grounder); + } + + private SystemConfig buildSystemConfig() { + SystemConfig config = new SystemConfig(); + config.setSolverName(solverName); + config.setNogoodStoreName(storeName); + config.setSeed(seed); + config.setBranchingHeuristic(heuristic); + config.setDebugInternalChecks(checks); + config.setDisableJustificationSearch(false); + return config; + } + + protected Solver getInstance(InputProgram program) { + Alpha system = new Alpha(); + AtomStore atomStore = new AtomStoreImpl(); + NormalProgram normalized = system.normalizeProgram(program); + InternalProgram preprocessed = InternalProgram.fromNormalProgram(normalized); + return getInstance(atomStore, GrounderFactory.getInstance(grounderName, preprocessed, atomStore, true)); + } + + protected Solver getInstance(String program) { + return getInstance(CharStreams.fromString(program)); + } + + protected Solver getInstance(CharStream program) { + try { + return getInstance(parser.parse(program)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + protected Set collectSet(String program) { + return getInstance(program).collectSet(); + } + + protected Set collectSet(InputProgram program) { + return getInstance(program).collectSet(); + } + + protected Set collectSet(CharStream program) { + return getInstance(program).collectSet(); + } + + protected void assertAnswerSets(String program, String... answerSets) { + Set actualAnswerSets = collectSet(program); + TestUtils.assertAnswerSetsEqual(answerSets, actualAnswerSets); + } + + protected void assertAnswerSet(String program, String answerSet) { + Set actualAnswerSets = collectSet(program); + TestUtils.assertAnswerSetsEqual(answerSet, actualAnswerSets); + } + + protected void assertAnswerSetsWithBase(String program, String base, String... answerSets) { + Set actualAnswerSets = collectSet(program); + TestUtils.assertAnswerSetsEqualWithBase(base, answerSets, actualAnswerSets); + } + + protected void assertAnswerSets(String program, Set answerSets) { + Set actualAnswerSets = collectSet(program); + TestUtils.assertAnswerSetsEqual(answerSets, actualAnswerSets); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java new file mode 100644 index 000000000..c21d5e971 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java @@ -0,0 +1,38 @@ +/** + * 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.solver; + +/** + * Executes {@link AggregatesTest} with {@code normalizationCountingGrid=true}. + */ +public class AggregatesCardinalityCountingGridTest extends AggregatesTest { + + @Override + protected boolean useCountingGridNormalization() { + return true; + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java new file mode 100644 index 000000000..9f0558e35 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java @@ -0,0 +1,38 @@ +/** + * 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.solver; + +/** + * Executes {@link AggregatesTest} with {@code normalizationCountingGrid=false}. + */ +public class AggregatesCardinalitySortingCircuitTest extends AggregatesTest { + + @Override + protected boolean useCountingGridNormalization() { + return false; + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java new file mode 100644 index 000000000..107e1790a --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2018-2019 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.solver; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; +import at.ac.tuwien.kr.alpha.core.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.core.grounder.transformation.CardinalityNormalization; +import at.ac.tuwien.kr.alpha.core.grounder.transformation.SumNormalization; + +import org.junit.Test; + +import java.io.IOException; + +/** + * Tests if correct answer sets for programs containing aggregates are computed. + * Only aggregates known to by syntactically supported by {@link CardinalityNormalization} or {@link SumNormalization} are currently tested. + */ +public abstract class AggregatesTest extends AbstractSolverTests { + + private static final String LS = System.lineSeparator(); + + @Test + public void testAggregate_Count_Ground_Positive() throws IOException { + String program = "a." + LS + + "b :- 1 <= #count { 1 : a }."; + assertAnswerSet(program, "a,b"); + } + + @Test + public void testAggregate_Count_Ground_Negative() throws IOException { + String program = "{a}." + LS + + "b :- not c." + LS + + "c :- 1 <= #count { 1 : a }."; + assertAnswerSets(program, "a,c", "b"); + } + + @Test + public void testAggregate_Count_NonGround_Positive() throws IOException { + String program = "n(1..3)." + LS + + "{x(N)} :- n(N)." + LS + + "min(3)." + LS + + "ok :- min(M), M <= #count { N : n(N), x(N) }."; + assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(3)", + "", "x(1)", "x(2)", "x(3)", "x(1), x(2)", "x(1), x(3)", + "x(2), x(3)", "x(1), x(2), x(3), ok"); + } + + @Test + public void testAggregate_Count_NonGround_LowerAndUpper() throws IOException { + String program = "n(1..3)." + LS + + "{x(N)} :- n(N)." + LS + + "min(2)." + LS + + "max(2)." + LS + + "ok :- min(M), M <= #count { N : n(N), x(N) }, not exceedsMax." + LS + + "exceedsMax :- max(M), M1 = M + 1, M1 <= #count { N : n(N), x(N) }."; + System.out.println(program); + assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(2), max(2)", + "", "x(1)", "x(2)", "x(3)", "x(1), x(2), ok", "x(1), x(3), ok", + "x(2), x(3), ok", "x(1), x(2), x(3), exceedsMax"); + } + + @Test + public void testAggregate_Sum_Ground_Lower() throws IOException { + String program = "a." + LS + + "b :- 5 <= #sum { 2 : a; 3 }."; + assertAnswerSet(program, "a,b"); + } + + @Test + public void testAggregate_Sum_NonGround_LowerAndUpper() throws IOException { + String program = "n(1..3)." + LS + + "{x(N)} :- n(N)." + LS + + "min(3)." + LS + + "max(4)." + LS + + "ok :- min(M), M <= #sum { N : n(N), x(N) }, not exceedsMax." + LS + + "exceedsMax :- max(M), M1 = M + 1, M1 <= #sum { N : n(N), x(N) }."; + System.out.println(program); + assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(3), max(4)", + "", "x(1)", "x(2)", "x(3), ok", "x(1), x(2), ok", "x(1), x(3), ok", + "x(2), x(3), exceedsMax", "x(1), x(2), x(3), exceedsMax"); + } + + @Test + public void testAggregate_Sum_NonGround_Lower() throws IOException { + String program = "n(1..3)." + LS + + "{x(N)} :- n(N)." + LS + + "min(3)." + LS + + "ok :- min(M), M <= #sum { N : n(N), x(N) }."; + System.out.println(program); + assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(3)", + "", "x(1)", "x(2)", "x(3), ok", "x(1), x(2), ok", "x(1), x(3), ok", + "x(2), x(3), ok", "x(1), x(2), x(3), ok"); + } + + /** + * TODO: Currently it is a bit tedious to compute sums. Support for equality comparison of aggregates, e.g. {@code sum(S) :- S = #sum { N : n(N), x(N) }.} is still lacking. + */ + @Test + public void testAggregate_Sum_Computed() throws IOException { + ignoreTestForNaiveSolver(); // Do not run this test case with the naive solver. + String program = "n(1..3)." + LS + + "{x(N)} :- n(N)." + LS + + "potential_sum(0..6)." + LS + + "min(S) :- S <= #sum { N : n(N), x(N) }, potential_sum(S)." + LS + + "sum(S) :- min(S), not min(Sp1), Sp1 = S+1."; + assertAnswerSetsWithBase(program, "n(1), n(2), n(3), potential_sum(0), potential_sum(1), " + + "potential_sum(2), potential_sum(3), potential_sum(4), potential_sum(5), potential_sum(6)", + "min(0), sum(0)", + "x(1), min(0), min(1), sum(1)", + "x(2), min(0), min(1), min(2), sum(2)", + "x(3), min(0), min(1), min(2), min(3), sum(3)", + "x(1), x(2), min(0), min(1), min(2), min(3), sum(3)", + "x(1), x(3), min(0), min(1), min(2), min(3), min(4), sum(4)", + "x(2), x(3), min(0), min(1), min(2), min(3), min(4), min(5), sum(5)", + "x(1), x(2), x(3), min(0), min(1), min(2), min(3), min(4), min(5), min(6), sum(6)"); + } + + @Test + public void testAggregate_Count_GlobalVariable() throws IOException { + String program = "box(1..2)." + LS + + "in(1,1)." + LS + + "in(1,2)." + LS + + "in(2,2)." + LS + + "full(B) :- box(B), 2 <= #count { I : in(I,B) }."; + assertAnswerSetsWithBase(program, "box(1), box(2), in(1,1), in(1,2), in(2,2)", + "full(2)"); + } + + @Test + public void testAggregate_Sum_GlobalVariable() throws IOException { + String program = "box(1..2)." + LS + + "item_size(I,I) :- I=1..2." + LS + + "in(1,1)." + LS + + "in(1,2)." + LS + + "in(2,2)." + LS + + "full(B) :- box(B), 3 <= #sum { S : item_size(I,S), in(I,B) }."; + assertAnswerSetsWithBase(program, "box(1), box(2), item_size(1,1), item_size(2,2), in(1,1), in(1,2), in(2,2)", + "full(2)"); + } + + @Override + protected Solver getInstance(InputProgram program) { + Alpha system = new Alpha(); + system.getConfig().setUseNormalizationGrid(useCountingGridNormalization()); + AtomStore atomStore = new AtomStoreImpl(); + NormalProgram normal = system.normalizeProgram(program); + InternalProgram preprocessed = InternalProgram.fromNormalProgram(normal); + return super.getInstance(atomStore, GrounderFactory.getInstance(grounderName, preprocessed, atomStore, p->true, new GrounderHeuristicsConfiguration(), true)); + } + + protected abstract boolean useCountingGridNormalization(); + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java new file mode 100644 index 000000000..0dce2db91 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java @@ -0,0 +1,32 @@ +package at.ac.tuwien.kr.alpha.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/solver/AtomCounterTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java new file mode 100644 index 000000000..9aae4b601 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2019 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.solver; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.ComparisonOperator; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.atoms.ChoiceAtom; +import at.ac.tuwien.kr.alpha.core.grounder.atoms.RuleAtom; + +public class AtomCounterTests { + + private AtomStore atomStore; + + @Before + public void setUp() { + this.atomStore = new AtomStoreImpl(); + } + + @Test + public void testGetNumberOfAtoms() throws NoSuchMethodException { + final AtomCounter atomCounter = atomStore.getAtomCounter(); + + expectGetNumberOfAtoms(atomCounter, BasicAtom.class, 0); + expectGetNumberOfAtoms(atomCounter, AggregateAtom.class, 0); + expectGetNumberOfAtoms(atomCounter, ChoiceAtom.class, 0); + expectGetNumberOfAtoms(atomCounter, RuleAtom.class, 0); + + createBasicAtom1(); + createBasicAtom2(); + createAggregateAtom(); + createChoiceAtom(); + createRuleAtom(); + + expectGetNumberOfAtoms(atomCounter, BasicAtom.class, 2); + expectGetNumberOfAtoms(atomCounter, AggregateAtom.class, 1); + expectGetNumberOfAtoms(atomCounter, ChoiceAtom.class, 1); + expectGetNumberOfAtoms(atomCounter, RuleAtom.class, 1); + } + + @Test + public void testGetStatsByType() throws NoSuchMethodException { + final AtomCounter atomCounter = atomStore.getAtomCounter(); + + createBasicAtom1(); + createBasicAtom2(); + createAggregateAtom(); + createChoiceAtom(); + createRuleAtom(); + + expectGetStatsByType(atomCounter, BasicAtom.class, 2); + expectGetStatsByType(atomCounter, AggregateAtom.class, 1); + expectGetStatsByType(atomCounter, ChoiceAtom.class, 1); + expectGetStatsByType(atomCounter, RuleAtom.class, 1); + } + + private void createBasicAtom1() { + atomStore.putIfAbsent(new BasicAtom(Predicate.getInstance("p", 0))); + } + + private void createBasicAtom2() { + atomStore.putIfAbsent(new BasicAtom(Predicate.getInstance("q", 1), ConstantTerm.getInstance(1))); + } + + private void createAggregateAtom() { + final ConstantTerm c1 = ConstantTerm.getInstance(1); + final ConstantTerm c2 = ConstantTerm.getInstance(2); + final ConstantTerm c3 = ConstantTerm.getInstance(3); + List basicTerms = Arrays.asList(c1, c2, c3); + AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, Collections.singletonList(new BasicAtom(Predicate.getInstance("p", 3), c1, c2, c3).toLiteral())); + atomStore.putIfAbsent(new AggregateAtom(ComparisonOperatorImpl.LE, c1, null, null, AggregateAtom.AGGREGATEFUNCTION.COUNT, Collections.singletonList(aggregateElement))); + } + + private void createChoiceAtom() { + atomStore.putIfAbsent(ChoiceAtom.on(1)); + } + + private void createRuleAtom() { + Atom atomAA = new BasicAtom(Predicate.getInstance("aa", 0)); + InternalRule ruleAA = new InternalRule(new NormalHead(atomAA), Collections.singletonList(new BasicAtom(Predicate.getInstance("bb", 0)).toLiteral(false))); + atomStore.putIfAbsent(new RuleAtom(ruleAA, new Substitution())); + } + + private void expectGetNumberOfAtoms(AtomCounter atomCounter, Class classOfAtoms, int expectedNumber) { + assertEquals("Unexpected number of " + classOfAtoms.getSimpleName() + "s", expectedNumber, atomCounter.getNumberOfAtoms(classOfAtoms)); + } + + private void expectGetStatsByType(AtomCounter atomCounter, Class classOfAtoms, int expectedNumber) { + assertTrue("Expected number of " + classOfAtoms.getSimpleName() + "s not contained in stats string", atomCounter.getStatsByType().contains(classOfAtoms.getSimpleName() + ": " + expectedNumber)); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java new file mode 100644 index 000000000..7327bea6e --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2017 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.solver; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +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.grounder.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static org.junit.Assert.assertTrue; + +public class ChoiceManagerTests extends AbstractSolverTests { + private Grounder grounder; + private ChoiceManager choiceManager; + private AtomStore atomStore; + + @Before + public void setUp() { + Alpha system = new Alpha(); + String testProgram = "h :- b1, b2, not b3, not b4."; + InputProgram parsedProgram = new ProgramParser().parse(testProgram); + NormalProgram normalProgram = system.normalizeProgram(parsedProgram); + InternalProgram internalProgram = InternalProgram.fromNormalProgram(normalProgram); + atomStore = new AtomStoreImpl(); + grounder = new NaiveGrounder(internalProgram, atomStore, true); + WritableAssignment assignment = new TrailAssignment(atomStore); + NoGoodStore store = new NoGoodStoreAlphaRoaming(assignment); + choiceManager = new ChoiceManager(assignment, store); + } + + @Test + public void testIsAtomChoice() { + Collection noGoods = getNoGoods(); + choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); + for (NoGood noGood : noGoods) { + for (Integer literal : noGood) { + int atom = atomOf(literal); + String atomToString = atomStore.atomToString(atom); + if (atomToString.startsWith(RuleAtom.PREDICATE.getName())) { + assertTrue("Atom not choice: " + atomToString, choiceManager.isAtomChoice(atom)); + } + } + } + } + + private Collection getNoGoods() { + return grounder.getNoGoods(null).values(); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java new file mode 100644 index 000000000..5de21fbf0 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java @@ -0,0 +1,44 @@ +package at.ac.tuwien.kr.alpha.solver; + +import org.antlr.v4.runtime.CharStreams; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +/** + * A more fine-grained test, mostly intended for debugging purposes, of the "simple" instance of the Hanoi Tower + * problem. + * + * Copyright (c) 2020, the Alpha Team. + */ +public class HanoiTowerDetailedTest { + + private static final String HANOI_TOWER_SRC = "/HanoiTower_Alpha.asp"; + private static final String SIMPLE_INSTANCE = "/HanoiTower_instances/simple.asp"; + + @Test + public void testHanoiTower() throws IOException { + Alpha alpha = new Alpha(); + // alpha.getConfig().setEvaluateStratifiedPart(false); + InputProgram.Builder programBuilder = InputProgram.builder(); + ProgramParser parser = new ProgramParser(); + InputStream baseProgStream = HanoiTowerDetailedTest.class.getResourceAsStream(HANOI_TOWER_SRC); + InputStream instanceStream = HanoiTowerDetailedTest.class.getResourceAsStream(SIMPLE_INSTANCE); + programBuilder.accumulate(parser.parse(CharStreams.fromStream(baseProgStream))); + programBuilder.accumulate(parser.parse(CharStreams.fromStream(instanceStream))); + InputProgram prog = programBuilder.build(); + InternalProgram preprocessed = InternalProgram.fromNormalProgram(alpha.normalizeProgram(prog)); + Optional solveResult = alpha.solve(preprocessed).findFirst(); + Assert.assertTrue(solveResult.isPresent()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java new file mode 100644 index 000000000..3b8c8a9c7 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2017-2019 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.solver; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.SortedSet; + +import static org.junit.Assert.assertTrue; + +/** + * Tests {@link AbstractSolver} using some hanoi tower test cases (see https://en.wikipedia.org/wiki/Tower_of_Hanoi). + * + */ +public class HanoiTowerTest extends AbstractSolverTests { + + private static final Logger LOGGER = LoggerFactory.getLogger(HanoiTowerTest.class); + + private final ProgramParser parser = new ProgramParser(); + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testInstance1() throws IOException { + testHanoiTower(1); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testInstance2() throws IOException { + testHanoiTower(2); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testInstance3() throws IOException { + testHanoiTower(3); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testInstance4() throws IOException { + testHanoiTower(4); + } + + @Test(timeout = 60000) + public void testSimple() throws IOException { + ignoreTestForNaiveSolver(); + ignoreNonDefaultDomainIndependentHeuristics(); + testHanoiTower("simple"); + } + + private void testHanoiTower(int instance) throws IOException { + testHanoiTower(String.valueOf(instance)); + } + + private void testHanoiTower(String instance) throws IOException { + Alpha system = new Alpha(); + InputProgram prog = system.readProgramFiles(false, null, Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), + Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); + Solver solver = getInstance(prog); + Optional answerSet = solver.stream().findFirst(); + assertTrue(answerSet.isPresent()); + checkGoal(prog, answerSet.get()); + } + + /** + * Conducts a very simple, non-comprehensive goal check (i.e. it may classify answer sets as correct that are actually wrong) by checking if for every goal/3 + * fact in the input there is a corresponding on/3 atom in the output. + */ + private void checkGoal(InputProgram parsedProgram, AnswerSet answerSet) { + Predicate ongoal = Predicate.getInstance("ongoal", 2); + Predicate on = Predicate.getInstance("on", 3); + int steps = getSteps(parsedProgram); + SortedSet onInstancesInAnswerSet = answerSet.getPredicateInstances(on); + for (Atom atom : parsedProgram.getFacts()) { + if (atom.getPredicate().getName().equals(ongoal.getName()) && atom.getPredicate().getArity() == ongoal.getArity()) { + Term expectedTop = atom.getTerms().get(0); + Term expectedBottom = atom.getTerms().get(1); + Term expectedSteps = ConstantTerm.getInstance(steps); + Atom expectedAtom = new BasicAtom(on, expectedSteps, expectedBottom, expectedTop); + assertTrue("Answer set does not contain " + expectedAtom, onInstancesInAnswerSet.contains(expectedAtom)); + } + } + } + + private int getSteps(InputProgram parsedProgram) { + Predicate steps = Predicate.getInstance("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()); + } + } + throw new IllegalArgumentException("No steps atom found in input program."); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java new file mode 100644 index 000000000..f038ec0ba --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java @@ -0,0 +1,319 @@ +/** + * Copyright (c) 2017 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.solver; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +/** + * Tests rule transformations described in the following research paper, and their effects on performance: + * + * Anger, Christian; Gebser, Martin; Janhunen, Tomi; Schaub, Torsten (2006): What's a head without a body? In G. Brewka, S. Coradeschi, A. Perini, P. Traverso + * (Eds.): Proceedings of the Seventeenth European Conference on Artificial Intelligence (ECAI'06): IOS Press, pp. 769–770. + * + */ +public class HeadBodyTransformationTests extends AbstractSolverTests { + + @Before + public void printSolverName() { + System.out.println(solverName); + } + + @Test(timeout = 10000) + public void testProgramB_N1() throws IOException { + test(constructProgramB(1)); + } + + @Test(timeout = 10000) + public void testProgramB_Transformed_N1() throws IOException { + test(constructProgramB_TransformationB(1)); + } + + @Test(timeout = 10000) + public void testProgramA_N1() throws IOException { + test(constructProgramA(1)); + } + + @Test(timeout = 10000) + public void testProgramA_Transformed_N1() throws IOException { + test(constructProgramA_TransformationA(1)); + } + + @Test(timeout = 10000) + public void testProgramB_N2() throws IOException { + test(constructProgramB(2)); + } + + @Test(timeout = 10000) + public void testProgramB_Transformed_N2() throws IOException { + test(constructProgramB_TransformationB(2)); + } + + @Test(timeout = 10000) + public void testProgramA_N2() throws IOException { + test(constructProgramA(2)); + } + + @Test(timeout = 10000) + public void testProgramA_Transformed_N2() throws IOException { + test(constructProgramA_TransformationA(2)); + } + + @Test(timeout = 10000) + public void testProgramB_N4() throws IOException { + test(constructProgramB(4)); + } + + @Test(timeout = 10000) + public void testProgramB_Transformed_N4() throws IOException { + test(constructProgramB_TransformationB(4)); + } + + @Test(timeout = 10000) + public void testProgramA_N4() throws IOException { + test(constructProgramA(4)); + } + + @Test(timeout = 10000) + public void testProgramA_Transformed_N4() throws IOException { + test(constructProgramA_TransformationA(4)); + } + + @Test(timeout = 10000) + public void testProgramB_N8() throws IOException { + test(constructProgramB(8)); + } + + @Test(timeout = 10000) + public void testProgramB_Transformed_N8() throws IOException { + test(constructProgramB_TransformationB(8)); + } + + @Test(timeout = 10000) + public void testProgramA_N8() throws IOException { + test(constructProgramA(8)); + } + + @Test(timeout = 10000) + public void testProgramA_Transformed_N8() throws IOException { + test(constructProgramA_TransformationA(8)); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testProgramB_N16() throws IOException { + test(constructProgramB(16)); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testProgramB_Transformed_N16() throws IOException { + test(constructProgramB_TransformationB(16)); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testProgramA_N16() throws IOException { + test(constructProgramA(16)); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testProgramA_Transformed_N16() throws IOException { + test(constructProgramA_TransformationA(16)); + } + + private void test(InputProgram program) { + Solver solver = getInstance(program); + Optional answerSet = solver.stream().findFirst(); + assertFalse(answerSet.isPresent()); + } + + /** + * Constructs program Pi^n_B from the paper + * + * @param n + */ + private InputProgram constructProgramB(int n) { + int numberOfRules = 3 * n + 1; + List strRules = new ArrayList<>(numberOfRules); + strRules.add("x :- not x."); + strRules.addAll(createXRules(n)); + strRules.addAll(createABRules(n)); + return checkNumberOfRulesAndParse(strRules, numberOfRules); + } + + /** + * Constructs program Pi^n_B transformed with Tau_B from the paper + * + * @param n + */ + private InputProgram constructProgramB_TransformationB(int n) { + int numberOfRules = 6 * n + 2; + List strRules = new ArrayList<>(numberOfRules); + strRules.add("b_notX :- not x."); + strRules.add("x :- b_notX."); + strRules.addAll(createXRules_TransformationB(n)); + strRules.addAll(createABRules_TransformationB(n)); + return checkNumberOfRulesAndParse(strRules, numberOfRules); + } + + /** + * Constructs program Pi^n_a from the paper + * + * @param n + */ + private InputProgram constructProgramA(int n) { + int numberOfRules = 4 * n + 1; + List strRules = new ArrayList<>(numberOfRules); + strRules.add(createXCRule(n)); + strRules.addAll(createCRules(n)); + strRules.addAll(createABRules(n)); + return checkNumberOfRulesAndParse(strRules, numberOfRules); + } + + /** + * Constructs program Pi^n_a from the paper + * + * @param n + */ + private InputProgram constructProgramA_TransformationA(int n) { + int numberOfRules = 7 * n + 2; + List strRules = new ArrayList<>(numberOfRules); + strRules.addAll(createXCRules_TransformationA(n)); + strRules.addAll(createCRules_TransformationA(n)); + strRules.addAll(createABRules_TransformationA(n)); + return checkNumberOfRulesAndParse(strRules, numberOfRules); + } + + private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { + assertEquals(numberOfRules, strRules.size()); + String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); + InputProgram parsedProgram = new ProgramParser().parse(strProgram); + assertEquals(numberOfRules, parsedProgram.getRules().size()); + return parsedProgram; + } + + private Collection createXRules(int n) { + Collection rules = new ArrayList<>(n); + for (int i = 1; i <= n; i++) { + rules.add(String.format("x :- not a%d, not b%d.", i, i)); + } + return rules; + } + + private Collection createXRules_TransformationB(int n) { + Collection rules = new ArrayList<>(n); + for (int i = 1; i <= n; i++) { + String beta = String.format("b_nota%dnotb%d", i, i); + rules.add(String.format("%s :- not a%d, not b%d.", beta, i, i)); + rules.add(String.format("x :- %s.", beta)); + } + return rules; + } + + private Collection createABRules(int n) { + Collection rules = new ArrayList<>(2 * n); + for (int i = 1; i <= n; i++) { + rules.add(String.format("a%d :- not b%d.", i, i)); + rules.add(String.format("b%d :- not a%d.", i, i)); + } + return rules; + } + + private Collection createABRules_TransformationB(int n) { + Collection rules = new ArrayList<>(4 * n); + for (int i = 1; i <= n; i++) { + rules.add(String.format("b_notb%d :- not b%d.", i, i)); + rules.add(String.format("a%d :- b_notb%d.", i, i)); + rules.add(String.format("b_nota%d :- not a%d.", i, i)); + rules.add(String.format("b%d :- b_nota%d.", i, i)); + } + return rules; + } + + private Collection createABRules_TransformationA(int n) { + Collection rules = new ArrayList<>(4 * n); + for (int i = 1; i <= n; i++) { + rules.add(String.format("a_a%d :- not b%d.", i, i)); + rules.add(String.format("a%d :- a_a%d.", i, i)); + rules.add(String.format("a_b%d :- not a%d.", i, i)); + rules.add(String.format("b%d :- a_b%d.", i, i)); + } + return rules; + } + + private String createXCRule(int n) { + StringBuilder stringBuilder = new StringBuilder("x :- "); + for (int i = 1; i <= n; i++) { + stringBuilder.append(String.format("c%d, ", i)); + } + stringBuilder.append("not x."); + return stringBuilder.toString(); + } + + private Collection createXCRules_TransformationA(int n) { + Collection rules = new ArrayList<>(2); + rules.add("x :- a_x."); + rules.add("a_" + createXCRule(n)); + return rules; + } + + private Collection createCRules(int n) { + Collection rules = new ArrayList<>(2 * n); + for (int i = 1; i <= n; i++) { + rules.add(String.format("c%d :- not a%d.", i, i)); + rules.add(String.format("c%d :- not b%d.", i, i)); + } + return rules; + } + + private Collection createCRules_TransformationA(int n) { + Collection rules = new ArrayList<>(3 * n); + for (int i = 1; i <= n; i++) { + rules.add(String.format("a_c%d :- not a%d.", i, i)); + rules.add(String.format("a_c%d :- not b%d.", i, i)); + rules.add(String.format("c%d :- a_c%d.", i, i)); + } + return rules; + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java new file mode 100644 index 000000000..ab6afb5eb --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java @@ -0,0 +1,149 @@ +/** + * Copyright (c) 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.solver; + +import at.ac.tuwien.kr.alpha.common.*; +import org.junit.Before; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static org.junit.Assert.*; + +public class LearnedNoGoodDeletionTest { + + private NoGoodStoreAlphaRoaming store; + private LearnedNoGoodDeletion learnedNoGoodDeletion; + + public LearnedNoGoodDeletionTest() { + AtomStore atomStore = new AtomStoreImpl(); + AtomStoreTest.fillAtomStore(atomStore, 200); + WritableAssignment assignment = new TrailAssignment(atomStore); + assignment.growForMaxAtomId(); + store = new NoGoodStoreAlphaRoaming(assignment); + learnedNoGoodDeletion = store.getLearnedNoGoodDeletion(); + } + + @Before + public void setUp() { + store.clear(); + store.growForMaxAtomId(fromOldLiterals(200)); + assertNull(store.add(1, new NoGood(fromOldLiterals(1, -2)))); + assertNull(store.add(2, new NoGood(fromOldLiterals(2, -3)))); + assertNull(store.add(3, new NoGood(fromOldLiterals(2, -4, -5)))); + assertNull(store.add(4, new NoGood(fromOldLiterals(3, 4, 5)))); + assertNull(store.propagate()); + } + + @Test + public void testDeletionRunningAfterConflicts() { + for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { + learnedNoGoodDeletion.increaseConflictCounter(); + } + assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + learnedNoGoodDeletion.increaseConflictCounter(); + assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + learnedNoGoodDeletion.runNoGoodDeletion(); + assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + } + + @Test + public void testDeletionRemovingWatches() { + for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { + learnedNoGoodDeletion.increaseConflictCounter(); + } + assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + learnedNoGoodDeletion.increaseConflictCounter(); + assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + assertNull(store.add(4, NoGood.learnt(fromOldLiterals(10, 11, 12)), 3)); + assertNull(store.add(5, NoGood.learnt(fromOldLiterals(10, -13, -14)), 4)); + List watchedNoGoods = learnedNoGoodDeletion.inspectLearnedNoGoods(); + assertTrue(watchedNoGoods.size() >= 2); + WatchedNoGood watchedNoGood = watchedNoGoods.get(0); + for (int i = 0; i < 10; i++) { + watchedNoGood.bumpActivity(); + } + learnedNoGoodDeletion.runNoGoodDeletion(); + watchedNoGoods = learnedNoGoodDeletion.inspectLearnedNoGoods(); + assertTrue(watchedNoGoods.size() < 2); + } + + @Test + public void testDeletionIncreasesDeletionCounter() { + for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { + learnedNoGoodDeletion.increaseConflictCounter(); + } + assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + learnedNoGoodDeletion.increaseConflictCounter(); + assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + assertNull(store.add(4, NoGood.learnt(fromOldLiterals(10, 11, 12)), 3)); + assertNull(store.add(5, NoGood.learnt(fromOldLiterals(10, -13, -14)), 4)); + assertEquals(0, learnedNoGoodDeletion.getNumberOfDeletedNoGoods()); + learnedNoGoodDeletion.runNoGoodDeletion(); + assertTrue(learnedNoGoodDeletion.getNumberOfDeletedNoGoods() > 0); + } + + @Test + public void testDeletionReducesNumberOfLearntNoGoods() { + for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { + learnedNoGoodDeletion.increaseConflictCounter(); + } + assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + learnedNoGoodDeletion.increaseConflictCounter(); + assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); + assertNull(store.add(4, NoGood.learnt(fromOldLiterals(10, 11, 12)), 3)); + assertNull(store.add(5, NoGood.learnt(fromOldLiterals(10, -13, -14)), 4)); + + final Map countersBeforeDeletion = countNoGoodsByType(store); + learnedNoGoodDeletion.runNoGoodDeletion(); + final Map countersAfterDeletion = countNoGoodsByType(store); + + for (Type type : Type.values()) { + if (type == Type.LEARNT) { + assertTrue("Count of LEARNT nogoods did not decrease during deletion", countersBeforeDeletion.get(type) > countersAfterDeletion.get(type)); + } else { + assertEquals("Unexpected count of " + type + " nogoods", countersBeforeDeletion.get(type), countersAfterDeletion.get(type)); + } + } + + } + + private Map countNoGoodsByType(NoGoodStore store) { + final Map counters = new HashMap<>(); + final NoGoodCounter noGoodCounter = store.getNoGoodCounter(); + for (Type type : Type.values()) { + counters.put(type, noGoodCounter.getNumberOfNoGoods(type)); + } + return counters; + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java new file mode 100644 index 000000000..33a069469 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java @@ -0,0 +1,588 @@ +package at.ac.tuwien.kr.alpha.solver; + +import at.ac.tuwien.kr.alpha.common.*; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static at.ac.tuwien.kr.alpha.common.NoGood.fact; +import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; +import static org.junit.Assert.*; + +/** + * Copyright (c) 2017, the Alpha Team. + */ +public class NaiveNoGoodStoreTest { + private final AtomStore atomStore; + private final TrailAssignment assignment; + private final NaiveNoGoodStore store; + + public NaiveNoGoodStoreTest() { + atomStore = new AtomStoreImpl(); + assignment = new TrailAssignment(atomStore); + store = new NaiveNoGoodStore(assignment); + } + + @Before + public void setUp() { + store.clear(); + AtomStoreTest.fillAtomStore(atomStore, 200); + assignment.growForMaxAtomId(); + } + + @Test + public void singleFact() { + store.add(1, fact(fromOldLiterals(-1))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void single() { + store.add(1, new NoGood(fromOldLiterals(-1))); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + public void constraintWithAssignment() { + assignment.assign(123, MBT); + assignment.assign(23, TRUE); + store.add(3, new NoGood(fromOldLiterals(-123, 22, 23))); + } + + @Test + public void assignment() { + store.add(3, headFirst(fromOldLiterals(-7, -4, -2))); + assignment.assign(4, TRUE); + assignment.assign(2, FALSE); + assignment.assign(7, FALSE); + assertNull(store.propagate()); + } + + + @Test + public void addNotCausingAssignment() { + assignment.assign(1, TRUE); + store.add(3, headFirst(fromOldLiterals(-3, -2, 1))); + + assertEquals(null, assignment.getTruth(3)); + } + + @Test + public void addNotCausingAssignmentUnassigned() { + assignment.assign(1, TRUE); + store.add(3, headFirst(fromOldLiterals(-5, 4, 1))); + + assertEquals(null, assignment.getTruth(5)); + } + + @Test + @Ignore("Checks for conflict detection in add.") + public void addNotCausingAssignmentFalse() { + assignment.assign(1, FALSE); + assignment.assign(4, TRUE); + store.add(3, headFirst(fromOldLiterals(-5, 4, -1))); + + assertEquals(TRUE, assignment.getTruth(5)); + } + + @Test + public void addNotCausingAssignmentTrue() { + assignment.assign(1, TRUE); + assignment.assign(2, TRUE); + store.add(1, headFirst(fromOldLiterals(-3, 2, -1))); + + assertEquals(null, assignment.getTruth(3)); + } + + @Test + public void propBinary() { + assignment.assign(2, FALSE); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assertEquals(null, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryFirstTrue() { + assignment.assign(2, TRUE); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryMBT() { + assignment.assign(2, MBT); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryTrue() { + assignment.assign(2, TRUE); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryMBTAfterAssignment() { + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assignment.assign(2, MBT); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryTrueAfterAssignment() { + store.add(1, headFirst(fromOldLiterals(-1, 2))); + assignment.assign(2, TRUE); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryMBTTwice() { + assignment.assign(2, MBT); + + store.add(1, new NoGood(fromOldLiterals(-1, 2))); + store.add(2, new NoGood(fromOldLiterals(-3, 1))); + + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(3)); + } + + + @Test + public void propagateBinaryMBTTwiceOutofSync() { + store.add(1, new NoGood(fromOldLiterals(-1, 2))); + store.add(2, new NoGood(fromOldLiterals(-3, 1))); + + assignment.assign(2, MBT); + + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(3)); + } + + @Test + public void propagateNaryTrue() { + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + + assertNull(store.add(1, headFirst(fromOldLiterals(-1, 2, 3)))); + + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateNaryFalse() { + assignment.assign(2, FALSE); + assignment.assign(3, FALSE); + + store.add(1, NoGood.headFirst(fromOldLiterals(-1, -3, -2))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void addFullyAssignedBinary() { + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + + store.add(1, headFirst(fromOldLiterals(-2, 3))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(2)); + assertEquals(TRUE, assignment.getTruth(3)); + } + + @Test + public void addFullyAssignedNary() { + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + assignment.assign(4, TRUE); + + store.add(1, headFirst(fromOldLiterals(-2, 3, 4))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(2)); + assertEquals(TRUE, assignment.getTruth(3)); + assertEquals(TRUE, assignment.getTruth(4)); + } + + @Test + public void propagateNaryMBT() { + final NoGood noGood = headFirst(fromOldLiterals(-1, 2, 3)); + + assignment.assign(2, MBT); + assignment.assign(3, MBT); + + store.add(1, noGood); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + @Ignore("Checks for propagation in add.") + public void propagateNaryMBTTwice() { + assignment.assign(4, FALSE); + assignment.assign(3, MBT); + assignment.assign(2, MBT); + + store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); + assertEquals(MBT, assignment.getTruth(1)); + + store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(5)); + } + + @Test + public void propagateNaryFactsMultiple() { + NoGood[] noGoods = new NoGood[]{ + headFirst(fromOldLiterals(-1, 2, 3)), // 1 <- 2, 3. + headFirst(fromOldLiterals(-5, 4, 1)), // 5 <- 4, 1. + fact(fromOldLiterals(-4)), // 4. + fact(fromOldLiterals(-3)), // 3. + fact(fromOldLiterals(-2)) // 2. + }; + for (int i = 0; i < noGoods.length; i++) { + assertNull(store.add(i + 1, noGoods[i])); + } + + // First deduce 1 from 2 and 3, then deduce + // 5 from -4 and 1. + store.propagate(); + assertTrue(store.didPropagate()); + + assertEquals(TRUE, assignment.getTruth(1)); + assertEquals(TRUE, assignment.getTruth(5)); + } + + @Test + public void moveThirdPointer() { + // 1 <- 2, 3. + store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); + assertNull(store.propagate()); + assertFalse(store.didPropagate()); + + // 2. + store.add(2, fact(fromOldLiterals(-2))); + assertNull(store.propagate()); + assertTrue(store.didPropagate()); + assertEquals(TRUE, assignment.getTruth(2)); + assertNull(assignment.getTruth(1)); + + // 3. + store.add(3, fact(fromOldLiterals(-3))); + assertNull(store.propagate()); + assertTrue(store.didPropagate()); + assertEquals(TRUE, assignment.getTruth(3)); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateNaryMBTTwiceReordered() { + // From 2 and 3 follows 1. + store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); + // From -4 and 1 follows 5. + store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); + + // Assign 4 to false (first premise for 5). + assignment.assign(4, FALSE); + + // Assign 3 and 2 to MBT (premises for 1). + assignment.assign(3, MBT); + assignment.assign(2, MBT); + + // Now 1 must follow from 2 and 3, + // and 5 must follow from -4 and 1. + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(5)); + } + + @Test + public void conflictingFact() { + final NoGood noGood = fact(fromOldLiterals(-1)); + assignment.assign(1, FALSE); + ConflictCause conflictCause = store.add(1, noGood); + assertNotNull(conflictCause); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + @Ignore("Checks for conflict detection in add.") + public void conflictingBinary() { + final NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assignment.assign(1, TRUE); + assignment.assign(2, TRUE); + ConflictCause conflictCause = store.add(1, noGood); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + @Ignore("Checks for conflict detection in add.") + public void conflictingNary() { + final NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assignment.assign(1, TRUE); + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + ConflictCause conflictCause = store.add(1, noGood); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void propagateViolatedConstraint() { + NoGood noGood = headFirst(fromOldLiterals(-3, -2, -1)); + assertNull(store.add(1, noGood)); + assertNull(assignment.assign(1, FALSE)); + assertNull(assignment.assign(2, FALSE)); + assertNull(assignment.assign(3, FALSE)); + ConflictCause conflictCause = store.propagate(); + assertNotNull(conflictCause); + assertFalse(store.didPropagate()); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void noViolation() { + assertNull(store.add(1, headFirst(fromOldLiterals(-7, -4, -2)))); + assertNull(assignment.assign(4, TRUE)); + assertNull(assignment.assign(2, FALSE)); + assertNull(assignment.assign(7, FALSE)); + assertNull(store.propagate()); + assertNull(store.propagate()); + } + + @Test + public void propagateViolatedConstraintHeadless() { + NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); + assertNull(store.add(24, noGood)); + assertNull(assignment.assign(3, TRUE)); + assertNull(assignment.assign(11, TRUE)); + assertNull(assignment.assign(19, TRUE)); + ConflictCause conflictCause = store.propagate(); + assertNotNull(conflictCause); + assertFalse(store.didPropagate()); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void propagateViolatedConstraintHeadlessMbt() { + NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); + assertNull(store.add(24, noGood)); + assertNull(assignment.assign(3, MBT)); + assertNull(assignment.assign(11, MBT)); + assertNull(assignment.assign(19, MBT)); + ConflictCause conflictCause = store.propagate(); + assertNotNull(conflictCause); + assertFalse(store.didPropagate()); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void neverViolatedNoGood() { + NoGood noGood = new NoGood(fromOldLiterals(-44, 10, 13, 44)); + assertNull(store.add(80, noGood)); + assertNull(assignment.assign(10, TRUE)); + assertNull(assignment.assign(13, TRUE)); + assertNull(assignment.assign(44, FALSE)); + assertNull(store.propagate()); + } + + @Test + public void naryNoGoodViolatedAfterAddition() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assertNull(store.add(11, noGood)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + assertNull(assignment.assign(3, MBT)); + assertNotNull(store.propagate()); + } + + @Test + @Ignore("Checks for conflict detection in add.") + public void naryNoGoodViolatedDuringAdditionAllTrue() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assertNull(assignment.assign(1, TRUE)); + assertNull(assignment.assign(2, TRUE)); + assertNull(assignment.assign(3, TRUE)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + @Ignore("Checks for conflict detection in add.") + public void naryNoGoodViolatedDuringAdditionAllMbt() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + assertNull(assignment.assign(3, MBT)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + public void binaryNoGoodViolatedAfterAddition() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assertNull(store.add(1, noGood)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + assertNotNull(store.propagate()); + } + + @Test + @Ignore("Checks for conflict detection in add.") + public void binaryNoGoodViolatedDuringAdditionAllTrue() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assertNull(assignment.assign(1, TRUE)); + assertNull(assignment.assign(2, TRUE)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + @Ignore("Checks for conflict detection in add.") + public void binaryNoGoodViolatedDuringAdditionAllMbt() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + public void addedViolatedBinaryNoGoodPropagatesAfterBacktracking() { + NoGood noGood = new NoGood(fromOldLiterals(70, 195)); + assertNull(assignment.choose(70, MBT)); + assertNull(assignment.choose(195, MBT)); + assertNotNull(store.add(3, noGood)); + assignment.backtrack(); + assertNull(store.add(3, noGood)); + store.propagate(); + assertEquals(FALSE, assignment.getTruth(195)); + } + + @Test + public void addedViolatedNaryNoGoodPropagatesAfterBacktracking() { + NoGood noGood = new NoGood(fromOldLiterals(70, 195, 36)); + assertNull(assignment.choose(70, MBT)); + assertNull(assignment.choose(195, MBT)); + assertNull(assignment.choose(36, MBT)); + assertNotNull(store.add(3, noGood)); + assignment.backtrack(); + assertNull(store.add(3, noGood)); + store.propagate(); + assertEquals(FALSE, assignment.getTruth(36)); + } + + @Test + public void binaryNoGoodPropagatesTrueFromFalse() { + NoGood noGood = headFirst(fromOldLiterals(-11, -12)); + assertNull(store.add(5, noGood)); + assertNull(assignment.choose(12, FALSE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(11)); + } + + @Test + public void binaryNoGoodPropagatesTrueFromTrue() { + NoGood noGood = headFirst(fromOldLiterals(-11, 12)); + assertNull(store.add(5, noGood)); + assertNull(assignment.choose(12, TRUE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(11)); + } + + + @Test + @Ignore("Checks for propagation in add.") + public void addedBinaryNoGoodPropagatesTrueFromFalse() { + NoGood noGood = headFirst(fromOldLiterals(-11, -12)); + assertNull(assignment.choose(12, FALSE)); + assertNull(store.add(5, noGood)); + assertEquals(TRUE, assignment.getTruth(11)); + } + + @Test + public void addedBinaryNoGoodPropagatesTrueFromTrue() { + NoGood noGood = headFirst(fromOldLiterals(-11, 12)); + assertNull(assignment.choose(12, TRUE)); + assertNull(store.add(5, noGood)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(11)); + } + + @Test + public void naryNoGoodPropagatesTrueFromFalse() { + NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); + assertNull(store.add(10, noGood)); + assertNull(assignment.assign(2, TRUE)); + store.propagate(); + assertNull(assignment.assign(3, FALSE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void naryNoGoodPropagatesTrueFromTrue() { + NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); + assertNull(store.add(10, noGood)); + assertNull(assignment.assign(3, FALSE)); + store.propagate(); + assertNull(assignment.assign(2, TRUE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + @Ignore("Not decision-level aware.") + public void propagationAtLowerDecisionLevel() { + NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); + assertNull(assignment.choose(3, FALSE)); + assertNull(assignment.choose(2, TRUE)); + assertNull(assignment.choose(4, TRUE)); + assertNull(store.add(10, noGood)); + assertNull(store.propagate()); + assertEquals(TRUE, assignment.getTruth(1)); + Assignment.Entry entry = assignment.get(1); + assertEquals(TRUE, entry.getTruth()); + assertEquals(2, entry.getDecisionLevel()); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java new file mode 100644 index 000000000..0f6d73acf --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java @@ -0,0 +1,615 @@ +package at.ac.tuwien.kr.alpha.solver; + +import at.ac.tuwien.kr.alpha.common.*; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static at.ac.tuwien.kr.alpha.common.NoGood.fact; +import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; +import static org.junit.Assert.*; + +/** + * Copyright (c) 2017, the Alpha Team. + */ +public class NoGoodStoreAlphaRoamingTest { + + private final AtomStore atomStore; + private final TrailAssignment assignment; + private final NoGoodStoreAlphaRoaming store; + + public NoGoodStoreAlphaRoamingTest() { + atomStore = new AtomStoreImpl(); + AtomStoreTest.fillAtomStore(atomStore, 200); + assignment = new TrailAssignment(atomStore); + assignment.growForMaxAtomId(); + store = new NoGoodStoreAlphaRoaming(assignment); + } + + @Before + public void setUp() { + store.clear(); + store.growForMaxAtomId(fromOldLiterals(200)); + } + + @Test + public void singleFact() { + store.add(1, fact(fromOldLiterals(-1))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void single() { + store.add(1, new NoGood(fromOldLiterals(-1))); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + public void constraintWithAssignment() { + assignment.assign(123, MBT); + assignment.assign(23, TRUE); + store.add(3, new NoGood(fromOldLiterals(-123, 22, 23))); + } + + @Test + public void assignment() { + store.add(3, headFirst(fromOldLiterals(-7, -4, -2))); + assignment.assign(4, TRUE); + assignment.assign(2, FALSE); + assignment.assign(7, FALSE); + assertNull(store.propagate()); + } + + + @Test + public void addNotCausingAssignment() { + assignment.assign(1, TRUE); + store.add(3, headFirst(fromOldLiterals(-3, -2, 1))); + + assertEquals(null, assignment.getTruth(3)); + } + + @Test + public void addNotCausingAssignmentUnassigned() { + assignment.assign(1, TRUE); + store.add(3, headFirst(fromOldLiterals(-5, 4, 1))); + + assertEquals(null, assignment.getTruth(5)); + } + + @Test + public void addNotCausingAssignmentFalse() { + assignment.assign(1, FALSE); + assignment.assign(4, TRUE); + store.add(3, headFirst(fromOldLiterals(-5, 4, -1))); + + assertEquals(TRUE, assignment.getTruth(5)); + } + + @Test + public void addNotCausingAssignmentTrue() { + assignment.assign(1, TRUE); + assignment.assign(2, TRUE); + store.add(1, headFirst(fromOldLiterals(-3, 2, -1))); + + assertEquals(null, assignment.getTruth(3)); + } + + @Test + public void propBinary() { + assignment.assign(2, FALSE); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assertEquals(null, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryFirstTrue() { + assignment.assign(2, TRUE); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryMBT() { + assignment.assign(2, MBT); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryTrue() { + assignment.assign(2, TRUE); + + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryMBTAfterAssignment() { + store.add(1, headFirst(fromOldLiterals(-1, 2))); + store.propagate(); + + assignment.assign(2, MBT); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryTrueAfterAssignment() { + store.add(1, headFirst(fromOldLiterals(-1, 2))); + assignment.assign(2, TRUE); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateBinaryMBTTwice() { + assignment.assign(2, MBT); + + store.add(1, new NoGood(fromOldLiterals(-1, 2))); + store.add(2, new NoGood(fromOldLiterals(-3, 1))); + + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(3)); + } + + + @Test + public void propagateBinaryMBTTwiceOutofSync() { + store.add(1, new NoGood(fromOldLiterals(-1, 2))); + store.add(2, new NoGood(fromOldLiterals(-3, 1))); + + assignment.assign(2, MBT); + + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(3)); + } + + @Test + public void propagateNaryTrue() { + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + + assertNull(store.add(1, headFirst(fromOldLiterals(-1, 2, 3)))); + + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateNaryFalse() { + assignment.assign(2, FALSE); + assignment.assign(3, FALSE); + + store.add(1, headFirst(fromOldLiterals(-1, -3, -2))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void addFullyAssignedBinary() { + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + + store.add(1, headFirst(fromOldLiterals(-2, 3))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(2)); + assertEquals(TRUE, assignment.getTruth(3)); + } + + @Test + public void addFullyAssignedNary() { + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + assignment.assign(4, TRUE); + + store.add(1, headFirst(fromOldLiterals(-2, 3, 4))); + store.propagate(); + + assertEquals(TRUE, assignment.getTruth(2)); + assertEquals(TRUE, assignment.getTruth(3)); + assertEquals(TRUE, assignment.getTruth(4)); + } + + @Test + public void propagateNaryMBT() { + final NoGood noGood = headFirst(fromOldLiterals(-1, 2, 3)); + + assignment.assign(2, MBT); + assignment.assign(3, MBT); + + store.add(1, noGood); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + } + + @Test + public void propagateNaryMBTTwice() { + assignment.assign(4, FALSE); + assignment.assign(3, MBT); + assignment.assign(2, MBT); + + store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); + assertEquals(MBT, assignment.getTruth(1)); + + store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(5)); + } + + @Test + public void propagateNaryFactsMultiple() { + NoGood[] noGoods = new NoGood[]{ + headFirst(fromOldLiterals(-1, 2, 3)), // 1 <- 2, 3. + headFirst(fromOldLiterals(-5, 4, 1)), // 5 <- 4, 1. + fact(fromOldLiterals(-4)), // 4. + fact(fromOldLiterals(-3)), // 3. + fact(fromOldLiterals(-2)) // 2. + }; + for (int i = 0; i < noGoods.length; i++) { + assertNull(store.add(i + 1, noGoods[i])); + } + + // First deduce 1 from 2 and 3, then deduce + // 5 from -4 and 1. + assertNull(store.propagate()); + assertTrue(store.didPropagate()); + + assertEquals(TRUE, assignment.getTruth(1)); + assertEquals(TRUE, assignment.getTruth(5)); + } + + @Test + public void moveThirdPointer() { + // 1 <- 2, 3. + store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); + assertNull(store.propagate()); + assertFalse(store.didPropagate()); + + // 2. + store.add(2, fact(fromOldLiterals(-2))); + assertNull(store.propagate()); + assertFalse(store.didPropagate()); + assertNull(assignment.getTruth(1)); + + // 3. + store.add(3, fact(fromOldLiterals(-3))); + assertNull(store.propagate()); + assertTrue(store.didPropagate()); + + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void propagateNaryMBTTwiceReordered() { + // From 2 and 3 follows 1. + store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); + // From -4 and 1 follows 5. + store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); + + // Assign 4 to false (first premise for 5). + assignment.assign(4, FALSE); + + // Assign 3 and 2 to MBT (premises for 1). + assignment.assign(3, MBT); + assignment.assign(2, MBT); + + // Now 1 must follow from 2 and 3, + // and 5 must follow from -4 and 1. + store.propagate(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(MBT, assignment.getTruth(5)); + } + + @Test + public void conflictingFact() { + final NoGood noGood = fact(fromOldLiterals(-1)); + assignment.assign(1, FALSE); + ConflictCause conflictCause = store.add(1, noGood); + assertNotNull(conflictCause); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void conflictingBinary() { + final NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assignment.assign(1, TRUE); + assignment.assign(2, TRUE); + ConflictCause conflictCause = store.add(1, noGood); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void conflictingNary() { + final NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assignment.assign(1, TRUE); + assignment.assign(2, TRUE); + assignment.assign(3, TRUE); + ConflictCause conflictCause = store.add(1, noGood); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void propagateViolatedConstraint() { + NoGood noGood = headFirst(fromOldLiterals(-3, -2, -1)); + assertNull(store.add(1, noGood)); + assertNull(assignment.assign(1, FALSE)); + assertNull(assignment.assign(2, FALSE)); + assertNull(assignment.assign(3, FALSE)); + ConflictCause conflictCause = store.propagate(); + assertNotNull(conflictCause); + assertFalse(store.didPropagate()); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void noViolation() { + assertNull(store.add(1, headFirst(fromOldLiterals(-7, -4, -2)))); + assertNull(assignment.assign(4, TRUE)); + assertNull(assignment.assign(2, FALSE)); + assertNull(assignment.assign(7, FALSE)); + assertNull(store.propagate()); + } + + @Test + public void propagateViolatedConstraintHeadless() { + NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); + assertNull(store.add(24, noGood)); + assertNull(assignment.assign(3, TRUE)); + assertNull(assignment.assign(11, TRUE)); + assertNull(assignment.assign(19, TRUE)); + ConflictCause conflictCause = store.propagate(); + assertFalse(store.didPropagate()); + assertNotNull(conflictCause); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void propagateViolatedConstraintHeadlessMbt() { + NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); + assertNull(store.add(24, noGood)); + assertNull(assignment.assign(3, MBT)); + assertNull(assignment.assign(11, MBT)); + assertNull(assignment.assign(19, MBT)); + ConflictCause conflictCause = store.propagate(); + assertFalse(store.didPropagate()); + assertNotNull(conflictCause); + assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); + } + + @Test + public void neverViolatedNoGood() { + NoGood noGood = new NoGood(fromOldLiterals(-44, 10, 13, 44)); + assertNull(store.add(80, noGood)); + assertNull(assignment.assign(10, TRUE)); + assertNull(assignment.assign(13, TRUE)); + assertNull(assignment.assign(44, FALSE)); + assertNull(store.propagate()); + } + + @Test + public void naryNoGoodViolatedAfterAddition() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assertNull(store.add(11, noGood)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + assertNull(assignment.assign(3, MBT)); + assertNotNull(store.propagate()); + } + + @Test + public void naryNoGoodViolatedDuringAdditionAllTrue() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assertNull(assignment.assign(1, TRUE)); + assertNull(assignment.assign(2, TRUE)); + assertNull(assignment.assign(3, TRUE)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + public void naryNoGoodViolatedDuringAdditionAllMbt() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + assertNull(assignment.assign(3, MBT)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + public void binaryNoGoodViolatedAfterAddition() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assertNull(store.add(11, noGood)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + assertNotNull(store.propagate()); + } + + @Test + public void binaryNoGoodViolatedDuringAdditionAllTrue() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assertNull(assignment.assign(1, TRUE)); + assertNull(assignment.assign(2, TRUE)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + public void binaryNoGoodViolatedDuringAdditionAllMbt() { + NoGood noGood = new NoGood(fromOldLiterals(1, 2)); + assertNull(assignment.assign(1, MBT)); + assertNull(assignment.assign(2, MBT)); + ConflictCause conflictCause = store.add(11, noGood); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + } + + @Test + public void addedViolatedBinaryNoGoodPropagatesAfterBacktracking() { + NoGood noGood = new NoGood(fromOldLiterals(70, 195)); + assertNull(assignment.choose(70, MBT)); + assertNull(assignment.choose(195, MBT)); + assertNotNull(store.add(3, noGood)); + assignment.backtrack(); + assertNull(store.add(3, noGood)); + store.propagate(); + assertEquals(FALSE, assignment.getTruth(195)); + } + + @Test + public void addedViolatedNaryNoGoodPropagatesAfterBacktracking() { + NoGood noGood = new NoGood(fromOldLiterals(70, 195, 36)); + assertNull(assignment.choose(70, MBT)); + assertNull(assignment.choose(195, MBT)); + assertNull(assignment.choose(36, MBT)); + assertNotNull(store.add(3, noGood)); + assignment.backtrack(); + assertNull(store.add(3, noGood)); + store.propagate(); + assertEquals(FALSE, assignment.getTruth(36)); + } + + @Test + public void binaryNoGoodPropagatesTrueFromFalse() { + NoGood noGood = headFirst(fromOldLiterals(-11, -12)); + assertNull(store.add(5, noGood)); + assertNull(assignment.choose(12, FALSE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(11)); + } + + @Test + public void binaryNoGoodPropagatesTrueFromTrue() { + NoGood noGood = headFirst(fromOldLiterals(-11, 12)); + assertNull(store.add(5, noGood)); + assertNull(assignment.choose(12, TRUE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(11)); + } + + + @Test + public void addedBinaryNoGoodPropagatesTrueFromFalse() { + NoGood noGood = headFirst(fromOldLiterals(-11, -12)); + assertNull(assignment.choose(12, FALSE)); + assertNull(store.add(5, noGood)); + assertEquals(TRUE, assignment.getTruth(11)); + } + + @Test + public void addedBinaryNoGoodPropagatesTrueFromTrue() { + NoGood noGood = headFirst(fromOldLiterals(-11, 12)); + assertNull(assignment.choose(12, TRUE)); + assertNull(store.add(5, noGood)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(11)); + } + + @Test + public void naryNoGoodPropagatesTrueFromFalse() { + NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); + assertNull(store.add(10, noGood)); + assertNull(assignment.assign(2, TRUE)); + store.propagate(); + assertNull(assignment.assign(3, FALSE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Test + public void naryNoGoodPropagatesTrueFromTrue() { + NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); + assertNull(store.add(10, noGood)); + assertNull(assignment.assign(3, FALSE)); + store.propagate(); + assertNull(assignment.assign(2, TRUE)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(1)); + } + + @Ignore // TrailAssignment no longer propagates at lower decision level. + @Test + public void propagationAtLowerDecisionLevel() { + NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); + assertNull(assignment.choose(3, FALSE)); + assertNull(assignment.choose(2, TRUE)); + assertNull(assignment.choose(4, TRUE)); + assertNull(store.add(10, noGood)); + store.propagate(); + assertEquals(TRUE, assignment.getTruth(1)); + Assignment.Entry entry = assignment.get(1); + assertEquals(TRUE, entry.getTruth()); + assertEquals(2, entry.getDecisionLevel()); + } + + @Test + public void violationByPropagationAtLowerDecisionLevel() { + assertNull(store.add(1, new NoGood(fromOldLiterals(1, -2)))); + assertNull(store.add(2, new NoGood(fromOldLiterals(2, -3)))); + assertNull(store.add(3, new NoGood(fromOldLiterals(2, -4)))); + assertNull(store.add(4, new NoGood(fromOldLiterals(3, 4, 5)))); + + assertNull(assignment.choose(7, FALSE)); + assertNull(store.propagate()); + assertNull(assignment.choose(6, FALSE)); + assertNull(store.propagate()); + assertNull(assignment.choose(5, TRUE)); + assertNull(store.propagate()); + + assertNull(store.add(5, new NoGood(fromOldLiterals(-1)))); + ConflictCause cause = store.propagate(); + assertNotNull(cause); + } + + @Test + public void alphaWatchNotIgnored() { + assertNull(assignment.choose(2, TRUE)); + assertNull(store.propagate()); + assertNull(assignment.choose(3, TRUE)); + assertNull(store.propagate()); + assertNull(assignment.choose(1, TRUE)); + assertNull(store.propagate()); + + assertNull(store.add(1, headFirst(fromOldLiterals(-1, 2, 3)))); + + store.backtrack(); + store.backtrack(); + assertNull(assignment.choose(3, TRUE)); + assertNull(store.propagate()); + assertEquals(TRUE, assignment.getTruth(1)); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java new file mode 100644 index 000000000..2e3b97f8c --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2017-2019 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.solver; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Optional; + +/** + * Tests {@link AbstractSolver} using Omiga benchmark problems. + * + */ +public class OmigaBenchmarksTest extends AbstractSolverTests { + + private static final Logger LOGGER = LoggerFactory.getLogger(OmigaBenchmarksTest.class); + + @Test(timeout = 10000) + public void test3Col_10_18() throws IOException { + test("3col", "3col-10-18.txt"); + } + + @Test(timeout = 10000) + public void test3Col_20_38() throws IOException { + test("3col", "3col-20-38.txt"); + } + + @Test(timeout = 15000) + public void testCutedge_100_30() throws IOException { + test("cutedge", "cutedge-100-30.txt"); + } + + @Test(timeout = 15000) + public void testCutedge_100_50() throws IOException { + test("cutedge", "cutedge-100-50.txt"); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testLocstrat_200() throws IOException { + test("locstrat", "locstrat-200.txt"); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testLocstrat_400() throws IOException { + test("locstrat", "locstrat-400.txt"); + } + + @Test(timeout = 15000) + public void testReach_1() throws IOException { + ignoreTestForNaiveSolver(); + ignoreNonDefaultDomainIndependentHeuristics(); + test("reach", "reach-1.txt"); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testReach_4() throws IOException { + test("reach", "reach-4.txt"); + } + + private void test(String folder, String aspFileName) throws IOException { + CharStream programInputStream = CharStreams.fromPath(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName)); + Optional answerSet = getInstance(programInputStream).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/solver/PartSubpartConfigurationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java new file mode 100644 index 000000000..f5a34eefd --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2017 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.solver; + +import org.junit.Ignore; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertFalse; + +/** + * Tests {@link AbstractSolver} using some configuration test cases in which subparts are assigned to parts. + * + */ +public class PartSubpartConfigurationTest extends AbstractSolverTests { + @Test(timeout = 1000) + public void testN2() throws IOException { + testPartSubpart(2); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN4() throws IOException { + testPartSubpart(4); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN8() throws IOException { + testPartSubpart(8); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN16() throws IOException { + testPartSubpart(16); + } + + @Test(timeout = 61000) + @Ignore("disabled to save resources during CI") + public void testN32() throws IOException { + testPartSubpart(32); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN60() throws IOException { + testPartSubpart(60); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN75() throws IOException { + testPartSubpart(75); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN100() throws IOException { + testPartSubpart(100); + } + + private void testPartSubpart(int n) throws IOException { + List rules = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + rules.add(String.format("n(%d).", i)); + } + + rules.addAll(Arrays.asList( + "part(N) :- n(N), not no_part(N).", + "no_part(N) :- n(N), not part(N).", + "subpartid(SP,ID) :- subpart(SP,P), n(ID), not no_subpartid(SP,ID).", + "no_subpartid(SP,ID) :- subpart(SP,P), n(ID), not subpartid(SP,ID).", + "subpart(SP,P) :- part(P), part(SP), P != SP, not no_subpart(SP,P).", + "no_subpart(SP,P) :- part(P), part(SP), P != SP, not subpart(SP,P).", + ":- subpart(SP,P1), subpart(SP,P2), P1 != P2.", + ":- subpart(SP1,P), subpart(SP2, P), SP1!=SP2, subpartid(SP1,ID), subpartid(SP2,ID)." + )); + + assertFalse(collectSet(concat(rules)).isEmpty()); + // TODO: check correctness of answer set + } + + private String concat(List rules) { + String ls = System.lineSeparator(); + return rules.stream().collect(Collectors.joining(ls)); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java new file mode 100644 index 000000000..48c9857b9 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java @@ -0,0 +1,180 @@ +/** + * Copyright (c) 2017 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.solver; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; +import org.junit.Ignore; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +/** + * Tests {@link AbstractSolver} using some pigeon-hole test cases (see https://en.wikipedia.org/wiki/Pigeonhole_principle). + */ +public class PigeonHoleTest extends AbstractSolverTests { + @Test(timeout = 5000) + public void test2Pigeons2Holes() throws IOException { + assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + testPigeonsHoles(2, 2); + } + + @Test(timeout = 5000) + public void test3Pigeons2Holes() throws IOException { + assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + testPigeonsHoles(3, 2); + } + + @Test(timeout = 5000) + public void test2Pigeons3Holes() throws IOException { + assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + testPigeonsHoles(2, 3); + } + + @Test(timeout = 10000) + public void test3Pigeons3Holes() throws IOException { + assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + testPigeonsHoles(3, 3); + } + + @Test(timeout = 10000) + public void test4Pigeons3Holes() throws IOException { + assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + testPigeonsHoles(4, 3); + } + + @Test(timeout = 10000) + public void test3Pigeons4Holes() throws IOException { + assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + testPigeonsHoles(3, 4); + } + + @Test(timeout = 10000) + public void test4Pigeons4Holes() throws IOException { + assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + testPigeonsHoles(4, 4); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void test10Pigeons10Holes() throws IOException { + testPigeonsHoles(10, 10); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void test19Pigeons20Holes() throws IOException { + testPigeonsHoles(19, 20); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void test28Pigeons30Holes() throws IOException { + testPigeonsHoles(28, 30); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void test37Pigeons40Holes() throws IOException { + testPigeonsHoles(37, 40); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void test46Pigeons50Holes() throws IOException { + testPigeonsHoles(46, 50); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void test55Pigeons60Holes() throws IOException { + testPigeonsHoles(55, 60); + } + + /** + * Tries to solve the problem of assigning P pigeons to H holes. + */ + private void testPigeonsHoles(int pigeons, int holes) throws IOException { + 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)."); + rules.add(":- pigeon(P), hole(H1), hole(H2), pos(P,H1), pos(P,H2), H1 != H2."); + rules.add(":- pigeon(P), not hashole(P)."); + rules.add("hashole(P) :- pigeon(P), hole(H), pos(P,H)."); + rules.add(":- pigeon(P1), pigeon(P2), hole(H), pos(P1,H), pos(P2,H), P1 != P2."); + + addPigeons(rules, pigeons); + addHoles(rules, holes); + + Set answerSets = collectSet(concat(rules)); + assertEquals(numberOfSolutions(pigeons, holes), answerSets.size()); + } + + private void addPigeons(List rules, int pigeons) { + addFacts(rules, "pigeon", 1, pigeons); + } + + private void addHoles(List rules, int holes) { + addFacts(rules, "hole", 1, holes); + } + + private void addFacts(List rules, String predicateName, int from, int to) { + for (int i = from; i <= to; i++) { + rules.add(String.format("%s(%d).", predicateName, i)); + } + } + + private String concat(List rules) { + String ls = System.lineSeparator(); + return rules.stream().collect(Collectors.joining(ls)); + } + + private long numberOfSolutions(int pigeons, int holes) { + if (pigeons > holes) { + return 0; + } else if (pigeons == holes) { + return factorial(pigeons); + } else { + return factorial(holes) / factorial(holes - pigeons); + // could be replaced by more efficient implementaton (but performance is not so important here) + } + } + + private long factorial(int n) { + return n <= 1 ? 1 : n * factorial(n - 1); + // could be replaced by more efficient implementaton (but performance is not so important here) + // see http://www.luschny.de/math/factorial/FastFactorialFunctions.htm + // TODO: we could use Apache Commons Math + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java new file mode 100644 index 000000000..4125dc5a7 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2017 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.solver; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.junit.Ignore; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Optional; + +/** + * Tests {@link AbstractSolver} using a racks configuration problem. + * + */ +@Ignore("disabled to save resources during CI") +public class RacksTest extends AbstractSolverTests { + @Test(timeout = 10000) + public void testRacks() throws IOException { + test(); + } + + private void test() throws IOException { + CharStream programInputStream = CharStreams.fromPath( + Paths.get("benchmarks", "siemens", "racks", "racks.lp") + ); + Solver solver = getInstance(programInputStream); + Optional answerSet = solver.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/solver/SolverStatisticsTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java new file mode 100644 index 000000000..cbd25f394 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2017-2019 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.solver; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.core.grounder.DummyGrounder; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +public class SolverStatisticsTests extends AbstractSolverTests { + + private AtomStore atomStore; + + @Before + public void setUp() { + this.atomStore = new AtomStoreImpl(); + } + + @Test + public void checkStatsStringZeroChoices() { + Solver solver = getInstance("a."); + assumeTrue(solver instanceof SolverMaintainingStatistics); + collectAnswerSetsAndCheckStats(solver, 1, 0, 0, 0, 0, 0, 0, 0); + } + + @Test + public void checkStatsStringOneChoice() { + Solver solver = getInstance("a :- not b. b :- not a."); + assumeTrue(solver instanceof SolverMaintainingStatistics); + collectAnswerSetsAndCheckStats(solver, 2, 1, 1, 1, 1, 0, 0, 0); + } + + @Test + public void checkNoGoodCounterStatsByTypeUsingDummyGrounder() { + Solver solver = getInstance(atomStore, new DummyGrounder(atomStore)); + assumeTrue(solver instanceof SolverMaintainingStatistics); + collectAnswerSetsAndCheckNoGoodCounterStatsByType(solver, 4, 0, 0, 0); + } + + @Test + public void checkNoGoodCounterStatsByCardinalityUsingDummyGrounder() { + Solver solver = getInstance(atomStore, new DummyGrounder(atomStore)); + assumeTrue(solver instanceof SolverMaintainingStatistics); + 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) { + Set answerSets = solver.collectSet(); + assertEquals(expectedNumberOfAnswerSets, answerSets.size()); + SolverMaintainingStatistics solverMaintainingStatistics = (SolverMaintainingStatistics) solver; + assertEquals( + String.format("g=%d, bt=%d, bj=%d, bt_within_bj=%d, mbt=%d, cac=%d, del_ng=%d", expectedNumberOfGuesses, expectedTotalNumberOfBacktracks, expectedNumberOfBackjumps, + expectedNumberOfBacktracksWithinBackjumps, expectedNumberOfMBTs, expectedNumberOfConflictsAfterClosing, expectedNumberOfDeletedNoGoods), + solverMaintainingStatistics.getStatisticsString()); + } + + private void collectAnswerSetsAndCheckNoGoodCounterStatsByType(Solver solver, int expectedNumberOfStaticNoGoods, int expectedNumberOfSupportNoGoods, int expectedNumberOfLearntNoGoods, int expectedNumberOfInternalNoGoods) { + solver.collectSet(); + SolverMaintainingStatistics solverMaintainingStatistics = (SolverMaintainingStatistics) solver; + final NoGoodCounter noGoodCounter = solverMaintainingStatistics.getNoGoodCounter(); + assertEquals("STATIC: " + expectedNumberOfStaticNoGoods + " SUPPORT: " + expectedNumberOfSupportNoGoods + " LEARNT: " + expectedNumberOfLearntNoGoods + " INTERNAL: " + expectedNumberOfInternalNoGoods, noGoodCounter.getStatsByType()); + } + + private void collectAnswerSetsAndCheckNoGoodCounterStatsByCardinality(Solver solver, int expectedNumberOfUnaryNoGoods, int expectedNumberOfBinaryNoGoods, int expectedNumberOfNAryNoGoods) { + solver.collectSet(); + SolverMaintainingStatistics solverMaintainingStatistics = (SolverMaintainingStatistics) solver; + final NoGoodCounter noGoodCounter = solverMaintainingStatistics.getNoGoodCounter(); + assertEquals("unary: " + expectedNumberOfUnaryNoGoods + " binary: " + expectedNumberOfBinaryNoGoods + " larger: " + expectedNumberOfNAryNoGoods, noGoodCounter.getStatsByCardinality()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java new file mode 100644 index 000000000..9cd3085c3 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java @@ -0,0 +1,808 @@ +/** + * Copyright (c) 2016, 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.solver; + +import static java.util.Collections.singleton; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.antlr.v4.runtime.CharStreams; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Paths; +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.SortedSet; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.config.SystemConfig; +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.parser.InlineDirectives; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; +import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; +import junit.framework.TestCase; + +public class SolverTests extends AbstractSolverTests { + private static class Thingy implements Comparable { + @Override + public String toString() { + return "thingy"; + } + + @Override + public int compareTo(Thingy o) { + return 0; + } + } + + @Test + public void testObjectProgram() throws IOException { + final Thingy thingy = new Thingy(); + + final Atom fact = new BasicAtom(Predicate.getInstance("foo", 1), ConstantTerm.getInstance(thingy)); + + final InputProgram program = new InputProgram( + Collections.emptyList(), + Collections.singletonList(fact), + new InlineDirectives() + ); + + assertEquals(singleton(new AnswerSetBuilder() + .predicate("foo").instance(thingy) + .build()), collectSet(program)); + } + + @Test + public void testFactsOnlyProgram() throws IOException { + assertAnswerSet( + "p(a). p(b). foo(13). foo(16). q(a). q(c).", + + "q(a), q(c), p(a), p(b), foo(13), foo(16)" + ); + } + + @Test + public void testSimpleRule() throws Exception { + assertAnswerSet( + "p(a). p(b). r(X) :- p(X).", + + "p(a), p(b), r(a), r(b)" + ); + } + + @Test + public void testSimpleRuleWithGroundPart() throws Exception { + assertAnswerSet( + "p(1)." + + "p(2)." + + "q(X) :- p(X), p(1).", + + "q(1), q(2), p(1), p(2)" + ); + } + + @Test + public void testProgramZeroArityPredicates() throws Exception { + assertAnswerSet( + "a. p(X) :- b, r(X).", + + "a" + ); + } + + @Test + public void testChoiceGroundProgram() throws Exception { + assertAnswerSets( + "a :- not b. b :- not a.", + + "a", + "b" + ); + } + + @Test + public void testChoiceProgramNonGround() throws Exception { + assertAnswerSetsWithBase( + "dom(1). dom(2). dom(3)." + + "p(X) :- dom(X), not q(X)." + + "q(X) :- dom(X), not p(X).", + + "dom(1), dom(2), dom(3)", + + "q(1), q(2), p(3)", + "q(1), p(2), p(3)", + "p(1), q(2), p(3)", + "p(1), p(2), p(3)", + "q(1), q(2), q(3)", + "q(1), p(2), q(3)", + "p(1), q(2), q(3)", + "p(1), p(2), q(3)" + ); + } + + @Test + public void choiceProgram3Way() throws IOException { + assertAnswerSets( + "a :- not b, not c." + + "b :- not a, not c." + + "c :- not a, not b.", + + "a", + "b", + "c" + ); + } + + @Test + public void emptyProgramYieldsEmptyAnswerSet() throws IOException { + assertAnswerSets("", ""); + } + + @Test + public void chooseMultipleAnswerSets() throws IOException { + assertAnswerSets( + "a :- not nota." + + "nota :- not a." + + "b :- not notb." + + "notb :- not b." + + "c :- not notc." + + "notc :- not c." + + ":- nota,notb,notc.", + + "a, b, c", + "nota, b, c", + "a, notb, c", + "nota, notb, c", + "a, b, notc", + "nota, b, notc", + "a, notb, notc" + ); + } + + @Test + public void builtinAtoms() throws IOException { + assertAnswerSet( + "dom(1). dom(2). dom(3). dom(4). dom(5)." + + "p(X) :- dom(X), X = 4." + + "r(Y) :- dom(Y), Y <= 2.", + + "dom(1), dom(2), dom(3), dom(4), dom(5), p(4), r(1), r(2)" + ); + } + + @Test + public void builtinAtomsGroundRule() throws IOException { + assertAnswerSet( + "a :- 13 != 4." + + "b :- 2 != 3, 2 = 3." + + "c :- 2 <= 3, not 2 > 3.", + + "a, c" + ); + } + + + @Test + public void choiceProgramConstraintSimple() throws IOException { + assertAnswerSet( + "fact(a).\n" + + "choice(either, X) :- fact(X), not choice(or, X).\n" + + "choice(or, X) :- fact(X), not choice(either, X).\n" + + ":- choice(or, X).", + + "fact(a), choice(either, a)" + ); + } + + @Test + public void choiceProgramConstraintSimple2() throws IOException { + assertAnswerSet( + "fact(a).\n" + + "desired(either).\n" + + "choice(either, X) :- fact(X), not choice(or, X).\n" + + "choice(or, X) :- fact(X), not choice(either, X).\n" + + ":- choice(C, X), not desired(C).", + + "fact(a), desired(either), choice(either, a)" + ); + } + + @Test + public void choiceProgramConstraint() throws IOException { + assertAnswerSetsWithBase( + "eq(1,1)." + + "eq(2,2)." + + "eq(3,3)." + + "var(1)." + + "var(2)." + + "var(3)." + + "val(VAR,1):-var(VAR),not val(VAR,2),not val(VAR,3)." + + "val(VAR,2):-var(VAR),not val(VAR,1),not val(VAR,3)." + + "val(VAR,3):-var(VAR),not val(VAR,1),not val(VAR,2)." + + ":- eq(VAL1,VAL2), not eq(VAR1,VAR2), val(VAR1,VAL1), val(VAR2,VAL2).", + + "eq(1, 1), eq(2, 2), eq(3, 3), var(1), var(2), var(3)", + + "val(1, 1), val(2, 2), val(3, 3)", + "val(1, 1), val(3, 2), val(2, 3)", + "val(2, 1), val(1, 2), val(3, 3)", + "val(2, 1), val(3, 2), val(1, 3)", + "val(3, 1), val(1, 2), val(2, 3)", + "val(3, 1), val(2, 2), val(1, 3)" + ); + } + + @Test + public void choiceProgramConstraintPermutation() throws IOException { + assertAnswerSetsWithBase( + "eq(1,1)." + + "eq(2,2)." + + "eq(3,3)." + + "var(1)." + + "var(2)." + + "var(3)." + + "val(VAR,1):-var(VAR),not val(VAR,2),not val(VAR,3)." + + "val(VAR,2):-var(VAR),not val(VAR,1),not val(VAR,3)." + + "val(VAR,3):-var(VAR),not val(VAR,1),not val(VAR,2)." + + ":- val(VAR1,VAL1), val(VAR2,VAL2), eq(VAL1,VAL2), not eq(VAR1,VAR2).", + + "eq(1,1), eq(2,2), eq(3,3), var(1), var(2), var(3)", + + "val(1,1), val(2,2), val(3,3)", + "val(1,1), val(3,2), val(2,3)", + "val(2,1), val(1,2), val(3,3)", + "val(2,1), val(3,2), val(1,3)", + "val(3,1), val(1,2), val(2,3)", + "val(3,1), val(2,2), val(1,3)" + ); + } + + @Test + public void simpleNoPropagation() throws IOException { + assertAnswerSet( + "val(1,1)." + + "val(2,2)." + + "something:- val(VAR1,VAL1), val(VAR2,VAL2), anything(VAL1,VAL2).", + + "val(1, 1), val(2, 2)" + ); + } + + @Test + public void choiceAndPropagationAfterwards() throws IOException { + assertAnswerSetsWithBase( + "node(a)." + + "node(b)." + + "in(X) :- not out(X), node(X)." + + "out(X) :- not in(X), node(X)." + + "pair(X,Y) :- in(X), in(Y).", + + "node(a), node(b)", + + "in(a), in(b), pair(a,a), pair(a,b), pair(b,a), pair(b,b)", + "in(b), out(a), pair(b,b)", + "in(a), out(b), pair(a,a)", + "out(a), out(b)" + ); + } + + @Test + public void choiceAndConstraints() throws IOException { + assertAnswerSetsWithBase( + "node(a)." + + "node(b)." + + "edge(b,a)." + + "in(X) :- not out(X), node(X)." + + "out(X) :- not in(X), node(X)." + + ":- in(X), in(Y), edge(X,Y).", + + "node(a), node(b), edge(b,a)", + + "in(b), out(a)", + "in(a), out(b)", + "out(a), out(b)" + ); + } + + @Test + public void testUnsatisfiableProgram() throws IOException { + assertAnswerSets("p(a). p(b). :- p(a), p(b)."); + } + + @Test + public void testFunctionTermEquality() throws IOException { + assertAnswerSet( + "r1(f(a,b)). r2(f(a,b)). a :- r1(X), r2(Y), X = Y.", + + "r1(f(a,b)), r2(f(a,b)), a" + ); + } + + @Test + public void builtinInequality() throws IOException { + assertAnswerSetsWithBase( + "location(a1)." + + "region(r1)." + + "region(r2)." + + "assign(L,R) :- location(L), region(R), not nassign(L,R)." + + "nassign(L,R) :- location(L), region(R), not assign(L,R)." + + ":- assign(L,R1), assign(L,R2), R1 != R2." + + "aux_ext_assign(a1,r1)." + + "aux_ext_assign(a1,r2)." + + "aux_not_assign(L,R) :- aux_ext_assign(L,R), not assign(L,R)." + + ":- aux_not_assign(L,R), assign(L,R).", + + "location(a1), region(r1), region(r2), aux_ext_assign(a1,r1), aux_ext_assign(a1,r2)", + + "assign(a1,r2), nassign(a1,r1), aux_not_assign(a1,r1)", + "assign(a1,r1), nassign(a1,r2), aux_not_assign(a1,r2)", + "nassign(a1,r1), nassign(a1,r2), aux_not_assign(a1,r1), aux_not_assign(a1,r2)" + ); + } + + @Test + public void choiceConstraintsInequality() throws IOException { + assertAnswerSetsWithBase( + "assign(L, R) :- not nassign(L, R), possible(L, R)." + + "nassign(L, R) :- not assign(L, R), possible(L, R)." + + "assigned(L) :- assign(L, R)." + + ":- possible(L,_), not assigned(L)." + + ":- assign(L, R1), assign(L, R2), R1 != R2." + + "possible(l1, r1). possible(l3, r3). possible(l4, r1). possible(l4, r3). possible(l5, r4). possible(l6, r2). possible(l7, r3). possible(l8, r2). possible(l9, r1). possible(l9, r4).", + + "possible(l1,r1), " + + "possible(l3,r3), " + + "possible(l4,r1), " + + "possible(l4,r3), " + + "possible(l5,r4), " + + "possible(l6,r2), " + + "possible(l7,r3), " + + "possible(l8,r2), " + + "possible(l9,r1), " + + "possible(l9,r4), " + + "assign(l1,r1), " + + "assign(l3,r3), " + + "assign(l5,r4), " + + "assign(l6,r2), " + + "assign(l7,r3), " + + "assign(l8,r2), " + + "assigned(l1), " + + "assigned(l3), " + + "assigned(l4), " + + "assigned(l5), " + + "assigned(l6), " + + "assigned(l7), " + + "assigned(l8), " + + "assigned(l9)", + + "assign(l4,r1), " + + "assign(l9,r4), " + + "nassign(l4,r3), " + + "nassign(l9,r1)", + + "assign(l4,r1), " + + "assign(l9,r1), " + + "nassign(l4,r3), " + + "nassign(l9,r4)", + + "assign(l4,r3), " + + "assign(l9,r4), " + + "nassign(l4,r1), " + + "nassign(l9,r1)", + + "assign(l4,r3), " + + "assign(l9,r1), " + + "nassign(l4,r1), " + + "nassign(l9,r4)" + ); + } + @Test + public void sameVariableTwiceInAtom() throws IOException { + assertAnswerSets( + "p(a, a)." + + "q(X) :- p(X, X).", + + "p(a,a), q(a)" + ); + } + + @Test + public void sameVariableTwiceInAtomConstraint() throws IOException { + assertAnswerSets( + "p(a, a)." + + ":- p(X, X)." + ); + } + + @Test + public void noPositiveSelfFounding() throws IOException { + assertAnswerSets( + "a :- b." + + "b:- a." + + ":- not b." + ); + } + + @Test + public void noPositiveCycleSelfFoundingChoice() throws IOException { + assertAnswerSets( + "c :- not d." + + "d :- not c." + + "a :- b, not c." + + "b:- a." + + ":- not b." + ); + } + + @Test + public void conflictFromUnaryNoGood() throws IOException { + assertAnswerSet( + "d(b)." + + "sel(X) :- not nsel(X), d(X)." + + "nsel(X) :- not sel(X), d(X)." + + "t(a) :- sel(b)." + + ":- t(X).", + + "d(b), nsel(b)" + ); + } + + @Test + public void intervalsInFacts() throws IOException { + assertAnswerSets( + "a." + + "facta(1..3)." + + "factb(t, 5..8, u)." + + "factc(1..3, w, 2 .. 4)." + + "b(1,2)." + + "b(3,4).", + + "facta(1), " + + "facta(2), " + + "facta(3), " + + + "factb(t, 5, u)," + + "factb(t, 6, u)," + + "factb(t, 7, u)," + + "factb(t, 8, u)," + + + "factc(1, w, 2)," + + "factc(2, w, 2)," + + "factc(3, w, 2)," + + "factc(1, w, 3)," + + "factc(2, w, 3)," + + "factc(3, w, 3)," + + "factc(1, w, 4)," + + "factc(2, w, 4)," + + "factc(3, w, 4)," + + + "a," + + + "b(1, 2)," + + "b(3, 4)" + ); + } + + @Test + public void intervalInRules() throws IOException { + assertAnswerSets( + "a :- 3 = 1..4 ." + + "p(X, 1..X) :- dom(X), X != 2." + + "dom(1). dom(2). dom(3).", + + "dom(1)," + + "dom(2)," + + "dom(3)," + + + "p(1, 1)," + + "p(3, 1)," + + "p(3, 2)," + + "p(3, 3)," + + + "a" + ); + } + + @Test + public void emptyIntervals() throws IOException { + assertAnswerSets( + "p(3..1)." + + "dom(5)." + + "p(X) :- dom(X), X = 7..2 .", + "dom(5)" + ); + } + + @Test + public void intervalInFunctionTermsInRules() throws IOException { + assertAnswerSets( + "a :- q(f(1..3,g(4..5)))." + + "q(f(2,g(4)))." + + "q(f(1,g(5)))." + + "p(f(1..3,g(4..5))) :- b." + + "b.", + + "a, " + + "b, " + + + "q(f(2,g(4))), " + + "q(f(1,g(5))), " + + + "p(f(1,g(4))), " + + "p(f(1,g(5))), " + + "p(f(2,g(4))), " + + "p(f(2,g(5))), " + + "p(f(3,g(4))), " + + "p(f(3,g(5)))" + ); + } + + @Test + public void groundAtomInRule() throws IOException { + assertAnswerSet( + "p :- dom(X), q, q2." + + "dom(1)." + + "q :- not nq." + + "nq :- not q." + + "q2 :- not nq2." + + "nq2 :- not q2." + + ":- not p.", + + "dom(1), p, q, q2" + ); + } + + @Test + public void simpleChoiceRule() throws IOException { + assertAnswerSetsWithBase( + "{ a; b; c} :- d." + + "d.", + + "d", + "", + "a", + "a, b", + "a, c", + "a, b, c", + "b", + "b, c", + "c" + ); + } + + @Test + public void conditionalChoiceRule() throws IOException { + assertAnswerSetsWithBase( + "dom(1..3)." + + "{ p(X): not q(X); r(Y): p(Y)} :- dom(X), q(Y)." + + "q(2).", + + "dom(1)," + + "dom(2)," + + "dom(3)," + + "q(2)", + + "p(1)," + + "p(3)", + + "", + + "p(3)", + + "p(1)" + ); + } + + @Test + public void doubleChoiceRule() throws IOException { + Solver solver = getInstance("{ a }. { a }."); + // Make sure that no superfluous answer sets that only differ on hidden atoms occur. + List actual = solver.collectList(); + assertEquals(2, actual.size()); + assertEquals(AnswerSetsParser.parse("{} { a }"), new HashSet<>(actual)); + } + + @Test + public void simpleArithmetics() throws IOException { + assertAnswerSet("eight(X) :- X = 4 + 5 - 1." + + "three(X) :- X = Z, Y = 1..10, Z = Y / 3, Z > 2, Z < 4.", + + "eight(8), three(3)"); + } + + @Test + public void arithmeticsMultiplicationBeforeAddition() throws IOException { + assertAnswerSet("seven(X) :- 1+2 * 3 = X.", + + "seven(7)"); + } + + /** + * Tests the fix for issue #101 + */ + @Test + public void involvedUnsatisfiableProgram() throws IOException { + assertAnswerSets("x :- c1, c2, not x." + + "c1 :- not a1." + + "c1 :- not b1." + + "c2 :- not a2." + + "c2 :- not b2." + + "a1 :- not b1." + + "b1 :- not a1." + + "a2 :- not b2." + + "b2 :- not a2."); + } + + @Test + public void instanceEnumerationAtom() throws IOException { + Set answerSets = getInstance("# enumeration_predicate_is enum." + + "dom(1). dom(2). dom(3)." + + "p(X) :- dom(X)." + + "q(Y) :- p(Y)." + + "unique_position(Term,Pos) :- q(Term), enum(id0,Term,Pos)." + + "wrong_double_occurrence :- unique_position(T1,P), unique_position(T2,P), T1 != T2.").collectSet(); + // Since enumeration depends on evaluation, we do not know which unique_position is actually assigned. + // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. + assertEquals(1, answerSets.size()); + AnswerSet answerSet = answerSets.iterator().next(); + assertEquals(null, answerSet.getPredicateInstances(Predicate.getInstance("wrong_double_occurrence", 0))); + SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position", 2)); + assertEnumerationPositions(positions, 3); + } + + @Test + public void instanceEnumerationArbitraryTerms() throws IOException { + Set answerSets = getInstance("# enumeration_predicate_is enum." + + "dom(a). dom(f(a,b)). dom(d)." + + "p(X) :- dom(X)." + + "q(Y) :- p(Y)." + + "unique_position(Term,Pos) :- q(Term), enum(id0,Term,Pos)." + + "wrong_double_occurrence :- unique_position(T1,P), unique_position(T2,P), T1 != T2.").collectSet(); + // Since enumeration depends on evaluation, we do not know which unique_position is actually assigned. + // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. + assertEquals(1, answerSets.size()); + AnswerSet answerSet = answerSets.iterator().next(); + assertPropositionalPredicateFalse(answerSet, Predicate.getInstance("wrong_double_occurrence", 0)); + SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position", 2)); + assertEnumerationPositions(positions, 3); + } + + @Test + public void instanceEnumerationMultipleIdentifiers() throws IOException { + Set answerSets = getInstance("# enumeration_predicate_is enum." + + "dom(a). dom(b). dom(c). dom(d)." + + "p(X) :- dom(X)." + + "unique_position1(Term,Pos) :- p(Term), enum(id,Term,Pos)." + + "unique_position2(Term,Pos) :- p(Term), enum(otherid,Term,Pos)." + + "wrong_double_occurrence :- unique_position(T1,P), unique_position(T2,P), T1 != T2." + + "wrong_double_occurrence :- unique_position2(T1,P), unique_position(T2,P), T1 != T2.").collectSet(); + // Since enumeration depends on evaluation, we do not know which unique_position is actually assigned. + // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. + assertEquals(1, answerSets.size()); + AnswerSet answerSet = answerSets.iterator().next(); + assertPropositionalPredicateFalse(answerSet, Predicate.getInstance("wrong_double_occurrence", 0)); + SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position1", 2)); + assertEnumerationPositions(positions, 4); + SortedSet positions2 = answerSet.getPredicateInstances(Predicate.getInstance("unique_position2", 2)); + assertEnumerationPositions(positions2, 4); + } + + private void assertPropositionalPredicateFalse(AnswerSet answerSet, Predicate predicate) { + assertEquals(null, answerSet.getPredicateInstances(predicate)); + } + + private void assertEnumerationPositions(SortedSet positions, int numPositions) { + assertEquals(numPositions, positions.size()); + boolean usedPositions[] = new boolean[numPositions]; + for (Atom position : positions) { + @SuppressWarnings("unchecked") + Integer atomPos = ((ConstantTerm) position.getTerms().get(1)).getObject() - 1; + assertTrue(atomPos < numPositions); + usedPositions[atomPos] = true; + } + for (int i = 0; i < numPositions; i++) { + assertTrue(usedPositions[i]); + } + } + + @Test + public void smallCardinalityAggregate() throws IOException { + assertAnswerSetsWithBase( + "dom(1..3)." + + "bound(1..4)." + + "{ value(X) : dom(X) }." + + "num(K) :- K <= #count {X : value(X) }, bound(K).", + + "dom(1), dom(2), dom(3), bound(1), bound(2), bound(3), bound(4)", + "", + "", + "value(1), num(1)", + "value(1), value(2), num(1), num(2)", + "value(1), value(2), value(3), num(1), num(2), num(3)", + "value(1), value(3), num(1), num(2)", + "value(2), num(1)", + "value(2), value(3), num(1), num(2)", + "value(3), num(1)" + ); + } + + @Test + public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { + final ProgramParser parser = new ProgramParser(); + InputProgram.Builder bld = InputProgram.builder(); + bld.accumulate(parser.parse(CharStreams.fromPath(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp")))); + bld.accumulate(parser.parse(CharStreams.fromPath(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp")))); + InputProgram parsedProgram = bld.build(); + + SystemConfig config = new SystemConfig(); + config.setSolverName("default"); + config.setNogoodStoreName("alpharoaming"); + config.setSeed(0); + config.setBranchingHeuristic(BranchingHeuristicFactory.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 Alpha(config); + Optional answerSet = alpha.solve(parsedProgram).findFirst(); + assertTrue(answerSet.isPresent()); + } + + + @Test + public void dummyGrounder() { + AtomStore atomStore = new AtomStoreImpl(); + TestCase.assertEquals(DummyGrounder.EXPECTED, getInstance(atomStore, new DummyGrounder(atomStore)).collectSet()); + } + + @Test + public void choiceGrounder() { + AtomStore atomStore = new AtomStoreImpl(); + TestCase.assertEquals(ChoiceGrounder.EXPECTED, getInstance(atomStore, new ChoiceGrounder(atomStore)).collectSet()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java new file mode 100644 index 000000000..d8923a166 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java @@ -0,0 +1,50 @@ +/** + * 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.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/solver/ThreeColouringRandomGraphTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java new file mode 100644 index 000000000..4dffa1968 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2017 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.solver; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Random; + +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +public class ThreeColouringRandomGraphTest extends AbstractSolverTests { + @Test(timeout = 1000) + public void testV3E3() throws IOException { + testThreeColouring(3, 3); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testV10E18() throws IOException { + testThreeColouring(10, 18); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testV20E38() throws IOException { + testThreeColouring(20, 38); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testV30E48() throws IOException { + testThreeColouring(30, 48); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testV200E300() throws IOException { + testThreeColouring(200, 300); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testV300E200() throws IOException { + testThreeColouring(300, 200); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testV300E300() throws IOException { + testThreeColouring(300, 300); + } + + private void testThreeColouring(int nVertices, int nEdges) throws IOException { + InputProgram tmpPrg = new ProgramParser().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); + prgBuilder.addFacts(createVertices(nVertices)); + prgBuilder.addFacts(createEdges(nVertices, nEdges)); + InputProgram program = prgBuilder.build(); + maybeShuffle(program); + + Optional answerSet = getInstance(program).stream().findAny(); + //System.out.println(answerSet); + + // TODO: check correctness of answer set + } + + 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 + // Collections.reverse(program.getRules()); + // Collections.shuffle(program.getRules()); + // Collections.reverse(program.getFacts()); + // Collections.shuffle(program.getFacts()); + } + + private List createVertices(int n) { + List facts = new ArrayList<>(n); + for (int i = 0; i < n; i++) { + facts.add(fact("v", i)); + } + return facts; + } + + private List createEdges(int vertices, int edges) { + Random rand = new Random(0); + List facts = new ArrayList<>(edges); + for (int i = 0; i < edges; i++) { + int v1 = 0; + int v2 = 0; + while (v1 == v2) { + v1 = rand.nextInt(vertices); + v2 = rand.nextInt(vertices); + } + facts.add(fact("e", v1, v2)); + facts.add(fact("e", v2, v1)); + } + return facts; + } + + private Atom fact(String predicateName, int... iTerms) { + List terms = new ArrayList<>(1); + for (int i : iTerms) { + terms.add(ConstantTerm.getInstance(i)); + } + return new BasicAtom(Predicate.getInstance(predicateName, iTerms.length), terms); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java new file mode 100644 index 000000000..93eec197d --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2017 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.solver; + +import org.junit.Ignore; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Random; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +/** + * Tests {@link AbstractSolver} 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: + * 10.1017/S1471068416000569 + */ +public class ThreeColouringTestWithRandom extends AbstractSolverTests { + @Test(timeout = 3000) + public void testN3() throws IOException { + testThreeColouring(3, false, 0); + } + + @Test(timeout = 4000) + public void testN4() throws IOException { + testThreeColouring(4, false, 0); + } + + @Test(timeout = 5000) + @Ignore("disabled to save resources during CI") + public void testN5() throws IOException { + testThreeColouring(5, false, 0); + } + + @Test(timeout = 6000) + @Ignore("disabled to save resources during CI") + public void testN6() throws IOException { + testThreeColouring(6, false, 0); + } + + @Test(timeout = 7000) + @Ignore("disabled to save resources during CI") + public void testN7() throws IOException { + testThreeColouring(7, false, 0); + } + + @Test(timeout = 8000) + @Ignore("disabled to save resources during CI") + public void testN8() throws IOException { + testThreeColouring(8, false, 0); + } + + @Test(timeout = 9000) + @Ignore("disabled to save resources during CI") + public void testN9() throws IOException { + testThreeColouring(9, false, 0); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testN10() throws IOException { + testThreeColouring(10, false, 0); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testN10Random0() throws IOException { + testThreeColouring(10, true, 0); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testN10Random1() throws IOException { + testThreeColouring(10, true, 1); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testN10Random2() throws IOException { + testThreeColouring(10, true, 2); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testN10Random3() throws IOException { + testThreeColouring(10, true, 3); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN19() throws IOException { + testThreeColouring(19, false, 0); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN19Random0() throws IOException { + testThreeColouring(19, true, 0); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN19Random1() throws IOException { + testThreeColouring(19, true, 1); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN19Random2() throws IOException { + testThreeColouring(19, true, 2); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN19Random3() throws IOException { + testThreeColouring(19, true, 3); + } + + @Test(timeout = 10000) + @Ignore("disabled to save resources during CI") + public void testN101() throws IOException { + testThreeColouring(101, false, 0); + } + + private void testThreeColouring(int n, boolean shuffle, int seed) throws IOException { + InputProgram tmpPrg = new ProgramParser() + .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); + prgBuilder.addFacts(createColors("1", "2", "3")); + prgBuilder.addFacts(createVertices(n)); + prgBuilder.addFacts(createEdges(n, shuffle, seed)); + InputProgram program = prgBuilder.build(); + + Solver solver = getInstance(program); + Optional answerSet = solver.stream().findAny(); + // System.out.println(answerSet); + // TODO: check correctness of answer set + } + + private List createColors(String... colours) { + List facts = new ArrayList<>(colours.length); + for (String colour : colours) { + List terms = new ArrayList<>(1); + terms.add(ConstantTerm.getInstance(colour)); + facts.add(new BasicAtom(Predicate.getInstance("c", 1), terms)); + } + return facts; + } + + private List createVertices(int n) { + List facts = new ArrayList<>(n); + for (int i = 1; i <= n; i++) { + facts.add(fact("v", i)); + } + return facts; + } + + /** + * + * @param n + * @param shuffle if true, the vertex indices are shuffled with the given seed + * @param seed + * @return + */ + private List createEdges(int n, boolean shuffle, int seed) { + List facts = new ArrayList<>(n); + List indices = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + indices.add(i); + } + if (shuffle) { + Collections.shuffle(indices, new Random(seed)); + } + + for (int i = 1; i < n; i++) { + facts.add(fact("e", indices.get(0), indices.get(i))); + } + for (int i = 1; i < n - 1; i++) { + facts.add(fact("e", indices.get(i), indices.get(i + 1))); + } + facts.add(fact("e", indices.get(1), indices.get(n - 1))); + return facts; + } + + private Atom fact(String predicateName, int... iTerms) { + List terms = new ArrayList<>(iTerms.length); + Predicate predicate = Predicate.getInstance(predicateName, iTerms.length); + for (int i : iTerms) { + terms.add(ConstantTerm.getInstance(i)); + } + return new BasicAtom(predicate, terms); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java new file mode 100644 index 000000000..a2882cd06 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2017 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.solver; + +import org.junit.Ignore; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; + +/** + * Tests {@link AbstractSolver} 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: 10.1017/S1471068416000569 + */ +public class ThreeColouringWheelTest extends AbstractSolverTests { + @Test(timeout = 1000) + public void testN4() throws IOException { + testThreeColouring(4); + } + + @Test(timeout = 1000) + public void testN5() throws IOException { + testThreeColouring(5); + } + + @Test(timeout = 6000) + @Ignore("disabled to save resources during CI") + public void testN6() throws IOException { + testThreeColouring(6); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN3() throws IOException { + testThreeColouring(3); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN7() throws IOException { + testThreeColouring(7); + } + + @Test(timeout = 60000) + @Ignore("disabled to save resources during CI") + public void testN11() throws IOException { + testThreeColouring(11); + } + + private void testThreeColouring(int n) throws IOException { + InputProgram tmpPrg = new ProgramParser().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); + prgBuilder.addFacts(createColors("red", "blue", "green")); + prgBuilder.addFacts(createVertices(n)); + prgBuilder.addFacts(createEdges(n)); + InputProgram program = prgBuilder.build(); + + maybeShuffle(program); + + Solver solver = getInstance(program); + + Optional answerSet = solver.stream().findAny(); + //System.out.println(answerSet); + + // TODO: check correctness of answer set + } + + private void maybeShuffle(InputProgram program) { + // FIXME since InputProgram is immutable this needs to be reworked a bit if used + // No shuffling here. + } + + private List createColors(String... colours) { + List facts = new ArrayList<>(colours.length); + Predicate predicate = Predicate.getInstance("c", 1); + for (String colour : colours) { + List terms = new ArrayList<>(1); + terms.add(ConstantTerm.getInstance(colour)); + facts.add(new BasicAtom(predicate, terms)); + } + return facts; + } + + private List createVertices(int n) { + List facts = new ArrayList<>(n); + for (int i = 1; i <= n; i++) { + facts.add(fact("v", i)); + } + return facts; + } + + private List createEdges(int n) { + List facts = new ArrayList<>(n); + for (int i = 2; i <= n; i++) { + facts.add(fact("e", 1, i)); + } + for (int i = 2; i <= n - 1; i++) { + facts.add(fact("e", i, i + 1)); + } + facts.add(fact("e", n, 2)); + return facts; + } + + private Atom fact(String predicateName, int... iTerms) { + List terms = new ArrayList<>(1); + Predicate predicate = Predicate.getInstance(predicateName, iTerms.length); + for (int i : iTerms) { + terms.add(ConstantTerm.getInstance(i)); + } + return new BasicAtom(predicate, terms); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java new file mode 100644 index 000000000..9cbda2250 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java @@ -0,0 +1,260 @@ +/** + * 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.solver; + +import at.ac.tuwien.kr.alpha.common.Assignment; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +import at.ac.tuwien.kr.alpha.common.IntIterator; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; +import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * Copyright (c) 2018-2020, the Alpha Team. + */ +public class TrailAssignmentTest { + private final TrailAssignment assignment; + + public TrailAssignmentTest() { + AtomStore atomStore = new AtomStoreImpl(); + AtomStoreTest.fillAtomStore(atomStore, 20); + assignment = new TrailAssignment(atomStore); + } + + @Before + public void setUp() { + assignment.clear(); + assignment.growForMaxAtomId(); + } + + @Test(expected = IllegalArgumentException.class) + public void assign() throws Exception { + assignment.assign(0, null); + } + + @Test(expected = IllegalArgumentException.class) + public void negativeAtomThrows() throws Exception { + assignment.assign(-1, null); + } + + @Test + public void alreadyAssignedThrows() throws Exception { + assertNull(assignment.assign(1, MBT)); + assertNotNull(assignment.assign(1, FALSE)); + } + + @Test + public void initializeDecisionLevelState() throws Exception { + assignment.assign(1, MBT); + assignment.choose(2, MBT); + assignment.choose(1, TRUE); + } + + @Test + public void checkToString() { + assignment.assign(1, FALSE); + assertEquals("[F_a(0)@0]", assignment.toString()); + + assignment.assign(2, TRUE); + assertEquals("[F_a(0)@0, T_a(1)@0]", assignment.toString()); + } + + @Test + public void reassignGracefully() { + assignment.assign(1, FALSE); + assignment.assign(1, FALSE); + } + + @Test + public void assignAndBacktrack() { + assignment.assign(1, MBT); + assignment.assign(2, FALSE); + assignment.assign(3, TRUE); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(FALSE, assignment.getTruth(2)); + assertEquals(TRUE, assignment.getTruth(3)); + assertEquals(assignment.getTrueAssignments(), new HashSet<>(Collections.singletonList(3))); + assertEquals(1, assignment.getMBTCount()); + + assignment.choose(1, TRUE); + + assertEquals(TRUE, assignment.getTruth(1)); + assertEquals(assignment.getTrueAssignments(), new HashSet<>(Arrays.asList(3, 1))); + assertEquals(0, assignment.getMBTCount()); + + assignment.backtrack(); + + assertEquals(MBT, assignment.getTruth(1)); + assertEquals(FALSE, assignment.getTruth(2)); + assertEquals(TRUE, assignment.getTruth(3)); + assertEquals(assignment.getTrueAssignments(), new HashSet<>(Collections.singletonList(3))); + assertEquals(1, assignment.getMBTCount()); + + assignment.choose(4, MBT); + assignment.assign(5, MBT); + + assertEquals(MBT, assignment.getTruth(4)); + assertEquals(MBT, assignment.getTruth(5)); + + assignment.backtrack(); + + assertFalse(assignment.isAssigned(4)); + assertFalse(assignment.isAssigned(5)); + + assignment.choose(4, TRUE); + + assertEquals(TRUE, assignment.getTruth(4)); + + assignment.backtrack(); + + assertNull(assignment.getTruth(4)); + } + + @Test + public void assignmentsToProcess() throws Exception { + assignment.assign(1, MBT); + + Assignment.Pollable queue = assignment.getAssignmentsToProcess(); + assertEquals(1, queue.remove()); + + assignment.choose(2, MBT); + assignment.choose(1, TRUE); + + assertEquals(2, queue.remove()); + assertEquals(1, queue.peek()); + + queue = assignment.getAssignmentsToProcess(); + assertEquals(1, queue.remove()); + } + + @Test + public void newAssignmentsIteratorAndBacktracking() throws Exception { + IntIterator newAssignmentsIterator; + + assignment.assign(1, MBT); + assignment.choose(2, MBT); + + newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); + + assertEquals(1, (int)newAssignmentsIterator.next()); + assertEquals(2, (int)newAssignmentsIterator.next()); + assertFalse(newAssignmentsIterator.hasNext()); + + + assignment.choose(1, TRUE); + assignment.backtrack(); + assignment.assign(3, FALSE); + + newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); + assertEquals(3, (int)newAssignmentsIterator.next()); + assertFalse(newAssignmentsIterator.hasNext()); + } + + @Test + public void newAssignmentsIteratorLowerDecisionLevelAndBacktracking() throws Exception { + IntIterator newAssignmentsIterator; + + assignment.choose(1, MBT); + assignment.choose(2, MBT); + assignment.assign(3, MBT, null, 1); + assignment.backtrack(); + + newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); + assertEquals(1, (int)newAssignmentsIterator.next()); + assertEquals(3, (int)newAssignmentsIterator.next()); + assertFalse(newAssignmentsIterator.hasNext()); + } + + @Test + public void iteratorAndBacktracking() throws Exception { + Assignment.Pollable assignmentsToProcess = assignment.getAssignmentsToProcess(); + + assignment.assign(1, MBT); + assertEquals(1, assignmentsToProcess.remove()); + + assignment.choose(2, MBT); + assertEquals(2, assignmentsToProcess.remove()); + + assignment.choose(1, TRUE); + assertEquals(1, assignmentsToProcess.remove()); + + assignment.backtrack(); + + assignment.assign(3, FALSE); + assertEquals(3, assignmentsToProcess.remove()); + } + + @Test + public void mbtCounterAssignMbtToFalseOnLowerDecisionLevel() { + assertNull(assignment.choose(1, TRUE)); + assertNull(assignment.choose(2, FALSE)); + + assertNull(assignment.assign(3, MBT, null, 2)); + assertEquals(1, assignment.getMBTCount()); + + assertNull(assignment.choose(4, TRUE)); + + assertNotNull(assignment.assign(3, FALSE, null, 1)); + + assignment.backtrack(); + assignment.backtrack(); + + assertEquals(0, assignment.getMBTCount()); + } + + @Test + public void numberOfAssignedAtoms() throws Exception { + assignment.assign(1, MBT); + assertEquals(1, assignment.getNumberOfAssignedAtoms()); + assignment.assign(2, FALSE); + assertEquals(2, assignment.getNumberOfAssignedAtoms()); + assignment.assign(3, MBT); + assignment.assign(3, TRUE); + assertEquals(3, assignment.getNumberOfAssignedAtoms()); + assignment.choose(1, TRUE); + assertEquals(3, assignment.getNumberOfAssignedAtoms()); + assertEquals(1, assignment.getNumberOfAtomsAssignedSinceLastDecision()); + assignment.assign(5, MBT); + assignment.assign(5, TRUE); + assertEquals(2, assignment.getNumberOfAtomsAssignedSinceLastDecision()); + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java new file mode 100644 index 000000000..ec2af6231 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java @@ -0,0 +1,170 @@ +/** + * 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.common.program.InputProgram; +import at.ac.tuwien.kr.alpha.common.program.InternalProgram; +import at.ac.tuwien.kr.alpha.common.program.NormalProgram; +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.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.solver.NaiveNoGoodStore; +import at.ac.tuwien.kr.alpha.solver.TestableChoiceManager; +import at.ac.tuwien.kr.alpha.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Tests assumptions made by {@link DependencyDrivenHeuristic} and other domain-independent heuristics. + * Even if these test cases do not test {@link DependencyDrivenHeuristic} directly, + * it will break if these test cases break. + * + * Copyright (c) 2017-2018 Siemens AG + * + */ +public class AlphaHeuristicTestAssumptions { + private Grounder grounder; + private WritableAssignment assignment; + private TestableChoiceManager choiceManager; + private AtomStore atomStore; + + @Before + public void setUp() { + Alpha system = new Alpha(); + String testProgram = "" + + "b1." + + "b2." + + "{b3}." + + "{b4}." + + "h :- b1, b2, not b3, not b4."; + InputProgram parsedProgram = new ProgramParser().parse(testProgram); + NormalProgram normal = system.normalizeProgram(parsedProgram); + InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + atomStore = new AtomStoreImpl(); + grounder = new NaiveGrounder(internalProgram, atomStore, true); + assignment = new TrailAssignment(atomStore); + choiceManager = new TestableChoiceManager(assignment, new NaiveNoGoodStore(assignment)); + } + + @Test + public void testNumbersOfNoGoods_GrounderIsAtomChoicePoint() { + testNumbersOfNoGoods(atomStore::isAtomChoicePoint); + } + + @Test + public void testNumbersOfNoGoods_ChoiceManagerIsAtomChoice() { + testNumbersOfNoGoods(choiceManager::isAtomChoice); + } + + private void testNumbersOfNoGoods(Predicate isRuleBody) { + int n = 0; + int bodyNotHead = 0; + int bodyElementsNotBody = 0; + int noHead = 0; + int other = 0; + + Collection noGoods = getNoGoods(); + assignment.growForMaxAtomId(); + choiceManager.growForMaxAtomId(atomStore.getMaxAtomId()); + choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); + for (NoGood noGood : noGoods) { + n++; + boolean knownType = false; + if (DependencyDrivenHeuristic.isBodyNotHead(noGood, isRuleBody)) { + bodyNotHead++; + knownType = true; + } + if (DependencyDrivenHeuristic.isBodyElementsNotBody(noGood, isRuleBody)) { + bodyElementsNotBody++; + knownType = true; + } + if (!noGood.hasHead()) { + noHead++; + knownType = true; + } + if (!knownType) { + other++; + } + } + + System.out.println(noGoods.stream().map(atomStore::noGoodToString).collect(Collectors.joining(", "))); + + assertEquals("Unexpected number of bodyNotHead nogoods", 5, bodyNotHead); + assertEquals("Unexpected number of bodyElementsNotBody nogoods", 5, bodyElementsNotBody); + assertGreaterThan("Unexpected number of nogoods without head", 4, noHead); + + // there may be other nogoods (e.g. for ChoiceOn, ChoiceOff) which we do not care for here + System.out.println("Total number of NoGoods: " + n); + System.out.println("Number of NoGoods of unknown type: " + other); + } + + @Test + public void testIsAtomChoice_GrounderIsAtomChoicePoint() { + testIsAtomChoice(atomStore::isAtomChoicePoint); + } + + @Test + public void testIsAtomChoice_ChoiceManagerIsAtomChoice() { + testIsAtomChoice(choiceManager::isAtomChoice); + } + + private void testIsAtomChoice(Predicate isRuleBody) { + Collection noGoods = getNoGoods(); + assignment.growForMaxAtomId(); + choiceManager.growForMaxAtomId(atomStore.getMaxAtomId()); + choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); + for (NoGood noGood : noGoods) { + for (Integer literal : noGood) { + int atom = atomOf(literal); + String atomToString = atomStore.atomToString(atom); + if (atomToString.startsWith("_R_")) { + assertTrue("Atom not choice: " + atomToString, isRuleBody.test(atom)); + } + } + } + } + + private Collection getNoGoods() { + return grounder.getNoGoods(null).values(); + } + + private void assertGreaterThan(String message, long expected, long actual) { + assertTrue(message, actual > expected); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java new file mode 100644 index 000000000..29227058f --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2016-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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.NaiveNoGoodStore; +import at.ac.tuwien.kr.alpha.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; +import java.util.Random; + +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static org.junit.Assert.assertEquals; + +/** + * Tests {@link BerkMin}. + * + * Copyright (c) 2016 Siemens AG + * + */ +public class BerkMinTest { + + /** + * The tolerable epsilon for double comparisons + */ + private static final double DOUBLE_COMPARISON_EPSILON = 0.000001; + + private BerkMin berkmin; + + @Before + public void setUp() { + AtomStore atomStore = new AtomStoreImpl(); + AtomStoreTest.fillAtomStore(atomStore, 2); + WritableAssignment assignment = new TrailAssignment(atomStore); + assignment.growForMaxAtomId(); + this.berkmin = new BerkMin( + assignment, + new PseudoChoiceManager(assignment, new NaiveNoGoodStore(assignment)), + new Random() + ); + } + + @Test + public void countPositiveLiteralsOnce() { + NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void countNegativeLiteralsOnce() { + NoGood violatedNoGood = new NoGood(fromOldLiterals(-1, -2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(1, berkmin.getActivity(fromOldLiterals(-1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(1, berkmin.getActivity(fromOldLiterals(-2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void countPositiveLiteralsTwice() { + NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(2, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void countNegativeLiteralsTwice() { + NoGood violatedNoGood = new NoGood(fromOldLiterals(-1, -2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(2, berkmin.getActivity(fromOldLiterals(-1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(2, berkmin.getActivity(fromOldLiterals(-2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void countMixedLiteralsTwice() { + NoGood violatedNoGood = new NoGood(fromOldLiterals(1, -2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(2, berkmin.getActivity(fromOldLiterals(-2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void countPositiveLiteralsThenNegativeLiterals() { + NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + violatedNoGood = new NoGood(fromOldLiterals(-1, -2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(2, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void reachDecayPeriodOnce() { + berkmin.setDecayPeriod(3); + berkmin.setDecayFactor(1.0 / 3); + NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(2, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void reachDecayPeriodTwice() { + berkmin.setDecayPeriod(2); + berkmin.setDecayFactor(0.75); + NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(1.5, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(1.5, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(2.5, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(2.5, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + berkmin.violatedNoGood(violatedNoGood); + berkmin.analyzedConflict(pseudo(violatedNoGood)); + assertEquals(2.625, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); + assertEquals(2.625, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void learnNoGood() { + NoGood learnedNoGood = NoGood.learnt(fromOldLiterals(1, 2)); + int backjumpLevel = 1; + boolean clearLastChoiceAfterBackjump = true; + Collection resolutionAtoms = Collections.emptySet(); + berkmin.analyzedConflict(new ConflictAnalysisResult(learnedNoGood, backjumpLevel, + resolutionAtoms)); + assertEquals(learnedNoGood, berkmin.getCurrentTopClause()); + } + + private static ConflictAnalysisResult pseudo(NoGood noGood) { + return new ConflictAnalysisResult(noGood, 0, Collections.emptySet()); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java new file mode 100644 index 000000000..519f14169 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.solver.*; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Tests {@link BranchingHeuristicFactory} + */ +public class BranchingHeuristicFactoryTest { + + private final BranchingHeuristicFactory factory = new BranchingHeuristicFactory(); + private final boolean debugInternalChecks = true; + private ChoiceManager choiceManager; + + @Before + public void setUp() { + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + NoGoodStore store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); + this.choiceManager = new ChoiceManager(assignment, store); + } + + @Test + public void testChainedHeuristicWithReplay() { + HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(BranchingHeuristicFactory.Heuristic.VSIDS).setReplayChoices(Arrays.asList(1, 2, 3)); + BranchingHeuristic branchingHeuristic = factory.getInstance(builder.build(), null, null, choiceManager, null); + assertEquals(ChainedBranchingHeuristics.class, branchingHeuristic.getClass()); + assertTrue("Unexpected type of branchingHeuristic: " + branchingHeuristic.getClass(), branchingHeuristic instanceof ChainedBranchingHeuristics); + assertEquals(ChainedBranchingHeuristics.class.getSimpleName() + "[" + ReplayHeuristic.class.getSimpleName() + ", " + VSIDS.class.getSimpleName() + "]", branchingHeuristic.toString()); + } + + @Test + public void testChainedHeuristicWithoutReplay() { + HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(BranchingHeuristicFactory.Heuristic.VSIDS).setReplayChoices(null); + BranchingHeuristic branchingHeuristic = factory.getInstance(builder.build(), null, null, choiceManager, null); + assertEquals(VSIDS.class, branchingHeuristic.getClass()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java new file mode 100644 index 000000000..a73882ed5 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.Literals; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Tests {@link HeapOfActiveAtoms}, including initial heuristic scores computed by {@link MOMs}. + * + */ +public class HeapOfActiveAtomsTest { + + private static final double DOUBLE_COMPARISON_EPSILON = 0.001; + + private AtomStore atomStore; + private WritableAssignment assignment; + private VSIDS vsids; + private NoGoodStoreAlphaRoaming noGoodStore; + + @Before + public void setUp() { + atomStore = new AtomStoreImpl(); + assignment = new TrailAssignment(atomStore); + noGoodStore = new NoGoodStoreAlphaRoaming(assignment); + ChoiceManager choiceManager = new PseudoChoiceManager(assignment, noGoodStore); + this.vsids = new VSIDS(assignment, choiceManager, MOMs.DEFAULT_STRATEGY); + } + + @Test + public void testAllAtomsEqualScore() { + int lit1 = Literals.atomToLiteral(1); + int lit2 = Literals.atomToLiteral(2); + int lit3 = Literals.atomToLiteral(3); + HeuristicTestUtils.addNoGoods(atomStore, assignment, noGoodStore, vsids, new NoGood(lit1, lit2), new NoGood(lit2, lit3), + new NoGood(lit1, lit3)); + double activity1 = vsids.heapOfActiveAtoms.getActivity(lit1); + double activity2 = vsids.heapOfActiveAtoms.getActivity(lit2); + double activity3 = vsids.heapOfActiveAtoms.getActivity(lit3); + assertEquals(activity1, activity2, DOUBLE_COMPARISON_EPSILON); + assertEquals(activity2, activity3, DOUBLE_COMPARISON_EPSILON); + } + + @Test + public void testOneAtomHigherScore() { + int lit1 = Literals.atomToLiteral(1); + int lit2 = Literals.atomToLiteral(2); + int lit3 = Literals.atomToLiteral(3); + int lit1Neg = Literals.atomToLiteral(1, false); + int lit2Neg = Literals.atomToLiteral(2, false); + int lit3Neg = Literals.atomToLiteral(3, false); + HeuristicTestUtils.addNoGoods(atomStore, assignment, noGoodStore, vsids, new NoGood(lit1, lit2Neg), new NoGood(lit1Neg, lit2), + new NoGood(lit2, lit3Neg), new NoGood(lit2Neg, lit3)); + double activity1 = vsids.heapOfActiveAtoms.getActivity(lit1); + double activity2 = vsids.heapOfActiveAtoms.getActivity(lit2); + double activity3 = vsids.heapOfActiveAtoms.getActivity(lit3); + assertLessThan(activity1, activity2); + assertLessThan(activity3, activity2); + } + + private static void assertLessThan(double d1, double d2) { + assertTrue(d1 < d2 + DOUBLE_COMPARISON_EPSILON); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java new file mode 100644 index 000000000..680dc6131 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +import at.ac.tuwien.kr.alpha.common.Literals; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; + +public class HeuristicTestUtils { + + static void addNoGoods(AtomStore atomStore, WritableAssignment assignment, NoGoodStoreAlphaRoaming noGoodStore, VSIDS vsids, NoGood... noGoods) { + int numberOfAtoms = Arrays.stream(noGoods).flatMapToInt(NoGood::stream).map(Literals::atomOf).max().getAsInt(); + AtomStoreTest.fillAtomStore(atomStore, numberOfAtoms); + assignment.growForMaxAtomId(); + noGoodStore.growForMaxAtomId(numberOfAtoms); + vsids.growForMaxAtomId(numberOfAtoms); + Collection setOfNoGoods = new HashSet<>(); + int noGoodId = 1; + for (NoGood noGood : noGoods) { + setOfNoGoods.add(noGood); + noGoodStore.add(noGoodId++, noGood); + } + vsids.heapOfActiveAtoms.newNoGoods(setOfNoGoods); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java new file mode 100644 index 000000000..55c95ccb0 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java @@ -0,0 +1,51 @@ +/** + * 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.solver.NoGoodStore; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; + +/** + * A {@link ChoiceManager} for testing purposes that regards all atoms as active choice atoms. + * + */ +class PseudoChoiceManager extends ChoiceManager { + + public PseudoChoiceManager(WritableAssignment assignment, NoGoodStore store) { + super(assignment, store); + } + + @Override + public boolean isAtomChoice(int atom) { + return true; + } + + @Override + public boolean isActiveChoiceAtom(int atom) { + return true; + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java new file mode 100644 index 000000000..81ec7bbd1 --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.solver.*; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; +import static org.junit.Assert.assertEquals; + +/** + * Tests {@link ReplayHeuristic} + */ +public class ReplayHeuristicTest { + + private final boolean debugInternalChecks = true; + private ChoiceManager choiceManager; + + @Before + public void setUp() { + AtomStore atomStore = new AtomStoreImpl(); + WritableAssignment assignment = new TrailAssignment(atomStore); + NoGoodStore store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); + this.choiceManager = new PseudoChoiceManager(assignment, store); + } + + @Test + public void testBasicChoiceSequence() { + final int literal1 = atomToLiteral(2); + final int signedAtom1 = 2; + + final int literal2 = atomToLiteral(4, false); + final int signedAtom2 = -4; + + final int literal3 = atomToLiteral(7); + final int signedAtom3 = 7; + + final List chosenSignedAtoms = Arrays.asList(signedAtom1, signedAtom2, signedAtom3); + final ReplayHeuristic replayHeuristic = new ReplayHeuristic(chosenSignedAtoms, choiceManager); + assertEquals(literal1, replayHeuristic.chooseLiteral()); + assertEquals(literal2, replayHeuristic.chooseLiteral()); + assertEquals(literal3, replayHeuristic.chooseLiteral()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java new file mode 100644 index 000000000..e4f4f714f --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2018-2019 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.solver.heuristics; + +import at.ac.tuwien.kr.alpha.common.*; +import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Tests {@link VSIDS}. + * + */ +public class VSIDSTest { + + /** + * The tolerable epsilon for double comparisons + */ + private static final double DOUBLE_COMPARISON_EPSILON = 0.000001; + + private VSIDS vsids; + private AtomStore atomStore; + private WritableAssignment assignment; + private NoGoodStoreAlphaRoaming noGoodStore; + + private int lit1Neg = Literals.atomToLiteral(1, false); + private int lit2Neg = Literals.atomToLiteral(2, false); + private int lit3Neg = Literals.atomToLiteral(3, false); + private int lit4Neg = Literals.atomToLiteral(4, false); + private int lit1 = Literals.atomToLiteral(1); + private int lit2 = Literals.atomToLiteral(2); + private int lit3 = Literals.atomToLiteral(3); + private int lit4 = Literals.atomToLiteral(4); + + @Before + public void setUp() { + atomStore = new AtomStoreImpl(); + AtomStoreTest.fillAtomStore(atomStore, 4); + assignment = new TrailAssignment(atomStore); + assignment.growForMaxAtomId(); + noGoodStore = new NoGoodStoreAlphaRoaming(assignment); + this.vsids = new VSIDS( + assignment, + new PseudoChoiceManager(assignment, noGoodStore), + null); + } + + /** + * Tests the following artificial situation: + * Static nogoods: { {-1, -2}, {-3, -4}} + * Learnt nogood: { 2, 3 } + * Atoms resolved out during conflict analysis: { 1 } + */ + @Test + public void testConflict() { + HeuristicTestUtils.addNoGoods(atomStore, assignment, noGoodStore, vsids, new NoGood(lit1Neg, lit2Neg), new NoGood(lit3Neg, lit4Neg)); + vsids.chooseLiteral(); // to make VSIDS ingest buffered nogoods + assertEquals(vsids.getActivity(lit1), vsids.getActivity(lit2), DOUBLE_COMPARISON_EPSILON); + assertEquals(vsids.getActivity(lit2), vsids.getActivity(lit3), DOUBLE_COMPARISON_EPSILON); + assertEquals(vsids.getActivity(lit3), vsids.getActivity(lit4), DOUBLE_COMPARISON_EPSILON); + + NoGood learnedNoGood = new NoGood(lit2, lit3); + Collection resolutionAtoms = Arrays.asList(1); + ConflictAnalysisResult analysisResult = new ConflictAnalysisResult(learnedNoGood, 1, resolutionAtoms); + vsids.analyzedConflict(analysisResult); + assertEquals(vsids.getActivity(lit1), vsids.getActivity(lit2), DOUBLE_COMPARISON_EPSILON); + assertEquals(vsids.getActivity(lit2), vsids.getActivity(lit3), DOUBLE_COMPARISON_EPSILON); + assertLessThan(vsids.getActivity(lit4), vsids.getActivity(lit3)); + + assertEquals(0, vsids.getSignBalance(1)); + assertEquals(1, vsids.getSignBalance(2)); + assertEquals(1, vsids.getSignBalance(3)); + assertEquals(0, vsids.getSignBalance(4)); + } + + /** + * First, calls {@link #testConflict()}. + * Then, simulates a second conflict, learning { -1, 4 } with resolved atoms { 2 }. + * Due to decay, scores of atoms { 1, 4, 2 } must increase by the increased activity delta of {@link VSIDS#DEFAULT_DECAY_FACTOR}. + * + */ + @Test + public void testTwoConflicts() { + testConflict(); + + double activity1 = vsids.getActivity(lit1); + double activity2 = vsids.getActivity(lit2); + double activity3 = vsids.getActivity(lit3); + double activity4 = vsids.getActivity(lit4); + + NoGood learnedNoGood = new NoGood(lit1Neg, lit4); + Collection resolutionAtoms = Arrays.asList(2); + ConflictAnalysisResult analysisResult = new ConflictAnalysisResult(learnedNoGood, 1, resolutionAtoms); + vsids.analyzedConflict(analysisResult); + assertEquals(activity1 + VSIDS.DEFAULT_DECAY_FACTOR, vsids.getActivity(lit1), DOUBLE_COMPARISON_EPSILON); + assertEquals(activity2 + VSIDS.DEFAULT_DECAY_FACTOR, vsids.getActivity(lit2), DOUBLE_COMPARISON_EPSILON); + assertEquals(activity3, vsids.getActivity(lit3), DOUBLE_COMPARISON_EPSILON); + assertEquals(activity4 + VSIDS.DEFAULT_DECAY_FACTOR, vsids.getActivity(lit4), DOUBLE_COMPARISON_EPSILON); + + assertEquals(-1, vsids.getSignBalance(1)); + assertEquals(1, vsids.getSignBalance(2)); + assertEquals(1, vsids.getSignBalance(3)); + assertEquals(1, vsids.getSignBalance(4)); + } + + private static void assertLessThan(double d1, double d2) { + assertTrue(d1 < d2 + DOUBLE_COMPARISON_EPSILON); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java new file mode 100644 index 000000000..238894bbd --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java @@ -0,0 +1,91 @@ +package at.ac.tuwien.kr.alpha.solver.learning; + +import at.ac.tuwien.kr.alpha.common.AtomStore; +import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +import at.ac.tuwien.kr.alpha.common.NoGood; +import at.ac.tuwien.kr.alpha.solver.*; +import org.junit.Ignore; +import org.junit.Test; + +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; +import static org.junit.Assert.*; + +/** + * Copyright (c) 2016-2019, the Alpha Team. + */ +public class GroundConflictNoGoodLearnerTest { + + private final WritableAssignment assignment; + private final NoGoodStore store; + private AtomStore atomStore; + + public GroundConflictNoGoodLearnerTest() { + atomStore = new AtomStoreImpl(); + AtomStoreTest.fillAtomStore(atomStore, 20); + this.assignment = new TrailAssignment(atomStore); + this.assignment.growForMaxAtomId(); + this.store = new NoGoodStoreAlphaRoaming(assignment); + this.store.growForMaxAtomId(20); + } + + @Test + public void smallConflictNonTrivial1UIP() { + GroundConflictNoGoodLearner learner = new GroundConflictNoGoodLearner(assignment, atomStore); + + NoGood n1 = new NoGood(fromOldLiterals(2, -8, 1)); + NoGood n2 = new NoGood(fromOldLiterals(-1, -7)); + NoGood n3 = new NoGood(fromOldLiterals(-3, 1)); + NoGood n4 = new NoGood(fromOldLiterals(5, 3)); + NoGood n5 = new NoGood(fromOldLiterals(6, -5)); + NoGood n6 = new NoGood(fromOldLiterals(4, -2)); + NoGood n7 = new NoGood(fromOldLiterals(-6, -4)); + store.add(10, n1); + store.add(11, n2); + store.add(12, n3); + store.add(13, n4); + store.add(14, n5); + store.add(15, n6); + store.add(16, n7); + + assignment.choose(9, ThriceTruth.TRUE); + assignment.choose(8, ThriceTruth.FALSE); + assertNull(store.propagate()); + assertFalse(store.didPropagate()); + assignment.choose(7, ThriceTruth.FALSE); + ConflictCause conflictCause = store.propagate(); + assertTrue(store.didPropagate()); + + assertNotNull(conflictCause); + Antecedent violatedNoGood = conflictCause.getAntecedent(); + assertNotNull(violatedNoGood); + assertTrue(antecedentsEquals(violatedNoGood, n5.asAntecedent()) || antecedentsEquals(violatedNoGood, n7.asAntecedent())); + GroundConflictNoGoodLearner.ConflictAnalysisResult analysisResult = learner.analyzeConflictingNoGood(conflictCause.getAntecedent()); + NoGood learnedNoGood = analysisResult.learnedNoGood; + assertEquals(new NoGood(fromOldLiterals(1, -8)), learnedNoGood); + int backjumpingDecisionLevel = analysisResult.backjumpLevel; + assertEquals(backjumpingDecisionLevel, 2); + } + + @Ignore // TrailAssignment no longer propagates at lower decision level. + @Test + public void subCurrentDLPropagationWithChoiceCauseOfConflict() { + GroundConflictNoGoodLearner learner = new GroundConflictNoGoodLearner(assignment, atomStore); + NoGood n1 = new NoGood(fromOldLiterals(1, -2)); + NoGood n2 = new NoGood(fromOldLiterals(2, 3)); + store.add(10, n1); + assignment.choose(1, ThriceTruth.TRUE); + assignment.choose(3, ThriceTruth.TRUE); + store.propagate(); + assertEquals(ThriceTruth.MBT, assignment.get(2).getTruth()); + assertEquals(1, assignment.get(2).getDecisionLevel()); + ConflictCause conflictCause = store.add(11, n2); + assertNotNull(conflictCause); + assertNotNull(conflictCause.getAntecedent()); + GroundConflictNoGoodLearner.ConflictAnalysisResult conflictAnalysisResult = learner.analyzeConflictingNoGood(conflictCause.getAntecedent()); + assertNull(conflictAnalysisResult.learnedNoGood); + assertEquals(2, conflictAnalysisResult.backjumpLevel); + + } +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java new file mode 100644 index 000000000..134aae94e --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java @@ -0,0 +1,91 @@ +package at.ac.tuwien.kr.alpha.test.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import at.ac.tuwien.kr.alpha.core.depgraph.DependencyGraph; +import at.ac.tuwien.kr.alpha.core.depgraph.Edge; +import at.ac.tuwien.kr.alpha.core.depgraph.Node; + +/** + * + * Copyright (c) 2019-2020, the Alpha Team. + */ +public final class DependencyGraphUtils { + + private DependencyGraphUtils() { + + } + + public static boolean isReachableFrom(Node dest, Node src, DependencyGraph dg) { + return DependencyGraphUtils.isReachableFrom(dest, src, dg, new HashSet<>()); + } + + private static boolean isReachableFrom(Node dest, Node src, DependencyGraph dg, Set discovered) { + List outgoingEdges; + if (src.equals(dest)) { + return true; + } + if ((outgoingEdges = dg.getAdjancencyMap().get(src)) == null) { + return false; + } + discovered.add(src); + // Checking all edges first before descending deeper. + for (Edge edge : outgoingEdges) { + if (edge.getTarget().equals(dest)) { + return true; + } + } + for (Edge tmp : outgoingEdges) { + if (discovered.contains(tmp.getTarget())) { + // Cycle found, do not descend deeper. + continue; + } + if (DependencyGraphUtils.isReachableFrom(dest, tmp.getTarget(), dg, discovered)) { + return true; + } + } + return false; + } + + /** + * Checks whether the given nodes are strongly connected within the given dependency graph. Strongly connected + * means every node in the given list is reachable from every other node in the list and vice versa. + * + * @param connectedNodes the nodes to check. + * @param dg the dependency graph in which to check. + * @return true if the given nodes are strongly connected, false otherwise. + */ + public static boolean areStronglyConnected(List connectedNodes, DependencyGraph dg) { + for (Node n1 : connectedNodes) { + for (Node n2 : connectedNodes) { + if (!(DependencyGraphUtils.isReachableFrom(n2, n1, dg) && DependencyGraphUtils.isReachableFrom(n1, n2, dg))) { + return false; + } + } + } + return true; + } + + public static boolean isStronglyConnectedComponent(List componentNodes, DependencyGraph dg) { + if (!DependencyGraphUtils.areStronglyConnected(componentNodes, dg)) { + return false; + } + // Check if the given set is maximal. + List lst = new ArrayList<>(componentNodes); + for (Node n : dg.getAdjancencyMap().keySet()) { + if (lst.contains(n)) { + continue; + } + lst.add(n); + if (DependencyGraphUtils.areStronglyConnected(lst, dg)) { + // Not a strongly connected component if there is a bigger set which is strongly connected. + return false; + } + } + return true; + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java new file mode 100644 index 000000000..bc95c1b8d --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2016-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.test.util; + +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.Literal; +import at.ac.tuwien.kr.alpha.common.rule.InternalRule; +import at.ac.tuwien.kr.alpha.core.grounder.Substitution; + +public class SubstitutionTestUtil { + + public static String groundAndPrintRule(InternalRule rule, Substitution substitution) { + StringBuilder ret = new StringBuilder(); + if (!rule.isConstraint()) { + Atom groundHead = rule.getHeadAtom().substitute(substitution); + ret.append(groundHead.toString()); + } + ret.append(" :- "); + boolean isFirst = true; + for (Literal lit : rule.getBody()) { + ret.append(groundLiteralToString(lit, substitution, isFirst)); + isFirst = false; + } + ret.append("."); + return ret.toString(); + } + + public static String groundLiteralToString(Literal literal, Substitution substitution, boolean isFirst) { + Literal groundLiteral = literal.substitute(substitution); + return (isFirst ? "" : ", ") + groundLiteral.toString(); + } +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java new file mode 100644 index 000000000..aa023207c --- /dev/null +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java @@ -0,0 +1,99 @@ +package at.ac.tuwien.kr.alpha.test.util; + +import at.ac.tuwien.kr.alpha.common.AnswerSet; +import at.ac.tuwien.kr.alpha.common.Predicate; +import at.ac.tuwien.kr.alpha.common.atoms.Atom; +import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.common.program.AbstractProgram; +import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.common.terms.Term; +import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; + +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.StringJoiner; + +import static java.util.Collections.emptySet; + +public class TestUtils { + + 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 { + Assert.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) { + TestUtils.assertAnswerSetsEqual(emptySet(), actual); + return; + } + StringJoiner joiner = new StringJoiner("} {", "{", "}"); + Arrays.stream(expected).forEach(joiner::add); + TestUtils.assertAnswerSetsEqual(AnswerSetsParser.parse(joiner.toString()), actual); + } + + public static void assertAnswerSetsEqual(String expectedAnswerSet, Set actual) { + TestUtils.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); + } + } + TestUtils.assertAnswerSetsEqual(expectedAnswerSets, actual); + } + + public static void assertFactsContainedInProgram(AbstractProgram prog, Atom... facts) { + for (Atom fact : facts) { + Assert.assertTrue(prog.getFacts().contains(fact)); + } + } + + public static Atom basicAtomWithStringTerms(String predicate, String... terms) { + Predicate pred = Predicate.getInstance(predicate, terms.length); + List trms = new ArrayList<>(); + for (String str : terms) { + trms.add(ConstantTerm.getInstance(str)); + } + return new BasicAtom(pred, trms); + } + + public static Atom basicAtomWithSymbolicTerms(String predicate, String... constantSymbols) { + Predicate pred = Predicate.getInstance(predicate, constantSymbols.length); + List trms = new ArrayList<>(); + for (String str : constantSymbols) { + trms.add(ConstantTerm.getSymbolicInstance(str)); + } + return new BasicAtom(pred, trms); + } + +} diff --git a/alpha-core/src/test/resources/HanoiTower_Alpha.asp b/alpha-core/src/test/resources/HanoiTower_Alpha.asp new file mode 100644 index 000000000..922962744 --- /dev/null +++ b/alpha-core/src/test/resources/HanoiTower_Alpha.asp @@ -0,0 +1,98 @@ +% HanoiTower +% Source: ASP Competition 2013 Official (disjunction shifted by ASP Shifter) +% ADAPTIONS FOR ALPHA: +% - replaced "TP1 = T + 1" by "succ(T,TP1)" because arithmetics are not supported +% - replaced "TM1 = T - 1" by "succ(TM1,T)" for the same reason + +peg(1). +peg(2). +peg(3). +peg(4). + +% Read in data +on(0, N1, N) :- on0(N, N1). +onG(K, N1, N) :- ongoal(N, N1), steps(K). + +% Specify valid arrangements of disks +% Basic condition. Smaller disks are on larger ones +:- time(T), on(T, N1, N), N1 >= N. + +% Specify a valid move (only for T + + + + %5relative %.-1level %20.20logger %msg %n + + + + junit.log + false + + + %-4r %-5level %logger{35}: %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/alpha-core/src/test/resources/partial-eval/pup_topological_order.asp b/alpha-core/src/test/resources/partial-eval/pup_topological_order.asp new file mode 100644 index 000000000..b8aacc3fd --- /dev/null +++ b/alpha-core/src/test/resources/partial-eval/pup_topological_order.asp @@ -0,0 +1,34 @@ +maxPU(2). + +comUnit(1). comUnit(2). + +% relation between zones and door sensors +zone2sensor(1,1). +zone2sensor(1,2). +zone2sensor(2,1). +zone2sensor(2,3). +zone2sensor(2,4). +zone2sensor(3,3). + +% helpers for QUICKPUP heuristics, inspired by quickpup.ascass by Erich Teppan: +sensor(S):-zone2sensor(Z,S). +zone(Z):-zone2sensor(Z,S). + +numZones(N) :- zone(N), not zone(N+1). +numSensors(N) :- sensor(N), not sensor(N+1). +numElems(M):-numZones(E),numSensors(F),M=E+F. + +numUnits(N) :- comUnit(N), not comUnit(N+1). + +%-------topological order--- +startZone(1). +zoneDist(Z0,0):-startZone(Z0). + +sensorDist(S,Dz+1):-zoneDist(Z,Dz),zone2sensor(Z,S),numElems(M),Dz actual = alpha.solve(program).collect(Collectors.toSet()); + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); + assertEquals(expected, actual); + } + + @Test + public void addsFacts() throws Exception { + Alpha system = new AlphaImpl(); + Thingy a = new Thingy(); + Thingy b = new Thingy(); + List things = asList(a, b); + InputProgram program = InputProgram.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); + } + + @Test(expected = IllegalArgumentException.class) + public void withExternalTypeConflict() throws Exception { + Alpha system = new AlphaImpl(); + 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 = new AlphaImpl(); + 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); + + Set actual = system.solve(program).collect(Collectors.toSet()); + Set expected = AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); + assertEquals(expected, actual); + } + + @Test + public void filterOutput() throws Exception { + Alpha system = new AlphaImpl(); + InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); + inputCfg.addPredicateMethod("getLargeGraphEdges", + Externals.processPredicate(() -> new HashSet<>(asList(asList(CoreConstantTerm.getInstance(1), CoreConstantTerm.getInstance(2)), + asList(CoreConstantTerm.getInstance(2), CoreConstantTerm.getInstance(1)), asList(CoreConstantTerm.getInstance(13), CoreConstantTerm.getInstance(1)))))); + ASPCore2Program 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); + } + + @Test + 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(CoreConstantTerm.getInstance(1))))); + ASPCore2Program prog = system.readProgram(cfg); + + Set expected = AnswerSetsParser.parse("{ node(1), a }"); + Set actual = system.solve(prog).collect(Collectors.toSet()); + assertEquals(expected, actual); + } + + @at.ac.tuwien.kr.alpha.api.externals.Predicate + public static Set>> bestNode() { + return singleton(singletonList(CoreConstantTerm.getInstance(1))); + } + + @Test + 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); + + Set expected = AnswerSetsParser.parse("{ node(1), a }"); + Set actual = system.solve(prog).collect(Collectors.toSet()); + assertEquals(expected, actual); + } + + @Test(expected = IllegalArgumentException.class) + public void smallGraphWithWrongType() throws Exception { + Alpha system = new AlphaImpl(); + 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); + + system.solve(prog).collect(Collectors.toSet()); + } + + public static Set>> neighbors(int node) { + if (node == 1) { + return new HashSet<>(asList(singletonList(CoreConstantTerm.getInstance(2)), singletonList(CoreConstantTerm.getInstance(3)))); + } + return emptySet(); + } + + public static Set>> coolNode(int node) { + if (node == 1) { + return singleton(emptyList()); + } + return emptySet(); + } + + @Test + @Ignore("Test program is not safe (external lacking output variables). This should throw some exception.") + public void smallGraphNoNeighbors() throws Exception { + Alpha system = new AlphaImpl(); + 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); + + Set expected = AnswerSetsParser.parse("{ noNeighbors(2) }"); + Set actual = system.solve(prog).collect(Collectors.toSet()); + assertEquals(expected, actual); + } + + @Test + public void smallGraphCoolNode() throws Exception { + Alpha system = new AlphaImpl(); + 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); + + Set actual = system.solve(prog).collect(Collectors.toSet()); + Set expected = AnswerSetsParser.parse("{ in(1), node(1), node(2) }"); + assertEquals(expected, actual); + } + + @Test + public void smallGraphSingleNeighbor() throws Exception { + Alpha system = new AlphaImpl(); + 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); + + Set expected = AnswerSetsParser.parse("{ in(1,2), in(1,3), node(1), node(2), node(3) }"); + Set actual = system.solve(prog).collect(Collectors.toSet()); + assertEquals(expected, actual); + } + + @Test + @Ignore("Test program is not safe (external lacking output variables). This should throw some exception.") + public void smallGraphSingleNeighborNoTerm() throws Exception { + Alpha system = new AlphaImpl(); + 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); + + Set expected = AnswerSetsParser.parse("{ success }"); + Set actual = system.solve(prog).collect(Collectors.toSet()); + assertEquals(expected, actual); + } + + private static class Thingy implements Comparable { + @Override + public String toString() { + return "thingy"; + } + + @Override + public int compareTo(Thingy o) { + return 0; + } + } + + private static class SubThingy extends Thingy { + } + + @Test + public void withExternalSubtype() throws Exception { + SubThingy thingy = new SubThingy(); + + BasicRule rule = new BasicRule( + new NormalHeadImpl(new BasicAtom(CorePredicate.getInstance("p", 1), CoreConstantTerm.getInstance("x"))), + singletonList(new ExternalLiteral(new ExternalAtom(CorePredicate.getInstance("thinger", 1), + new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(CoreConstantTerm.getInstance(thingy)), + emptyList()), true))); + + Alpha system = new AlphaImpl(); + + InputProgram prog = new InputProgram(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())); + assertEquals(expected, actual); + } + + @Test + public void withExternalViaAnnotation() throws Exception { + Alpha system = new AlphaImpl(); + InputConfig cfg = InputConfig.forString("a :- &isOne[1]."); + cfg.addPredicateMethods(Externals.scan(this.getClass())); + ASPCore2Program prog = system.readProgram(cfg); + + Set actual = system.solve(prog).collect(Collectors.toSet()); + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); + assertEquals(expected, actual); + } + + /** + * Externals may only be scanned once per implementation. + * If at the time of a scan, the name of an external is already registered, + * an exception is thrown. + */ + @Test(expected = IllegalArgumentException.class) + public void errorDuplicateExternal() throws Exception { + 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 = new AlphaImpl(); + InputConfig cfg = InputConfig.forString("a :- &isTwo[2]."); + cfg.addPredicateMethod("isTwo", Externals.processPredicate((Integer t) -> t == 2)); + ASPCore2Program prog = system.readProgram(cfg); + + Set actual = system.solve(prog).collect(Collectors.toSet()); + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); + assertEquals(expected, actual); + } + + @Test + @Ignore("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(); + 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); + + int before = invocations; + Set actual = system.solve(prog).collect(Collectors.toSet()); + int after = invocations; + + assertEquals(2, after - before); + + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); + assertEquals(expected, actual); + } + + @Test + @Ignore("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(); + 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); + + int before = invocations; + Set actual = system.solve(prog).collect(Collectors.toSet()); + int after = invocations; + + assertEquals(2, after - before); + + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); + assertEquals(expected, actual); + } + + @Test + @Ignore("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(); + 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); + + int before = invocations; + Set actual = system.solve(prog).collect(Collectors.toSet()); + int after = invocations; + + assertEquals(1, after - before); + + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); + assertEquals(expected, actual); + } + + @Test + @SuppressWarnings("unchecked") + public void programWithExternalStringStuff() throws IOException { + Alpha alpha = new AlphaImpl(); + ASPCore2Program 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) { + for (Atom atom : as.getPredicateInstances(CorePredicate.getInstance("resultstring", 1))) { + String resultstring = ((ConstantTerm) atom.getTerms().get(0)).getObject(); + Assert.assertEquals(6, resultstring.length()); + Assert.assertTrue(resultstring.contains("foo")); + } + } + } + + @Test + @SuppressWarnings("unchecked") + public void withNegatedExternal() throws IOException { + Alpha alpha = new AlphaImpl(); + ASPCore2Program prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); + Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); + Assert.assertEquals(31, answerSets.size()); + // Verify every result string has length 6 and contains "foo" + for (AnswerSet as : answerSets) { + for (Atom atom : as.getPredicateInstances(CorePredicate.getInstance("resultstring", 1))) { + String resultstring = ((ConstantTerm) atom.getTerms().get(0)).getObject(); + LOGGER.debug("ResultString is {}", resultstring); + Assert.assertEquals(6, resultstring.length()); + Assert.assertTrue(resultstring.contains("foo")); + } + } + } + + @Test + public void basicUsage() throws Exception { + Alpha system = new AlphaImpl(); + 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); + } + + @Test + public void basicUsageWithString() throws Exception { + Alpha system = new AlphaImpl(); + 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); + } + + /** + * Verifies that filters are handled correctly (regression test case introduced when fixing issue #189). + */ + @Test + public void filterTest() { + String progstr = "a. b. c. d :- c. e(a, b) :- d."; + Alpha system = new AlphaImpl(); + ASPCore2Program prog = system.readProgramString(progstr, null); + Set actual = system.solve(prog, (p) -> p.equals(CorePredicate.getInstance("a", 0)) || p.equals(CorePredicate.getInstance("e", 2))) + .collect(Collectors.toSet()); + Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").predicate("e").symbolicInstance("a", "b").build())); + assertEquals(expected, actual); + } + + /** + * Verifies that no stratified evaluation is performed up-front when disabled in config. + */ + @Test + public void disableStratifiedEvalTest() { + String progstr = "p(a). q(X) :- p(X)."; + SystemConfig cfg = new SystemConfig(); + cfg.setEvaluateStratifiedPart(false); + Alpha system = new AlphaImpl(cfg); + ASPCore2Program input = system.readProgramString(progstr); + Program> normal = system.normalizeProgram(input); + CompiledProgram preprocessed = system.performProgramPreprocessing(InternalProgram.fromNormalProgram(normal)); + Assert.assertFalse("Preprocessed program contains fact derived from stratifiable rule, but should not!", + preprocessed.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "a"))); + } + + /** + * Verifies that stratified evaluation is performed up-front if not otherwise configured. + */ + @Test + public void enableStratifiedEvalTest() { + String progstr = "p(a). q(X) :- p(X)."; + SystemConfig cfg = new SystemConfig(); + Alpha system = new AlphaImpl(cfg); + ASPCore2Program input = system.readProgramString(progstr); + Program> normal = system.normalizeProgram(input); + CompiledProgram preprocessed = system.performProgramPreprocessing(InternalProgram.fromNormalProgram(normal)); + Assert.assertTrue("Preprocessed program does not contain fact derived from stratifiable rule, but should!", + preprocessed.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "a"))); + } + + /** + * Runs a test that formerly caused some sort of exception. + */ + @Test + public void problematicRun_3col_1119654162577372() throws IOException { + /* + * NOTE: This was constructed from the following commandline invocation: -DebugEnableInternalChecks -q -g naive -s + * default -e 1119654162577372 -n 200 -i + * 3col-20-38.txt + */ + problematicRun("3col-20-38.txt", 1119654162577372L, 200); + } + + /** + * Runs a test that formerly caused some sort of exception. + */ + @Test + public void problematicRun_3col_1119718541727902() throws IOException { + /* + * NOTE: This was constructed from the following commandline invocation: + * -DebugEnableInternalChecks -q -g naive -s default -e 1119718541727902 -n 200 -i + * 3col-20-38.txt + */ + problematicRun("3col-20-38.txt", 1119718541727902L, 200); + } + + /** + * Runs a test that formerly caused some sort of exception. + */ + @Test + public void problematicRun_vehicle_97598271567626() throws IOException { + /* + * NOTE: This was constructed from the following commandline invocation: + * -DebugEnableInternalChecks -q -g naive -s default -e 97598271567626 -n 2 -i vehicle_normal_small.asp + */ + problematicRun("vehicle_normal_small.asp", 1119718541727902L, 2); + } + + /** + * Runs a test that formerly caused some sort of exception. + */ + @Test + public void problematicRun_3col_1119718541727902_sorted_400() throws IOException { + /* + * NOTE: This was constructed from the following commandline invocation: + * -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 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); + + assertFalse(system.solve(prog).sorted().limit(400).collect(Collectors.toList()).isEmpty()); + } + + 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); + InputConfig inputCfg = new InputConfig(); + List files = new ArrayList<>(); + files.add(base.resolve(program).toString()); + inputCfg.setFiles(files); + ASPCore2Program prog = system.readProgram(inputCfg); + assertFalse(system.solve(prog).limit(limit).collect(Collectors.toList()).isEmpty()); + } +} diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java new file mode 100644 index 000000000..623809068 --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java @@ -0,0 +1,195 @@ +package at.ac.tuwien.kr.alpha.impl; + +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 org.junit.Assert; +import org.junit.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.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; +import at.ac.tuwien.kr.alpha.core.externals.Externals; + +public class FixedInterpretationLiteralsTest { + + @at.ac.tuwien.kr.alpha.api.externals.Predicate + public static boolean isOne(int value) { + return value == 1; + } + + /** + * Dummy method to test external atoms with more than one output term list. + * Dummy input param which is not used exists solely to avoid producing an edge + * case where there is output, but no input + */ + @at.ac.tuwien.kr.alpha.api.externals.Predicate + public static Set>> connection(String dummy) { + Set>> retVal = new HashSet<>(); + List> l1 = new ArrayList<>(); + List> l2 = new ArrayList<>(); + List> l3 = new ArrayList<>(); + l1.add(CoreConstantTerm.getInstance("Klagenfurt")); + l1.add(CoreConstantTerm.getInstance("Villach")); + l2.add(CoreConstantTerm.getInstance("Klagenfurt")); + l2.add(CoreConstantTerm.getInstance("Graz")); + l3.add(CoreConstantTerm.getInstance("Villach")); + l3.add(CoreConstantTerm.getInstance("Salzburg")); + retVal.add(l1); + retVal.add(l2); + retVal.add(l3); + return retVal; + } + + private static final String TEST_PROG = "positive_numeric_comparison :- 2 < 3." + + "negative_numeric_comparison :- not 3 < 2." + + "positive_unary_external :- &isOne[1]." + + "negative_unary_external :- not &isOne[2]." + + "positive_external_with_output :- " + + "&stdlib_datetime_parse[\"01.01.2121 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S), Y = 2121, MO = 1, D = 1, H = 21, MI = 11, S = 12." + + "positive_external_with_output_dontfire :- " + + "&stdlib_datetime_parse[\"01.01.2121 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S), Y = 2345, MO = 1, D = 1, H = 21, MI = 11, S = 12." + + "negative_external_with_output :- Y = 2121, MO = 1, D = 1, H = 21, MI = 11, S = 12, " + + "not &stdlib_datetime_parse[\"22.02.2222 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S)." + + "negative_external_with_output_dontfire :- Y = 2222, MO = 2, D = 22, H = 21, MI = 11, S = 12," + + "not &stdlib_datetime_parse[\"22.02.2222 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S)." + + "negative_external_multioutput :- START = \"Graz\", END = \"Salzburg\", not &connection[train_network](START, END)." + + "negative_external_multioutput_dontfire :- START = \"Klagenfurt\", END = \"Villach\", not &connection[train_network](START, END)." + + "positive_external_multioutput :- START = \"Klagenfurt\", END = \"Villach\", &connection[train_network](START, END)." + + "positive_external_multioutput_dontfire :- START = \"Graz\", END = \"Salzburg\", &connection[train_network](START, END)." + + "positive_external_binding_output(START, END) :- &connection[train_network](START, END)."; + + private Alpha alpha; + private Map externals; + + public FixedInterpretationLiteralsTest() { + this.alpha = new AlphaImpl(); + this.externals = new HashMap<>(); + this.externals.putAll(Externals.scan(AspStandardLibrary.class)); + this.externals.putAll(Externals.scan(FixedInterpretationLiteralsTest.class)); + } + + @Test + public void positiveNumericComparison() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("positive_numeric_comparison", 0))); + } + + @Test + public void negativeNumericComparison() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("negative_numeric_comparison", 0))); + } + + @Test + public void positiveUnaryExternal() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("positive_unary_external", 0))); + } + + @Test + public void negativeUnaryExternal() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("negative_unary_external", 0))); + } + + @Test + public void positiveExternalWithOutput() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("positive_external_with_output", 0))); + } + + @Test + public void positiveExternalWithOutputDontfire() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertFalse(answerSet.getPredicates().contains(CorePredicate.getInstance("positive_external_with_output_dontfire", 0))); + } + + @Test + public void negativeExternalWithOutput() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("negative_external_with_output", 0))); + } + + @Test + public void negativeExternalWithOutputDontfire() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertFalse(answerSet.getPredicates().contains(CorePredicate.getInstance("negative_external_with_output_dontfire", 0))); + } + + @Test + public void negativeExternalMultioutput() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("negative_external_multioutput", 0))); + } + + @Test + public void negativeExternalMultioutputDontfire() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertFalse(answerSet.getPredicates().contains(CorePredicate.getInstance("negative_external_multioutput_dontfire", 0))); + } + + @Test + public void positiveExternalMultioutput() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertTrue(answerSet.getPredicates().contains(CorePredicate.getInstance("positive_external_multioutput", 0))); + } + + @Test + public void positiveExternalMultioutputDontfire() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Assert.assertFalse(answerSet.getPredicates().contains(CorePredicate.getInstance("positive_external_multioutput_dontfire", 0))); + } + + @Test + public void positiveExternalBindingOutput() { + Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); + Assert.assertTrue(answer.isPresent()); + AnswerSet answerSet = answer.get(); + Predicate pred = CorePredicate.getInstance("positive_external_binding_output", 2); + Assert.assertTrue(answerSet.getPredicates().contains(pred)); + Set instances = answerSet.getPredicateInstances(pred); + Assert.assertEquals(3, instances.size()); + Assert.assertTrue(instances.contains(new BasicAtom(pred, CoreConstantTerm.getInstance("Klagenfurt"), CoreConstantTerm.getInstance("Villach")))); + Assert.assertTrue(instances.contains(new BasicAtom(pred, CoreConstantTerm.getInstance("Klagenfurt"), CoreConstantTerm.getInstance("Graz")))); + Assert.assertTrue(instances.contains(new BasicAtom(pred, CoreConstantTerm.getInstance("Villach"), CoreConstantTerm.getInstance("Salzburg")))); + } + +} diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java new file mode 100644 index 000000000..7b38eb746 --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java @@ -0,0 +1,100 @@ +package at.ac.tuwien.kr.alpha.test.util; + +import static java.util.Collections.emptySet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.StringJoiner; + +import org.junit.Assert; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.programs.AbstractProgram; +import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; + +public class TestUtils { + + 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 { + Assert.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) { + TestUtils.assertAnswerSetsEqual(emptySet(), actual); + return; + } + StringJoiner joiner = new StringJoiner("} {", "{", "}"); + Arrays.stream(expected).forEach(joiner::add); + TestUtils.assertAnswerSetsEqual(AnswerSetsParser.parse(joiner.toString()), actual); + } + + public static void assertAnswerSetsEqual(String expectedAnswerSet, Set actual) { + TestUtils.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); + } + } + TestUtils.assertAnswerSetsEqual(expectedAnswerSets, actual); + } + + public static void assertFactsContainedInProgram(AbstractProgram prog, Atom... facts) { + for (Atom fact : facts) { + Assert.assertTrue(prog.getFacts().contains(fact)); + } + } + + public static Atom basicAtomWithStringTerms(String predicate, String... terms) { + Predicate pred = CorePredicate.getInstance(predicate, terms.length); + List trms = new ArrayList<>(); + for (String str : terms) { + trms.add(CoreConstantTerm.getInstance(str)); + } + return new BasicAtom(pred, trms); + } + + public static Atom basicAtomWithSymbolicTerms(String predicate, String... constantSymbols) { + Predicate pred = CorePredicate.getInstance(predicate, constantSymbols.length); + List trms = new ArrayList<>(); + for (String str : constantSymbols) { + trms.add(CoreConstantTerm.getSymbolicInstance(str)); + } + return new BasicAtom(pred, trms); + } + +} diff --git a/build.gradle b/build.gradle index 64084a8f3..2a71f3f78 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ plugins { id 'com.github.kt3k.coveralls' version '2.8.1' } +// TODO project property for dependency versions wrapper { gradleVersion = '6.7' distributionType = 'ALL' From 61b1bb3a009f50679d212915d786750b83dd2c15 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 29 Jan 2021 22:46:56 +0100 Subject: [PATCH 019/111] WIP: fix tests --- .../kr/alpha/AnswerSetToXlsxWriterTest.java | 64 -- .../ac/tuwien/kr/alpha/AnswerSetsParser.java | 44 - .../java/at/ac/tuwien/kr/alpha/MainTest.java | 87 -- .../java/at/ac/tuwien/kr/alpha/TestUtil.java | 72 -- .../java/at/ac/tuwien/kr/alpha/UtilTest.java | 20 - .../ac/tuwien/kr/alpha/antlr/ParserTest.java | 225 ----- .../at/ac/tuwien/kr/alpha/api/AlphaTest.java | 516 ----------- .../stdlib/AspStandardLibraryTest.java | 177 ---- .../mapper/AnswerSetToWorkbookMapperTest.java | 98 --- .../alpha/common/AnswerSetFormatterTest.java | 16 - .../tuwien/kr/alpha/common/AtomStoreTest.java | 17 - .../kr/alpha/common/BasicAnswerSetTest.java | 79 -- .../ac/tuwien/kr/alpha/common/NoGoodTest.java | 109 --- .../tuwien/kr/alpha/common/ProgramTest.java | 49 -- .../ac/tuwien/kr/alpha/common/RuleTest.java | 51 -- .../ac/tuwien/kr/alpha/common/TermTest.java | 91 -- .../kr/alpha/common/atoms/AtomsTest.java | 138 --- ...LiteralBindingNonBindingVariablesTest.java | 203 ----- .../common/depgraph/DependencyGraphTest.java | 265 ------ .../depgraph/StratificationAlgorithmTest.java | 239 ------ .../FixedInterpretationLiteralsTest.java | 191 ----- .../graphio/ComponentGraphWriterTest.java | 65 -- .../graphio/DependencyGraphWriterTest.java | 61 -- .../kr/alpha/common/terms/TermsTest.java | 30 - .../kr/alpha/common/terms/TestMinusTerm.java | 55 -- .../alpha/config/CommandLineParserTest.java | 173 ---- .../kr/alpha/grounder/ChoiceGrounder.java | 210 ----- .../kr/alpha/grounder/DummyGrounder.java | 189 ---- .../grounder/IndexedInstanceStorageTest.java | 94 -- .../kr/alpha/grounder/NaiveGrounderTest.java | 447 ---------- .../alpha/grounder/NoGoodGeneratorTest.java | 84 -- .../grounder/ProgramTransformationTest.java | 72 -- .../grounder/RuleGroundingOrderTest.java | 161 ---- .../kr/alpha/grounder/RuleToStringTest.java | 102 --- .../kr/alpha/grounder/SubstitutionTest.java | 169 ---- .../tuwien/kr/alpha/grounder/UnifierTest.java | 81 -- .../GrounderHeuristicConfigurationTest.java | 95 -- .../LiteralInstantiationStrategyTest.java | 368 -------- .../LiteralInstantiatorTest.java | 152 ---- .../structure/AnalyzeUnjustifiedTest.java | 218 ----- .../StratifiedEvaluationRegressionTest.java | 260 ------ .../StratifiedEvaluationTest.java | 276 ------ .../kr/alpha/solver/AbstractSolverTests.java | 266 ------ ...AggregatesCardinalityCountingGridTest.java | 38 - ...gregatesCardinalitySortingCircuitTest.java | 38 - .../kr/alpha/solver/AggregatesTest.java | 181 ---- .../kr/alpha/solver/AntecedentTest.java | 32 - .../kr/alpha/solver/AtomCounterTests.java | 134 --- .../kr/alpha/solver/ChoiceManagerTests.java | 84 -- .../alpha/solver/HanoiTowerDetailedTest.java | 44 - .../kr/alpha/solver/HanoiTowerTest.java | 134 --- .../solver/HeadBodyTransformationTests.java | 319 ------- .../solver/LearnedNoGoodDeletionTest.java | 149 ---- .../kr/alpha/solver/NaiveNoGoodStoreTest.java | 588 ------------- .../solver/NoGoodStoreAlphaRoamingTest.java | 615 ------------- .../kr/alpha/solver/OmigaBenchmarksTest.java | 100 --- .../solver/PartSubpartConfigurationTest.java | 116 --- .../kr/alpha/solver/PigeonHoleTest.java | 180 ---- .../ac/tuwien/kr/alpha/solver/RacksTest.java | 58 -- .../alpha/solver/SolverStatisticsTests.java | 102 --- .../tuwien/kr/alpha/solver/SolverTests.java | 808 ------------------ .../alpha/solver/TestableChoiceManager.java | 50 -- .../solver/ThreeColouringRandomGraphTest.java | 149 ---- .../solver/ThreeColouringTestWithRandom.java | 229 ----- .../alpha/solver/ThreeColouringWheelTest.java | 152 ---- .../kr/alpha/solver/TrailAssignmentTest.java | 260 ------ .../AlphaHeuristicTestAssumptions.java | 170 ---- .../alpha/solver/heuristics/BerkMinTest.java | 193 ----- .../BranchingHeuristicFactoryTest.java | 72 -- .../heuristics/HeapOfActiveAtomsTest.java | 99 --- .../solver/heuristics/HeuristicTestUtils.java | 56 -- .../heuristics/PseudoChoiceManager.java | 51 -- .../heuristics/ReplayHeuristicTest.java | 74 -- .../kr/alpha/solver/heuristics/VSIDSTest.java | 141 --- .../GroundConflictNoGoodLearnerTest.java | 91 -- .../alpha/test/util/DependencyGraphUtils.java | 91 -- .../alpha/test/util/SubstitutionTestUtil.java | 58 -- .../tuwien/kr/alpha/test/util/TestUtils.java | 98 --- src/test/resources/HanoiTower_Alpha.asp | 98 --- src/test/resources/HanoiTower_instances/1.asp | 85 -- src/test/resources/HanoiTower_instances/2.asp | 91 -- src/test/resources/HanoiTower_instances/3.asp | 89 -- src/test/resources/HanoiTower_instances/4.asp | 95 -- .../HanoiTower_instances/instances.txt | 4 - .../resources/HanoiTower_instances/simple.asp | 24 - .../PreviouslyProblematic/3col-20-38.txt | 67 -- .../vehicle_normal_small.asp | 86 -- src/test/resources/escaped_quotes.asp | 1 - src/test/resources/logback.xml | 24 - .../partial-eval/pup_topological_order.asp | 34 - .../recursive_w_negated_condition.asp | 34 - src/test/resources/show.asp | 1 - .../transform-test/choice-to-normal.1.in | 1 - .../transform-test/choice-to-normal.1.out | 6 - .../resources/transform-test/interval.1.in | 6 - .../resources/transform-test/interval.1.out | 4 - 96 files changed, 12883 deletions(-) delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/AnswerSetsParser.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/MainTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/UtilTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/api/AlphaTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapperTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatterTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraphTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithmTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/FixedInterpretationLiteralsTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriterTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriterTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/config/CommandLineParserTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/ChoiceGrounder.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/DummyGrounder.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorageTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounderTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGeneratorTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/ProgramTransformationTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrderTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleToStringTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/SubstitutionTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/UnifierTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java delete mode 100644 src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java delete mode 100644 src/test/resources/HanoiTower_Alpha.asp delete mode 100644 src/test/resources/HanoiTower_instances/1.asp delete mode 100644 src/test/resources/HanoiTower_instances/2.asp delete mode 100644 src/test/resources/HanoiTower_instances/3.asp delete mode 100644 src/test/resources/HanoiTower_instances/4.asp delete mode 100644 src/test/resources/HanoiTower_instances/instances.txt delete mode 100644 src/test/resources/HanoiTower_instances/simple.asp delete mode 100644 src/test/resources/PreviouslyProblematic/3col-20-38.txt delete mode 100644 src/test/resources/PreviouslyProblematic/vehicle_normal_small.asp delete mode 100644 src/test/resources/escaped_quotes.asp delete mode 100644 src/test/resources/logback.xml delete mode 100644 src/test/resources/partial-eval/pup_topological_order.asp delete mode 100644 src/test/resources/partial-eval/recursive_w_negated_condition.asp delete mode 100644 src/test/resources/show.asp delete mode 100644 src/test/resources/transform-test/choice-to-normal.1.in delete mode 100644 src/test/resources/transform-test/choice-to-normal.1.out delete mode 100644 src/test/resources/transform-test/interval.1.in delete mode 100644 src/test/resources/transform-test/interval.1.out diff --git a/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java b/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java deleted file mode 100644 index 82d1d0b1f..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetToXlsxWriterTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package at.ac.tuwien.kr.alpha; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.junit.Assert; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToWorkbookMapperTest; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; - -public class AnswerSetToXlsxWriterTest { - - @Test - public void writeAnswerSetFilesTest() throws IOException { - AnswerSet as = new AnswerSetBuilder().predicate("bla").instance("blubb", "blubb").instance("foo", "bar").predicate("foo").instance("bar") - .instance("baz").predicate("complex").instance(Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)).build(); - Path tmpDir = Files.createTempDirectory("alpha-test-xlsx-output"); - AnswerSetToXlsxWriter writer = new AnswerSetToXlsxWriter(tmpDir.toString() + "/alphaAnswerSet"); - writer.accept(0, as); - File tmpDirFile = tmpDir.toFile(); - File[] generatedFiles = tmpDirFile.listFiles(); - Assert.assertEquals(generatedFiles.length, 1); - File answerSetFile = generatedFiles[0]; - Assert.assertEquals("alphaAnswerSet.0.xlsx", answerSetFile.getName()); - Workbook wb = WorkbookFactory.create(answerSetFile); - AnswerSetToWorkbookMapperTest.assertWorkbookMatchesAnswerSet(wb, as); - wb.close(); - // clean up - answerSetFile.delete(); - tmpDirFile.delete(); - } - - @Test - public void writeUnsatTest() throws IOException { - Path tmpDir = Files.createTempDirectory("alpha-test-xlsx-unsat"); - AnswerSetToXlsxWriter.writeUnsatInfo(Paths.get(tmpDir.toString() + "/alphaAnswerSet.UNSAT.xlsx")); - File tmpDirFile = tmpDir.toFile(); - File[] generatedFiles = tmpDirFile.listFiles(); - Assert.assertEquals(generatedFiles.length, 1); - File unsatFile = generatedFiles[0]; - Assert.assertEquals("alphaAnswerSet.UNSAT.xlsx", unsatFile.getName()); - Workbook wb = WorkbookFactory.create(unsatFile); - Sheet unsatSheet = wb.getSheet("Unsatisfiable"); - Assert.assertNotNull(unsatSheet); - Cell cell = unsatSheet.getRow(0).getCell(0); - Assert.assertNotNull(cell); - String cellValue = cell.getStringCellValue(); - Assert.assertEquals("Input is unsatisfiable - No answer sets!", cellValue); - wb.close(); - // clean up - unsatFile.delete(); - tmpDirFile.delete(); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetsParser.java b/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetsParser.java deleted file mode 100644 index d957f17ec..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/AnswerSetsParser.java +++ /dev/null @@ -1,44 +0,0 @@ -package at.ac.tuwien.kr.alpha; - -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.grounder.parser.ParseTreeVisitor; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; - -import java.io.IOException; -import java.util.Collections; -import java.util.Set; - -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 (IOException e) { - // In this case we assume that something went fundamentally - // wrong when using a String as input. The caller probably - // assumes that I/O on a String should always be fine. - throw new RuntimeException("Encountered I/O-related exception while parsing a String.", e); - } 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) throws IOException { - 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/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java b/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java deleted file mode 100644 index 186779999..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.Arrays; - -import static at.ac.tuwien.kr.alpha.Main.main; -import static org.junit.Assert.assertTrue; - -@RunWith(Parameterized.class) -public class MainTest { - private static final String INPUT = "p(a). " + System.lineSeparator() + " b :- p(X)." + System.lineSeparator(); - - @Parameters - public static Iterable data() { - return Arrays.asList( - new String[][][] {{{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-e", "1119654162577372", "-n", "20", "-str", INPUT }}, - {{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "0", "-str", INPUT }}, - {{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "1", "-str", INPUT }}, - {{"-g", "naive", "-s", "default", "-r", "naive", "-e", "1119654162577372", "--numAS", "1", "-str", INPUT }}}); - } - - @Parameter - public String[] argv; - - /** - * Temporarily redirects System.err and System.out while running the solver from the main entry point with the - * given parameters. - * Warning: this test is fragile and may require adaptions if printing is changed anywhere in Alpha. - */ - @Test - public void test() { - PrintStream sysOut = System.out; - ByteArrayOutputStream newOut = new ByteArrayOutputStream(); - System.setOut(new PrintStream(newOut)); - main(argv); - System.setOut(sysOut); - assertTrue(newOut.toString().contains("{ b, p(a) }")); - } - - @Test - public void filterTest() { - PrintStream sysOut = System.out; - ByteArrayOutputStream newOut = new ByteArrayOutputStream(); - System.setOut(new PrintStream(newOut)); - String[] args = Arrays.copyOf(argv, argv.length + 2); - args[args.length - 2] = "-f"; - args[args.length - 1] = "b"; - main(args); - System.setOut(sysOut); - assertTrue(newOut.toString().contains("{ b }")); - } - -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java b/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java deleted file mode 100644 index ac8eb6e2a..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2019-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; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import org.apache.commons.lang3.StringUtils; - -import java.util.Collection; -import java.util.stream.Collectors; - -/** - * Provides utility methods for test cases - * - */ -public class TestUtil { - - 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] = VariableTerm.getInstance(termString); - } else { - terms[i] = ConstantTerm.getInstance(termString); - } - } - return new BasicAtom(Predicate.getInstance(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] = ConstantTerm.getInstance(termInts[i]); - } - return new BasicAtom(Predicate.getInstance(predicateName, terms.length), terms); - } - - public static void printNoGoods(AtomStore atomStore, Collection noGoods) { - System.out.println(noGoods.stream().map(atomStore::noGoodToString).collect(Collectors.toSet())); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/UtilTest.java b/src/test/java/at/ac/tuwien/kr/alpha/UtilTest.java deleted file mode 100644 index 8caeb2998..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/UtilTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package at.ac.tuwien.kr.alpha; - -import org.junit.Test; - -public class UtilTest { - @Test(expected = RuntimeException.class) - public void oops() throws Exception { - throw Util.oops("Ha", new UnsupportedOperationException("Ho")); - } - - @Test(expected = RuntimeException.class) - public void oops1() throws Exception { - throw Util.oops("Ha"); - } - - @Test(expected = RuntimeException.class) - public void oops2() throws Exception { - throw Util.oops(); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java b/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java deleted file mode 100644 index 1a8bcf64e..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java +++ /dev/null @@ -1,225 +0,0 @@ -/** - * Copyright (c) 2016-2017, 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.antlr; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.Assert; -import org.junit.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 at.ac.tuwien.kr.alpha.Util; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.head.ChoiceHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public class ParserTest { - private final ProgramParser parser = new ProgramParser(); - - @Test - public void parseFact() throws IOException { - InputProgram parsedProgram = parser.parse("p(a,b)."); - - assertEquals("Program contains one fact.", 1, parsedProgram.getFacts().size()); - assertEquals("Predicate name of fact is p.", "p", parsedProgram.getFacts().get(0).getPredicate().getName()); - assertEquals("Fact has two terms.", 2, parsedProgram.getFacts().get(0).getPredicate().getArity()); - assertEquals("First term is a.", "a", (parsedProgram.getFacts().get(0).getTerms().get(0)).toString()); - assertEquals("Second term is b.", "b", (parsedProgram.getFacts().get(0).getTerms().get(1)).toString()); - } - - @Test - public void parseFactWithFunctionTerms() throws IOException { - InputProgram parsedProgram = parser.parse("p(f(a),g(h(Y)))."); - - assertEquals("Program contains one fact.", 1, parsedProgram.getFacts().size()); - assertEquals("Predicate name of fact is p.", "p", parsedProgram.getFacts().get(0).getPredicate().getName()); - assertEquals("Fact has two terms.", 2, parsedProgram.getFacts().get(0).getPredicate().getArity()); - assertEquals("First term is function term f.", "f", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(0)).getSymbol()); - assertEquals("Second term is function term g.", "g", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(1)).getSymbol()); - } - - @Test - public void parseSmallProgram() throws IOException { - InputProgram parsedProgram = parser.parse( - "a :- b, not d." + System.lineSeparator() + - "c(X) :- p(X,a,_), q(Xaa,xaa)." + System.lineSeparator() + - ":- f(Y)."); - - assertEquals("Program contains three rules.", 3, parsedProgram.getRules().size()); - } - - @Test(expected = IllegalArgumentException.class) - public void parseBadSyntax() throws IOException { - parser.parse("Wrong Syntax."); - } - - @Test - public void parseBuiltinAtom() throws IOException { - InputProgram parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); - assertEquals(1, parsedProgram.getRules().size()); - assertEquals(3, parsedProgram.getRules().get(0).getBody().size()); - } - - @Test(expected = UnsupportedOperationException.class) - // Change expected after Alpha can deal with disjunction. - public void parseProgramWithDisjunctionInHead() throws IOException { - parser.parse("r(X) | q(X) :- q(X)." + System.lineSeparator() + "q(a)." + System.lineSeparator()); - } - - @Test - public void parseInterval() throws IOException { - 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(ConstantTerm.getInstance(2), ConstantTerm.getInstance(5)))); - IntervalTerm bodyInterval = (IntervalTerm) ((Literal) parsedProgram.getRules().get(0).getBody().stream().findFirst().get()).getTerms().get(1); - assertTrue(bodyInterval.equals(IntervalTerm.getInstance(ConstantTerm.getInstance(3), VariableTerm.getInstance("X")))); - } - - @Test - public void parseChoiceRule() throws IOException { - 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).choiceAtom.toString().equals("a")); - assertTrue(choiceHead.getChoiceElements().get(1).choiceAtom.toString().equals("b")); - assertEquals(null, choiceHead.getLowerBound()); - assertEquals(null, choiceHead.getUpperBound()); - } - - @Test - public void parseChoiceRuleBounded() throws IOException { - 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).choiceAtom.toString().equals("a")); - assertTrue(choiceHead.getChoiceElements().get(1).choiceAtom.toString().equals("b")); - List conditionalLiterals = choiceHead.getChoiceElements().get(0).conditionLiterals; - assertEquals(2, conditionalLiterals.size()); - assertFalse(conditionalLiterals.get(0).isNegated()); - assertTrue(conditionalLiterals.get(1).isNegated()); - assertEquals(ConstantTerm.getInstance(1), choiceHead.getLowerBound()); - assertEquals(ComparisonOperator.LT, choiceHead.getLowerOperator()); - assertEquals(ConstantTerm.getInstance(13), choiceHead.getUpperBound()); - assertEquals(ComparisonOperator.LE, choiceHead.getUpperOperator()); - } - - @Test - public void literate() throws IOException { - final ReadableByteChannel input = Util.streamToChannel(Util.literate(Stream.of( - "This is some description.", - "", - " p(a).", - "", - "Test!"))); - - final String actual = new ProgramParser().parse(CharStreams.fromChannel(input)).toString(); - final String expected = "p(a)." + System.lineSeparator(); - - assertEquals(expected, actual); - } - - @Test(expected = IllegalArgumentException.class) - public void testMalformedInputNotIgnored() { - String program = "foo(a) :- p(b).\n" + - "// rule :- q.\n" + - "r(1).\n" + - "r(2).\n"; - parser.parse(program); - } - - @Test(expected = IllegalArgumentException.class) - public void testMissingDotNotIgnored() { - parser.parse("p(X,Y) :- q(X), r(Y) p(a). q(b)."); - } - - @Test - public void parseEnumerationDirective() throws IOException { - InputProgram parsedProgram = parser.parse("p(a,1)." + - "# enumeration_predicate_is mune." + - "r(X) :- p(X), mune(X)." + - "p(b,2)."); - String directive = parsedProgram.getInlineDirectives().getDirectiveValue(InlineDirectives.DIRECTIVE.enum_predicate_is); - assertEquals("mune", directive); - } - - @Test - public void cardinalityAggregate() throws IOException { - 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(); - AggregateLiteral parsedAggregate = (AggregateLiteral) bodyElement; - VariableTerm x = VariableTerm.getInstance("X"); - VariableTerm y = VariableTerm.getInstance("Y"); - VariableTerm z = VariableTerm.getInstance("Z"); - List basicTerms = Arrays.asList(x, y, z); - AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, - Collections.singletonList(new BasicAtom(Predicate.getInstance("p", 3), x, y, z).toLiteral())); - AggregateAtom expectedAggregate = new AggregateAtom(ComparisonOperator.LE, VariableTerm.getInstance("K"), null, null, - AggregateAtom.AGGREGATEFUNCTION.COUNT, Collections.singletonList(aggregateElement)); - assertEquals(expectedAggregate, parsedAggregate.getAtom()); - } - - @Test - public void stringWithEscapedQuotes() throws IOException { - CharStream stream = CharStreams.fromStream(ParserTest.class.getResourceAsStream("/escaped_quotes.asp")); - InputProgram prog = parser.parse(stream); - Assert.assertEquals(1, prog.getFacts().size()); - Atom stringAtom = prog.getFacts().get(0); - String stringWithQuotes = stringAtom.getTerms().get(0).toString(); - Assert.assertEquals("\"a string with \"quotes\"\"", stringWithQuotes); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/api/AlphaTest.java b/src/test/java/at/ac/tuwien/kr/alpha/api/AlphaTest.java deleted file mode 100644 index fa20250d2..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/api/AlphaTest.java +++ /dev/null @@ -1,516 +0,0 @@ -/** - * Copyright (c) 2017-2018, 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.api; - -import at.ac.tuwien.kr.alpha.AnswerSetsParser; -import at.ac.tuwien.kr.alpha.api.externals.Externals; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ExternalAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ExternalLiteral; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.MethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; -import at.ac.tuwien.kr.alpha.test.util.TestUtils; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptySet; -import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -public class AlphaTest { - private static int invocations; - - @at.ac.tuwien.kr.alpha.api.externals.Predicate - public static boolean isOne(int term) { - invocations++; - return term == 1; - } - - @at.ac.tuwien.kr.alpha.api.externals.Predicate - public static boolean isFoo(Integer a) { - return a == 0xF00; - } - - @at.ac.tuwien.kr.alpha.api.externals.Predicate - public static boolean thinger(Thingy thingy) { - return true; - } - - @Test - public void withExternal() throws Exception { - Alpha alpha = new Alpha(); - InputConfig inputCfg = InputConfig.forString("a :- &isOne[1]."); - inputCfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - 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); - } - - @Test - public void addsFacts() throws Exception { - Alpha system = new Alpha(); - Thingy a = new Thingy(); - Thingy b = new Thingy(); - List things = asList(a, b); - InputProgram program = InputProgram.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); - } - - @Test(expected = IllegalArgumentException.class) - public void withExternalTypeConflict() throws Exception { - Alpha system = new Alpha(); - 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 = new Alpha(); - 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 = AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); - assertEquals(expected, actual); - } - - @Test - public void filterOutput() throws Exception { - Alpha system = new Alpha(); - InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); - inputCfg.addPredicateMethod("getLargeGraphEdges", - Externals.processPredicate(() -> new HashSet<>(asList(asList(ConstantTerm.getInstance(1), ConstantTerm.getInstance(2)), - asList(ConstantTerm.getInstance(2), ConstantTerm.getInstance(1)), asList(ConstantTerm.getInstance(13), ConstantTerm.getInstance(1)))))); - 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); - } - - @Test - public void supplier() throws Exception { - Alpha system = new Alpha(); - InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); - cfg.addPredicateMethod("bestNode", Externals.processPredicate(() -> singleton(singletonList(ConstantTerm.getInstance(1))))); - InputProgram prog = system.readProgram(cfg); - - Set expected = AnswerSetsParser.parse("{ node(1), a }"); - Set actual = system.solve(prog).collect(Collectors.toSet()); - assertEquals(expected, actual); - } - - @at.ac.tuwien.kr.alpha.api.externals.Predicate - public static Set>> bestNode() { - return singleton(singletonList(ConstantTerm.getInstance(1))); - } - - @Test - public void noInput() throws Exception { - Alpha system = new Alpha(); - 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); - - Set expected = AnswerSetsParser.parse("{ node(1), a }"); - Set actual = system.solve(prog).collect(Collectors.toSet()); - assertEquals(expected, actual); - } - - @Test(expected = IllegalArgumentException.class) - public void smallGraphWithWrongType() throws Exception { - Alpha system = new Alpha(); - 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()); - } - - public static Set>> neighbors(int node) { - if (node == 1) { - return new HashSet<>(asList(singletonList(ConstantTerm.getInstance(2)), singletonList(ConstantTerm.getInstance(3)))); - } - return emptySet(); - } - - public static Set>> coolNode(int node) { - if (node == 1) { - return singleton(emptyList()); - } - return emptySet(); - } - - @Test - @Ignore("Test program is not safe (external lacking output variables). This should throw some exception.") - public void smallGraphNoNeighbors() throws Exception { - Alpha system = new Alpha(); - 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); - - Set expected = AnswerSetsParser.parse("{ noNeighbors(2) }"); - Set actual = system.solve(prog).collect(Collectors.toSet()); - assertEquals(expected, actual); - } - - @Test - public void smallGraphCoolNode() throws Exception { - Alpha system = new Alpha(); - 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); - - Set actual = system.solve(prog).collect(Collectors.toSet()); - Set expected = AnswerSetsParser.parse("{ in(1), node(1), node(2) }"); - assertEquals(expected, actual); - } - - @Test - public void smallGraphSingleNeighbor() throws Exception { - Alpha system = new Alpha(); - 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); - - Set expected = AnswerSetsParser.parse("{ in(1,2), in(1,3), node(1), node(2), node(3) }"); - Set actual = system.solve(prog).collect(Collectors.toSet()); - assertEquals(expected, actual); - } - - @Test - @Ignore("Test program is not safe (external lacking output variables). This should throw some exception.") - public void smallGraphSingleNeighborNoTerm() throws Exception { - Alpha system = new Alpha(); - 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); - - Set expected = AnswerSetsParser.parse("{ success }"); - Set actual = system.solve(prog).collect(Collectors.toSet()); - assertEquals(expected, actual); - } - - private static class Thingy implements Comparable { - @Override - public String toString() { - return "thingy"; - } - - @Override - public int compareTo(Thingy o) { - return 0; - } - } - - private static class SubThingy extends Thingy { - } - - @Test - public void withExternalSubtype() throws Exception { - SubThingy thingy = new SubThingy(); - - BasicRule rule = new BasicRule( - new NormalHead(new BasicAtom(Predicate.getInstance("p", 1), ConstantTerm.getInstance("x"))), - singletonList(new ExternalLiteral(new ExternalAtom(Predicate.getInstance("thinger", 1), - new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(ConstantTerm.getInstance(thingy)), - emptyList()), true))); - - Alpha system = new Alpha(); - - InputProgram prog = new InputProgram(singletonList(rule), emptyList(), new InlineDirectives()); - - Set actual = system.solve(prog).collect(Collectors.toSet()); - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("x").build())); - assertEquals(expected, actual); - } - - @Test - public void withExternalViaAnnotation() throws Exception { - Alpha system = new Alpha(); - InputConfig cfg = InputConfig.forString("a :- &isOne[1]."); - cfg.addPredicateMethods(Externals.scan(this.getClass())); - InputProgram prog = system.readProgram(cfg); - - Set actual = system.solve(prog).collect(Collectors.toSet()); - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); - assertEquals(expected, actual); - } - - /** - * Externals may only be scanned once per implementation. - * If at the time of a scan, the name of an external is already registered, - * an exception is thrown. - */ - @Test(expected = IllegalArgumentException.class) - public void errorDuplicateExternal() throws Exception { - 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 = new Alpha(); - InputConfig cfg = InputConfig.forString("a :- &isTwo[2]."); - cfg.addPredicateMethod("isTwo", Externals.processPredicate((Integer t) -> t == 2)); - InputProgram prog = system.readProgram(cfg); - - Set actual = system.solve(prog).collect(Collectors.toSet()); - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); - assertEquals(expected, actual); - } - - @Test - @Ignore("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 Alpha(); - 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); - - int before = invocations; - Set actual = system.solve(prog).collect(Collectors.toSet()); - int after = invocations; - - assertEquals(2, after - before); - - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); - assertEquals(expected, actual); - } - - @Test - @Ignore("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 Alpha(); - 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); - - int before = invocations; - Set actual = system.solve(prog).collect(Collectors.toSet()); - int after = invocations; - - assertEquals(2, after - before); - - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); - assertEquals(expected, actual); - } - - @Test - @Ignore("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 Alpha(); - 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); - - int before = invocations; - Set actual = system.solve(prog).collect(Collectors.toSet()); - int after = invocations; - - assertEquals(1, after - before); - - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); - assertEquals(expected, actual); - } - - @Test - public void basicUsage() throws Exception { - Alpha system = new Alpha(); - 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); - } - - @Test - public void basicUsageWithString() throws Exception { - Alpha system = new Alpha(); - 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); - } - - /** - * Verifies that filters are handled correctly (regression test case introduced when fixing issue #189). - */ - @Test - public void filterTest() { - String progstr = "a. b. c. d :- c. e(a, b) :- d."; - Alpha system = new Alpha(); - InputProgram prog = system.readProgramString(progstr, null); - Set actual = system.solve(prog, (p) -> p.equals(Predicate.getInstance("a", 0)) || p.equals(Predicate.getInstance("e", 2))) - .collect(Collectors.toSet()); - Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").predicate("e").symbolicInstance("a", "b").build())); - assertEquals(expected, actual); - } - - /** - * Verifies that no stratified evaluation is performed up-front when disabled in config. - */ - @Test - public void disableStratifiedEvalTest() { - String progstr = "p(a). q(X) :- p(X)."; - SystemConfig cfg = new SystemConfig(); - cfg.setEvaluateStratifiedPart(false); - Alpha system = new Alpha(cfg); - InputProgram input = system.readProgramString(progstr); - NormalProgram normal = system.normalizeProgram(input); - InternalProgram preprocessed = system.performProgramPreprocessing(InternalProgram.fromNormalProgram(normal)); - Assert.assertFalse("Preprocessed program contains fact derived from stratifiable rule, but should not!", - preprocessed.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "a"))); - } - - /** - * Verifies that stratified evaluation is performed up-front if not otherwise configured. - */ - @Test - public void enableStratifiedEvalTest() { - String progstr = "p(a). q(X) :- p(X)."; - SystemConfig cfg = new SystemConfig(); - Alpha system = new Alpha(cfg); - InputProgram input = system.readProgramString(progstr); - NormalProgram normal = system.normalizeProgram(input); - InternalProgram preprocessed = system.performProgramPreprocessing(InternalProgram.fromNormalProgram(normal)); - Assert.assertTrue("Preprocessed program does not contain fact derived from stratifiable rule, but should!", - preprocessed.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "a"))); - } - - /** - * Runs a test that formerly caused some sort of exception. - */ - @Test - public void problematicRun_3col_1119654162577372() throws IOException { - /* - * NOTE: This was constructed from the following commandline invocation: -DebugEnableInternalChecks -q -g naive -s - * default -e 1119654162577372 -n 200 -i - * 3col-20-38.txt - */ - problematicRun("3col-20-38.txt", 1119654162577372L, 200); - } - - /** - * Runs a test that formerly caused some sort of exception. - */ - @Test - public void problematicRun_3col_1119718541727902() throws IOException { - /* - * NOTE: This was constructed from the following commandline invocation: - * -DebugEnableInternalChecks -q -g naive -s default -e 1119718541727902 -n 200 -i - * 3col-20-38.txt - */ - problematicRun("3col-20-38.txt", 1119718541727902L, 200); - } - - /** - * Runs a test that formerly caused some sort of exception. - */ - @Test - public void problematicRun_vehicle_97598271567626() throws IOException { - /* - * NOTE: This was constructed from the following commandline invocation: - * -DebugEnableInternalChecks -q -g naive -s default -e 97598271567626 -n 2 -i vehicle_normal_small.asp - */ - problematicRun("vehicle_normal_small.asp", 1119718541727902L, 2); - } - - /** - * Runs a test that formerly caused some sort of exception. - */ - @Test - public void problematicRun_3col_1119718541727902_sorted_400() throws IOException { - /* - * NOTE: This was constructed from the following commandline invocation: - * -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 Alpha(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); - InputProgram prog = system.readProgram(inputCfg); - - assertFalse(system.solve(prog).sorted().limit(400).collect(Collectors.toList()).isEmpty()); - } - - 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 Alpha(cfg); - InputConfig inputCfg = new InputConfig(); - List files = new ArrayList<>(); - files.add(base.resolve(program).toString()); - inputCfg.setFiles(files); - InputProgram prog = system.readProgram(inputCfg); - assertFalse(system.solve(prog).limit(limit).collect(Collectors.toList()).isEmpty()); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java b/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java deleted file mode 100644 index b744d7518..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java +++ /dev/null @@ -1,177 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.externals.stdlib; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.config.InputConfig; - -public class AspStandardLibraryTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(AspStandardLibrary.class); - - //@formatter:off - private static final String STRINGSTUFF_ASP = - "string(\"bla\")." - + "string(\"blubb\")." - + "string(\"foo\")." - + "string(\"bar\")." - + "{ strcat(S1, S2) } :- string(S1), string(S2)." - + "resultstring(SCAT) :- strcat(S1, S2), &stdlib_string_concat[S1, S2](SCAT)." - + ":- resultstring(S), &stdlib_string_length[S](LEN), LEN != 6." - + "containsFoo(S) :- resultstring(S), &stdlib_string_matches_regex[S, \".*foo.*\"]." - + ":- resultstring(S), not containsFoo(S)." - + "has_resultstring :- resultstring(_)." - + ":- not has_resultstring."; - - // same as stringstuff asp, but without the "containsFoo" intermediate predicate - private static final String NEGATED_EXTERNAL_ASP = - "string(\"bla\")." - + "string(\"blubb\")." - + "string(\"foo\")." - + "string(\"bar\")." - + "{ strcat(S1, S2) } :- string(S1), string(S2)." - + "resultstring(SCAT) :- strcat(S1, S2), &stdlib_string_concat[S1, S2](SCAT)." - + ":- resultstring(S), &stdlib_string_length[S](LEN), LEN != 6." - + ":- resultstring(S), not &stdlib_string_matches_regex[S, \".*foo.*\"]." - + "has_resultstring :- resultstring(_)." - + ":- not has_resultstring."; - //@formatter:on - - @Test - public void parseDateTime1() { - Set>> dtSubstitution = AspStandardLibrary.datetimeParse("20.05.2020 01:19:13", "dd.MM.yyyy HH:mm:ss"); - Assert.assertEquals(1, dtSubstitution.size()); - List> dtTerms = dtSubstitution.stream().findFirst().get(); - Assert.assertEquals(6, dtTerms.size()); - Assert.assertEquals(ConstantTerm.getInstance(2020), dtTerms.get(0)); - Assert.assertEquals(ConstantTerm.getInstance(5), dtTerms.get(1)); - Assert.assertEquals(ConstantTerm.getInstance(20), dtTerms.get(2)); - Assert.assertEquals(ConstantTerm.getInstance(1), dtTerms.get(3)); - Assert.assertEquals(ConstantTerm.getInstance(19), dtTerms.get(4)); - Assert.assertEquals(ConstantTerm.getInstance(13), dtTerms.get(5)); - } - - @Test - public void parseDateTime2() { - Set>> dtSubstitution = AspStandardLibrary.datetimeParse("07/2123/18 22/37/01", "MM/yyyy/dd HH/mm/ss"); - Assert.assertEquals(1, dtSubstitution.size()); - List> dtTerms = dtSubstitution.stream().findFirst().get(); - Assert.assertEquals(6, dtTerms.size()); - Assert.assertEquals(ConstantTerm.getInstance(2123), dtTerms.get(0)); - Assert.assertEquals(ConstantTerm.getInstance(7), dtTerms.get(1)); - Assert.assertEquals(ConstantTerm.getInstance(18), dtTerms.get(2)); - Assert.assertEquals(ConstantTerm.getInstance(22), dtTerms.get(3)); - Assert.assertEquals(ConstantTerm.getInstance(37), dtTerms.get(4)); - Assert.assertEquals(ConstantTerm.getInstance(1), dtTerms.get(5)); - } - - @Test - public void parseDateTime3() { - Set>> dtSubstitution = AspStandardLibrary.datetimeParse("\"03,12,2019\", \"11:00:00\"", - "\"dd,MM,yyyy\", \"HH:mm:ss\""); - Assert.assertEquals(1, dtSubstitution.size()); - List> dtTerms = dtSubstitution.stream().findFirst().get(); - Assert.assertEquals(6, dtTerms.size()); - Assert.assertEquals(ConstantTerm.getInstance(2019), dtTerms.get(0)); - Assert.assertEquals(ConstantTerm.getInstance(12), dtTerms.get(1)); - Assert.assertEquals(ConstantTerm.getInstance(3), dtTerms.get(2)); - Assert.assertEquals(ConstantTerm.getInstance(11), dtTerms.get(3)); - Assert.assertEquals(ConstantTerm.getInstance(0), dtTerms.get(4)); - Assert.assertEquals(ConstantTerm.getInstance(0), dtTerms.get(5)); - } - - @Test - public void datetimeBefore() { - Assert.assertTrue(AspStandardLibrary.datetimeIsBefore(1990, 2, 14, 15, 16, 17, 1990, 3, 1, 0, 59, 1)); - Assert.assertFalse(AspStandardLibrary.datetimeIsBefore(2015, 5, 13, 12, 1, 33, 2003, 1, 1, 0, 0, 1)); - Assert.assertFalse(AspStandardLibrary.datetimeIsBefore(2022, 2, 22, 22, 22, 22, 2022, 2, 22, 22, 22, 22)); - } - - @Test - public void datetimeEqual() { - Assert.assertTrue(AspStandardLibrary.datetimeIsEqual(1990, 2, 14, 15, 16, 17, 1990, 2, 14, 15, 16, 17)); - Assert.assertFalse(AspStandardLibrary.datetimeIsEqual(2015, 5, 13, 12, 1, 33, 2003, 1, 1, 0, 0, 1)); - } - - @Test - public void datetimeBeforeOrEqual() { - Assert.assertTrue(AspStandardLibrary.datetimeIsBeforeOrEqual(1990, 2, 14, 15, 16, 17, 1990, 3, 1, 0, 59, 1)); - Assert.assertFalse(AspStandardLibrary.datetimeIsBeforeOrEqual(2015, 5, 13, 12, 1, 33, 2003, 1, 1, 0, 0, 1)); - Assert.assertTrue(AspStandardLibrary.datetimeIsBeforeOrEqual(2022, 2, 22, 22, 22, 22, 2022, 2, 22, 22, 22, 22)); - - } - - @Test - public void matchesRegex() { - Assert.assertTrue(AspStandardLibrary.stringMatchesRegex("Blaaaaa Blubbb!!", "Bla+ Blub+!!")); - Assert.assertFalse(AspStandardLibrary.stringMatchesRegex("Foobar", "Bla+ Blub+!!")); - } - - @Test - public void stringLength() { - Set>> result = AspStandardLibrary.stringLength("A String of length 21"); - Assert.assertEquals(1, result.size()); - List> lengthTerms = result.stream().findFirst().get(); - Assert.assertEquals(1, lengthTerms.size()); - ConstantTerm lenTerm = lengthTerms.get(0); - Assert.assertEquals(ConstantTerm.getInstance(21), lenTerm); - } - - @Test - public void stringConcat() { - Set>> result = AspStandardLibrary.stringConcat("Foo", "bar"); - Assert.assertEquals(1, result.size()); - List> concatTerms = result.stream().findFirst().get(); - Assert.assertEquals(1, concatTerms.size()); - ConstantTerm concat = concatTerms.get(0); - Assert.assertEquals(ConstantTerm.getInstance("Foobar"), concat); - } - - @Test - @SuppressWarnings("unchecked") - public void programWithStringStuff() throws IOException { - Alpha alpha = new Alpha(); - 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) { - for (Atom atom : as.getPredicateInstances(Predicate.getInstance("resultstring", 1))) { - String resultstring = ((ConstantTerm) atom.getTerms().get(0)).getObject(); - Assert.assertEquals(6, resultstring.length()); - Assert.assertTrue(resultstring.contains("foo")); - } - } - } - - @Test - @SuppressWarnings("unchecked") - public void negatedExternal() throws IOException { - Alpha alpha = new Alpha(); - InputProgram prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); - Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); - Assert.assertEquals(31, answerSets.size()); - // Verify every result string has length 6 and contains "foo" - for (AnswerSet as : answerSets) { - for (Atom atom : as.getPredicateInstances(Predicate.getInstance("resultstring", 1))) { - String resultstring = ((ConstantTerm) atom.getTerms().get(0)).getObject(); - LOGGER.debug("ResultString is {}", resultstring); - Assert.assertEquals(6, resultstring.length()); - Assert.assertTrue(resultstring.contains("foo")); - } - } - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapperTest.java b/src/test/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapperTest.java deleted file mode 100644 index c9fcc28c6..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/api/mapper/AnswerSetToWorkbookMapperTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.mapper; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.terms.Term; - -public class AnswerSetToWorkbookMapperTest { - - private AnswerSetToWorkbookMapper mapper = new AnswerSetToWorkbookMapper(); - - @Test - public void smokeTest() throws IOException { - AnswerSet as = new AnswerSetBuilder().predicate("bla").instance("blubb", "blubb").instance("foo", "bar").predicate("foo").instance("bar") - .instance("baz").predicate("complex").instance(Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)).build(); - Workbook wb = this.mapper.mapFromAnswerSet(as); - Assert.assertNotNull(wb.getSheet("Flags")); - Assert.assertNotNull(wb.getSheet("bla_2")); - Assert.assertNotNull(wb.getSheet("foo_1")); - Assert.assertNotNull(wb.getSheet("complex_3")); - wb.close(); - } - - @Test - public void solveAndWriteWorkbookTest() { - //@formatter:off - String progstr = "aFlag. oneMoreFlag. yetAnotherFlag. createPs. maxP(5). r(s(1, 2, 3), 4). r(bla, blubb). r(foo, bar(baaz))." - + "p(0) :- createPs. " - + "p(N) :- p(I), N = I + 1, N <= MX, maxP(MX)." - + "q(A, B) :- p(A), p(B)."; - //@formatter:on - Alpha alpha = new Alpha(); - List answerSets = alpha.solve(alpha.readProgramString(progstr, null)).collect(Collectors.toList()); - Assert.assertEquals(1, answerSets.size()); - AnswerSet as = answerSets.get(0); - Workbook answerSetWorkbook = this.mapper.mapFromAnswerSet(as); - AnswerSetToWorkbookMapperTest.assertWorkbookMatchesAnswerSet(answerSetWorkbook, as); - } - - public static void assertWorkbookMatchesAnswerSet(Workbook wb, AnswerSet as) { - for (Predicate pred : as.getPredicates()) { - if (pred.getArity() == 0) { - boolean flagFound = false; - Sheet flagsSheet = wb.getSheet("Flags"); - Assert.assertNotNull(flagsSheet); - for (Row row : flagsSheet) { - if (row.getCell(0).getStringCellValue().equals(pred.getName())) { - flagFound = true; - break; - } - } - Assert.assertTrue("0-arity predicate " + pred.getName() + " not found in workbook!", flagFound); - } else { - Sheet predicateSheet = wb.getSheet(pred.getName() + "_" + pred.getArity()); - for (Atom atom : as.getPredicateInstances(pred)) { - boolean atomFound = false; - Assert.assertNotNull(predicateSheet); - for (Row row : predicateSheet) { - if (AnswerSetToWorkbookMapperTest.rowMatchesAtom(row, atom)) { - atomFound = true; - break; - } - } - Assert.assertTrue("Atom " + atom.toString() + " not found in workbook!", atomFound); - } - } - } - } - - private static boolean rowMatchesAtom(Row row, Atom atom) { - List terms = atom.getTerms(); - Cell cell; - for (int i = 0; i < terms.size(); i++) { - cell = row.getCell(i); - if (cell == null) { - return false; - } - if (!(cell.getStringCellValue().equals(terms.get(i).toString()))) { - return false; - } - } - return true; - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatterTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatterTest.java deleted file mode 100644 index d7e423877..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/AnswerSetFormatterTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import org.junit.Assert; -import org.junit.Test; - -public class AnswerSetFormatterTest { - - @Test - public void basicFormatterWithSeparator() { - AnswerSetFormatter fmt = new SimpleAnswerSetFormatter(" bla "); - AnswerSet as = new AnswerSetBuilder().predicate("p").instance("a").predicate("q").instance("b").build(); - String formatted = fmt.format(as); - Assert.assertEquals("{ p(\"a\") bla q(\"b\") }", formatted); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java deleted file mode 100644 index 17bce93b8..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - -/** - * Copyright (c) 2018, the Alpha Team. - */ -public class AtomStoreTest { - - public static void fillAtomStore(AtomStore atomStore, int numberOfAtomsToFill) { - Predicate predA = Predicate.getInstance("a", 1); - for (int i = 0; i < numberOfAtomsToFill; i++) { - atomStore.putIfAbsent(new BasicAtom(predA, ConstantTerm.getInstance(i))); - } - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java deleted file mode 100644 index efcd847bf..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java +++ /dev/null @@ -1,79 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import org.junit.Test; - -import java.util.*; - -import static at.ac.tuwien.kr.alpha.common.terms.ConstantTerm.getInstance; -import static java.util.Arrays.asList; -import static java.util.Collections.singleton; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public class BasicAnswerSetTest { - @Test - public void areAnswerSetsEqual() throws Exception { - Predicate a = Predicate.getInstance("a", 0); - Predicate foo = Predicate.getInstance("foo", 1); - SortedSet fooAndA = new TreeSet<>(asList(foo, a)); - - Predicate q = Predicate.getInstance("q", 0); - Predicate p = Predicate.getInstance("p", 1); - SortedSet qAndP = new TreeSet<>(asList(q, p)); - - ConstantTerm bar = getInstance("bar"); - ConstantTerm baz = getInstance("baz"); - - Map> inst1 = new HashMap<>(); - inst1.put(a, new TreeSet<>(singleton(new BasicAtom(a)))); - inst1.put(foo, new TreeSet<>(asList( - new BasicAtom(foo, bar), - new BasicAtom(foo, baz) - ))); - // as1 = { a, foo(bar), foo(baz) } - - Map> inst2 = new HashMap<>(); - inst2.put(a, new TreeSet<>(singleton(new BasicAtom(a)))); - inst2.put(foo, new TreeSet<>(asList( - new BasicAtom(foo, baz), - new BasicAtom(foo, bar) - ))); - // as1 = { a, foo(baz), foo(bar) } - - Map> inst3 = new HashMap<>(); - inst3.put(q, new TreeSet<>(singleton(new BasicAtom(q)))); - inst3.put(p, new TreeSet<>(asList( - new BasicAtom(p, bar), - new BasicAtom(p, baz) - ))); - // as3 = { q, p(bar), p(baz) } - - Map> inst4 = new HashMap<>(); - inst4.put(a, new TreeSet<>(singleton(new BasicAtom(a)))); - inst4.put(foo, new TreeSet<>(asList( - new BasicAtom(foo, bar), - new BasicAtom(foo, baz), - new BasicAtom(foo, getInstance("batsinga")) - ))); - // as4 = { a, foo(bar), foo(baz), foo(batsinga) } - - final List answerSets = asList( - new BasicAnswerSet(fooAndA, inst1), - new BasicAnswerSet(fooAndA, inst2), - new BasicAnswerSet(qAndP, inst3), - new BasicAnswerSet(fooAndA, inst4) - ); - - assertEquals(answerSets.get(0), answerSets.get(1)); - assertEquals(answerSets.get(1), answerSets.get(0)); - - assertNotEquals(answerSets.get(0), answerSets.get(2)); - assertNotEquals(answerSets.get(0), answerSets.get(3)); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java deleted file mode 100644 index b8262aa55..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/NoGoodTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import org.junit.Test; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToNegatedLiteral; -import static org.junit.Assert.*; - -public class NoGoodTest { - /** - * Constructs an array of literals with the new representation (least-significant bit is polarity, other bits - * are atom id) from an array of literals from the old representation (positive literal is atom id, negative - * literal is negated atom id). - * @param literals - * @return - */ - public static int[] fromOldLiterals(int... literals) { - int[] newLiterals = new int[literals.length]; - for (int i = 0; i < literals.length; i++) { - newLiterals[i] = literals[i] >= 0 ? atomToLiteral(literals[i]) : atomToNegatedLiteral(-literals[i]); - } - return newLiterals; - } - - public static int fromOldLiterals(int literal) { - return literal >= 0 ? atomToLiteral(literal) : atomToNegatedLiteral(-literal); - } - - @Test - public void iteration() throws Exception { - Iterator i = new NoGood(1).iterator(); - assertEquals(1, (int)i.next()); - assertFalse(i.hasNext()); - } - - @Test(expected = NullPointerException.class) - public void compareToNull() throws Exception { - new NoGood().compareTo(null); - } - - @Test - public void compareToSame() throws Exception { - assertEquals(0, new NoGood(1).compareTo(new NoGood(1))); - } - - @Test - public void compareToLengthShort() throws Exception { - assertEquals(-1, new NoGood(1).compareTo(new NoGood(1, 2))); - } - - @Test - public void compareToLengthLong() throws Exception { - assertEquals(+1, new NoGood(1, 2).compareTo(new NoGood(1))); - } - - @Test - public void compareToLexicographicSmall() throws Exception { - assertEquals(-1, new NoGood(1, 2).compareTo(new NoGood(2, 3))); - } - - @Test - public void compareToLexicographicBig() throws Exception { - assertEquals(+1, new NoGood(2, 3).compareTo(new NoGood(1, 2))); - } - - @Test - public void deleteDuplicates() { - NoGood ng = NoGood.headFirst(fromOldLiterals(-3, 1, -2, -2)); - assertEquals("Duplicate entry must be removed.", 3, ng.size()); - assertEquals(fromOldLiterals(-3), ng.getLiteral(0)); - assertEquals(fromOldLiterals(1), ng.getLiteral(1)); - assertEquals(fromOldLiterals(-2), ng.getLiteral(2)); - - NoGood ng2 = NoGood.headFirst(fromOldLiterals(-2, 3, 3, -6, -1, 5, 5, -6, 7)); - assertEquals("Duplicate entries must be removed.", 6, ng2.size()); - assertEquals(fromOldLiterals(-2), ng2.getLiteral(0)); - assertEquals(fromOldLiterals(-1), ng2.getLiteral(1)); - assertEquals(fromOldLiterals(3), ng2.getLiteral(2)); - assertEquals(fromOldLiterals(5), ng2.getLiteral(3)); - assertEquals(fromOldLiterals(-6), ng2.getLiteral(4)); - assertEquals(fromOldLiterals(7), ng2.getLiteral(5)); - - NoGood ng3 = NoGood.headFirst(fromOldLiterals(-1, 2, -3, -4)); - assertEquals("NoGood contains no duplicates, size must stay the same.", 4, ng3.size()); - assertEquals(fromOldLiterals(-1), ng3.getLiteral(0)); - assertEquals(fromOldLiterals(2), ng3.getLiteral(1)); - assertEquals(fromOldLiterals(-3), ng3.getLiteral(2)); - assertEquals(fromOldLiterals(-4), ng3.getLiteral(3)); - - } - - @Test - public void noGoodsInHashMap() { - NoGood ng1 = NoGood.headFirst(-1, 2, -3, -4); - NoGood ng2 = NoGood.headFirst(-1, 2, -4); - NoGood ng3 = NoGood.headFirst(-1, 2, -3, -4); - Map noGoodIdentifiers = new LinkedHashMap<>(); - noGoodIdentifiers.put(ng1, 1); - noGoodIdentifiers.put(ng1, 2); - noGoodIdentifiers.put(ng2, 4); - assertTrue(noGoodIdentifiers.containsKey(ng3)); - noGoodIdentifiers.put(ng3, 5); - assertEquals(2, noGoodIdentifiers.size()); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java deleted file mode 100644 index 2f4540101..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/ProgramTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2017 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.common; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -public class ProgramTest { - - @Test - public void testToString() { - InputProgram parsedProgram = new ProgramParser().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(), - parsedProgram.toString()); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java deleted file mode 100644 index 73b69e80b..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/RuleTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import static org.junit.Assert.assertEquals; - -import org.junit.Assert; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Copyright (c) 2018, the Alpha Team. - */ -public class RuleTest { - - private final ProgramParser parser = new ProgramParser(); - - @Test - public void renameVariables() { - String originalRule = "p(X,Y) :- a, f(Z) = 1, q(X,g(Y),Z), dom(A)."; - BasicRule rule = parser.parse(originalRule).getRules().get(0); - InternalRule normalRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); - InternalRule renamedRule = normalRule.renameVariables("_13"); - BasicRule 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); - InternalRule expectedRenamedNormalRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(expectedRenamedRule)); - assertEquals(expectedRenamedNormalRule.toString(), renamedRule.toString()); - } - - @Test - public void testRulesEqual() { - InputProgram p1 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); - BasicRule r1 = p1.getRules().get(0); - InputProgram p2 = parser.parse("p(X, Y) :- bla(X), blub(Y), foo(X, Y), not bar(X)."); - BasicRule r2 = p2.getRules().get(0); - InputProgram p3 = parser.parse("p(X, Y) :- bla(X), blub(X), foo(X, X), not bar(X)."); - BasicRule r3 = p3.getRules().get(0); - Assert.assertTrue(r1.equals(r2)); - Assert.assertTrue(r2.equals(r1)); - Assert.assertTrue(r1.hashCode() == r2.hashCode()); - Assert.assertFalse(r1.equals(r3)); - Assert.assertFalse(r3.equals(r1)); - Assert.assertTrue(r1.hashCode() != r3.hashCode()); - Assert.assertFalse(r2.equals(r3)); - Assert.assertFalse(r3.equals(r2)); - Assert.assertTrue(r2.hashCode() != r3.hashCode()); - } - -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java deleted file mode 100644 index d062c0454..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package at.ac.tuwien.kr.alpha.common; - -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public class TermTest { - - @Test - public void testTermReferenceEquality() { - // Terms must have a unique representation so that reference comparison is - // sufficient to check - // whether two terms are equal. - ConstantTerm ta1 = ConstantTerm.getInstance("a"); - ConstantTerm ta2 = ConstantTerm.getInstance("a"); - assertTrue("Two instances of ConstantTerms for the same term symbol must be the same object", ta1 == ta2); - - List termList = new LinkedList<>(); - termList.add(ta1); - termList.add(ta2); - FunctionTerm ft1 = FunctionTerm.getInstance("f", termList); - List termList2 = new LinkedList<>(); - termList2.add(ta1); - termList2.add(ta2); - FunctionTerm ft2 = FunctionTerm.getInstance("f", termList2); - assertTrue("Two instances of FunctionTerms for the same term symbol and equal term lists must be the same object", ft1 == ft2); - } - - @Test - public void testTermVariableOccurrences() { - ConstantTerm ta = ConstantTerm.getInstance("a"); - VariableTerm tx = VariableTerm.getInstance("X"); - FunctionTerm tf = FunctionTerm.getInstance("f", ta, tx); - List occurringVariables = tf.getOccurringVariables(); - - assertEquals("Variable occurring as subterm must be reported as occurring variable.", occurringVariables.get(0), tx); - } - - @Test - public void testTermOrdering() throws Exception { - Term cts = ConstantTerm.getInstance("abc"); - Term cti = ConstantTerm.getInstance(2); - Term cto = ConstantTerm.getInstance(new UUID(0, 0)); - Term ft = FunctionTerm.getInstance("f", ConstantTerm.getInstance("a")); - - assertTrue(cts.compareTo(cti) > 0); - assertTrue(cti.compareTo(cts) < 0); - - assertTrue(cts.compareTo(cto) < 0); - assertTrue(cto.compareTo(cts) > 0); - - assertTrue(cts.compareTo(ft) < 0); - assertTrue(ft.compareTo(cts) > 0); - - assertTrue(cto.compareTo(ft) < 0); - assertTrue(ft.compareTo(cto) > 0); - } - - @Test - public void testStringVsConstantSymbolEquality() { - String theString = "string"; - ConstantTerm stringConstant = ConstantTerm.getInstance(theString); - ConstantTerm constantSymbol = ConstantTerm.getSymbolicInstance(theString); - // Reference equality must hold for both the string constant and the constant - // symbol. - Assert.assertTrue(stringConstant == ConstantTerm.getInstance(theString)); - ConstantTerm sameConstantSymbol = ConstantTerm.getSymbolicInstance(theString); - Assert.assertTrue(constantSymbol == sameConstantSymbol); - // Make sure both hashCode and equals understand that stringConstant and - // constantSymbol are NOT the same thing! - Assert.assertNotEquals(stringConstant.hashCode(), constantSymbol.hashCode()); - Assert.assertNotEquals(stringConstant, constantSymbol); - // This also applies to compareTo - it must behave in sync with equals and - // hashCode, i.e. return a non-zero result for non-equal objects - Assert.assertNotEquals(0, stringConstant.compareTo(constantSymbol)); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java deleted file mode 100644 index 4a349a4c1..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java +++ /dev/null @@ -1,138 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.atoms; - -import at.ac.tuwien.kr.alpha.api.externals.Externals; -import at.ac.tuwien.kr.alpha.api.externals.Predicate; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import org.junit.Assert; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Test for basic functionality of various implementations of {@link Atom}. - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public class AtomsTest { - - private final ProgramParser parser; - - public AtomsTest() throws NoSuchMethodException, SecurityException { - Map 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 ProgramParser(externals); - } - - @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(ConstantTerm.getSymbolicInstance(Integer.toString(in))); - retVal.add(lst); - return retVal; - } - - @Test - public void testIsBasicAtomGround() { - InputProgram p = parser.parse("bla(blubb, foo(bar))."); - Atom a = p.getFacts().get(0); - assertBasicAtomGround(a, true); - InputProgram p1 = parser.parse("foo(1, 2, 3, \"bar\")."); - Atom a1 = p1.getFacts().get(0); - assertBasicAtomGround(a1, true); - InputProgram p2 = parser.parse("foo(BAR)."); - Atom a2 = p2.getFacts().get(0); - assertBasicAtomGround(a2, false); - InputProgram p3 = parser.parse("foo(b, a, r(\"bla\", BLUBB))."); - Atom a3 = p3.getFacts().get(0); - assertBasicAtomGround(a3, false); - } - - @Test - public void testAreBasicAtomsEqual() { - InputProgram p1 = parser.parse("bla(blubb, foo(bar)). bla(blubb, foo(bar))."); - Atom a1 = p1.getFacts().get(0); - Atom a2 = p1.getFacts().get(1); - Assert.assertEquals(a1, a2); - 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); - Assert.assertEquals(a3, a4); - InputProgram p3 = parser.parse("foo(BAR). foo(BAR)."); - Atom a5 = p3.getFacts().get(0); - Atom a6 = p3.getFacts().get(1); - Assert.assertEquals(a5, a6); - 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); - Assert.assertEquals(a7, a8); - - Assert.assertFalse(a1.equals(a3)); - Assert.assertFalse(a3.equals(a1)); - Assert.assertFalse(a1.equals(a5)); - Assert.assertFalse(a5.equals(a1)); - Assert.assertFalse(a1.equals(a7)); - Assert.assertFalse(a7.equals(a1)); - } - - @Test - public void testIsExternalAtomGround() { - InputProgram p1 = parser.parse("a :- &isFoo[1]."); - Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext1, true); - InputProgram p2 = parser.parse("a :- &isFoo[bar(1)]."); - Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext2, true); - InputProgram p3 = parser.parse("a :- &isFoo[BLA]."); - Atom ext3 = p3.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext3, false); - } - - @Test - @SuppressWarnings("unlikely-arg-type") - public void testAreExternalAtomsEqual() { - InputProgram p1 = parser.parse("a :- &isFoo[1]."); - Atom ext1 = p1.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - InputProgram p2 = parser.parse("a :- &isFoo[1]."); - Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - Assert.assertEquals(ext1, ext2); - Assert.assertEquals(ext2, ext1); - - Assert.assertFalse(ext1.equals(null)); - Assert.assertFalse(ext1.equals("bla")); - Assert.assertTrue(ext1.hashCode() == ext2.hashCode()); - } - - @Test - public void testExternalHasOutput() { - InputProgram p = parser.parse("a:- &extWithOutput[1](OUT)."); - Atom ext = p.getRules().get(0).getBody().stream().findFirst().get().getAtom(); - assertExternalAtomGround(ext, false); - Assert.assertTrue(((ExternalAtom) ext).hasOutput()); - } - - private void assertBasicAtomGround(Atom a, boolean expectedGround) { - Assert.assertTrue(a instanceof BasicAtom); - Assert.assertEquals(expectedGround, a.isGround()); - } - - private void assertExternalAtomGround(Atom a, boolean expectedGround) { - Assert.assertTrue(a instanceof ExternalAtom); - Assert.assertEquals(expectedGround, a.isGround()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java deleted file mode 100644 index edf252ca7..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java +++ /dev/null @@ -1,203 +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.common.atoms; - -import static org.junit.Assert.assertEquals; - -import org.junit.Ignore; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.IntPredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Tests the behaviour of {@link Literal#getBindingVariables()} and {@link Literal#getNonBindingVariables()} - * on classes implementing {@link Atom}. - * - */ -public class LiteralBindingNonBindingVariablesTest { - - private final Map externals = new HashMap<>(); - private final ProgramParser parser = new ProgramParser(externals); - - @Test - public void testPositiveBasicLiteral() { - Literal literal = parser.parse("p(X,Y) :- q(X,Y).").getRules().get(0).getBody().stream().findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables(), "X", "Y"); - expectVariables(literal.getNonBindingVariables()); - } - - @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(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "X", "Y"); - } - - @Test - public void testPositiveComparisonLiteral_EQ_LeftAssigning() { - BasicRule rule = parser.parse("p(X) :- q(X,Y), Y = 5.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperator.EQ.predicate()).findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables(), "Y"); - expectVariables(literal.getNonBindingVariables()); - } - - @Test - public void testNegativeComparisonLiteral_EQ_LeftAssigning() { - BasicRule rule = parser.parse("p(X) :- q(X,Y), not Y = 5.").getRules().get(0); - Literal literal = rule.getNegativeBody().stream().findFirst().get(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "Y"); - } - - @Test - public void testPositiveComparisonLiteral_EQ_RightAssigning() { - BasicRule rule = parser.parse("p(X) :- q(X,Y), 5 = Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperator.EQ.predicate()).findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables(), "Y"); - expectVariables(literal.getNonBindingVariables()); - } - - @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(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "Y"); - } - - @Test - @Ignore("Literals of this kind are compiled away by VariableEqualityRemoval") - public void testPositiveComparisonLiteral_EQ_Bidirectional() { - BasicRule rule = parser.parse("p(X) :- q(X,Y), X = Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperator.EQ.predicate()).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(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "X", "Y"); - } - - @Test - public void testPositiveComparisonLiteral_NEQ_LeftAssigning() { - BasicRule rule = parser.parse("p(X) :- q(X,Y), Y != 5.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperator.NE.predicate()).findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "Y"); - } - - @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(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables(), "Y"); - expectVariables(literal.getNonBindingVariables()); - } - - @Test - public void testPositiveComparisonLiteral_NEQ_RightAssigning() { - BasicRule rule = parser.parse("p(X) :- q(X,Y), 5 != Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperator.NE.predicate()).findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "Y"); - } - - @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(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables(), "Y"); - expectVariables(literal.getNonBindingVariables()); - } - - @Test - public void testPositiveComparisonLiteral_NEQ_Bidirectional() { - BasicRule rule = parser.parse("p(X) :- q(X,Y), X != Y.").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate() == ComparisonOperator.NE.predicate()).findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "X", "Y"); - } - - @Test - @Ignore("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(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables(), "X", "Y"); - expectVariables(literal.getNonBindingVariables()); - } - - @Test - public void testPositiveExternalLiteral() { - externals.put("ext", new IntPredicateInterpretation(i -> i > 0)); - BasicRule rule = parser.parse("p(X) :- q(Y), &ext[Y](X).").getRules().get(0); - Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate().getName().equals("ext")).findFirst().get(); - assertEquals(false, literal.isNegated()); - expectVariables(literal.getBindingVariables(), "X"); - expectVariables(literal.getNonBindingVariables(), "Y"); - } - - @Test - public void testNegativeExternalLiteral() { - externals.put("ext", new IntPredicateInterpretation(i -> i > 0)); - Literal literal = parser.parse("p(X) :- q(Y), not &ext[Y](X).").getRules().get(0).getNegativeBody().stream().findFirst().get(); - assertEquals(true, literal.isNegated()); - expectVariables(literal.getBindingVariables()); - expectVariables(literal.getNonBindingVariables(), "X", "Y"); - } - - private void expectVariables(Collection variables, String... expectedVariableNames) { - Set setActualVariableNames = variables.stream().map(VariableTerm::toString).collect(Collectors.toSet()); - Set setExpectedVariableNames = Arrays.stream(expectedVariableNames).collect(Collectors.toSet()); - assertEquals(setExpectedVariableNames, setActualVariableNames); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraphTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraphTest.java deleted file mode 100644 index 852143021..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/DependencyGraphTest.java +++ /dev/null @@ -1,265 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.depgraph; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.test.util.DependencyGraphUtils; -import org.junit.Assert; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class DependencyGraphTest { - - // 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 = Predicate.getInstance("test", 2, false, false); - Edge e1 = new Edge(new Node(testPredicate), true); - Edge e2 = new Edge(new Node(testPredicate), true); - Assert.assertEquals(e1, e2); - } - - @Test - public void reachabilityCheckSimpleTest() { - Alpha system = new Alpha(); - - InputProgram prog = system.readProgramString("b :- a.", null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - - Node a = dg.getNodeForPredicate(Predicate.getInstance("a", 0)); - Node b = dg.getNodeForPredicate(Predicate.getInstance("b", 0)); - - Node nonExistent = new Node(Predicate.getInstance("notHere", 0)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); - Assert.assertFalse(DependencyGraphUtils.isReachableFrom(a, b, dg)); - Assert.assertFalse(DependencyGraphUtils.isReachableFrom(nonExistent, a, dg)); - Assert.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"); - Alpha system = new Alpha(); - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - Node a = dg.getNodeForPredicate(Predicate.getInstance("a", 0)); - Node b = dg.getNodeForPredicate(Predicate.getInstance("b", 0)); - Node c = dg.getNodeForPredicate(Predicate.getInstance("c", 0)); - Node d = dg.getNodeForPredicate(Predicate.getInstance("d", 0)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, a, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, a, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, b, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, b, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, b, dg)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, c, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, c, dg)); - - Assert.assertFalse(DependencyGraphUtils.isReachableFrom(a, d, dg)); - Assert.assertFalse(DependencyGraphUtils.isReachableFrom(a, c, dg)); - Assert.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."); - Alpha system = new Alpha(); - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - Node a = dg.getNodeForPredicate(Predicate.getInstance("a", 0)); - Node b = dg.getNodeForPredicate(Predicate.getInstance("b", 0)); - Node c = dg.getNodeForPredicate(Predicate.getInstance("c", 0)); - Node d = dg.getNodeForPredicate(Predicate.getInstance("d", 0)); - Node f1 = dg.getNodeForPredicate(Predicate.getInstance("f1", 0)); - Node x = dg.getNodeForPredicate(Predicate.getInstance("x", 0)); - Node notInGraph = new Node(Predicate.getInstance("notInGraph", 0)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, a, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, a, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, a, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, a, dg)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, b, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, b, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(b, b, dg)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(d, c, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, c, dg)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, d, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, c, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(a, b, dg)); - - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(x, f1, dg)); - Assert.assertTrue(DependencyGraphUtils.isReachableFrom(c, f1, dg)); - - Assert.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"); - Alpha system = new Alpha(); - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - Node a = dg.getNodeForPredicate(Predicate.getInstance("a", 0)); - Node b = dg.getNodeForPredicate(Predicate.getInstance("b", 0)); - - List componentA = new ArrayList<>(); - componentA.add(a); - Assert.assertTrue(DependencyGraphUtils.areStronglyConnected(componentA, dg)); - Assert.assertFalse(DependencyGraphUtils.isStronglyConnectedComponent(componentA, dg)); - - List componentB = new ArrayList<>(); - componentB.add(b); - Assert.assertTrue(DependencyGraphUtils.areStronglyConnected(componentB, dg)); - Assert.assertFalse(DependencyGraphUtils.isStronglyConnectedComponent(componentB, dg)); - - List componentAll = new ArrayList<>(); - componentAll.add(a); - componentAll.add(b); - Assert.assertTrue(DependencyGraphUtils.areStronglyConnected(componentAll, dg)); - Assert.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."; - - Alpha system = new Alpha(); - InputProgram prog = system.readProgramString(inputProgram); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - - Node f0 = dg.getNodeForPredicate(Predicate.getInstance("f0", 0)); - Node f1 = dg.getNodeForPredicate(Predicate.getInstance("f1", 0)); - Node f2 = dg.getNodeForPredicate(Predicate.getInstance("f2", 0)); - Node f3 = dg.getNodeForPredicate(Predicate.getInstance("f3", 0)); - Node a = dg.getNodeForPredicate(Predicate.getInstance("a", 0)); - Node b = dg.getNodeForPredicate(Predicate.getInstance("b", 0)); - Node c = dg.getNodeForPredicate(Predicate.getInstance("c", 0)); - Node d = dg.getNodeForPredicate(Predicate.getInstance("d", 0)); - Node x = dg.getNodeForPredicate(Predicate.getInstance("x", 0)); - Node y = dg.getNodeForPredicate(Predicate.getInstance("y", 0)); - Node z = dg.getNodeForPredicate(Predicate.getInstance("z", 0)); - - StronglyConnectedComponentsAlgorithm.SccResult sccResult = StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg); - Map nodesByComponent = sccResult.nodesByComponentId; - List> stronglyConnectedComponents = sccResult.stronglyConnectedComponents; - Assert.assertEquals(8, stronglyConnectedComponents.size()); - - for (int i = 0; i < stronglyConnectedComponents.size(); i++) { - List stronglyConnectedComponent = stronglyConnectedComponents.get(i); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(stronglyConnectedComponent, dg)); - for (Node node : stronglyConnectedComponent) { - Assert.assertEquals(Integer.valueOf(i), nodesByComponent.get(node)); - } - } - - List c1 = new ArrayList<>(); - c1.add(a); - c1.add(b); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c1, dg)); - Assert.assertEquals(nodesByComponent.get(a), nodesByComponent.get(b)); - - List c2 = new ArrayList<>(); - c2.add(c); - c2.add(d); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c2, dg)); - Assert.assertEquals(nodesByComponent.get(c), nodesByComponent.get(d)); - - List c3 = new ArrayList<>(); - c3.add(x); - c3.add(y); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c3, dg)); - Assert.assertEquals(nodesByComponent.get(x), nodesByComponent.get(y)); - - List c4 = new ArrayList<>(); - c4.add(z); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c4, dg)); - - List c5 = new ArrayList<>(); - c5.add(f0); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c5, dg)); - - List c6 = new ArrayList<>(); - c6.add(f1); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c6, dg)); - - List c7 = new ArrayList<>(); - c7.add(f2); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c7, dg)); - - List c8 = new ArrayList<>(); - c8.add(f3); - Assert.assertTrue(DependencyGraphUtils.isStronglyConnectedComponent(c8, dg)); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithmTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithmTest.java deleted file mode 100644 index a709e65a6..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/depgraph/StratificationAlgorithmTest.java +++ /dev/null @@ -1,239 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.depgraph; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph.SCComponent; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class StratificationAlgorithmTest { - - 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() { - Alpha system = new Alpha(); - InputProgram prog = system.readProgramString("a :- b.", null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicate.getInstance("a", 0); - Predicate b = Predicate.getInstance("b", 0); - - assertEquals(2, strata.size()); - assertTrue(predicateIsBeforePredicateInOrder(b, a, strata)); - } - - @Test - public void stratifyTwoRulesTest() { - Alpha system = new Alpha(); - StringBuilder bld = new StringBuilder(); - bld.append("b :- a.").append("\n"); - bld.append("c :- b.").append("\n"); - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicate.getInstance("a", 0); - Predicate b = Predicate.getInstance("b", 0); - Predicate c = Predicate.getInstance("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() throws IOException { - Alpha system = new Alpha(); - 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"); - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicate.getInstance("a", 0); - Predicate b = Predicate.getInstance("b", 0); - Predicate c = Predicate.getInstance("c", 0); - Predicate d = Predicate.getInstance("d", 0); - Predicate e = Predicate.getInstance("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() { - Alpha system = new Alpha(); - 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)."); - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate ancestorOf = Predicate.getInstance("ancestor_of", 2); - Predicate parentOf = Predicate.getInstance("parent_of", 2); - - assertEquals(2, strata.size()); - assertTrue(predicateIsBeforePredicateInOrder(parentOf, ancestorOf, strata)); - } - - @Test - public void stratifyLargeGraphTest() { - Alpha system = new Alpha(); - 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."); - - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicate.getInstance("a", 0); - Predicate b = Predicate.getInstance("b", 0); - Predicate c = Predicate.getInstance("c", 0); - Predicate d = Predicate.getInstance("d", 0); - Predicate e = Predicate.getInstance("e", 0); - Predicate f = Predicate.getInstance("f", 0); - Predicate h = Predicate.getInstance("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() { - Alpha system = new Alpha(); - 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."); - - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicate.getInstance("a", 0); - Predicate b = Predicate.getInstance("b", 0); - Predicate c = Predicate.getInstance("c", 0); - Predicate d = Predicate.getInstance("d", 0); - Predicate e = Predicate.getInstance("e", 0); - Predicate f = Predicate.getInstance("f", 0); - Predicate h = Predicate.getInstance("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() { - Alpha system = new Alpha(); - StringBuilder bld = new StringBuilder(); - bld.append("b :- a."); - bld.append("c :- b."); - bld.append("c :- a."); - - InputProgram prog = system.readProgramString(bld.toString(), null); - NormalProgram normalProg = system.normalizeProgram(prog); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); - DependencyGraph dg = analyzed.getDependencyGraph(); - ComponentGraph cg = ComponentGraph.buildComponentGraph(dg, StronglyConnectedComponentsAlgorithm.findStronglyConnectedComponents(dg)); - List strata = StratificationAlgorithm.calculateStratification(cg); - - Predicate a = Predicate.getInstance("a", 0); - Predicate b = Predicate.getInstance("b", 0); - Predicate c = Predicate.getInstance("c", 0); - - assertTrue(predicateIsBeforePredicateInOrder(a, b, strata)); - assertTrue(predicateIsBeforePredicateInOrder(b, c, strata)); - assertTrue(predicateIsBeforePredicateInOrder(a, c, strata)); - - assertEquals(3, strata.size()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/FixedInterpretationLiteralsTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/FixedInterpretationLiteralsTest.java deleted file mode 100644 index 39c7827ee..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/fixedinterpretations/FixedInterpretationLiteralsTest.java +++ /dev/null @@ -1,191 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.fixedinterpretations; - -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 org.junit.Assert; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.api.externals.Externals; -import at.ac.tuwien.kr.alpha.api.externals.stdlib.AspStandardLibrary; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; - -public class FixedInterpretationLiteralsTest { - - @at.ac.tuwien.kr.alpha.api.externals.Predicate - public static boolean isOne(int value) { - return value == 1; - } - - /** - * Dummy method to test external atoms with more than one output term list. - * Dummy input param which is not used exists solely to avoid producing an edge - * case where there is output, but no input - */ - @at.ac.tuwien.kr.alpha.api.externals.Predicate - public static Set>> connection(String dummy) { - Set>> retVal = new HashSet<>(); - List> l1 = new ArrayList<>(); - List> l2 = new ArrayList<>(); - List> l3 = new ArrayList<>(); - l1.add(ConstantTerm.getInstance("Klagenfurt")); - l1.add(ConstantTerm.getInstance("Villach")); - l2.add(ConstantTerm.getInstance("Klagenfurt")); - l2.add(ConstantTerm.getInstance("Graz")); - l3.add(ConstantTerm.getInstance("Villach")); - l3.add(ConstantTerm.getInstance("Salzburg")); - retVal.add(l1); - retVal.add(l2); - retVal.add(l3); - return retVal; - } - - private static final String TEST_PROG = "positive_numeric_comparison :- 2 < 3." - + "negative_numeric_comparison :- not 3 < 2." - + "positive_unary_external :- &isOne[1]." - + "negative_unary_external :- not &isOne[2]." - + "positive_external_with_output :- " - + "&stdlib_datetime_parse[\"01.01.2121 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S), Y = 2121, MO = 1, D = 1, H = 21, MI = 11, S = 12." - + "positive_external_with_output_dontfire :- " - + "&stdlib_datetime_parse[\"01.01.2121 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S), Y = 2345, MO = 1, D = 1, H = 21, MI = 11, S = 12." - + "negative_external_with_output :- Y = 2121, MO = 1, D = 1, H = 21, MI = 11, S = 12, " - + "not &stdlib_datetime_parse[\"22.02.2222 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S)." - + "negative_external_with_output_dontfire :- Y = 2222, MO = 2, D = 22, H = 21, MI = 11, S = 12," - + "not &stdlib_datetime_parse[\"22.02.2222 21:11:12\", \"dd.MM.yyyy HH:mm:ss\"](Y, MO, D, H, MI, S)." - + "negative_external_multioutput :- START = \"Graz\", END = \"Salzburg\", not &connection[train_network](START, END)." - + "negative_external_multioutput_dontfire :- START = \"Klagenfurt\", END = \"Villach\", not &connection[train_network](START, END)." - + "positive_external_multioutput :- START = \"Klagenfurt\", END = \"Villach\", &connection[train_network](START, END)." - + "positive_external_multioutput_dontfire :- START = \"Graz\", END = \"Salzburg\", &connection[train_network](START, END)." - + "positive_external_binding_output(START, END) :- &connection[train_network](START, END)."; - - private Alpha alpha; - private Map externals; - - public FixedInterpretationLiteralsTest() { - this.alpha = new Alpha(); - this.externals = new HashMap<>(); - this.externals.putAll(Externals.scan(AspStandardLibrary.class)); - this.externals.putAll(Externals.scan(FixedInterpretationLiteralsTest.class)); - } - - @Test - public void positiveNumericComparison() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("positive_numeric_comparison", 0))); - } - - @Test - public void negativeNumericComparison() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("negative_numeric_comparison", 0))); - } - - @Test - public void positiveUnaryExternal() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("positive_unary_external", 0))); - } - - @Test - public void negativeUnaryExternal() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("negative_unary_external", 0))); - } - - @Test - public void positiveExternalWithOutput() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("positive_external_with_output", 0))); - } - - @Test - public void positiveExternalWithOutputDontfire() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertFalse(answerSet.getPredicates().contains(Predicate.getInstance("positive_external_with_output_dontfire", 0))); - } - - @Test - public void negativeExternalWithOutput() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("negative_external_with_output", 0))); - } - - @Test - public void negativeExternalWithOutputDontfire() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertFalse(answerSet.getPredicates().contains(Predicate.getInstance("negative_external_with_output_dontfire", 0))); - } - - @Test - public void negativeExternalMultioutput() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("negative_external_multioutput", 0))); - } - - @Test - public void negativeExternalMultioutputDontfire() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertFalse(answerSet.getPredicates().contains(Predicate.getInstance("negative_external_multioutput_dontfire", 0))); - } - - @Test - public void positiveExternalMultioutput() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertTrue(answerSet.getPredicates().contains(Predicate.getInstance("positive_external_multioutput", 0))); - } - - @Test - public void positiveExternalMultioutputDontfire() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Assert.assertFalse(answerSet.getPredicates().contains(Predicate.getInstance("positive_external_multioutput_dontfire", 0))); - } - - @Test - public void positiveExternalBindingOutput() { - Optional answer = this.alpha.solve(this.alpha.readProgramString(TEST_PROG, this.externals)).findFirst(); - Assert.assertTrue(answer.isPresent()); - AnswerSet answerSet = answer.get(); - Predicate pred = Predicate.getInstance("positive_external_binding_output", 2); - Assert.assertTrue(answerSet.getPredicates().contains(pred)); - Set instances = answerSet.getPredicateInstances(pred); - Assert.assertEquals(3, instances.size()); - Assert.assertTrue(instances.contains(new BasicAtom(pred, ConstantTerm.getInstance("Klagenfurt"), ConstantTerm.getInstance("Villach")))); - Assert.assertTrue(instances.contains(new BasicAtom(pred, ConstantTerm.getInstance("Klagenfurt"), ConstantTerm.getInstance("Graz")))); - Assert.assertTrue(instances.contains(new BasicAtom(pred, ConstantTerm.getInstance("Villach"), ConstantTerm.getInstance("Salzburg")))); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriterTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriterTest.java deleted file mode 100644 index b1c3a6d59..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/graphio/ComponentGraphWriterTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.graphio; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.depgraph.ComponentGraph; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayOutputStream; - -public class ComponentGraphWriterTest { - private static final String LS = System.lineSeparator(); - - @Test - public void smokeTest() { - // Note: rather than testing correct implementation of dot file format, - // (which would be a lot of work), just test correct dot code generation - // for one component graph that has all possible "special" node constellations, - // i.e. positive and negative dependencies, cycle through negation, constraints. - String asp = "p(X) :- q(X), r(X)." + LS + - "s(X) :- p(X), q(X), not r(X)." + LS + - "t(X) :- p(X), not u(X)." + LS + - "u(X) :- p(X), not t(X)." + LS + - ":- p(X), not q(X), not r(X)."; - String expectedGraph = "digraph componentGraph" + LS + - "{" + LS + - "splines=false;" + LS + - "ranksep=4.0;" + LS + - "label = <" + LS + - " " + LS + - " " + LS + - " " + LS - + - "
      Component Id012345
      Predicatesq/1
      r/1
      p/1
      [constr_1]/0
      t/1
      u/1
      s/1
      " + LS + - ">" + LS + - "" + LS + - "n0 [label = C0]" + LS + - "n1 [label = C1]" + LS + - "n2 [label = C2]" + LS + - "n0 -> n2 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n1 -> n2 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n3 [label = C3]" + LS + - "n0 -> n3 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n1 -> n3 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n2 -> n3 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n4 [label = C4]" + LS + - "n2 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n5 [label = C5]" + LS + - "n0 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n2 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + - "}" + LS; - Alpha alpha = new Alpha(); - AnalyzedProgram prog = AnalyzedProgram.analyzeNormalProgram( - alpha.normalizeProgram(alpha.readProgramString(asp))); - ComponentGraph compgraph = prog.getComponentGraph(); - ComponentGraphWriter writer = new ComponentGraphWriter(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - writer.writeAsDot(compgraph, out); - String actualGraph = out.toString(); - System.out.println(actualGraph); - Assert.assertEquals(expectedGraph, actualGraph); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriterTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriterTest.java deleted file mode 100644 index 9ae48a3d3..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/graphio/DependencyGraphWriterTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.graphio; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayOutputStream; - -public class DependencyGraphWriterTest { - private static final String LS = System.lineSeparator(); - - @Test - public void smokeTest() { - // Note: rather than testing correct implementation of dot file format, - // (which would be a lot of work), just test correct dot code generation - // for one dependency graph that has all possible "special" node constellations, - // i.e. positive and negative dependencies, cycle through negation, constraints. - String asp = "p(X) :- q(X), r(X)." + LS + - "s(X) :- p(X), q(X), not r(X)." + LS + - "t(X) :- p(X), not u(X)." + LS + - "u(X) :- p(X), not t(X)." + LS + - ":- p(X), not q(X), not r(X)."; - String expectedGraph = "digraph dependencyGraph" + LS + - "{" + LS + - "splines=false;" + LS + - "ranksep=4.0;" + LS + - "n0 [label = \"r/1\"]" + LS + - "n1 [label = \"q/1\"]" + LS + - "n2 [label = \"t/1\"]" + LS + - "n3 [label = \"s/1\"]" + LS + - "n4 [label = \"u/1\"]" + LS + - "n5 [label = \"[constr_1]/0\"]" + LS + - "n6 [label = \"p/1\"]" + LS + - "n0 -> n6 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n0 -> n3 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n0 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n1 -> n6 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n1 -> n3 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n2 -> n4 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n4 -> n2 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n5 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + - "n6 -> n3 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n6 -> n2 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n6 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + - "n6 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + - "}" + LS; - Alpha alpha = new Alpha(); - AnalyzedProgram prog = AnalyzedProgram.analyzeNormalProgram( - alpha.normalizeProgram(alpha.readProgramString(asp))); - DependencyGraph depgraph = prog.getDependencyGraph(); - DependencyGraphWriter writer = new DependencyGraphWriter(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - writer.writeAsDot(depgraph, out); - String actualGraph = out.toString(); - Assert.assertEquals(expectedGraph, actualGraph); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java b/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java deleted file mode 100644 index c67ed0459..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; - -public class TermsTest { - - @Test - public void integersAsTermList() { - List> intTerms = Terms.asTermList(1, 2, 3, 4, 5, 6); - Assert.assertEquals(6, intTerms.size()); - Assert.assertEquals(ConstantTerm.getInstance(1), intTerms.get(0)); - Assert.assertEquals(ConstantTerm.getInstance(2), intTerms.get(1)); - Assert.assertEquals(ConstantTerm.getInstance(3), intTerms.get(2)); - Assert.assertEquals(ConstantTerm.getInstance(4), intTerms.get(3)); - Assert.assertEquals(ConstantTerm.getInstance(5), intTerms.get(4)); - Assert.assertEquals(ConstantTerm.getInstance(6), intTerms.get(5)); - } - - @Test - public void stringsAsTermList() { - List> terms = Terms.asTermList("bla", "blubb"); - Assert.assertEquals(2, terms.size()); - Assert.assertEquals("\"bla\"", terms.get(0).toString()); - Assert.assertEquals("\"blubb\"", terms.get(1).toString()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java b/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java deleted file mode 100644 index 425ae9423..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2019 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.common.terms; - -import at.ac.tuwien.kr.alpha.common.terms.ArithmeticTerm.MinusTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term.RenameCounter; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * Tests {@link MinusTerm} - */ -public class TestMinusTerm { - - private final String renamePrefix = "Renamed"; - private final RenameCounter counter = new RenameCounter(0); - - @Test - public void testNormalizeVariablesNoVariable() { - Term m2 = MinusTerm.getInstance(ConstantTerm.getInstance(2)); - assertEquals(m2, m2.normalizeVariables(renamePrefix, counter)); - } - - @Test - public void testNormalizeVariablesWithVariable() { - Term mX = MinusTerm.getInstance(VariableTerm.getInstance("X")); - Term expected = MinusTerm.getInstance(VariableTerm.getInstance(renamePrefix + 0)); - assertEquals(expected, mX.normalizeVariables(renamePrefix, counter)); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/config/CommandLineParserTest.java b/src/test/java/at/ac/tuwien/kr/alpha/config/CommandLineParserTest.java deleted file mode 100644 index dac73ea93..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/config/CommandLineParserTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Copyright (c) 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.config; - -import org.apache.commons.cli.ParseException; -import org.junit.Assert; -import org.junit.Test; - -import java.util.Arrays; -import java.util.function.Consumer; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class CommandLineParserTest { - - private static final String DEFAULT_COMMAND_LINE = "java -jar Alpha-bundled.jar"; - private static final Consumer DEFAULT_ABORT_ACTION = (msg) -> { }; - - /** - * Tests that a help message is written to the consumer configured in the - * parser. - * - * @throws ParseException shouldn't happen - */ - @Test - public void help() throws ParseException { - StringBuilder bld = new StringBuilder(); - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, (msg) -> bld.append(msg)); - parser.parseCommandLine(new String[] {"-h"}); - assertTrue(!(bld.toString().isEmpty())); - } - - @Test - public void basicUsageWithFile() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig ctx = parser.parseCommandLine(new String[] {"-i", "someFile.asp", "-i", "someOtherFile.asp"}); - assertEquals(Arrays.asList(new String[] {"someFile.asp", "someOtherFile.asp"}), ctx.getInputConfig().getFiles()); - } - - @Test - public void basicUsageWithString() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig ctx = parser.parseCommandLine(new String[] {"-str", "b :- a.", "-str", "c :- a, b."}); - assertEquals(Arrays.asList(new String[] {"b :- a.", "c :- a, b."}), ctx.getInputConfig().getAspStrings()); - } - - @Test(expected = ParseException.class) - public void invalidUsageNoInput() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - parser.parseCommandLine(new String[] {}); - } - - @Test - public void moreThanOneInputSource() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - parser.parseCommandLine(new String[] {"-i", "a.b", "-i", "b.c", "-str", "aString."}); - } - - @Test(expected = ParseException.class) - public void invalidUsageMissingInputFlag() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - parser.parseCommandLine(new String[] {"-i", "a.b", "b.c"}); - } - - @Test - public void numAnswerSets() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig ctx = parser.parseCommandLine(new String[] {"-str", "aString.", "-n", "00435"}); - assertEquals(435, ctx.getInputConfig().getNumAnswerSets()); - } - - @Test(expected = ParseException.class) - public void noInputGiven() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - parser.parseCommandLine(new String[] {}); - } - - @Test - public void replay() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-rc", "\"1,2, 3\""}); - assertEquals(Arrays.asList(1, 2, 3), alphaConfig.getSystemConfig().getReplayChoices()); - } - - @Test(expected = ParseException.class) - public void replayWithNonNumericLiteral() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - parser.parseCommandLine(new String[]{"-str", "aString.", "-rc", "\"1, 2, x\""}); - } - - @Test - public void grounderToleranceConstraints_numeric() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtc", "-1"}); - assertEquals("-1", alphaConfig.getSystemConfig().getGrounderToleranceConstraints()); - } - - @Test - public void grounderToleranceConstraints_string() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtc", "strict"}); - assertEquals("strict", alphaConfig.getSystemConfig().getGrounderToleranceConstraints()); - } - - @Test - public void grounderToleranceRules_numeric() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtr", "1"}); - assertEquals("1", alphaConfig.getSystemConfig().getGrounderToleranceRules()); - } - - @Test - public void grounderToleranceRules_string() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtr", "permissive"}); - assertEquals("permissive", alphaConfig.getSystemConfig().getGrounderToleranceRules()); - } - - @Test - public void noInstanceRemoval() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-acc"}); - 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"}); - Assert.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"}); - Assert.assertFalse(ctx.getSystemConfig().isEvaluateStratifiedPart()); - } - - @Test - public void atomSeparator() throws ParseException { - CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION); - AlphaConfig cfg = parser.parseCommandLine(new String[]{"-str", "aString.", "-sep", "some-string"}); - assertEquals("some-string", cfg.getSystemConfig().getAtomSeparator()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/ChoiceGrounder.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/ChoiceGrounder.java deleted file mode 100644 index e090fec20..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/ChoiceGrounder.java +++ /dev/null @@ -1,210 +0,0 @@ -/** - * 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 - * 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.grounder; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.stream.Stream; - -import static at.ac.tuwien.kr.alpha.Util.entriesToMap; -import static at.ac.tuwien.kr.alpha.Util.entry; -import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static java.util.Arrays.asList; -import static java.util.Collections.singleton; - -/** - * Represents a small ASP program with choices {@code { aa :- not bb. bb :- not aa. }}. - */ -public class ChoiceGrounder implements Grounder { - public static final Set EXPECTED = new HashSet<>(asList( - new AnswerSetBuilder() - .predicate("aa") - .build(), - new AnswerSetBuilder() - .predicate("bb") - .build() - )); - - private static final int ATOM_AA = 1; - private static final int ATOM_BB = 2; - private static final int ATOM_BR1 = 3; - private static final int ATOM_BR2 = 4; - private static final int ATOM_EN_BR1 = 5; - private static final int ATOM_EN_BR2 = 6; - private static final int ATOM_DIS_BR1 = 7; - private static final int ATOM_DIS_BR2 = 8; - private static final int RULE_AA = 11; // { -aa, _br1 } - private static final int BRULE_AA = 12; // { -_br1, -bb } - private static final int RULE_BB = 13; // { -bb, _br2 } - 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_BR2 = 18; // { -dis_br2, aa } - private static final Map NOGOODS = Stream.of( - entry(RULE_AA, headFirst(fromOldLiterals(-ATOM_AA, ATOM_BR1))), - entry(BRULE_AA, headFirst(fromOldLiterals(-ATOM_BR1, -ATOM_BB))), - entry(RULE_BB, headFirst(fromOldLiterals(-ATOM_BB, ATOM_BR2))), - entry(BRULE_BB, headFirst(fromOldLiterals(-ATOM_BR2, -ATOM_AA))), - 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()); - private static final Map CHOICE_ENABLE = Stream.of( - entry(ATOM_BR1, ATOM_EN_BR1), - 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()); - private static Atom atomAA = new BasicAtom(Predicate.getInstance("aa", 0)); - private static Atom atomBB = new BasicAtom(Predicate.getInstance("bb", 0)); - private static BasicRule ruleAA = new BasicRule(new NormalHead(atomAA), Collections.singletonList(new BasicAtom(Predicate.getInstance("bb", 0)).toLiteral(false))); - private static BasicRule ruleBB = new BasicRule(new NormalHead(atomBB), Collections.singletonList(new BasicAtom(Predicate.getInstance("aa", 0)).toLiteral(false))); - private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(NormalRule.fromBasicRule(ruleAA)), new Substitution()); - private static Atom rule2 = new RuleAtom(InternalRule.fromNormalRule(NormalRule.fromBasicRule(ruleBB)), new Substitution()); - private static Atom atomEnBR1 = ChoiceAtom.on(1); - private static Atom atomEnBR2 = ChoiceAtom.on(2); - private static Atom atomDisBR1 = ChoiceAtom.off(3); - private static Atom atomDisBR2 = ChoiceAtom.off(4); - private final AtomStore atomStore; - private boolean returnedAllNogoods; - - private final java.util.function.Predicate filter; - - public ChoiceGrounder(AtomStore atomStore) { - this(atomStore, p -> true); - } - - public ChoiceGrounder(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); - } - - @Override - public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { - SortedSet trueAtomPredicates = new TreeSet<>(); - for (int trueAtom : trueAtoms) { - Predicate atomPredicate = atomStore.get(trueAtom).getPredicate(); - if (!filter.test(atomPredicate)) { - continue; - } - if (atomPredicate.isInternal()) { - continue; - } - trueAtomPredicates.add(atomPredicate); - } - - // Add the atom instances - Map> predicateInstances = new HashMap<>(); - for (Predicate trueAtomPredicate : trueAtomPredicates) { - BasicAtom basicAtom = new BasicAtom(trueAtomPredicate); - 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. - return new BasicAnswerSet(trueAtomPredicates, predicateInstances); - } - - @Override - public Map getNoGoods(Assignment assignment) { - if (!returnedAllNogoods) { - returnedAllNogoods = true; - return NOGOODS; - } else { - return new HashMap<>(); - } - } - - private boolean isFirst = true; - - @Override - public Pair, Map> getChoiceAtoms() { - if (isFirst) { - isFirst = false; - return new ImmutablePair<>(CHOICE_ENABLE, CHOICE_DISABLE); - } else { - return new ImmutablePair<>(new HashMap<>(), new HashMap<>()); - } - } - - @Override - public Map> getHeadsToBodies() { - return Collections.emptyMap(); - } - - @Override - public void updateAssignment(IntIterator it) { - // This test grounder reports all NoGoods immediately, irrespective of any assignment. - } - - @Override - public void forgetAssignment(int[] atomIds) { - } - - private int solverDerivedNoGoodIdCounter = 20; - private Map solverDerivedNoGoods = new HashMap<>(); - - @Override - public int register(NoGood noGood) { - if (!solverDerivedNoGoods.containsKey(noGood)) { - solverDerivedNoGoods.put(noGood, solverDerivedNoGoodIdCounter++); - } - return solverDerivedNoGoods.get(noGood); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/DummyGrounder.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/DummyGrounder.java deleted file mode 100644 index 4ab84e0b2..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/DummyGrounder.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * 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 - * 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.grounder; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.BasicAnswerSet; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.stream.Stream; - -import static at.ac.tuwien.kr.alpha.Util.entriesToMap; -import static at.ac.tuwien.kr.alpha.Util.entry; -import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; - -/** - * Represents a small ASP program {@code { c :- a, b. a. b. }}. - * - * Copyright (c) 2016, the Alpha Team. - */ -public class DummyGrounder implements Grounder { - public static final Set EXPECTED = new HashSet<>(singletonList(new AnswerSetBuilder() - .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))) - ).collect(entriesToMap()); - private final AtomStore atomStore; - private final java.util.function.Predicate filter; - private byte[] currentTruthValues = new byte[]{-2, -1, -1, -1, -1}; - private static Atom atomAA = new BasicAtom(Predicate.getInstance("a", 0)); - private static Atom atomBB = new BasicAtom(Predicate.getInstance("b", 0)); - private static Atom atomCC = new BasicAtom(Predicate.getInstance("c", 0)); - private static BasicRule ruleABC = new BasicRule(new NormalHead(atomCC), Arrays.asList(atomAA.toLiteral(), atomBB.toLiteral())); - private static Atom rule1 = new RuleAtom(InternalRule.fromNormalRule(NormalRule.fromBasicRule(ruleABC)), new Substitution()); - private Set returnedNogoods = new HashSet<>(); - - public DummyGrounder(AtomStore atomStore) { - this(atomStore, p -> true); - } - - public DummyGrounder(AtomStore atomStore, java.util.function.Predicate filter) { - this.atomStore = atomStore; - this.filter = filter; - Arrays.asList(atomAA, atomBB, rule1, atomCC).forEach(atomStore::putIfAbsent); - } - - @Override - public void forgetAssignment(int[] atomIds) { - for (int atomId : atomIds) { - currentTruthValues[atomId] = -1; - } - } - - private int solverDerivedNoGoodIdCounter = 20; - private Map solverDerivedNoGoods = new HashMap<>(); - - @Override - public int register(NoGood noGood) { - if (!solverDerivedNoGoods.containsKey(noGood)) { - solverDerivedNoGoods.put(noGood, solverDerivedNoGoodIdCounter++); - } - return solverDerivedNoGoods.get(noGood); - } - - @Override - public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { - // 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. - - SortedSet trueAtomPredicates = new TreeSet<>(); - for (int trueAtom : trueAtoms) { - Predicate atomPredicate = atomStore.get(trueAtom).getPredicate(); - if (!filter.test(atomPredicate)) { - continue; - } - if (atomPredicate.isInternal()) { - continue; - } - trueAtomPredicates.add(atomPredicate); - } - - // Add the atom instances - Map> predicateInstances = new HashMap<>(); - for (Predicate trueAtomPredicate : trueAtomPredicates) { - BasicAtom internalBasicAtom = new BasicAtom(trueAtomPredicate); - predicateInstances.put(trueAtomPredicate, new TreeSet<>(singleton(internalBasicAtom))); - } - - return new BasicAnswerSet(trueAtomPredicates, predicateInstances); - } - - @Override - public Map getNoGoods(Assignment assignment) { - // Return NoGoods depending on current assignment. - HashMap returnNoGoods = new HashMap<>(); - if (currentTruthValues[1] == 1 && currentTruthValues[2] == 1) { - addNoGoodIfNotAlreadyReturned(returnNoGoods, RULE_B); - addNoGoodIfNotAlreadyReturned(returnNoGoods, RULE_H); - } else { - addNoGoodIfNotAlreadyReturned(returnNoGoods, FACT_A); - addNoGoodIfNotAlreadyReturned(returnNoGoods, FACT_B); - } - return returnNoGoods; - } - - @Override - public Pair, Map> getChoiceAtoms() { - return new ImmutablePair<>(new HashMap<>(), new HashMap<>()); - } - - @Override - public Map> getHeadsToBodies() { - return Collections.emptyMap(); - } - - @Override - public void updateAssignment(IntIterator it) { - while (it.hasNext()) { - currentTruthValues[it.next()] = 1; - } - } - - private void addNoGoodIfNotAlreadyReturned(Map integerNoGoodMap, Integer idNoGood) { - if (!returnedNogoods.contains(idNoGood)) { - integerNoGoodMap.put(idNoGood, NOGOODS.get(idNoGood)); - returnedNogoods.add(idNoGood); - } - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorageTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorageTest.java deleted file mode 100644 index 9a05b4e66..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/IndexedInstanceStorageTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.grounder; - -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import org.junit.Test; - -import java.util.List; - -import static org.junit.Assert.*; - -/** - * Copyright (c) 2016, the Alpha Team. - */ -public class IndexedInstanceStorageTest { - @Test - public void testIndexedInstanceStorage() { - IndexedInstanceStorage storage = new IndexedInstanceStorage(Predicate.getInstance("p", 4), true); - storage.addIndexPosition(0); - storage.addIndexPosition(2); - ConstantTerm t0 = ConstantTerm.getInstance("0"); - ConstantTerm t1 = ConstantTerm.getInstance("1"); - ConstantTerm t2 = ConstantTerm.getInstance("2"); - ConstantTerm t3 = ConstantTerm.getInstance("3"); - ConstantTerm t4 = ConstantTerm.getInstance("4"); - ConstantTerm t5 = ConstantTerm.getInstance("5"); - - Instance badInst1 = new Instance(t1, t1, t0); - Instance badInst2 = new Instance(t5, t5, t5, t5, t5); - - try { - storage.addInstance(badInst1); - fail(); - } catch (Exception e) { - assertTrue(e.getMessage().startsWith("Instance length does not match arity of IndexedInstanceStorage")); - } - - try { - storage.addInstance(badInst2); - fail(); - } catch (Exception e) { - assertTrue(e.getMessage().startsWith("Instance length does not match arity of IndexedInstanceStorage")); - } - - Instance inst1 = new Instance(t1, t1, t1, t1); - Instance inst2 = new Instance(t1, t2, t3, t4); - Instance inst3 = new Instance(t4, t3, t3, t5); - Instance inst4 = new Instance(t1, t2, t1, t1); - Instance inst5 = new Instance(t5, t4, t3, t2); - - storage.addInstance(inst1); - storage.addInstance(inst2); - storage.addInstance(inst3); - storage.addInstance(inst4); - storage.addInstance(inst5); - - List matching3 = storage.getInstancesMatchingAtPosition(t3, 2); - assertEquals(matching3.size(), 3); - assertTrue(matching3.contains(new Instance(t1, t2, t3, t4))); - assertTrue(matching3.contains(new Instance(t4, t3, t3, t5))); - assertTrue(matching3.contains(new Instance(t5, t4, t3, t2))); - assertFalse(matching3.contains(new Instance(t1, t1, t1, t1))); - - List matching1 = storage.getInstancesMatchingAtPosition(t2, 0); - assertEquals(matching1.size(), 0); - } - -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounderTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounderTest.java deleted file mode 100644 index a6c649193..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounderTest.java +++ /dev/null @@ -1,447 +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.grounder; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.instantiation.BindingResult; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static at.ac.tuwien.kr.alpha.TestUtil.atom; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * 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 ProgramParser(); - private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); - - 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)"); - - @Before - 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() { - Alpha system = new Alpha(); - InputProgram program = PROGRAM_PARSER.parse("a :- not b. " - + "b :- not a. " - + "c :- b."); - NormalProgram normal = system.normalizeProgram(program); - InternalProgram prog = system.performProgramPreprocessing(InternalProgram.fromNormalProgram(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() { - Alpha system = new Alpha(); - InputProgram program = PROGRAM_PARSER.parse("a :- not b. " - + "b :- not a. " - + "c :- b. " - + "d :- b, c. "); - NormalProgram normal = system.normalizeProgram(program); - InternalProgram prog = system.performProgramPreprocessing(InternalProgram.fromNormalProgram(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() { - Alpha system = new Alpha(); - InputProgram program = PROGRAM_PARSER.parse("a :- not b. " - + "b :- not a. " - + ":- b."); - NormalProgram normal = system.normalizeProgram(program); - InternalProgram prog = system.performProgramPreprocessing(InternalProgram.fromNormalProgram(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() { - RuleGroundingOrder groundingOrderP1 = new RuleGroundingOrder(litP1X, - Arrays.asList(litP2X, litQ2Y, litQ1Y), -1, false); - testDeadEnd("p1", groundingOrderP1, true); - } - - @Test - public void avoidDeadEndsWithPermissiveGrounderHeuristicForQ1() { - RuleGroundingOrder groundingOrderQ1 = new RuleGroundingOrder(litQ1Y, - Arrays.asList(litQ2Y, litP2X, litP1X), -1, false); - testDeadEnd("q1", groundingOrderQ1, true); - } - - @Test - public void noDeadEndWithPermissiveGrounderHeuristicForP1() { - RuleGroundingOrder groundingOrderP1 = new RuleGroundingOrder(litP1X, - Arrays.asList(litP2X, litQ1Y, litQ2Y), -1, false); - testDeadEnd("p1", groundingOrderP1, true); - } - - @Test - public void noDeadEndWithPermissiveGrounderHeuristicForQ1() { - RuleGroundingOrder groundingOrderQ1 = new RuleGroundingOrder(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, RuleGroundingOrder 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). "; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram program = InternalProgram.fromNormalProgram( - system.normalizeProgram( - system.readProgramString(aspStr) - ) - ); - - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", program, atomStore, p -> true, GrounderHeuristicsConfiguration.permissive(), true); - - InternalRule nonGroundRule = grounder.getNonGroundRule(0); - String strLiteral = "p1".equals(predicateNameOfStartingLiteral) ? "p1(X)" : "p1(Y)"; - final Literal startingLiteral = PROGRAM_PART_PARSER.parseLiteral(strLiteral); - nonGroundRule.getGroundingOrders().groundingOrders.put(startingLiteral, groundingOrder); - - grounder.bootstrap(); - TrailAssignment currentAssignment = new TrailAssignment(atomStore); - final Substitution subst1 = Substitution.specializeSubstitution(startingLiteral, new Instance(ConstantTerm.getInstance(1)), Substitution.EMPTY_SUBSTITUTION); - final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, groundingOrder, subst1, currentAssignment); - - assertEquals(expectNoGoods, bindingResult.size() > 0); - } - - @Test - public void testGroundingOfRuleSwitchedOffByFalsePositiveBody() { - 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); - } - - @Test - public void testGroundingOfRuleNotSwitchedOffByTruePositiveBody() { - 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); - } - - @Test - @Ignore("Currently, rule grounding is not switched off by a true negative body atom") - public void testGroundingOfRuleSwitchedOffByTrueNegativeBody() { - 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); - } - - @Test - public void testGroundingOfRuleNotSwitchedOffByFalseNegativeBody() { - InputProgram 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(InputProgram program, int ruleID, Literal startingLiteral, int startingInstance, ThriceTruth bTruth, boolean expectNoGoods) { - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(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 InternalRule nonGroundRule = grounder.getNonGroundRule(ruleID); - final Substitution substStartingLiteral = Substitution.specializeSubstitution(startingLiteral, new Instance(ConstantTerm.getInstance(startingInstance)), Substitution.EMPTY_SUBSTITUTION); - final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingOrders().groundingOrders.get(startingLiteral), substStartingLiteral, currentAssignment); - assertEquals(expectNoGoods, bindingResult.size() > 0); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_0_reject() { - 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)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_accept() { - 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)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_reject() { - 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)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_2_accept() { - 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)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_accept_two_substitutions() { - 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[] {TRUE, TRUE}, 2, true, Arrays.asList(0, 0)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_1_accept_accept_two_substitutions_with_different_remaining_tolerances() { - 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)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_2_reject() { - 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)); - } - - @Test - public void testPermissiveGrounderHeuristicTolerance_2_accept_multiple_facts_of_same_variable() { - 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(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); - } - - /** - * 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(InputProgram program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, ThriceTruth[] truthsOfB, int arityOfB, boolean expectNoGoods, List expectedNumbersOfUnassignedPositiveBodyAtoms) { - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(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 InternalRule nonGroundRule = grounder.getNonGroundRule(ruleID); - final Substitution substStartingLiteral = Substitution.specializeSubstitution(startingLiteral, new Instance(ConstantTerm.getInstance(startingInstance)), Substitution.EMPTY_SUBSTITUTION); - final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingOrders().groundingOrders.get(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, 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/src/test/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGeneratorTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGeneratorTest.java deleted file mode 100644 index bc147d1aa..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/NoGoodGeneratorTest.java +++ /dev/null @@ -1,84 +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.grounder; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import org.junit.Test; - -import java.util.List; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static org.junit.Assert.assertEquals; - -/** - * Tests {@link NoGoodGenerator} - */ -public class NoGoodGeneratorTest { - - private static final ProgramParser PARSER = new ProgramParser(); - - private static final ConstantTerm A = ConstantTerm.getSymbolicInstance("a"); - private static final ConstantTerm B = ConstantTerm.getSymbolicInstance("b"); - - private static final VariableTerm X = VariableTerm.getInstance("X"); - private static final VariableTerm Y = VariableTerm.getInstance("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() { - Alpha system = new Alpha(); - InputProgram input = PARSER.parse("p(a,b). " - + "q(a,b) :- not nq(a,b). " - + "nq(a,b) :- not q(a,b)."); - NormalProgram normal = system.normalizeProgram(input); - InternalProgram program = InternalProgram.fromNormalProgram(normal); - - InternalRule 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 Substitution(); - substitution.put(X, A); - substitution.put(Y, B); - List collectedNeg = noGoodGenerator.collectNegLiterals(rule, substitution); - assertEquals(1, collectedNeg.size()); - String negAtomString = atomStore.atomToString(atomOf(collectedNeg.get(0))); - assertEquals("q(a, b)", negAtomString); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/ProgramTransformationTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/ProgramTransformationTest.java deleted file mode 100644 index 4b4397331..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/ProgramTransformationTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.function.Function; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.program.AbstractProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.grounder.transformation.ChoiceHeadToNormal; -import at.ac.tuwien.kr.alpha.grounder.transformation.IntervalTermToIntervalAtom; -import at.ac.tuwien.kr.alpha.grounder.transformation.ProgramTransformation; - -public class ProgramTransformationTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ProgramTransformationTest.class); - - private static final String TESTFILES_PATH = "/transform-test/"; - - private Alpha alpha = new Alpha(); - - private ChoiceHeadToNormal choiceToNormal = new ChoiceHeadToNormal(); - private IntervalTermToIntervalAtom intervalRewriting = new IntervalTermToIntervalAtom(); - - private static String readTestResource(String resource) throws IOException { - InputStream is = ProgramTransformationTest.class.getResourceAsStream(TESTFILES_PATH + resource); - BufferedReader br = new BufferedReader(new InputStreamReader(is)); - StringBuilder bld = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) { - bld.append(line).append(System.lineSeparator()); - } - br.close(); - return bld.toString(); - } - - private , O extends AbstractProgram> void genericTransformationTest(ProgramTransformation transform, - Function prepareFunc, String resourceSet) { - try { - String inputCode = ProgramTransformationTest.readTestResource(resourceSet + ".in"); - String expectedResult = ProgramTransformationTest.readTestResource(resourceSet + ".out"); - InputProgram inputProg = this.alpha.readProgramString(inputCode); - I transformInput = prepareFunc.apply(inputProg); - String beforeTransformProg = transformInput.toString(); - O transformedProg = transform.apply(transformInput); - Assert.assertEquals("Transformation result doesn't match expected result", expectedResult, transformedProg.toString()); - Assert.assertEquals("Transformation modified source program (breaks immutability!)", beforeTransformProg, transformInput.toString()); - } catch (Exception ex) { - LOGGER.error("Exception in test, nested exception: " + ex.getMessage(), ex); - throw new RuntimeException(ex); - } - } - - @Test - public void choiceHeadToNormalSimpleTest() { - this.genericTransformationTest(this.choiceToNormal, Function.identity(), "choice-to-normal.1"); - } - - @Test - public void intervalTermToIntervalAtomSimpleTest() { - this.genericTransformationTest(this.intervalRewriting, NormalProgram::fromInputProgram, "interval.1"); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrderTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrderTest.java deleted file mode 100644 index 0145c216b..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleGroundingOrderTest.java +++ /dev/null @@ -1,161 +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.grounder; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.junit.Test; - -import java.io.IOException; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramPartParser; - -/** - * Copyright (c) 2017-2019, the Alpha Team. - */ -public class RuleGroundingOrderTest { - - private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); - - - @Test - public void groundingOrder() throws IOException { - 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."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - InternalRule rule0 = internalPrg.getRules().get(0); - RuleGroundingOrders rgo0 = new RuleGroundingOrders(rule0); - rgo0.computeGroundingOrders(); - assertEquals(4, rgo0.getStartingLiterals().size()); - - InternalRule rule1 = internalPrg.getRules().get(1); - RuleGroundingOrders rgo1 = new RuleGroundingOrders(rule1); - rgo1.computeGroundingOrders(); - assertEquals(4, rgo1.getStartingLiterals().size()); - - InternalRule rule2 = internalPrg.getRules().get(2); - RuleGroundingOrders rgo2 = new RuleGroundingOrders(rule2); - rgo2.computeGroundingOrders(); - assertTrue(rgo2.fixedInstantiation()); - } - - @Test(expected = RuntimeException.class) - public void groundingOrderUnsafe() throws IOException { - String aspStr = "h(X,C) :- X = Y, Y = C .. 3, C = X."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - computeGroundingOrdersForRule(internalPrg, 0); - } - - @Test - public void testPositionFromWhichAllVarsAreBound_ground() { - String aspStr = "a :- b, not c."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders rgo0 = computeGroundingOrdersForRule(internalPrg, 0); - assertEquals(0, rgo0.getFixedGroundingOrder().getPositionFromWhichAllVarsAreBound()); - } - - @Test - public void testPositionFromWhichAllVarsAreBound_simpleNonGround() { - String aspStr = "a(X) :- b(X), not c(X)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders 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)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders 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)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders 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)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders 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 RuleGroundingOrders computeGroundingOrdersForRule(InternalProgram program, int ruleIndex) { - InternalRule rule = program.getRules().get(ruleIndex); - RuleGroundingOrders rgo = new RuleGroundingOrders(rule); - rgo.computeGroundingOrders(); - return rgo; - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleToStringTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleToStringTest.java deleted file mode 100644 index fa6199f92..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/RuleToStringTest.java +++ /dev/null @@ -1,102 +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.grounder; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Tests {@link BasicRule#toString()} and {@link InternalRule#toString()}. - */ -public class RuleToStringTest { - private final ProgramParser parser = new ProgramParser(); - - @Test - public void positiveRuleToString() { - parseSingleRuleAndCheckToString("a :- b1, b2."); - } - - @Test - public void ruleWithNegativeBodyToString() { - parseSingleRuleAndCheckToString("a :- b1, b2."); - } - - @Test - public void normalRuleToString() { - parseSingleRuleAndCheckToString("a :- b1, b2, not c1, not c2."); - } - - @Test - public void constraintToString() { - parseSingleRuleAndCheckToString(":- b1, b2, not c1, not c2."); - } - - @Test - public void nonGroundPositiveRuleToString() { - constructNonGroundRuleAndCheckToString("a :- b1, b2."); - } - - @Test - public void nonGroundRuleWithNegativeBodyToString() { - constructNonGroundRuleAndCheckToString("a :- b1, b2."); - } - - @Test - public void nonGroundRuleToString() { - constructNonGroundRuleAndCheckToString("a(X) :- b1(X), b2(X), not c1(X), not c2(X)."); - } - - @Test - public void nonGroundConstraintToString() { - constructNonGroundRuleAndCheckToString(":- b1(X), b2(X), not c1(X), not c2(X)."); - } - - private void parseSingleRuleAndCheckToString(String rule) { - BasicRule parsedRule = parseSingleRule(rule); - assertEquals(rule, parsedRule.toString()); - } - - private void constructNonGroundRuleAndCheckToString(String textualRule) { - InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(parseSingleRule(textualRule))); - assertEquals(textualRule, nonGroundRule.toString()); - } - - private BasicRule parseSingleRule(String rule) { - InputProgram program = parser.parse(rule); - List rules = program.getRules(); - assertEquals("Number of rules", 1, rules.size()); - return rules.get(0); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/SubstitutionTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/SubstitutionTest.java deleted file mode 100644 index 3faa81739..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/SubstitutionTest.java +++ /dev/null @@ -1,169 +0,0 @@ -/** - * Copyright (c) 2016-2018, 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.grounder; - -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.test.util.SubstitutionTestUtil; -import org.junit.Test; - -import java.util.Arrays; - -import static org.junit.Assert.assertEquals; - -public class SubstitutionTest { - private static final ProgramParser PARSER = new ProgramParser(); - - private static final ConstantTerm A = ConstantTerm.getSymbolicInstance("a"); - private static final ConstantTerm B = ConstantTerm.getSymbolicInstance("b"); - private static final ConstantTerm C = ConstantTerm.getSymbolicInstance("c"); - - private static final VariableTerm X = VariableTerm.getInstance("X"); - private static final VariableTerm Y = VariableTerm.getInstance("Y"); - private static final BasicAtom PX = new BasicAtom(Predicate.getInstance("p", 1), X); - private static final BasicAtom PY = new BasicAtom(Predicate.getInstance("p", 1), Y); - private static final Instance PA = new Instance(A); - private static final Instance PB = new Instance(B); - - @Test - public void putSimpleBinding() { - Substitution substitution = new Substitution(); - substitution.put(Y, A); - assertEquals(A, substitution.eval(Y)); - } - - @Test - public void specializeTermsSimpleBinding() { - Substitution substitution = Substitution.specializeSubstitution(PY, PA, Substitution.EMPTY_SUBSTITUTION); - assertEquals(A, substitution.eval(Y)); - } - - @Test - public void specializeTermsFunctionTermBinding() { - Substitution substitution = new Substitution(); - substitution.put(Y, A); - - FunctionTerm groundFunctionTerm = FunctionTerm.getInstance("f", B, C); - Instance qfBC = new Instance(groundFunctionTerm); - Term nongroundFunctionTerm = FunctionTerm.getInstance("f", B, X); - BasicAtom qfBX = new BasicAtom(Predicate.getInstance("q", 2), nongroundFunctionTerm); - - Substitution substitution1 = Substitution.specializeSubstitution(qfBX, qfBC, substitution); - - assertEquals(C, substitution1.eval(X)); - assertEquals(A, substitution1.eval(Y)); - } - - @Test - public void substitutePositiveBasicAtom() { - substituteBasicAtomLiteral(false); - } - - @Test - public void substituteNegativeBasicAtom() { - substituteBasicAtomLiteral(true); - } - - @Test - public void groundAndPrintRule() { - BasicRule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); - InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); - Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); - Substitution substitution2 = Substitution.specializeSubstitution(PY, PB, substitution1); - String printedString = SubstitutionTestUtil.groundAndPrintRule(nonGroundRule, substitution2); - assertEquals("x :- p(a, b), not q(a, b).", printedString); - } - - @Test - public void specializeBasicAtom() { - Predicate p = Predicate.getInstance("p", 2); - BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); - Instance instance = new Instance(A, B); - Substitution substitution = Substitution.specializeSubstitution(atom, instance, Substitution.EMPTY_SUBSTITUTION); - BasicAtom substituted = atom.substitute(substitution); - assertEquals(p, substituted.getPredicate()); - assertEquals(A, substituted.getTerms().get(0)); - assertEquals(B, substituted.getTerms().get(1)); - } - - private void substituteBasicAtomLiteral(boolean negated) { - Predicate p = Predicate.getInstance("p", 2); - BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); - Literal literal = new BasicLiteral(atom, !negated); - Substitution substitution = new Substitution(); - substitution.put(X, A); - substitution.put(Y, B); - literal = literal.substitute(substitution); - assertEquals(p, literal.getPredicate()); - assertEquals(A, literal.getTerms().get(0)); - assertEquals(B, literal.getTerms().get(1)); - assertEquals(negated, literal.isNegated()); - } - - @Test - public void groundLiteralToString_PositiveBasicAtom() { - groundLiteralToString(false); - } - - @Test - public void groundLiteralToString_NegativeBasicAtom() { - groundLiteralToString(true); - } - - private void groundLiteralToString(boolean negated) { - Predicate p = Predicate.getInstance("p", 2); - BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); - Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); - Substitution substitution = Substitution.specializeSubstitution(PY, PB, substitution1); - String printedString = SubstitutionTestUtil.groundLiteralToString(atom.toLiteral(!negated), substitution, true); - assertEquals((negated ? "not " : "") + "p(a, b)", printedString); - } - - @Test - public void substitutionFromString() { - BasicRule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); - InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); - Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); - Substitution substitution = Substitution.specializeSubstitution(PY, PB, substitution1); - RuleAtom ruleAtom = new RuleAtom(nonGroundRule, substitution); - String substitutionString = (String) ((ConstantTerm) ruleAtom.getTerms().get(1)).getObject(); - Substitution fromString = Substitution.fromString(substitutionString); - assertEquals(substitution, fromString); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/UnifierTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/UnifierTest.java deleted file mode 100644 index 20bf54d9a..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/UnifierTest.java +++ /dev/null @@ -1,81 +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.grounder; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class UnifierTest extends SubstitutionTest { - - @Test - public void extendUnifier() { - VariableTerm varX = VariableTerm.getInstance("X"); - VariableTerm varY = VariableTerm.getInstance("Y"); - Unifier sub1 = new Unifier(); - sub1.put(varX, varY); - Unifier sub2 = new Unifier(); - sub2.put(varY, ConstantTerm.getInstance("a")); - - sub1.extendWith(sub2); - BasicAtom atom1 = parseAtom("p(X)"); - - Atom atomSubstituted = atom1.substitute(sub1); - assertEquals(ConstantTerm.getInstance("a"), atomSubstituted.getTerms().get(0)); - } - - @Test - public void mergeUnifierIntoLeft() { - VariableTerm varX = VariableTerm.getInstance("X"); - VariableTerm varY = VariableTerm.getInstance("Y"); - VariableTerm varZ = VariableTerm.getInstance("Z"); - Term constA = ConstantTerm.getInstance("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 ProgramParser(); - InputProgram program = programParser.parse(atom + "."); - return (BasicAtom) program.getFacts().get(0); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java deleted file mode 100644 index 44d4ff6e2..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright (c) 2019 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.grounder.heuristics; - -import org.junit.Test; - -import static at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration.PERMISSIVE_STRING; -import static at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration.STRICT_STRING; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Tests {@link GrounderHeuristicsConfiguration} - */ -public class GrounderHeuristicConfigurationTest { - - @Test - public void testGetInstanceStrictStrict() { - GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(STRICT_STRING, STRICT_STRING); - assertFalse(grounderHeuristicsConfiguration.isPermissive(true)); - assertFalse(grounderHeuristicsConfiguration.isPermissive(false)); - assertEquals(0, grounderHeuristicsConfiguration.getToleranceConstraints()); - assertEquals(0, grounderHeuristicsConfiguration.getToleranceRules()); - } - - @Test - public void testGetInstanceStrictPermissive() { - GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(STRICT_STRING, PERMISSIVE_STRING); - assertFalse(grounderHeuristicsConfiguration.isPermissive(true)); - assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); - assertEquals(0, grounderHeuristicsConfiguration.getToleranceConstraints()); - assertEquals(-1, grounderHeuristicsConfiguration.getToleranceRules()); - } - - @Test - public void testGetInstancePermissiveStrict() { - GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(PERMISSIVE_STRING, STRICT_STRING); - assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); - assertFalse(grounderHeuristicsConfiguration.isPermissive(false)); - assertEquals(-1, grounderHeuristicsConfiguration.getToleranceConstraints()); - assertEquals(0, grounderHeuristicsConfiguration.getToleranceRules()); - } - - @Test - public void testGetInstancePermissivePermissive() { - GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(PERMISSIVE_STRING, PERMISSIVE_STRING); - assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); - assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); - assertEquals(-1, grounderHeuristicsConfiguration.getToleranceConstraints()); - assertEquals(-1, grounderHeuristicsConfiguration.getToleranceRules()); - } - - @Test - public void testGetInstanceIntInt() { - GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance(5, 1); - assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); - assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); - assertEquals(5, grounderHeuristicsConfiguration.getToleranceConstraints()); - assertEquals(1, grounderHeuristicsConfiguration.getToleranceRules()); - } - - @Test - public void testGetInstanceStringIntStringInt() { - GrounderHeuristicsConfiguration grounderHeuristicsConfiguration = GrounderHeuristicsConfiguration.getInstance("5", "1"); - assertTrue(grounderHeuristicsConfiguration.isPermissive(true)); - assertTrue(grounderHeuristicsConfiguration.isPermissive(false)); - assertEquals(5, grounderHeuristicsConfiguration.getToleranceConstraints()); - assertEquals(1, grounderHeuristicsConfiguration.getToleranceRules()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java deleted file mode 100644 index 68fd468d9..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java +++ /dev/null @@ -1,368 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.instantiation; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.Assert; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; - -public class LiteralInstantiationStrategyTest { - - @Test - public void workingMemoryBasedInstantiationAcceptLiteral() { - Predicate p = Predicate.getInstance("p", 1); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); - LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); - Literal positiveAcceptedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); - Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(positiveAcceptedLiteral)); - Literal negativeAcceptedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("b")), false); - Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(negativeAcceptedLiteral)); - } - - @Test - public void workingMemoryBasedInstantiationRejectLiteral() { - Predicate p = Predicate.getInstance("p", 1); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); - LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); - Literal positiveRejectedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("b")), true); - Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(positiveRejectedLiteral)); - Literal negativeRejectedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), false); - Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(negativeRejectedLiteral)); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth - * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". - * - * In this case, the instantiation strategy does not have an assignment set (as - * is the case when {@link NaiveGrounder} is in bootstrap), - * so we expect the instantiation strategy to determine that p(a) is TRUE. - * Furthermore, the stale atom set (used by {@link NaiveGrounder} to clean up - * atoms that should be deleted from working memory) must stay empty. - */ - @Test - public void defaultLazyGroundingNoAssignmentGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); - WorkingMemory workingMemory = new WorkingMemory(); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(null); - - - AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); - Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - Assert.assertTrue(staleSet.isEmpty()); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find ground - * instances for the partially ground positive literal "q(a, X)". - * - * In this case, the instantiation strategy does not have an assignment set (as - * is the case when {@link NaiveGrounder} is in bootstrap), so we expect the - * assignment status (i.e. assignment status of the found ground instance) - * passed back with the substitution to be TRUE. Furthermore, the stale atom set - * (used by {@link NaiveGrounder} to clean up atoms that should be deleted from - * working memory) must stay empty. - */ - @Test - public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(null); - - List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); - Assert.assertEquals(1, result.size()); - ImmutablePair substitutionInfo = result.get(0); - Substitution substitution = substitutionInfo.left; - AssignmentStatus assignmentStatus = substitutionInfo.right; - Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); - Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); - Assert.assertTrue(staleSet.isEmpty()); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth - * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". - * - * In this case, the instantiation strategy has an empty assignment, - * so we expect the instantiation strategy to determine that p(a) is UNASSIGNED. - * Since UNASSIGNED and FALSE atoms are (potentially) stale in working memory, - * we expect the atom "p(a)" to be added to the stale set by the instantiation - * strategy. - */ - @Test - public void defaultLazyGroundingCheckUnassignedGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); - WorkingMemory workingMemory = new WorkingMemory(); - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(assignment); - - AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); - Assert.assertEquals(AssignmentStatus.UNASSIGNED, assignmentStatus); - - Assert.assertEquals(1, staleSet.size()); - Assert.assertTrue(staleSet.contains(pOfA)); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth - * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". - * - * In this case, the instantiation strategy has an assignment where the atom - * "p(a)" is assigned ThriceTruth.FALSE, so we expect the instantiation strategy - * to determine that p(a) is FALSE. Since UNASSIGNED and FALSE atoms are - * (potentially) stale in working memory, we expect the atom "p(a)" to be added - * to the stale set by the instantiation strategy. - */ - @Test - public void defaultLazyGroundingCheckFalseGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); - WorkingMemory workingMemory = new WorkingMemory(); - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - atomStore.putIfAbsent(pOfA); - assignment.growForMaxAtomId(); - assignment.assign(atomStore.get(pOfA), ThriceTruth.FALSE); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(assignment); - - AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); - Assert.assertEquals(AssignmentStatus.FALSE, assignmentStatus); - - Assert.assertEquals(1, staleSet.size()); - Assert.assertTrue(staleSet.contains(pOfA)); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth - * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". - * - * In this case, the instantiation strategy has an assignment where the atom - * "p(a)" is assigned ThriceTruth.TRUE, so we expect the instantiation strategy - * to determine that p(a) is TRUE. Furthermore, the stale atom set - * (used by {@link NaiveGrounder} to clean up atoms that should be deleted from - * working memory) must stay empty. - */ - @Test - public void defaultLazyGroundingCheckTrueGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); - WorkingMemory workingMemory = new WorkingMemory(); - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - atomStore.putIfAbsent(pOfA); - assignment.growForMaxAtomId(); - assignment.assign(atomStore.get(pOfA), ThriceTruth.TRUE); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(assignment); - - AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); - Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - - Assert.assertTrue(staleSet.isEmpty()); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to check the truth - * (i.e. {@link AssignmentStatus}) of the positive ground literal "p(a)". - * - * In this case, the instantiation strategy has an assignment where the atom - * "p(a)" is assigned ThriceTruth.MBT, so we expect the instantiation strategy - * to determine that p(a) is TRUE. Furthermore, the stale atom set - * (used by {@link NaiveGrounder} to clean up atoms that should be deleted from - * working memory) must stay empty. - */ - @Test - public void defaultLazyGroundingCheckMustBeTrueGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); - WorkingMemory workingMemory = new WorkingMemory(); - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - atomStore.putIfAbsent(pOfA); - assignment.growForMaxAtomId(); - assignment.assign(atomStore.get(pOfA), ThriceTruth.MBT); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(assignment); - - AssignmentStatus assignmentStatus = strategy.getTruthForGroundLiteral(new BasicLiteral(pOfA, true)); - Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - - Assert.assertTrue(staleSet.isEmpty()); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find the ground - * instance "q(a, b)" for the partially ground positive literal "q(a, X)". - * - * In this case, the instantiation strategy has an empty assignment, so we - * expect the assignment status (i.e. assignment status of the found ground - * instance) passed back with the substitution to be UNASSIGNED. Since - * UNASSIGNED and FALSE atoms are (potentially) stale in working memory, we - * expect the atom "q(a, b)" to be added to the stale set by the instantiation - * strategy. - */ - @Test - public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(assignment); - - List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); - Assert.assertEquals(1, result.size()); - ImmutablePair substitutionInfo = result.get(0); - Substitution substitution = substitutionInfo.left; - AssignmentStatus assignmentStatus = substitutionInfo.right; - Assert.assertEquals(AssignmentStatus.UNASSIGNED, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); - Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); - - Assert.assertEquals(1, staleSet.size()); - Assert.assertTrue(staleSet.contains(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")))); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find the ground - * instance "q(a, b)" for the partially ground positive literal "q(a, X)". - * - * In this case, the instantiation strategy has an assignment where q(a, b) is - * assigned ThriceTruth.TRUE, so we expect the assignment status (i.e. - * assignment status of the found ground instance) passed back with the - * substitution to be TRUE. Furthermore, we expect the stale atom set to stay - * empty. - */ - @Test - public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - BasicAtom groundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")); - atomStore.putIfAbsent(groundAtom); - assignment.growForMaxAtomId(); - assignment.assign(atomStore.get(groundAtom), ThriceTruth.TRUE); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(assignment); - - List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); - Assert.assertEquals(1, result.size()); - ImmutablePair substitutionInfo = result.get(0); - Substitution substitution = substitutionInfo.left; - AssignmentStatus assignmentStatus = substitutionInfo.right; - Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); - Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); - - Assert.assertTrue(staleSet.isEmpty()); - } - - /** - * Uses {@link DefaultLazyGroundingInstantiationStrategy} to find the ground - * instance "q(a, b)" for the partially ground positive literal "q(a, X)". - * - * In this case, the instantiation strategy has an assignment where q(a, b) is - * assigned ThriceTruth.FALSE, so we expect an empty list from - * {@link LiteralInstantiationStrategy#getAcceptedSubstitutions(Literal, Substitution)}. - * Furthermore, we expect the atom q(a, b) to be added to the stale atom set. - */ - @Test - public void defaultLazyGroundingSubstituteNonGroundLiteralWithFalseInstance() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - BasicAtom groundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")); - atomStore.putIfAbsent(groundAtom); - assignment.growForMaxAtomId(); - assignment.assign(atomStore.get(groundAtom), ThriceTruth.FALSE); - LinkedHashSet staleSet = new LinkedHashSet<>(); - DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, - Collections.emptyMap()); - strategy.setStaleWorkingMemoryEntries(staleSet); - strategy.setCurrentAssignment(assignment); - - List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); - Assert.assertTrue(result.isEmpty()); - - Assert.assertEquals(1, staleSet.size()); - Assert.assertTrue(staleSet.contains(groundAtom)); - } - -} - \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java deleted file mode 100644 index f218ae78a..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.instantiation; - -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.grounder.atoms.EnumerationLiteral; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.Assert; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; - -public class LiteralInstantiatorTest { - - @Test - public void instantiateSatisfiedFixedInterpretationLiteral() { - ComparisonAtom equalsThree = new ComparisonAtom(ConstantTerm.getInstance(3), VariableTerm.getInstance("THREE"), ComparisonOperator.EQ); - Literal lit = new ComparisonLiteral(equalsThree, true); - Substitution substitution = new Substitution(); - LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); - LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); - Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); - List> resultSubstitutions = result.getSubstitutions(); - Assert.assertEquals(1, resultSubstitutions.size()); - Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitutions.get(0).right); - Substitution extendedSubstitution = resultSubstitutions.get(0).left; - Assert.assertTrue(extendedSubstitution.isVariableSet(VariableTerm.getInstance("THREE"))); - Assert.assertEquals(ConstantTerm.getInstance(3), extendedSubstitution.eval(VariableTerm.getInstance("THREE"))); - } - - @Test - public void instantiateUnsatisfiedFixedInterpretationLiteral() { - ComparisonAtom fiveEqualsThree = new ComparisonAtom(VariableTerm.getInstance("FIVE"), VariableTerm.getInstance("THREE"), ComparisonOperator.EQ); - Literal lit = new ComparisonLiteral(fiveEqualsThree, true); - Substitution substitution = new Substitution(); - substitution.put(VariableTerm.getInstance("FIVE"), ConstantTerm.getInstance(5)); - substitution.put(VariableTerm.getInstance("THREE"), ConstantTerm.getInstance(3)); - LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); - LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); - Assert.assertEquals(LiteralInstantiationResult.Type.STOP_BINDING, result.getType()); - } - - @Test - public void instantiateEnumLiteral() { - VariableTerm enumTerm = VariableTerm.getInstance("E"); - VariableTerm idTerm = VariableTerm.getInstance("X"); - VariableTerm indexTerm = VariableTerm.getInstance("I"); - List termList = new ArrayList<>(); - termList.add(enumTerm); - termList.add(idTerm); - termList.add(indexTerm); - EnumerationAtom enumAtom = new EnumerationAtom(termList); - EnumerationLiteral lit = new EnumerationLiteral(enumAtom); - Substitution substitution = new Substitution(); - substitution.put(enumTerm, ConstantTerm.getSymbolicInstance("enum1")); - substitution.put(idTerm, ConstantTerm.getSymbolicInstance("someElement")); - LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); - LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); - Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); - List> resultSubstitutions = result.getSubstitutions(); - Assert.assertEquals(1, resultSubstitutions.size()); - Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitutions.get(0).right); - Assert.assertTrue(resultSubstitutions.get(0).left.isVariableSet(indexTerm)); - } - - @Test - public void workingMemoryBasedVerifyPositiveGroundLiteralSatisfied() { - Predicate p = Predicate.getInstance("p", 2); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("y")), true); - VariableTerm x = VariableTerm.getInstance("X"); - VariableTerm y = VariableTerm.getInstance("Y"); - Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); - Substitution substitution = new Substitution(); - substitution.put(x, ConstantTerm.getSymbolicInstance("x")); - substitution.put(y, ConstantTerm.getSymbolicInstance("y")); - LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); - LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); - Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); - List> substitutions = result.getSubstitutions(); - Assert.assertEquals(1, substitutions.size()); - Assert.assertEquals(AssignmentStatus.TRUE, substitutions.get(0).right); - Substitution resultSubstitution = substitutions.get(0).left; - // With the given input substitution, lit is ground and satisfied - - // we expect the instantiator to verify that. - Assert.assertEquals(substitution, resultSubstitution); - } - - @Test - public void workingMemoryBasedVerifyPositiveGroundLiteralUnsatisfied() { - Predicate p = Predicate.getInstance("p", 2); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(p); - VariableTerm x = VariableTerm.getInstance("X"); - VariableTerm y = VariableTerm.getInstance("Y"); - Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); - Substitution substitution = new Substitution(); - substitution.put(x, ConstantTerm.getSymbolicInstance("x")); - substitution.put(y, ConstantTerm.getSymbolicInstance("y")); - LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); - LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); - // With the given input substitution, lit is ground, but not satisfied - - // we expect the instantiator to verify that and return an empty list of - // substitutions. - Assert.assertEquals(LiteralInstantiationResult.Type.STOP_BINDING, result.getType()); - } - - @Test - public void workingMemoryBasedInstantiatePositiveBasicLiteral() { - Predicate p = Predicate.getInstance("p", 2); - WorkingMemory workingMemory = new WorkingMemory(); - workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("y")), true); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("z")), true); - VariableTerm x = VariableTerm.getInstance("X"); - VariableTerm y = VariableTerm.getInstance("Y"); - Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); - Substitution substitution = new Substitution(); - substitution.put(x, ConstantTerm.getSymbolicInstance("x")); - LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); - LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); - Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); - List> substitutions = result.getSubstitutions(); - Assert.assertEquals(2, substitutions.size()); - boolean ySubstituted = false; - boolean zSubstituted = false; - for (ImmutablePair resultSubstitution : substitutions) { - Assert.assertTrue(resultSubstitution.left.isVariableSet(y)); - Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitution.right); - if (resultSubstitution.left.eval(y).equals(ConstantTerm.getSymbolicInstance("y"))) { - ySubstituted = true; - } else if (resultSubstitution.left.eval(y).equals(ConstantTerm.getSymbolicInstance("z"))) { - zSubstituted = true; - } else { - Assert.fail("Invalid substitution for variable Y"); - } - } - Assert.assertTrue(ySubstituted && zSubstituted); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java deleted file mode 100644 index 83df6278f..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java +++ /dev/null @@ -1,218 +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.grounder.structure; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; - -import static junit.framework.TestCase.assertFalse; -import static org.junit.Assert.assertNotEquals; - -/** - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class AnalyzeUnjustifiedTest { - - private final ProgramParser parser = new ProgramParser(); - - @Test - public void justifySimpleRules() { - Alpha system = new Alpha(); - String program = "p(X) :- q(X)." + - "q(X) :- p(X)." + - "q(5) :- r." + - "r :- not nr." + - "nr :- not r." + - ":- not p(5)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); - grounder.getNoGoods(null); - TrailAssignment assignment = new TrailAssignment(atomStore); - int rId = atomStore.get(new BasicAtom(Predicate.getInstance("r", 0))); - int nrId = atomStore.get(new BasicAtom(Predicate.getInstance("nr", 0))); - assignment.growForMaxAtomId(); - assignment.assign(rId, ThriceTruth.FALSE); - assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = new BasicAtom(Predicate.getInstance("p", 1), Collections.singletonList(ConstantTerm.getInstance(5))); - assignment.assign(atomStore.get(p5), ThriceTruth.MBT); - Set reasons = grounder.justifyAtom(atomStore.get(p5), assignment); - assertFalse(reasons.isEmpty()); - } - - @Test - public void justifyLargerRules() { - Alpha system = new Alpha(); - 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)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); - 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() { - Alpha system = new Alpha(); - 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)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); - 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 = Predicate.getInstance("_nq", 2, true); - Atom nqa = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("a"))); - Atom nqb = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("b"))); - Atom nqc = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("c"))); - Atom nqd = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("d"))); - Atom nqe = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("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() { - Alpha system = new Alpha(); - 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)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); - AtomStore atomStore = new AtomStoreImpl(); - NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); - grounder.getNoGoods(null); - TrailAssignment assignment = new TrailAssignment(atomStore); - int rId = atomStore.get(new BasicAtom(Predicate.getInstance("r", 0))); - int nrId = atomStore.get(new BasicAtom(Predicate.getInstance("nr", 0))); - assignment.growForMaxAtomId(); - assignment.assign(rId, ThriceTruth.FALSE); - assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = new BasicAtom(Predicate.getInstance("p", 1), Collections.singletonList(ConstantTerm.getInstance(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(), Predicate.getInstance("forbidden", 2)); - } - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java deleted file mode 100644 index b196005a4..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java +++ /dev/null @@ -1,260 +0,0 @@ -package at.ac.tuwien.kr.alpha.grounder.transformation; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.test.util.TestUtils; - -@RunWith(Parameterized.class) -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); - - @Parameters(name = "Run {index}: aspString={0}, programVerifier={1}, answerSetsVerifier={2}") - public static Iterable 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(new Object[] {pair.left, pair.right.left, pair.right.right })); - return paramList; - } - - private String aspString; - private Consumer programVerifier; - private Consumer> answerSetsVerifier; - - public StratifiedEvaluationRegressionTest(String aspString, Consumer programVerifier, Consumer> answerSetsVerifier) { - this.aspString = aspString; - this.programVerifier = programVerifier; - this.answerSetsVerifier = answerSetsVerifier; - } - - @Test - public void runTest() { - String aspStr = this.aspString; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(aspStr); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - this.programVerifier.accept(evaluated); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); - this.answerSetsVerifier.accept(answerSets); - } - - private static void verifyProgramBasic(InternalProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("a"), TestUtils.basicAtomWithSymbolicTerms("b")); - Assert.assertEquals(2, evaluated.getFacts().size()); - Assert.assertTrue(evaluated.getRules().size() == 0); - } - - private static void verifyAnswerSetsBasic(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a, b", answerSets); - } - - private static void verifyProgramBasicMultiInstance(InternalProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("q", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "b")); - Assert.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(InternalProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("s", "a", "b"), - TestUtils.basicAtomWithSymbolicTerms("s", "a", "d")); - Assert.assertEquals(7, evaluated.getFacts().size()); - Assert.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(InternalProgram 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()); - Assert.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(InternalProgram evaluated) { - Predicate num = Predicate.getInstance("num", 1); - TestUtils.assertFactsContainedInProgram(evaluated, new BasicAtom(Predicate.getInstance("max_num", 1), ConstantTerm.getInstance(10)), - new BasicAtom(num, ConstantTerm.getInstance(0)), - new BasicAtom(num, ConstantTerm.getInstance(1)), new BasicAtom(num, ConstantTerm.getInstance(2)), - new BasicAtom(num, ConstantTerm.getInstance(3)), new BasicAtom(num, ConstantTerm.getInstance(4)), - new BasicAtom(num, ConstantTerm.getInstance(5)), new BasicAtom(num, ConstantTerm.getInstance(6)), - new BasicAtom(num, ConstantTerm.getInstance(7)), new BasicAtom(num, ConstantTerm.getInstance(8)), - new BasicAtom(num, ConstantTerm.getInstance(9)), new BasicAtom(num, ConstantTerm.getInstance(10))); - LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); - Assert.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(InternalProgram evaluated) { - Assert.assertTrue(evaluated.getRules().isEmpty()); - Assert.assertTrue(evaluated.getRulesById().isEmpty()); - Assert.assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - Assert.assertTrue(evaluated.getFacts().isEmpty()); - Assert.assertTrue(evaluated.getFactsByPredicate().isEmpty()); - } - - private static void verifyAnswerSetsEmptyProg(Set answerSets) { - Assert.assertEquals(1, answerSets.size()); - Assert.assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramFactsOnly(InternalProgram evaluated) { - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("a"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("b"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("c"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("p", "a"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "b", "c"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("r", "c", "c", "a"))); - Assert.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(InternalProgram evaluated) { - Assert.assertTrue(evaluated.getFacts().isEmpty()); - } - - private static void verifyAnswerSetsStratNoFacts(Set answerSets) { - Assert.assertEquals(1, answerSets.size()); - Assert.assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramStratWithFacts(InternalProgram evaluated) { - // rules should all be taken care of at this point - Assert.assertTrue(evaluated.getRules().isEmpty()); - Assert.assertTrue(evaluated.getRulesById().isEmpty()); - Assert.assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - - // facts should be the full answer set - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "a"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "b"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("incomp", "b"))); - - // below facts from stratified evaluation - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("base", "a"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_base", "a", "a"))); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("dep_b_hlp", "a"))); - Assert.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(InternalProgram evaluated) { - Assert.assertEquals(0, evaluated.getRules().size()); - Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("equal"))); - } - - private static void verifyAnswerSetsEquality(Set answerSets) { - TestUtils.assertAnswerSetsEqual("equal", answerSets); - } - - private static void verifyProgramEqualityWithVar(InternalProgram evaluated) { - Assert.assertEquals(0, evaluated.getRules().size()); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("a", 1), ConstantTerm.getInstance(1)))); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("c", 1), ConstantTerm.getInstance(2)))); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("d", 1), ConstantTerm.getInstance(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/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java b/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java deleted file mode 100644 index ac5d146bc..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java +++ /dev/null @@ -1,276 +0,0 @@ -/** - * Copyright (c) 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.grounder.transformation; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.antlr.v4.runtime.CharStreams; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.api.externals.Externals; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.program.Programs; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.grounder.Instance; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.test.util.TestUtils; - -public class StratifiedEvaluationTest { - - @Test - public void testDuplicateFacts() { - String aspStr = "p(a). p(b). q(b). q(X) :- p(X)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(aspStr); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Instance qOfB = new Instance(TestUtils.basicAtomWithSymbolicTerms("q", "b").getTerms()); - Set facts = evaluated.getFactsByPredicate().get(at.ac.tuwien.kr.alpha.common.Predicate.getInstance("q", 1)); - int numQOfB = 0; - for (Instance at : facts) { - if (at.equals(qOfB)) { - numQOfB++; - } - } - assertEquals(1, numQOfB); - } - - @Test - public void testEqualityWithConstantTerms() { - String aspStr = "equal :- 1 = 1."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(aspStr); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Atom equal = TestUtils.basicAtomWithSymbolicTerms("equal"); - 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)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(aspStr); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); - TestUtils.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)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); - TestUtils.assertAnswerSetsEqual("p(a), q(a,b)", answerSets); - } - - @Test - public void testCountAggregate() { - String asp = "a. b :- 1 <= #count { 1 : a }."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); - TestUtils.assertAnswerSetsEqual("a, b", answerSets); - } - - @Test - public void testIntervalFact() { - String asp = "a(1..3)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); - } - - @Test - public void testAggregateSpecial() { - String asp = "thing(1..3).\n" + "% choose exactly one - since Alpha doesn't support bounds,\n" + "% this needs two constraints\n" - + "{ 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."; - Alpha system = new Alpha(); - // system.getConfig().setUseNormalizationGrid(true); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("allThings"))); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); - TestUtils.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."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); - TestUtils.assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); - } - - @at.ac.tuwien.kr.alpha.api.externals.Predicate - 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]."; - Alpha alpha = new Alpha(); - InputConfig inputCfg = InputConfig.forString(asp); - inputCfg.addPredicateMethod("sayTrue", Externals.processPredicateMethod(this.getClass().getMethod("sayTrue", Object.class))); - InputProgram input = alpha.readProgram(inputCfg); - NormalProgram normal = alpha.normalizeProgram(input); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = alpha.solve(evaluated).collect(Collectors.toSet()); - TestUtils.assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); - } - - /** - * Tests an encoding associated with the partner units problem (PUP) that computes a topological order to be used by - * domain-specific heuristics. The entire program can be solved by stratified evaluation. - */ - @Test - public void testPartnerUnitsProblemTopologicalOrder() throws IOException { - Alpha system = new Alpha(); - InputProgram prg = new ProgramParser().parse(CharStreams.fromStream(this.getClass().getResourceAsStream("/partial-eval/pup_topological_order.asp"))); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - assertTrue("Not all rules eliminated by stratified evaluation", evaluated.getRules().isEmpty()); - assertEquals(57, evaluated.getFacts().size()); - } - - /** - * 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 - String expectedAnswerSet = "basefact1(1), basefact2(1), max_value(10), min_value(1), " - + "basefact1(9), basefact2(9), base(1), base(9), " - + "inc_value(1), inc_value(2), inc_value(2), inc_value(3), " - + "inc_value(4), inc_value(5), inc_value(6), inc_value(7), " - + "inc_value(8)"; - //@formatter:on - InputProgram prog = Programs.fromInputStream( - StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), - new HashMap<>()); - Alpha systemStratified = new Alpha(); - systemStratified.getConfig().setEvaluateStratifiedPart(true); - Set asStrat = systemStratified.solve(prog).collect(Collectors.toSet()); - TestUtils.assertAnswerSetsEqual(expectedAnswerSet, asStrat); - Alpha systemNoStratEval = new Alpha(); - systemNoStratEval.getConfig().setEvaluateStratifiedPart(false); - Set as = systemNoStratEval.solve(prog).collect(Collectors.toSet()); - TestUtils.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" + - " R = K + 1."; - //@formatter:on - Alpha alpha = new Alpha(); - InputProgram prog = alpha.readProgramString(asp); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(alpha.normalizeProgram(prog)); - StratifiedEvaluation evaluation = new StratifiedEvaluation(); - InternalProgram evaluated = evaluation.apply(analyzed); - Predicate rank = Predicate.getInstance("thing_rank", 2); - BasicAtom rank1 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getInstance(1)); - BasicAtom rank2 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("b"), ConstantTerm.getInstance(2)); - BasicAtom rank3 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("c"), ConstantTerm.getInstance(3)); - List evaluatedFacts = evaluated.getFacts(); - Assert.assertTrue(evaluatedFacts.contains(rank1)); - Assert.assertTrue(evaluatedFacts.contains(rank2)); - Assert.assertTrue(evaluatedFacts.contains(rank3)); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java deleted file mode 100644 index e11c2923c..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java +++ /dev/null @@ -1,266 +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.solver; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic; -import at.ac.tuwien.kr.alpha.test.util.TestUtils; -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Random; -import java.util.Set; - -@RunWith(Parameterized.class) -public abstract class AbstractSolverTests { - - private static final String[] NON_DEPRECATED_HEURISTICS_NAMES; - static { - final List nonDeprecatedHeuristicsNames = new ArrayList<>(); - for (Field field : Heuristic.class.getFields()) { - if (field.getAnnotation(Deprecated.class) == null) { - nonDeprecatedHeuristicsNames.add(field.getName()); - } - } - NON_DEPRECATED_HEURISTICS_NAMES = nonDeprecatedHeuristicsNames.toArray(new String[]{}); - } - - private final ProgramParser parser = new ProgramParser(); - - /** - * Sets the logging level to TRACE. Useful for debugging; call at beginning of test case. - */ - protected static void enableTracing() { - Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - root.setLevel(ch.qos.logback.classic.Level.TRACE); - } - - protected static void enableDebugLog() { - Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - root.setLevel(Level.DEBUG); - } - - /** - * Calling this method in a test leads to the test being ignored for the naive solver. - * Note: use this sparingly and only on tests that require too much run time with the naive solver. - */ - void ignoreTestForNaiveSolver() { - org.junit.Assume.assumeFalse(solverName.equals("naive")); - } - - /** - * Calling this method in a test leads to the test being ignored for non-default domain-independent heuristics. - * Note: use this sparingly and only on tests that require too much run time with non-default heuristics - * (which are not tuned for good performance as well as VSIDS). - */ - void ignoreNonDefaultDomainIndependentHeuristics() { - org.junit.Assume.assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - } - - private static String[] getProperty(String subKey, String def) { - return System.getProperty("test." + subKey, def).split(","); - } - - @Parameters(name = "{0}/{1}/{2}/{3}/seed={4}/checks={5}/gtc={6}/gtr={7}/dir={8}") - public static Collection parameters() { - // Check whether we are running in a CI environment. - boolean ci = Boolean.valueOf(System.getenv("CI")); - - String[] solvers = getProperty("solvers", ci ? "default,naive" : "default"); - String[] grounders = getProperty("grounders", "naive"); - String[] stores = getProperty("stores", ci ? "alpharoaming,naive" : "alpharoaming"); - String[] heuristics = getProperty("heuristics", ci ? "NON_DEPRECATED" : "NAIVE,VSIDS"); - String[] gtcValues = getProperty("grounderToleranceConstraints", "strict,permissive"); - String[] gtrValues = getProperty("grounderToleranceRules", "strict"); - String[] dirValues = getProperty("disableInstanceRemoval", ci ? "false,true" : "false"); - - // "ALL" is a magic value that will be expanded to contain all heuristics. - if ("ALL".equals(heuristics[0])) { - BranchingHeuristicFactory.Heuristic[] values = BranchingHeuristicFactory.Heuristic.values(); - heuristics = new String[values.length]; - int i = 0; - for (BranchingHeuristicFactory.Heuristic heuristic : values) { - heuristics[i++] = heuristic.toString(); - } - } - // "NON_DEPRECATED" is a magic value that will be expanded to contain all non-deprecated heuristics. - if ("NON_DEPRECATED".equals(heuristics[0])) { - heuristics = NON_DEPRECATED_HEURISTICS_NAMES; - } - - // NOTE: - // It is handy to set the seed for reproducing bugs. However, the reverse is also sometimes needed: - // A test case fails, now what was the seed that "caused" it? To allow this, we need full control over - // the seed, so we generate one in any case. - // If your test case fails you can inspect the property called "seed" of AbstractSolverTests and extract - // its value. - String seedProperty = System.getProperty("seed", ci ? "0" : ""); - long seed = seedProperty.isEmpty() ? (new Random().nextLong()) : Long.valueOf(seedProperty); - - boolean checks = true; - - Collection factories = new ArrayList<>(); - - for (String solver : solvers) { - for (String grounder : grounders) { - for (String store : stores) { - for (String heuristic : heuristics) { - for (String gtc : gtcValues) { - for (String gtr : gtrValues) { - for (String dir : dirValues) { - factories.add(new Object[]{ - solver, grounder, store, BranchingHeuristicFactory.Heuristic.valueOf(heuristic), seed, checks, gtc, gtr, Boolean.valueOf(dir) - }); - } - } - } - } - } - } - } - - return factories; - } - - @Parameter(0) - public String solverName; - - @Parameter(1) - public String grounderName; - - @Parameter(2) - public String storeName; - - @Parameter(3) - public BranchingHeuristicFactory.Heuristic heuristic; - - @Parameter(4) - public long seed; - - @Parameter(5) - public boolean checks; - - @Parameter(6) - public String grounderToleranceConstraints; - - @Parameter(7) - public String grounderToleranceRules; - - @Parameter(8) - public boolean disableInstanceRemoval; - - protected Solver getInstance(AtomStore atomStore, Grounder grounder) { - return SolverFactory.getInstance(buildSystemConfig(), atomStore, grounder); - } - - private SystemConfig buildSystemConfig() { - SystemConfig config = new SystemConfig(); - config.setSolverName(solverName); - config.setNogoodStoreName(storeName); - config.setSeed(seed); - config.setBranchingHeuristic(heuristic); - config.setDebugInternalChecks(checks); - config.setDisableJustificationSearch(false); - return config; - } - - protected Solver getInstance(InputProgram program) { - Alpha system = new Alpha(); - AtomStore atomStore = new AtomStoreImpl(); - NormalProgram normalized = system.normalizeProgram(program); - InternalProgram preprocessed = InternalProgram.fromNormalProgram(normalized); - return getInstance(atomStore, GrounderFactory.getInstance(grounderName, preprocessed, atomStore, true)); - } - - protected Solver getInstance(String program) { - return getInstance(CharStreams.fromString(program)); - } - - protected Solver getInstance(CharStream program) { - try { - return getInstance(parser.parse(program)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - protected Set collectSet(String program) { - return getInstance(program).collectSet(); - } - - protected Set collectSet(InputProgram program) { - return getInstance(program).collectSet(); - } - - protected Set collectSet(CharStream program) { - return getInstance(program).collectSet(); - } - - protected void assertAnswerSets(String program, String... answerSets) { - Set actualAnswerSets = collectSet(program); - TestUtils.assertAnswerSetsEqual(answerSets, actualAnswerSets); - } - - protected void assertAnswerSet(String program, String answerSet) { - Set actualAnswerSets = collectSet(program); - TestUtils.assertAnswerSetsEqual(answerSet, actualAnswerSets); - } - - protected void assertAnswerSetsWithBase(String program, String base, String... answerSets) { - Set actualAnswerSets = collectSet(program); - TestUtils.assertAnswerSetsEqualWithBase(base, answerSets, actualAnswerSets); - } - - protected void assertAnswerSets(String program, Set answerSets) { - Set actualAnswerSets = collectSet(program); - TestUtils.assertAnswerSetsEqual(answerSets, actualAnswerSets); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java deleted file mode 100644 index c21d5e971..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java +++ /dev/null @@ -1,38 +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.solver; - -/** - * Executes {@link AggregatesTest} with {@code normalizationCountingGrid=true}. - */ -public class AggregatesCardinalityCountingGridTest extends AggregatesTest { - - @Override - protected boolean useCountingGridNormalization() { - return true; - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java deleted file mode 100644 index 9f0558e35..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java +++ /dev/null @@ -1,38 +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.solver; - -/** - * Executes {@link AggregatesTest} with {@code normalizationCountingGrid=false}. - */ -public class AggregatesCardinalitySortingCircuitTest extends AggregatesTest { - - @Override - protected boolean useCountingGridNormalization() { - return false; - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java deleted file mode 100644 index 9cb5c5a99..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.grounder.transformation.CardinalityNormalization; -import at.ac.tuwien.kr.alpha.grounder.transformation.SumNormalization; -import org.junit.Test; - -import java.io.IOException; - -/** - * Tests if correct answer sets for programs containing aggregates are computed. - * Only aggregates known to by syntactically supported by {@link CardinalityNormalization} or {@link SumNormalization} are currently tested. - */ -public abstract class AggregatesTest extends AbstractSolverTests { - - private static final String LS = System.lineSeparator(); - - @Test - public void testAggregate_Count_Ground_Positive() throws IOException { - String program = "a." + LS - + "b :- 1 <= #count { 1 : a }."; - assertAnswerSet(program, "a,b"); - } - - @Test - public void testAggregate_Count_Ground_Negative() throws IOException { - String program = "{a}." + LS - + "b :- not c." + LS - + "c :- 1 <= #count { 1 : a }."; - assertAnswerSets(program, "a,c", "b"); - } - - @Test - public void testAggregate_Count_NonGround_Positive() throws IOException { - String program = "n(1..3)." + LS - + "{x(N)} :- n(N)." + LS - + "min(3)." + LS - + "ok :- min(M), M <= #count { N : n(N), x(N) }."; - assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(3)", - "", "x(1)", "x(2)", "x(3)", "x(1), x(2)", "x(1), x(3)", - "x(2), x(3)", "x(1), x(2), x(3), ok"); - } - - @Test - public void testAggregate_Count_NonGround_LowerAndUpper() throws IOException { - String program = "n(1..3)." + LS - + "{x(N)} :- n(N)." + LS - + "min(2)." + LS - + "max(2)." + LS - + "ok :- min(M), M <= #count { N : n(N), x(N) }, not exceedsMax." + LS - + "exceedsMax :- max(M), M1 = M + 1, M1 <= #count { N : n(N), x(N) }."; - System.out.println(program); - assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(2), max(2)", - "", "x(1)", "x(2)", "x(3)", "x(1), x(2), ok", "x(1), x(3), ok", - "x(2), x(3), ok", "x(1), x(2), x(3), exceedsMax"); - } - - @Test - public void testAggregate_Sum_Ground_Lower() throws IOException { - String program = "a." + LS - + "b :- 5 <= #sum { 2 : a; 3 }."; - assertAnswerSet(program, "a,b"); - } - - @Test - public void testAggregate_Sum_NonGround_LowerAndUpper() throws IOException { - String program = "n(1..3)." + LS - + "{x(N)} :- n(N)." + LS - + "min(3)." + LS - + "max(4)." + LS - + "ok :- min(M), M <= #sum { N : n(N), x(N) }, not exceedsMax." + LS - + "exceedsMax :- max(M), M1 = M + 1, M1 <= #sum { N : n(N), x(N) }."; - System.out.println(program); - assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(3), max(4)", - "", "x(1)", "x(2)", "x(3), ok", "x(1), x(2), ok", "x(1), x(3), ok", - "x(2), x(3), exceedsMax", "x(1), x(2), x(3), exceedsMax"); - } - - @Test - public void testAggregate_Sum_NonGround_Lower() throws IOException { - String program = "n(1..3)." + LS - + "{x(N)} :- n(N)." + LS - + "min(3)." + LS - + "ok :- min(M), M <= #sum { N : n(N), x(N) }."; - System.out.println(program); - assertAnswerSetsWithBase(program, "n(1), n(2), n(3), min(3)", - "", "x(1)", "x(2)", "x(3), ok", "x(1), x(2), ok", "x(1), x(3), ok", - "x(2), x(3), ok", "x(1), x(2), x(3), ok"); - } - - /** - * TODO: Currently it is a bit tedious to compute sums. Support for equality comparison of aggregates, e.g. {@code sum(S) :- S = #sum { N : n(N), x(N) }.} is still lacking. - */ - @Test - public void testAggregate_Sum_Computed() throws IOException { - ignoreTestForNaiveSolver(); // Do not run this test case with the naive solver. - String program = "n(1..3)." + LS - + "{x(N)} :- n(N)." + LS - + "potential_sum(0..6)." + LS - + "min(S) :- S <= #sum { N : n(N), x(N) }, potential_sum(S)." + LS - + "sum(S) :- min(S), not min(Sp1), Sp1 = S+1."; - assertAnswerSetsWithBase(program, "n(1), n(2), n(3), potential_sum(0), potential_sum(1), " - + "potential_sum(2), potential_sum(3), potential_sum(4), potential_sum(5), potential_sum(6)", - "min(0), sum(0)", - "x(1), min(0), min(1), sum(1)", - "x(2), min(0), min(1), min(2), sum(2)", - "x(3), min(0), min(1), min(2), min(3), sum(3)", - "x(1), x(2), min(0), min(1), min(2), min(3), sum(3)", - "x(1), x(3), min(0), min(1), min(2), min(3), min(4), sum(4)", - "x(2), x(3), min(0), min(1), min(2), min(3), min(4), min(5), sum(5)", - "x(1), x(2), x(3), min(0), min(1), min(2), min(3), min(4), min(5), min(6), sum(6)"); - } - - @Test - public void testAggregate_Count_GlobalVariable() throws IOException { - String program = "box(1..2)." + LS - + "in(1,1)." + LS - + "in(1,2)." + LS - + "in(2,2)." + LS - + "full(B) :- box(B), 2 <= #count { I : in(I,B) }."; - assertAnswerSetsWithBase(program, "box(1), box(2), in(1,1), in(1,2), in(2,2)", - "full(2)"); - } - - @Test - public void testAggregate_Sum_GlobalVariable() throws IOException { - String program = "box(1..2)." + LS - + "item_size(I,I) :- I=1..2." + LS - + "in(1,1)." + LS - + "in(1,2)." + LS - + "in(2,2)." + LS - + "full(B) :- box(B), 3 <= #sum { S : item_size(I,S), in(I,B) }."; - assertAnswerSetsWithBase(program, "box(1), box(2), item_size(1,1), item_size(2,2), in(1,1), in(1,2), in(2,2)", - "full(2)"); - } - - @Override - protected Solver getInstance(InputProgram program) { - Alpha system = new Alpha(); - system.getConfig().setUseNormalizationGrid(useCountingGridNormalization()); - AtomStore atomStore = new AtomStoreImpl(); - NormalProgram normal = system.normalizeProgram(program); - InternalProgram preprocessed = InternalProgram.fromNormalProgram(normal); - return super.getInstance(atomStore, GrounderFactory.getInstance(grounderName, preprocessed, atomStore, p->true, new GrounderHeuristicsConfiguration(), true)); - } - - protected abstract boolean useCountingGridNormalization(); - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java deleted file mode 100644 index 0dce2db91..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package at.ac.tuwien.kr.alpha.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/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java deleted file mode 100644 index 148988d62..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (c) 2019 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.solver; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.grounder.Substitution; -import at.ac.tuwien.kr.alpha.grounder.atoms.ChoiceAtom; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; - -public class AtomCounterTests { - - private AtomStore atomStore; - - @Before - public void setUp() { - this.atomStore = new AtomStoreImpl(); - } - - @Test - public void testGetNumberOfAtoms() throws NoSuchMethodException { - final AtomCounter atomCounter = atomStore.getAtomCounter(); - - expectGetNumberOfAtoms(atomCounter, BasicAtom.class, 0); - expectGetNumberOfAtoms(atomCounter, AggregateAtom.class, 0); - expectGetNumberOfAtoms(atomCounter, ChoiceAtom.class, 0); - expectGetNumberOfAtoms(atomCounter, RuleAtom.class, 0); - - createBasicAtom1(); - createBasicAtom2(); - createAggregateAtom(); - createChoiceAtom(); - createRuleAtom(); - - expectGetNumberOfAtoms(atomCounter, BasicAtom.class, 2); - expectGetNumberOfAtoms(atomCounter, AggregateAtom.class, 1); - expectGetNumberOfAtoms(atomCounter, ChoiceAtom.class, 1); - expectGetNumberOfAtoms(atomCounter, RuleAtom.class, 1); - } - - @Test - public void testGetStatsByType() throws NoSuchMethodException { - final AtomCounter atomCounter = atomStore.getAtomCounter(); - - createBasicAtom1(); - createBasicAtom2(); - createAggregateAtom(); - createChoiceAtom(); - createRuleAtom(); - - expectGetStatsByType(atomCounter, BasicAtom.class, 2); - expectGetStatsByType(atomCounter, AggregateAtom.class, 1); - expectGetStatsByType(atomCounter, ChoiceAtom.class, 1); - expectGetStatsByType(atomCounter, RuleAtom.class, 1); - } - - private void createBasicAtom1() { - atomStore.putIfAbsent(new BasicAtom(Predicate.getInstance("p", 0))); - } - - private void createBasicAtom2() { - atomStore.putIfAbsent(new BasicAtom(Predicate.getInstance("q", 1), ConstantTerm.getInstance(1))); - } - - private void createAggregateAtom() { - final ConstantTerm c1 = ConstantTerm.getInstance(1); - final ConstantTerm c2 = ConstantTerm.getInstance(2); - final ConstantTerm c3 = ConstantTerm.getInstance(3); - List basicTerms = Arrays.asList(c1, c2, c3); - AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, Collections.singletonList(new BasicAtom(Predicate.getInstance("p", 3), c1, c2, c3).toLiteral())); - atomStore.putIfAbsent(new AggregateAtom(ComparisonOperator.LE, c1, null, null, AggregateAtom.AGGREGATEFUNCTION.COUNT, Collections.singletonList(aggregateElement))); - } - - private void createChoiceAtom() { - atomStore.putIfAbsent(ChoiceAtom.on(1)); - } - - private void createRuleAtom() { - Atom atomAA = new BasicAtom(Predicate.getInstance("aa", 0)); - InternalRule ruleAA = new InternalRule(new NormalHead(atomAA), Collections.singletonList(new BasicAtom(Predicate.getInstance("bb", 0)).toLiteral(false))); - atomStore.putIfAbsent(new RuleAtom(ruleAA, new Substitution())); - } - - private void expectGetNumberOfAtoms(AtomCounter atomCounter, Class classOfAtoms, int expectedNumber) { - assertEquals("Unexpected number of " + classOfAtoms.getSimpleName() + "s", expectedNumber, atomCounter.getNumberOfAtoms(classOfAtoms)); - } - - private void expectGetStatsByType(AtomCounter atomCounter, Class classOfAtoms, int expectedNumber) { - assertTrue("Expected number of " + classOfAtoms.getSimpleName() + "s not contained in stats string", atomCounter.getStatsByType().contains(classOfAtoms.getSimpleName() + ": " + expectedNumber)); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java deleted file mode 100644 index 52514f66c..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static org.junit.Assert.assertTrue; - -public class ChoiceManagerTests extends AbstractSolverTests { - private Grounder grounder; - private ChoiceManager choiceManager; - private AtomStore atomStore; - - @Before - public void setUp() { - Alpha system = new Alpha(); - String testProgram = "h :- b1, b2, not b3, not b4."; - InputProgram parsedProgram = new ProgramParser().parse(testProgram); - NormalProgram normalProgram = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normalProgram); - atomStore = new AtomStoreImpl(); - grounder = new NaiveGrounder(internalProgram, atomStore, true); - WritableAssignment assignment = new TrailAssignment(atomStore); - NoGoodStore store = new NoGoodStoreAlphaRoaming(assignment); - choiceManager = new ChoiceManager(assignment, store); - } - - @Test - public void testIsAtomChoice() { - Collection noGoods = getNoGoods(); - choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); - for (NoGood noGood : noGoods) { - for (Integer literal : noGood) { - int atom = atomOf(literal); - String atomToString = atomStore.atomToString(atom); - if (atomToString.startsWith(RuleAtom.PREDICATE.getName())) { - assertTrue("Atom not choice: " + atomToString, choiceManager.isAtomChoice(atom)); - } - } - } - } - - private Collection getNoGoods() { - return grounder.getNoGoods(null).values(); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java deleted file mode 100644 index 28df5d165..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import org.antlr.v4.runtime.CharStreams; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * A more fine-grained test, mostly intended for debugging purposes, of the "simple" instance of the Hanoi Tower - * problem. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class HanoiTowerDetailedTest { - - private static final String HANOI_TOWER_SRC = "/HanoiTower_Alpha.asp"; - private static final String SIMPLE_INSTANCE = "/HanoiTower_instances/simple.asp"; - - @Test - public void testHanoiTower() throws IOException { - Alpha alpha = new Alpha(); - // alpha.getConfig().setEvaluateStratifiedPart(false); - InputProgram.Builder programBuilder = InputProgram.builder(); - ProgramParser parser = new ProgramParser(); - InputStream baseProgStream = HanoiTowerDetailedTest.class.getResourceAsStream(HANOI_TOWER_SRC); - InputStream instanceStream = HanoiTowerDetailedTest.class.getResourceAsStream(SIMPLE_INSTANCE); - programBuilder.accumulate(parser.parse(CharStreams.fromStream(baseProgStream))); - programBuilder.accumulate(parser.parse(CharStreams.fromStream(instanceStream))); - InputProgram prog = programBuilder.build(); - InternalProgram preprocessed = InternalProgram.fromNormalProgram(alpha.normalizeProgram(prog)); - Optional solveResult = alpha.solve(preprocessed).findFirst(); - Assert.assertTrue(solveResult.isPresent()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java deleted file mode 100644 index ab69d49ef..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (c) 2017-2019 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.solver; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Paths; -import java.util.Optional; -import java.util.SortedSet; - -import static org.junit.Assert.assertTrue; - -/** - * Tests {@link AbstractSolver} using some hanoi tower test cases (see https://en.wikipedia.org/wiki/Tower_of_Hanoi). - * - */ -public class HanoiTowerTest extends AbstractSolverTests { - - private static final Logger LOGGER = LoggerFactory.getLogger(HanoiTowerTest.class); - - private final ProgramParser parser = new ProgramParser(); - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testInstance1() throws IOException { - testHanoiTower(1); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testInstance2() throws IOException { - testHanoiTower(2); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testInstance3() throws IOException { - testHanoiTower(3); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testInstance4() throws IOException { - testHanoiTower(4); - } - - @Test(timeout = 60000) - public void testSimple() throws IOException { - ignoreTestForNaiveSolver(); - ignoreNonDefaultDomainIndependentHeuristics(); - testHanoiTower("simple"); - } - - private void testHanoiTower(int instance) throws IOException { - testHanoiTower(String.valueOf(instance)); - } - - private void testHanoiTower(String instance) throws IOException { - Alpha system = new Alpha(); - InputProgram prog = system.readProgramFiles(false, null, Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), - Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); - Solver solver = getInstance(prog); - Optional answerSet = solver.stream().findFirst(); - assertTrue(answerSet.isPresent()); - checkGoal(prog, answerSet.get()); - } - - /** - * Conducts a very simple, non-comprehensive goal check (i.e. it may classify answer sets as correct that are actually wrong) by checking if for every goal/3 - * fact in the input there is a corresponding on/3 atom in the output. - */ - private void checkGoal(InputProgram parsedProgram, AnswerSet answerSet) { - Predicate ongoal = Predicate.getInstance("ongoal", 2); - Predicate on = Predicate.getInstance("on", 3); - int steps = getSteps(parsedProgram); - SortedSet onInstancesInAnswerSet = answerSet.getPredicateInstances(on); - for (Atom atom : parsedProgram.getFacts()) { - if (atom.getPredicate().getName().equals(ongoal.getName()) && atom.getPredicate().getArity() == ongoal.getArity()) { - Term expectedTop = atom.getTerms().get(0); - Term expectedBottom = atom.getTerms().get(1); - Term expectedSteps = ConstantTerm.getInstance(steps); - Atom expectedAtom = new BasicAtom(on, expectedSteps, expectedBottom, expectedTop); - assertTrue("Answer set does not contain " + expectedAtom, onInstancesInAnswerSet.contains(expectedAtom)); - } - } - } - - private int getSteps(InputProgram parsedProgram) { - Predicate steps = Predicate.getInstance("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()); - } - } - throw new IllegalArgumentException("No steps atom found in input program."); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java deleted file mode 100644 index 3db78001c..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java +++ /dev/null @@ -1,319 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Tests rule transformations described in the following research paper, and their effects on performance: - * - * Anger, Christian; Gebser, Martin; Janhunen, Tomi; Schaub, Torsten (2006): What's a head without a body? In G. Brewka, S. Coradeschi, A. Perini, P. Traverso - * (Eds.): Proceedings of the Seventeenth European Conference on Artificial Intelligence (ECAI'06): IOS Press, pp. 769–770. - * - */ -public class HeadBodyTransformationTests extends AbstractSolverTests { - - @Before - public void printSolverName() { - System.out.println(solverName); - } - - @Test(timeout = 10000) - public void testProgramB_N1() throws IOException { - test(constructProgramB(1)); - } - - @Test(timeout = 10000) - public void testProgramB_Transformed_N1() throws IOException { - test(constructProgramB_TransformationB(1)); - } - - @Test(timeout = 10000) - public void testProgramA_N1() throws IOException { - test(constructProgramA(1)); - } - - @Test(timeout = 10000) - public void testProgramA_Transformed_N1() throws IOException { - test(constructProgramA_TransformationA(1)); - } - - @Test(timeout = 10000) - public void testProgramB_N2() throws IOException { - test(constructProgramB(2)); - } - - @Test(timeout = 10000) - public void testProgramB_Transformed_N2() throws IOException { - test(constructProgramB_TransformationB(2)); - } - - @Test(timeout = 10000) - public void testProgramA_N2() throws IOException { - test(constructProgramA(2)); - } - - @Test(timeout = 10000) - public void testProgramA_Transformed_N2() throws IOException { - test(constructProgramA_TransformationA(2)); - } - - @Test(timeout = 10000) - public void testProgramB_N4() throws IOException { - test(constructProgramB(4)); - } - - @Test(timeout = 10000) - public void testProgramB_Transformed_N4() throws IOException { - test(constructProgramB_TransformationB(4)); - } - - @Test(timeout = 10000) - public void testProgramA_N4() throws IOException { - test(constructProgramA(4)); - } - - @Test(timeout = 10000) - public void testProgramA_Transformed_N4() throws IOException { - test(constructProgramA_TransformationA(4)); - } - - @Test(timeout = 10000) - public void testProgramB_N8() throws IOException { - test(constructProgramB(8)); - } - - @Test(timeout = 10000) - public void testProgramB_Transformed_N8() throws IOException { - test(constructProgramB_TransformationB(8)); - } - - @Test(timeout = 10000) - public void testProgramA_N8() throws IOException { - test(constructProgramA(8)); - } - - @Test(timeout = 10000) - public void testProgramA_Transformed_N8() throws IOException { - test(constructProgramA_TransformationA(8)); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testProgramB_N16() throws IOException { - test(constructProgramB(16)); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testProgramB_Transformed_N16() throws IOException { - test(constructProgramB_TransformationB(16)); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testProgramA_N16() throws IOException { - test(constructProgramA(16)); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testProgramA_Transformed_N16() throws IOException { - test(constructProgramA_TransformationA(16)); - } - - private void test(InputProgram program) { - Solver solver = getInstance(program); - Optional answerSet = solver.stream().findFirst(); - assertFalse(answerSet.isPresent()); - } - - /** - * Constructs program Pi^n_B from the paper - * - * @param n - */ - private InputProgram constructProgramB(int n) { - int numberOfRules = 3 * n + 1; - List strRules = new ArrayList<>(numberOfRules); - strRules.add("x :- not x."); - strRules.addAll(createXRules(n)); - strRules.addAll(createABRules(n)); - return checkNumberOfRulesAndParse(strRules, numberOfRules); - } - - /** - * Constructs program Pi^n_B transformed with Tau_B from the paper - * - * @param n - */ - private InputProgram constructProgramB_TransformationB(int n) { - int numberOfRules = 6 * n + 2; - List strRules = new ArrayList<>(numberOfRules); - strRules.add("b_notX :- not x."); - strRules.add("x :- b_notX."); - strRules.addAll(createXRules_TransformationB(n)); - strRules.addAll(createABRules_TransformationB(n)); - return checkNumberOfRulesAndParse(strRules, numberOfRules); - } - - /** - * Constructs program Pi^n_a from the paper - * - * @param n - */ - private InputProgram constructProgramA(int n) { - int numberOfRules = 4 * n + 1; - List strRules = new ArrayList<>(numberOfRules); - strRules.add(createXCRule(n)); - strRules.addAll(createCRules(n)); - strRules.addAll(createABRules(n)); - return checkNumberOfRulesAndParse(strRules, numberOfRules); - } - - /** - * Constructs program Pi^n_a from the paper - * - * @param n - */ - private InputProgram constructProgramA_TransformationA(int n) { - int numberOfRules = 7 * n + 2; - List strRules = new ArrayList<>(numberOfRules); - strRules.addAll(createXCRules_TransformationA(n)); - strRules.addAll(createCRules_TransformationA(n)); - strRules.addAll(createABRules_TransformationA(n)); - return checkNumberOfRulesAndParse(strRules, numberOfRules); - } - - private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { - assertEquals(numberOfRules, strRules.size()); - String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - InputProgram parsedProgram = new ProgramParser().parse(strProgram); - assertEquals(numberOfRules, parsedProgram.getRules().size()); - return parsedProgram; - } - - private Collection createXRules(int n) { - Collection rules = new ArrayList<>(n); - for (int i = 1; i <= n; i++) { - rules.add(String.format("x :- not a%d, not b%d.", i, i)); - } - return rules; - } - - private Collection createXRules_TransformationB(int n) { - Collection rules = new ArrayList<>(n); - for (int i = 1; i <= n; i++) { - String beta = String.format("b_nota%dnotb%d", i, i); - rules.add(String.format("%s :- not a%d, not b%d.", beta, i, i)); - rules.add(String.format("x :- %s.", beta)); - } - return rules; - } - - private Collection createABRules(int n) { - Collection rules = new ArrayList<>(2 * n); - for (int i = 1; i <= n; i++) { - rules.add(String.format("a%d :- not b%d.", i, i)); - rules.add(String.format("b%d :- not a%d.", i, i)); - } - return rules; - } - - private Collection createABRules_TransformationB(int n) { - Collection rules = new ArrayList<>(4 * n); - for (int i = 1; i <= n; i++) { - rules.add(String.format("b_notb%d :- not b%d.", i, i)); - rules.add(String.format("a%d :- b_notb%d.", i, i)); - rules.add(String.format("b_nota%d :- not a%d.", i, i)); - rules.add(String.format("b%d :- b_nota%d.", i, i)); - } - return rules; - } - - private Collection createABRules_TransformationA(int n) { - Collection rules = new ArrayList<>(4 * n); - for (int i = 1; i <= n; i++) { - rules.add(String.format("a_a%d :- not b%d.", i, i)); - rules.add(String.format("a%d :- a_a%d.", i, i)); - rules.add(String.format("a_b%d :- not a%d.", i, i)); - rules.add(String.format("b%d :- a_b%d.", i, i)); - } - return rules; - } - - private String createXCRule(int n) { - StringBuilder stringBuilder = new StringBuilder("x :- "); - for (int i = 1; i <= n; i++) { - stringBuilder.append(String.format("c%d, ", i)); - } - stringBuilder.append("not x."); - return stringBuilder.toString(); - } - - private Collection createXCRules_TransformationA(int n) { - Collection rules = new ArrayList<>(2); - rules.add("x :- a_x."); - rules.add("a_" + createXCRule(n)); - return rules; - } - - private Collection createCRules(int n) { - Collection rules = new ArrayList<>(2 * n); - for (int i = 1; i <= n; i++) { - rules.add(String.format("c%d :- not a%d.", i, i)); - rules.add(String.format("c%d :- not b%d.", i, i)); - } - return rules; - } - - private Collection createCRules_TransformationA(int n) { - Collection rules = new ArrayList<>(3 * n); - for (int i = 1; i <= n; i++) { - rules.add(String.format("a_c%d :- not a%d.", i, i)); - rules.add(String.format("a_c%d :- not b%d.", i, i)); - rules.add(String.format("c%d :- a_c%d.", i, i)); - } - return rules; - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java deleted file mode 100644 index ab6afb5eb..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright (c) 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.solver; - -import at.ac.tuwien.kr.alpha.common.*; -import org.junit.Before; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static org.junit.Assert.*; - -public class LearnedNoGoodDeletionTest { - - private NoGoodStoreAlphaRoaming store; - private LearnedNoGoodDeletion learnedNoGoodDeletion; - - public LearnedNoGoodDeletionTest() { - AtomStore atomStore = new AtomStoreImpl(); - AtomStoreTest.fillAtomStore(atomStore, 200); - WritableAssignment assignment = new TrailAssignment(atomStore); - assignment.growForMaxAtomId(); - store = new NoGoodStoreAlphaRoaming(assignment); - learnedNoGoodDeletion = store.getLearnedNoGoodDeletion(); - } - - @Before - public void setUp() { - store.clear(); - store.growForMaxAtomId(fromOldLiterals(200)); - assertNull(store.add(1, new NoGood(fromOldLiterals(1, -2)))); - assertNull(store.add(2, new NoGood(fromOldLiterals(2, -3)))); - assertNull(store.add(3, new NoGood(fromOldLiterals(2, -4, -5)))); - assertNull(store.add(4, new NoGood(fromOldLiterals(3, 4, 5)))); - assertNull(store.propagate()); - } - - @Test - public void testDeletionRunningAfterConflicts() { - for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { - learnedNoGoodDeletion.increaseConflictCounter(); - } - assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - learnedNoGoodDeletion.increaseConflictCounter(); - assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - learnedNoGoodDeletion.runNoGoodDeletion(); - assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - } - - @Test - public void testDeletionRemovingWatches() { - for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { - learnedNoGoodDeletion.increaseConflictCounter(); - } - assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - learnedNoGoodDeletion.increaseConflictCounter(); - assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - assertNull(store.add(4, NoGood.learnt(fromOldLiterals(10, 11, 12)), 3)); - assertNull(store.add(5, NoGood.learnt(fromOldLiterals(10, -13, -14)), 4)); - List watchedNoGoods = learnedNoGoodDeletion.inspectLearnedNoGoods(); - assertTrue(watchedNoGoods.size() >= 2); - WatchedNoGood watchedNoGood = watchedNoGoods.get(0); - for (int i = 0; i < 10; i++) { - watchedNoGood.bumpActivity(); - } - learnedNoGoodDeletion.runNoGoodDeletion(); - watchedNoGoods = learnedNoGoodDeletion.inspectLearnedNoGoods(); - assertTrue(watchedNoGoods.size() < 2); - } - - @Test - public void testDeletionIncreasesDeletionCounter() { - for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { - learnedNoGoodDeletion.increaseConflictCounter(); - } - assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - learnedNoGoodDeletion.increaseConflictCounter(); - assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - assertNull(store.add(4, NoGood.learnt(fromOldLiterals(10, 11, 12)), 3)); - assertNull(store.add(5, NoGood.learnt(fromOldLiterals(10, -13, -14)), 4)); - assertEquals(0, learnedNoGoodDeletion.getNumberOfDeletedNoGoods()); - learnedNoGoodDeletion.runNoGoodDeletion(); - assertTrue(learnedNoGoodDeletion.getNumberOfDeletedNoGoods() > 0); - } - - @Test - public void testDeletionReducesNumberOfLearntNoGoods() { - for (int i = 0; i < LearnedNoGoodDeletion.RUN_AFTER_AT_LEAST; i++) { - learnedNoGoodDeletion.increaseConflictCounter(); - } - assertFalse(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - learnedNoGoodDeletion.increaseConflictCounter(); - assertTrue(learnedNoGoodDeletion.needToRunNoGoodDeletion()); - assertNull(store.add(4, NoGood.learnt(fromOldLiterals(10, 11, 12)), 3)); - assertNull(store.add(5, NoGood.learnt(fromOldLiterals(10, -13, -14)), 4)); - - final Map countersBeforeDeletion = countNoGoodsByType(store); - learnedNoGoodDeletion.runNoGoodDeletion(); - final Map countersAfterDeletion = countNoGoodsByType(store); - - for (Type type : Type.values()) { - if (type == Type.LEARNT) { - assertTrue("Count of LEARNT nogoods did not decrease during deletion", countersBeforeDeletion.get(type) > countersAfterDeletion.get(type)); - } else { - assertEquals("Unexpected count of " + type + " nogoods", countersBeforeDeletion.get(type), countersAfterDeletion.get(type)); - } - } - - } - - private Map countNoGoodsByType(NoGoodStore store) { - final Map counters = new HashMap<>(); - final NoGoodCounter noGoodCounter = store.getNoGoodCounter(); - for (Type type : Type.values()) { - counters.put(type, noGoodCounter.getNumberOfNoGoods(type)); - } - return counters; - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java deleted file mode 100644 index 33a069469..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java +++ /dev/null @@ -1,588 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import at.ac.tuwien.kr.alpha.common.*; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import static at.ac.tuwien.kr.alpha.common.NoGood.fact; -import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; -import static org.junit.Assert.*; - -/** - * Copyright (c) 2017, the Alpha Team. - */ -public class NaiveNoGoodStoreTest { - private final AtomStore atomStore; - private final TrailAssignment assignment; - private final NaiveNoGoodStore store; - - public NaiveNoGoodStoreTest() { - atomStore = new AtomStoreImpl(); - assignment = new TrailAssignment(atomStore); - store = new NaiveNoGoodStore(assignment); - } - - @Before - public void setUp() { - store.clear(); - AtomStoreTest.fillAtomStore(atomStore, 200); - assignment.growForMaxAtomId(); - } - - @Test - public void singleFact() { - store.add(1, fact(fromOldLiterals(-1))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void single() { - store.add(1, new NoGood(fromOldLiterals(-1))); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - public void constraintWithAssignment() { - assignment.assign(123, MBT); - assignment.assign(23, TRUE); - store.add(3, new NoGood(fromOldLiterals(-123, 22, 23))); - } - - @Test - public void assignment() { - store.add(3, headFirst(fromOldLiterals(-7, -4, -2))); - assignment.assign(4, TRUE); - assignment.assign(2, FALSE); - assignment.assign(7, FALSE); - assertNull(store.propagate()); - } - - - @Test - public void addNotCausingAssignment() { - assignment.assign(1, TRUE); - store.add(3, headFirst(fromOldLiterals(-3, -2, 1))); - - assertEquals(null, assignment.getTruth(3)); - } - - @Test - public void addNotCausingAssignmentUnassigned() { - assignment.assign(1, TRUE); - store.add(3, headFirst(fromOldLiterals(-5, 4, 1))); - - assertEquals(null, assignment.getTruth(5)); - } - - @Test - @Ignore("Checks for conflict detection in add.") - public void addNotCausingAssignmentFalse() { - assignment.assign(1, FALSE); - assignment.assign(4, TRUE); - store.add(3, headFirst(fromOldLiterals(-5, 4, -1))); - - assertEquals(TRUE, assignment.getTruth(5)); - } - - @Test - public void addNotCausingAssignmentTrue() { - assignment.assign(1, TRUE); - assignment.assign(2, TRUE); - store.add(1, headFirst(fromOldLiterals(-3, 2, -1))); - - assertEquals(null, assignment.getTruth(3)); - } - - @Test - public void propBinary() { - assignment.assign(2, FALSE); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assertEquals(null, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryFirstTrue() { - assignment.assign(2, TRUE); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryMBT() { - assignment.assign(2, MBT); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryTrue() { - assignment.assign(2, TRUE); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryMBTAfterAssignment() { - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assignment.assign(2, MBT); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryTrueAfterAssignment() { - store.add(1, headFirst(fromOldLiterals(-1, 2))); - assignment.assign(2, TRUE); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryMBTTwice() { - assignment.assign(2, MBT); - - store.add(1, new NoGood(fromOldLiterals(-1, 2))); - store.add(2, new NoGood(fromOldLiterals(-3, 1))); - - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(3)); - } - - - @Test - public void propagateBinaryMBTTwiceOutofSync() { - store.add(1, new NoGood(fromOldLiterals(-1, 2))); - store.add(2, new NoGood(fromOldLiterals(-3, 1))); - - assignment.assign(2, MBT); - - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(3)); - } - - @Test - public void propagateNaryTrue() { - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - - assertNull(store.add(1, headFirst(fromOldLiterals(-1, 2, 3)))); - - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateNaryFalse() { - assignment.assign(2, FALSE); - assignment.assign(3, FALSE); - - store.add(1, NoGood.headFirst(fromOldLiterals(-1, -3, -2))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void addFullyAssignedBinary() { - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - - store.add(1, headFirst(fromOldLiterals(-2, 3))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(2)); - assertEquals(TRUE, assignment.getTruth(3)); - } - - @Test - public void addFullyAssignedNary() { - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - assignment.assign(4, TRUE); - - store.add(1, headFirst(fromOldLiterals(-2, 3, 4))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(2)); - assertEquals(TRUE, assignment.getTruth(3)); - assertEquals(TRUE, assignment.getTruth(4)); - } - - @Test - public void propagateNaryMBT() { - final NoGood noGood = headFirst(fromOldLiterals(-1, 2, 3)); - - assignment.assign(2, MBT); - assignment.assign(3, MBT); - - store.add(1, noGood); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - @Ignore("Checks for propagation in add.") - public void propagateNaryMBTTwice() { - assignment.assign(4, FALSE); - assignment.assign(3, MBT); - assignment.assign(2, MBT); - - store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); - assertEquals(MBT, assignment.getTruth(1)); - - store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(5)); - } - - @Test - public void propagateNaryFactsMultiple() { - NoGood[] noGoods = new NoGood[]{ - headFirst(fromOldLiterals(-1, 2, 3)), // 1 <- 2, 3. - headFirst(fromOldLiterals(-5, 4, 1)), // 5 <- 4, 1. - fact(fromOldLiterals(-4)), // 4. - fact(fromOldLiterals(-3)), // 3. - fact(fromOldLiterals(-2)) // 2. - }; - for (int i = 0; i < noGoods.length; i++) { - assertNull(store.add(i + 1, noGoods[i])); - } - - // First deduce 1 from 2 and 3, then deduce - // 5 from -4 and 1. - store.propagate(); - assertTrue(store.didPropagate()); - - assertEquals(TRUE, assignment.getTruth(1)); - assertEquals(TRUE, assignment.getTruth(5)); - } - - @Test - public void moveThirdPointer() { - // 1 <- 2, 3. - store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); - assertNull(store.propagate()); - assertFalse(store.didPropagate()); - - // 2. - store.add(2, fact(fromOldLiterals(-2))); - assertNull(store.propagate()); - assertTrue(store.didPropagate()); - assertEquals(TRUE, assignment.getTruth(2)); - assertNull(assignment.getTruth(1)); - - // 3. - store.add(3, fact(fromOldLiterals(-3))); - assertNull(store.propagate()); - assertTrue(store.didPropagate()); - assertEquals(TRUE, assignment.getTruth(3)); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateNaryMBTTwiceReordered() { - // From 2 and 3 follows 1. - store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); - // From -4 and 1 follows 5. - store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); - - // Assign 4 to false (first premise for 5). - assignment.assign(4, FALSE); - - // Assign 3 and 2 to MBT (premises for 1). - assignment.assign(3, MBT); - assignment.assign(2, MBT); - - // Now 1 must follow from 2 and 3, - // and 5 must follow from -4 and 1. - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(5)); - } - - @Test - public void conflictingFact() { - final NoGood noGood = fact(fromOldLiterals(-1)); - assignment.assign(1, FALSE); - ConflictCause conflictCause = store.add(1, noGood); - assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - @Ignore("Checks for conflict detection in add.") - public void conflictingBinary() { - final NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assignment.assign(1, TRUE); - assignment.assign(2, TRUE); - ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - @Ignore("Checks for conflict detection in add.") - public void conflictingNary() { - final NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assignment.assign(1, TRUE); - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void propagateViolatedConstraint() { - NoGood noGood = headFirst(fromOldLiterals(-3, -2, -1)); - assertNull(store.add(1, noGood)); - assertNull(assignment.assign(1, FALSE)); - assertNull(assignment.assign(2, FALSE)); - assertNull(assignment.assign(3, FALSE)); - ConflictCause conflictCause = store.propagate(); - assertNotNull(conflictCause); - assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void noViolation() { - assertNull(store.add(1, headFirst(fromOldLiterals(-7, -4, -2)))); - assertNull(assignment.assign(4, TRUE)); - assertNull(assignment.assign(2, FALSE)); - assertNull(assignment.assign(7, FALSE)); - assertNull(store.propagate()); - assertNull(store.propagate()); - } - - @Test - public void propagateViolatedConstraintHeadless() { - NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); - assertNull(store.add(24, noGood)); - assertNull(assignment.assign(3, TRUE)); - assertNull(assignment.assign(11, TRUE)); - assertNull(assignment.assign(19, TRUE)); - ConflictCause conflictCause = store.propagate(); - assertNotNull(conflictCause); - assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void propagateViolatedConstraintHeadlessMbt() { - NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); - assertNull(store.add(24, noGood)); - assertNull(assignment.assign(3, MBT)); - assertNull(assignment.assign(11, MBT)); - assertNull(assignment.assign(19, MBT)); - ConflictCause conflictCause = store.propagate(); - assertNotNull(conflictCause); - assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void neverViolatedNoGood() { - NoGood noGood = new NoGood(fromOldLiterals(-44, 10, 13, 44)); - assertNull(store.add(80, noGood)); - assertNull(assignment.assign(10, TRUE)); - assertNull(assignment.assign(13, TRUE)); - assertNull(assignment.assign(44, FALSE)); - assertNull(store.propagate()); - } - - @Test - public void naryNoGoodViolatedAfterAddition() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assertNull(store.add(11, noGood)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - assertNull(assignment.assign(3, MBT)); - assertNotNull(store.propagate()); - } - - @Test - @Ignore("Checks for conflict detection in add.") - public void naryNoGoodViolatedDuringAdditionAllTrue() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assertNull(assignment.assign(1, TRUE)); - assertNull(assignment.assign(2, TRUE)); - assertNull(assignment.assign(3, TRUE)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - @Ignore("Checks for conflict detection in add.") - public void naryNoGoodViolatedDuringAdditionAllMbt() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - assertNull(assignment.assign(3, MBT)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - public void binaryNoGoodViolatedAfterAddition() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assertNull(store.add(1, noGood)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - assertNotNull(store.propagate()); - } - - @Test - @Ignore("Checks for conflict detection in add.") - public void binaryNoGoodViolatedDuringAdditionAllTrue() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assertNull(assignment.assign(1, TRUE)); - assertNull(assignment.assign(2, TRUE)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - @Ignore("Checks for conflict detection in add.") - public void binaryNoGoodViolatedDuringAdditionAllMbt() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - public void addedViolatedBinaryNoGoodPropagatesAfterBacktracking() { - NoGood noGood = new NoGood(fromOldLiterals(70, 195)); - assertNull(assignment.choose(70, MBT)); - assertNull(assignment.choose(195, MBT)); - assertNotNull(store.add(3, noGood)); - assignment.backtrack(); - assertNull(store.add(3, noGood)); - store.propagate(); - assertEquals(FALSE, assignment.getTruth(195)); - } - - @Test - public void addedViolatedNaryNoGoodPropagatesAfterBacktracking() { - NoGood noGood = new NoGood(fromOldLiterals(70, 195, 36)); - assertNull(assignment.choose(70, MBT)); - assertNull(assignment.choose(195, MBT)); - assertNull(assignment.choose(36, MBT)); - assertNotNull(store.add(3, noGood)); - assignment.backtrack(); - assertNull(store.add(3, noGood)); - store.propagate(); - assertEquals(FALSE, assignment.getTruth(36)); - } - - @Test - public void binaryNoGoodPropagatesTrueFromFalse() { - NoGood noGood = headFirst(fromOldLiterals(-11, -12)); - assertNull(store.add(5, noGood)); - assertNull(assignment.choose(12, FALSE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(11)); - } - - @Test - public void binaryNoGoodPropagatesTrueFromTrue() { - NoGood noGood = headFirst(fromOldLiterals(-11, 12)); - assertNull(store.add(5, noGood)); - assertNull(assignment.choose(12, TRUE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(11)); - } - - - @Test - @Ignore("Checks for propagation in add.") - public void addedBinaryNoGoodPropagatesTrueFromFalse() { - NoGood noGood = headFirst(fromOldLiterals(-11, -12)); - assertNull(assignment.choose(12, FALSE)); - assertNull(store.add(5, noGood)); - assertEquals(TRUE, assignment.getTruth(11)); - } - - @Test - public void addedBinaryNoGoodPropagatesTrueFromTrue() { - NoGood noGood = headFirst(fromOldLiterals(-11, 12)); - assertNull(assignment.choose(12, TRUE)); - assertNull(store.add(5, noGood)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(11)); - } - - @Test - public void naryNoGoodPropagatesTrueFromFalse() { - NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); - assertNull(store.add(10, noGood)); - assertNull(assignment.assign(2, TRUE)); - store.propagate(); - assertNull(assignment.assign(3, FALSE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void naryNoGoodPropagatesTrueFromTrue() { - NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); - assertNull(store.add(10, noGood)); - assertNull(assignment.assign(3, FALSE)); - store.propagate(); - assertNull(assignment.assign(2, TRUE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - @Ignore("Not decision-level aware.") - public void propagationAtLowerDecisionLevel() { - NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); - assertNull(assignment.choose(3, FALSE)); - assertNull(assignment.choose(2, TRUE)); - assertNull(assignment.choose(4, TRUE)); - assertNull(store.add(10, noGood)); - assertNull(store.propagate()); - assertEquals(TRUE, assignment.getTruth(1)); - Assignment.Entry entry = assignment.get(1); - assertEquals(TRUE, entry.getTruth()); - assertEquals(2, entry.getDecisionLevel()); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java deleted file mode 100644 index 0f6d73acf..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java +++ /dev/null @@ -1,615 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import at.ac.tuwien.kr.alpha.common.*; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import static at.ac.tuwien.kr.alpha.common.NoGood.fact; -import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; -import static org.junit.Assert.*; - -/** - * Copyright (c) 2017, the Alpha Team. - */ -public class NoGoodStoreAlphaRoamingTest { - - private final AtomStore atomStore; - private final TrailAssignment assignment; - private final NoGoodStoreAlphaRoaming store; - - public NoGoodStoreAlphaRoamingTest() { - atomStore = new AtomStoreImpl(); - AtomStoreTest.fillAtomStore(atomStore, 200); - assignment = new TrailAssignment(atomStore); - assignment.growForMaxAtomId(); - store = new NoGoodStoreAlphaRoaming(assignment); - } - - @Before - public void setUp() { - store.clear(); - store.growForMaxAtomId(fromOldLiterals(200)); - } - - @Test - public void singleFact() { - store.add(1, fact(fromOldLiterals(-1))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void single() { - store.add(1, new NoGood(fromOldLiterals(-1))); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - public void constraintWithAssignment() { - assignment.assign(123, MBT); - assignment.assign(23, TRUE); - store.add(3, new NoGood(fromOldLiterals(-123, 22, 23))); - } - - @Test - public void assignment() { - store.add(3, headFirst(fromOldLiterals(-7, -4, -2))); - assignment.assign(4, TRUE); - assignment.assign(2, FALSE); - assignment.assign(7, FALSE); - assertNull(store.propagate()); - } - - - @Test - public void addNotCausingAssignment() { - assignment.assign(1, TRUE); - store.add(3, headFirst(fromOldLiterals(-3, -2, 1))); - - assertEquals(null, assignment.getTruth(3)); - } - - @Test - public void addNotCausingAssignmentUnassigned() { - assignment.assign(1, TRUE); - store.add(3, headFirst(fromOldLiterals(-5, 4, 1))); - - assertEquals(null, assignment.getTruth(5)); - } - - @Test - public void addNotCausingAssignmentFalse() { - assignment.assign(1, FALSE); - assignment.assign(4, TRUE); - store.add(3, headFirst(fromOldLiterals(-5, 4, -1))); - - assertEquals(TRUE, assignment.getTruth(5)); - } - - @Test - public void addNotCausingAssignmentTrue() { - assignment.assign(1, TRUE); - assignment.assign(2, TRUE); - store.add(1, headFirst(fromOldLiterals(-3, 2, -1))); - - assertEquals(null, assignment.getTruth(3)); - } - - @Test - public void propBinary() { - assignment.assign(2, FALSE); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assertEquals(null, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryFirstTrue() { - assignment.assign(2, TRUE); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryMBT() { - assignment.assign(2, MBT); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryTrue() { - assignment.assign(2, TRUE); - - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryMBTAfterAssignment() { - store.add(1, headFirst(fromOldLiterals(-1, 2))); - store.propagate(); - - assignment.assign(2, MBT); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryTrueAfterAssignment() { - store.add(1, headFirst(fromOldLiterals(-1, 2))); - assignment.assign(2, TRUE); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateBinaryMBTTwice() { - assignment.assign(2, MBT); - - store.add(1, new NoGood(fromOldLiterals(-1, 2))); - store.add(2, new NoGood(fromOldLiterals(-3, 1))); - - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(3)); - } - - - @Test - public void propagateBinaryMBTTwiceOutofSync() { - store.add(1, new NoGood(fromOldLiterals(-1, 2))); - store.add(2, new NoGood(fromOldLiterals(-3, 1))); - - assignment.assign(2, MBT); - - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(3)); - } - - @Test - public void propagateNaryTrue() { - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - - assertNull(store.add(1, headFirst(fromOldLiterals(-1, 2, 3)))); - - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateNaryFalse() { - assignment.assign(2, FALSE); - assignment.assign(3, FALSE); - - store.add(1, headFirst(fromOldLiterals(-1, -3, -2))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void addFullyAssignedBinary() { - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - - store.add(1, headFirst(fromOldLiterals(-2, 3))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(2)); - assertEquals(TRUE, assignment.getTruth(3)); - } - - @Test - public void addFullyAssignedNary() { - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - assignment.assign(4, TRUE); - - store.add(1, headFirst(fromOldLiterals(-2, 3, 4))); - store.propagate(); - - assertEquals(TRUE, assignment.getTruth(2)); - assertEquals(TRUE, assignment.getTruth(3)); - assertEquals(TRUE, assignment.getTruth(4)); - } - - @Test - public void propagateNaryMBT() { - final NoGood noGood = headFirst(fromOldLiterals(-1, 2, 3)); - - assignment.assign(2, MBT); - assignment.assign(3, MBT); - - store.add(1, noGood); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - } - - @Test - public void propagateNaryMBTTwice() { - assignment.assign(4, FALSE); - assignment.assign(3, MBT); - assignment.assign(2, MBT); - - store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); - assertEquals(MBT, assignment.getTruth(1)); - - store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(5)); - } - - @Test - public void propagateNaryFactsMultiple() { - NoGood[] noGoods = new NoGood[]{ - headFirst(fromOldLiterals(-1, 2, 3)), // 1 <- 2, 3. - headFirst(fromOldLiterals(-5, 4, 1)), // 5 <- 4, 1. - fact(fromOldLiterals(-4)), // 4. - fact(fromOldLiterals(-3)), // 3. - fact(fromOldLiterals(-2)) // 2. - }; - for (int i = 0; i < noGoods.length; i++) { - assertNull(store.add(i + 1, noGoods[i])); - } - - // First deduce 1 from 2 and 3, then deduce - // 5 from -4 and 1. - assertNull(store.propagate()); - assertTrue(store.didPropagate()); - - assertEquals(TRUE, assignment.getTruth(1)); - assertEquals(TRUE, assignment.getTruth(5)); - } - - @Test - public void moveThirdPointer() { - // 1 <- 2, 3. - store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); - assertNull(store.propagate()); - assertFalse(store.didPropagate()); - - // 2. - store.add(2, fact(fromOldLiterals(-2))); - assertNull(store.propagate()); - assertFalse(store.didPropagate()); - assertNull(assignment.getTruth(1)); - - // 3. - store.add(3, fact(fromOldLiterals(-3))); - assertNull(store.propagate()); - assertTrue(store.didPropagate()); - - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void propagateNaryMBTTwiceReordered() { - // From 2 and 3 follows 1. - store.add(1, headFirst(fromOldLiterals(-1, 2, 3))); - // From -4 and 1 follows 5. - store.add(2, headFirst(fromOldLiterals(-5, -4, 1))); - - // Assign 4 to false (first premise for 5). - assignment.assign(4, FALSE); - - // Assign 3 and 2 to MBT (premises for 1). - assignment.assign(3, MBT); - assignment.assign(2, MBT); - - // Now 1 must follow from 2 and 3, - // and 5 must follow from -4 and 1. - store.propagate(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(MBT, assignment.getTruth(5)); - } - - @Test - public void conflictingFact() { - final NoGood noGood = fact(fromOldLiterals(-1)); - assignment.assign(1, FALSE); - ConflictCause conflictCause = store.add(1, noGood); - assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void conflictingBinary() { - final NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assignment.assign(1, TRUE); - assignment.assign(2, TRUE); - ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void conflictingNary() { - final NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assignment.assign(1, TRUE); - assignment.assign(2, TRUE); - assignment.assign(3, TRUE); - ConflictCause conflictCause = store.add(1, noGood); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void propagateViolatedConstraint() { - NoGood noGood = headFirst(fromOldLiterals(-3, -2, -1)); - assertNull(store.add(1, noGood)); - assertNull(assignment.assign(1, FALSE)); - assertNull(assignment.assign(2, FALSE)); - assertNull(assignment.assign(3, FALSE)); - ConflictCause conflictCause = store.propagate(); - assertNotNull(conflictCause); - assertFalse(store.didPropagate()); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void noViolation() { - assertNull(store.add(1, headFirst(fromOldLiterals(-7, -4, -2)))); - assertNull(assignment.assign(4, TRUE)); - assertNull(assignment.assign(2, FALSE)); - assertNull(assignment.assign(7, FALSE)); - assertNull(store.propagate()); - } - - @Test - public void propagateViolatedConstraintHeadless() { - NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); - assertNull(store.add(24, noGood)); - assertNull(assignment.assign(3, TRUE)); - assertNull(assignment.assign(11, TRUE)); - assertNull(assignment.assign(19, TRUE)); - ConflictCause conflictCause = store.propagate(); - assertFalse(store.didPropagate()); - assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void propagateViolatedConstraintHeadlessMbt() { - NoGood noGood = new NoGood(fromOldLiterals(3, 11, 19)); - assertNull(store.add(24, noGood)); - assertNull(assignment.assign(3, MBT)); - assertNull(assignment.assign(11, MBT)); - assertNull(assignment.assign(19, MBT)); - ConflictCause conflictCause = store.propagate(); - assertFalse(store.didPropagate()); - assertNotNull(conflictCause); - assertTrue(antecedentsEquals(noGood.asAntecedent(), conflictCause.getAntecedent())); - } - - @Test - public void neverViolatedNoGood() { - NoGood noGood = new NoGood(fromOldLiterals(-44, 10, 13, 44)); - assertNull(store.add(80, noGood)); - assertNull(assignment.assign(10, TRUE)); - assertNull(assignment.assign(13, TRUE)); - assertNull(assignment.assign(44, FALSE)); - assertNull(store.propagate()); - } - - @Test - public void naryNoGoodViolatedAfterAddition() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assertNull(store.add(11, noGood)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - assertNull(assignment.assign(3, MBT)); - assertNotNull(store.propagate()); - } - - @Test - public void naryNoGoodViolatedDuringAdditionAllTrue() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assertNull(assignment.assign(1, TRUE)); - assertNull(assignment.assign(2, TRUE)); - assertNull(assignment.assign(3, TRUE)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - public void naryNoGoodViolatedDuringAdditionAllMbt() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2, 3)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - assertNull(assignment.assign(3, MBT)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - public void binaryNoGoodViolatedAfterAddition() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assertNull(store.add(11, noGood)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - assertNotNull(store.propagate()); - } - - @Test - public void binaryNoGoodViolatedDuringAdditionAllTrue() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assertNull(assignment.assign(1, TRUE)); - assertNull(assignment.assign(2, TRUE)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - public void binaryNoGoodViolatedDuringAdditionAllMbt() { - NoGood noGood = new NoGood(fromOldLiterals(1, 2)); - assertNull(assignment.assign(1, MBT)); - assertNull(assignment.assign(2, MBT)); - ConflictCause conflictCause = store.add(11, noGood); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - } - - @Test - public void addedViolatedBinaryNoGoodPropagatesAfterBacktracking() { - NoGood noGood = new NoGood(fromOldLiterals(70, 195)); - assertNull(assignment.choose(70, MBT)); - assertNull(assignment.choose(195, MBT)); - assertNotNull(store.add(3, noGood)); - assignment.backtrack(); - assertNull(store.add(3, noGood)); - store.propagate(); - assertEquals(FALSE, assignment.getTruth(195)); - } - - @Test - public void addedViolatedNaryNoGoodPropagatesAfterBacktracking() { - NoGood noGood = new NoGood(fromOldLiterals(70, 195, 36)); - assertNull(assignment.choose(70, MBT)); - assertNull(assignment.choose(195, MBT)); - assertNull(assignment.choose(36, MBT)); - assertNotNull(store.add(3, noGood)); - assignment.backtrack(); - assertNull(store.add(3, noGood)); - store.propagate(); - assertEquals(FALSE, assignment.getTruth(36)); - } - - @Test - public void binaryNoGoodPropagatesTrueFromFalse() { - NoGood noGood = headFirst(fromOldLiterals(-11, -12)); - assertNull(store.add(5, noGood)); - assertNull(assignment.choose(12, FALSE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(11)); - } - - @Test - public void binaryNoGoodPropagatesTrueFromTrue() { - NoGood noGood = headFirst(fromOldLiterals(-11, 12)); - assertNull(store.add(5, noGood)); - assertNull(assignment.choose(12, TRUE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(11)); - } - - - @Test - public void addedBinaryNoGoodPropagatesTrueFromFalse() { - NoGood noGood = headFirst(fromOldLiterals(-11, -12)); - assertNull(assignment.choose(12, FALSE)); - assertNull(store.add(5, noGood)); - assertEquals(TRUE, assignment.getTruth(11)); - } - - @Test - public void addedBinaryNoGoodPropagatesTrueFromTrue() { - NoGood noGood = headFirst(fromOldLiterals(-11, 12)); - assertNull(assignment.choose(12, TRUE)); - assertNull(store.add(5, noGood)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(11)); - } - - @Test - public void naryNoGoodPropagatesTrueFromFalse() { - NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); - assertNull(store.add(10, noGood)); - assertNull(assignment.assign(2, TRUE)); - store.propagate(); - assertNull(assignment.assign(3, FALSE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Test - public void naryNoGoodPropagatesTrueFromTrue() { - NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); - assertNull(store.add(10, noGood)); - assertNull(assignment.assign(3, FALSE)); - store.propagate(); - assertNull(assignment.assign(2, TRUE)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(1)); - } - - @Ignore // TrailAssignment no longer propagates at lower decision level. - @Test - public void propagationAtLowerDecisionLevel() { - NoGood noGood = headFirst(fromOldLiterals(-1, 2, -3)); - assertNull(assignment.choose(3, FALSE)); - assertNull(assignment.choose(2, TRUE)); - assertNull(assignment.choose(4, TRUE)); - assertNull(store.add(10, noGood)); - store.propagate(); - assertEquals(TRUE, assignment.getTruth(1)); - Assignment.Entry entry = assignment.get(1); - assertEquals(TRUE, entry.getTruth()); - assertEquals(2, entry.getDecisionLevel()); - } - - @Test - public void violationByPropagationAtLowerDecisionLevel() { - assertNull(store.add(1, new NoGood(fromOldLiterals(1, -2)))); - assertNull(store.add(2, new NoGood(fromOldLiterals(2, -3)))); - assertNull(store.add(3, new NoGood(fromOldLiterals(2, -4)))); - assertNull(store.add(4, new NoGood(fromOldLiterals(3, 4, 5)))); - - assertNull(assignment.choose(7, FALSE)); - assertNull(store.propagate()); - assertNull(assignment.choose(6, FALSE)); - assertNull(store.propagate()); - assertNull(assignment.choose(5, TRUE)); - assertNull(store.propagate()); - - assertNull(store.add(5, new NoGood(fromOldLiterals(-1)))); - ConflictCause cause = store.propagate(); - assertNotNull(cause); - } - - @Test - public void alphaWatchNotIgnored() { - assertNull(assignment.choose(2, TRUE)); - assertNull(store.propagate()); - assertNull(assignment.choose(3, TRUE)); - assertNull(store.propagate()); - assertNull(assignment.choose(1, TRUE)); - assertNull(store.propagate()); - - assertNull(store.add(1, headFirst(fromOldLiterals(-1, 2, 3)))); - - store.backtrack(); - store.backtrack(); - assertNull(assignment.choose(3, TRUE)); - assertNull(store.propagate()); - assertEquals(TRUE, assignment.getTruth(1)); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java deleted file mode 100644 index 2e3b97f8c..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright (c) 2017-2019 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.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Paths; -import java.util.Optional; - -/** - * Tests {@link AbstractSolver} using Omiga benchmark problems. - * - */ -public class OmigaBenchmarksTest extends AbstractSolverTests { - - private static final Logger LOGGER = LoggerFactory.getLogger(OmigaBenchmarksTest.class); - - @Test(timeout = 10000) - public void test3Col_10_18() throws IOException { - test("3col", "3col-10-18.txt"); - } - - @Test(timeout = 10000) - public void test3Col_20_38() throws IOException { - test("3col", "3col-20-38.txt"); - } - - @Test(timeout = 15000) - public void testCutedge_100_30() throws IOException { - test("cutedge", "cutedge-100-30.txt"); - } - - @Test(timeout = 15000) - public void testCutedge_100_50() throws IOException { - test("cutedge", "cutedge-100-50.txt"); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testLocstrat_200() throws IOException { - test("locstrat", "locstrat-200.txt"); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testLocstrat_400() throws IOException { - test("locstrat", "locstrat-400.txt"); - } - - @Test(timeout = 15000) - public void testReach_1() throws IOException { - ignoreTestForNaiveSolver(); - ignoreNonDefaultDomainIndependentHeuristics(); - test("reach", "reach-1.txt"); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testReach_4() throws IOException { - test("reach", "reach-4.txt"); - } - - private void test(String folder, String aspFileName) throws IOException { - CharStream programInputStream = CharStreams.fromPath(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName)); - Optional answerSet = getInstance(programInputStream).stream().findFirst(); - // System.out.println(answerSet); - // TODO: check correctness of answer set - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java deleted file mode 100644 index f5a34eefd..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import org.junit.Ignore; -import org.junit.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.Assert.assertFalse; - -/** - * Tests {@link AbstractSolver} using some configuration test cases in which subparts are assigned to parts. - * - */ -public class PartSubpartConfigurationTest extends AbstractSolverTests { - @Test(timeout = 1000) - public void testN2() throws IOException { - testPartSubpart(2); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN4() throws IOException { - testPartSubpart(4); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN8() throws IOException { - testPartSubpart(8); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN16() throws IOException { - testPartSubpart(16); - } - - @Test(timeout = 61000) - @Ignore("disabled to save resources during CI") - public void testN32() throws IOException { - testPartSubpart(32); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN60() throws IOException { - testPartSubpart(60); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN75() throws IOException { - testPartSubpart(75); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN100() throws IOException { - testPartSubpart(100); - } - - private void testPartSubpart(int n) throws IOException { - List rules = new ArrayList<>(); - for (int i = 1; i <= n; i++) { - rules.add(String.format("n(%d).", i)); - } - - rules.addAll(Arrays.asList( - "part(N) :- n(N), not no_part(N).", - "no_part(N) :- n(N), not part(N).", - "subpartid(SP,ID) :- subpart(SP,P), n(ID), not no_subpartid(SP,ID).", - "no_subpartid(SP,ID) :- subpart(SP,P), n(ID), not subpartid(SP,ID).", - "subpart(SP,P) :- part(P), part(SP), P != SP, not no_subpart(SP,P).", - "no_subpart(SP,P) :- part(P), part(SP), P != SP, not subpart(SP,P).", - ":- subpart(SP,P1), subpart(SP,P2), P1 != P2.", - ":- subpart(SP1,P), subpart(SP2, P), SP1!=SP2, subpartid(SP1,ID), subpartid(SP2,ID)." - )); - - assertFalse(collectSet(concat(rules)).isEmpty()); - // TODO: check correctness of answer set - } - - private String concat(List rules) { - String ls = System.lineSeparator(); - return rules.stream().collect(Collectors.joining(ls)); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java deleted file mode 100644 index 48c9857b9..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; -import org.junit.Ignore; -import org.junit.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; - -/** - * Tests {@link AbstractSolver} using some pigeon-hole test cases (see https://en.wikipedia.org/wiki/Pigeonhole_principle). - */ -public class PigeonHoleTest extends AbstractSolverTests { - @Test(timeout = 5000) - public void test2Pigeons2Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - testPigeonsHoles(2, 2); - } - - @Test(timeout = 5000) - public void test3Pigeons2Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - testPigeonsHoles(3, 2); - } - - @Test(timeout = 5000) - public void test2Pigeons3Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - testPigeonsHoles(2, 3); - } - - @Test(timeout = 10000) - public void test3Pigeons3Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - testPigeonsHoles(3, 3); - } - - @Test(timeout = 10000) - public void test4Pigeons3Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - testPigeonsHoles(4, 3); - } - - @Test(timeout = 10000) - public void test3Pigeons4Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - testPigeonsHoles(3, 4); - } - - @Test(timeout = 10000) - public void test4Pigeons4Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); - testPigeonsHoles(4, 4); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void test10Pigeons10Holes() throws IOException { - testPigeonsHoles(10, 10); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void test19Pigeons20Holes() throws IOException { - testPigeonsHoles(19, 20); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void test28Pigeons30Holes() throws IOException { - testPigeonsHoles(28, 30); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void test37Pigeons40Holes() throws IOException { - testPigeonsHoles(37, 40); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void test46Pigeons50Holes() throws IOException { - testPigeonsHoles(46, 50); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void test55Pigeons60Holes() throws IOException { - testPigeonsHoles(55, 60); - } - - /** - * Tries to solve the problem of assigning P pigeons to H holes. - */ - private void testPigeonsHoles(int pigeons, int holes) throws IOException { - 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)."); - rules.add(":- pigeon(P), hole(H1), hole(H2), pos(P,H1), pos(P,H2), H1 != H2."); - rules.add(":- pigeon(P), not hashole(P)."); - rules.add("hashole(P) :- pigeon(P), hole(H), pos(P,H)."); - rules.add(":- pigeon(P1), pigeon(P2), hole(H), pos(P1,H), pos(P2,H), P1 != P2."); - - addPigeons(rules, pigeons); - addHoles(rules, holes); - - Set answerSets = collectSet(concat(rules)); - assertEquals(numberOfSolutions(pigeons, holes), answerSets.size()); - } - - private void addPigeons(List rules, int pigeons) { - addFacts(rules, "pigeon", 1, pigeons); - } - - private void addHoles(List rules, int holes) { - addFacts(rules, "hole", 1, holes); - } - - private void addFacts(List rules, String predicateName, int from, int to) { - for (int i = from; i <= to; i++) { - rules.add(String.format("%s(%d).", predicateName, i)); - } - } - - private String concat(List rules) { - String ls = System.lineSeparator(); - return rules.stream().collect(Collectors.joining(ls)); - } - - private long numberOfSolutions(int pigeons, int holes) { - if (pigeons > holes) { - return 0; - } else if (pigeons == holes) { - return factorial(pigeons); - } else { - return factorial(holes) / factorial(holes - pigeons); - // could be replaced by more efficient implementaton (but performance is not so important here) - } - } - - private long factorial(int n) { - return n <= 1 ? 1 : n * factorial(n - 1); - // could be replaced by more efficient implementaton (but performance is not so important here) - // see http://www.luschny.de/math/factorial/FastFactorialFunctions.htm - // TODO: we could use Apache Commons Math - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java deleted file mode 100644 index 4125dc5a7..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.Ignore; -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Paths; -import java.util.Optional; - -/** - * Tests {@link AbstractSolver} using a racks configuration problem. - * - */ -@Ignore("disabled to save resources during CI") -public class RacksTest extends AbstractSolverTests { - @Test(timeout = 10000) - public void testRacks() throws IOException { - test(); - } - - private void test() throws IOException { - CharStream programInputStream = CharStreams.fromPath( - Paths.get("benchmarks", "siemens", "racks", "racks.lp") - ); - Solver solver = getInstance(programInputStream); - Optional answerSet = solver.stream().findFirst(); - //System.out.println(answerSet); - // TODO: check correctness of answer set - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java deleted file mode 100644 index a5f9df004..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright (c) 2017-2019 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.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.grounder.DummyGrounder; -import org.junit.Before; -import org.junit.Test; - -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; - -public class SolverStatisticsTests extends AbstractSolverTests { - - private AtomStore atomStore; - - @Before - public void setUp() { - this.atomStore = new AtomStoreImpl(); - } - - @Test - public void checkStatsStringZeroChoices() { - Solver solver = getInstance("a."); - assumeTrue(solver instanceof SolverMaintainingStatistics); - collectAnswerSetsAndCheckStats(solver, 1, 0, 0, 0, 0, 0, 0, 0); - } - - @Test - public void checkStatsStringOneChoice() { - Solver solver = getInstance("a :- not b. b :- not a."); - assumeTrue(solver instanceof SolverMaintainingStatistics); - collectAnswerSetsAndCheckStats(solver, 2, 1, 1, 1, 1, 0, 0, 0); - } - - @Test - public void checkNoGoodCounterStatsByTypeUsingDummyGrounder() { - Solver solver = getInstance(atomStore, new DummyGrounder(atomStore)); - assumeTrue(solver instanceof SolverMaintainingStatistics); - collectAnswerSetsAndCheckNoGoodCounterStatsByType(solver, 4, 0, 0, 0); - } - - @Test - public void checkNoGoodCounterStatsByCardinalityUsingDummyGrounder() { - Solver solver = getInstance(atomStore, new DummyGrounder(atomStore)); - assumeTrue(solver instanceof SolverMaintainingStatistics); - 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) { - Set answerSets = solver.collectSet(); - assertEquals(expectedNumberOfAnswerSets, answerSets.size()); - SolverMaintainingStatistics solverMaintainingStatistics = (SolverMaintainingStatistics) solver; - assertEquals( - String.format("g=%d, bt=%d, bj=%d, bt_within_bj=%d, mbt=%d, cac=%d, del_ng=%d", expectedNumberOfGuesses, expectedTotalNumberOfBacktracks, expectedNumberOfBackjumps, - expectedNumberOfBacktracksWithinBackjumps, expectedNumberOfMBTs, expectedNumberOfConflictsAfterClosing, expectedNumberOfDeletedNoGoods), - solverMaintainingStatistics.getStatisticsString()); - } - - private void collectAnswerSetsAndCheckNoGoodCounterStatsByType(Solver solver, int expectedNumberOfStaticNoGoods, int expectedNumberOfSupportNoGoods, int expectedNumberOfLearntNoGoods, int expectedNumberOfInternalNoGoods) { - solver.collectSet(); - SolverMaintainingStatistics solverMaintainingStatistics = (SolverMaintainingStatistics) solver; - final NoGoodCounter noGoodCounter = solverMaintainingStatistics.getNoGoodCounter(); - assertEquals("STATIC: " + expectedNumberOfStaticNoGoods + " SUPPORT: " + expectedNumberOfSupportNoGoods + " LEARNT: " + expectedNumberOfLearntNoGoods + " INTERNAL: " + expectedNumberOfInternalNoGoods, noGoodCounter.getStatsByType()); - } - - private void collectAnswerSetsAndCheckNoGoodCounterStatsByCardinality(Solver solver, int expectedNumberOfUnaryNoGoods, int expectedNumberOfBinaryNoGoods, int expectedNumberOfNAryNoGoods) { - solver.collectSet(); - SolverMaintainingStatistics solverMaintainingStatistics = (SolverMaintainingStatistics) solver; - final NoGoodCounter noGoodCounter = solverMaintainingStatistics.getNoGoodCounter(); - assertEquals("unary: " + expectedNumberOfUnaryNoGoods + " binary: " + expectedNumberOfBinaryNoGoods + " larger: " + expectedNumberOfNAryNoGoods, noGoodCounter.getStatsByCardinality()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java deleted file mode 100644 index bf9a61c12..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java +++ /dev/null @@ -1,808 +0,0 @@ -/** - * Copyright (c) 2016, 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.solver; - -import static java.util.Collections.singleton; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.antlr.v4.runtime.CharStreams; -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Paths; -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.SortedSet; - -import at.ac.tuwien.kr.alpha.AnswerSetsParser; -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -import at.ac.tuwien.kr.alpha.grounder.ChoiceGrounder; -import at.ac.tuwien.kr.alpha.grounder.DummyGrounder; -import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; -import junit.framework.TestCase; - -public class SolverTests extends AbstractSolverTests { - private static class Thingy implements Comparable { - @Override - public String toString() { - return "thingy"; - } - - @Override - public int compareTo(Thingy o) { - return 0; - } - } - - @Test - public void testObjectProgram() throws IOException { - final Thingy thingy = new Thingy(); - - final Atom fact = new BasicAtom(Predicate.getInstance("foo", 1), ConstantTerm.getInstance(thingy)); - - final InputProgram program = new InputProgram( - Collections.emptyList(), - Collections.singletonList(fact), - new InlineDirectives() - ); - - assertEquals(singleton(new AnswerSetBuilder() - .predicate("foo").instance(thingy) - .build()), collectSet(program)); - } - - @Test - public void testFactsOnlyProgram() throws IOException { - assertAnswerSet( - "p(a). p(b). foo(13). foo(16). q(a). q(c).", - - "q(a), q(c), p(a), p(b), foo(13), foo(16)" - ); - } - - @Test - public void testSimpleRule() throws Exception { - assertAnswerSet( - "p(a). p(b). r(X) :- p(X).", - - "p(a), p(b), r(a), r(b)" - ); - } - - @Test - public void testSimpleRuleWithGroundPart() throws Exception { - assertAnswerSet( - "p(1)." + - "p(2)." + - "q(X) :- p(X), p(1).", - - "q(1), q(2), p(1), p(2)" - ); - } - - @Test - public void testProgramZeroArityPredicates() throws Exception { - assertAnswerSet( - "a. p(X) :- b, r(X).", - - "a" - ); - } - - @Test - public void testChoiceGroundProgram() throws Exception { - assertAnswerSets( - "a :- not b. b :- not a.", - - "a", - "b" - ); - } - - @Test - public void testChoiceProgramNonGround() throws Exception { - assertAnswerSetsWithBase( - "dom(1). dom(2). dom(3)." + - "p(X) :- dom(X), not q(X)." + - "q(X) :- dom(X), not p(X).", - - "dom(1), dom(2), dom(3)", - - "q(1), q(2), p(3)", - "q(1), p(2), p(3)", - "p(1), q(2), p(3)", - "p(1), p(2), p(3)", - "q(1), q(2), q(3)", - "q(1), p(2), q(3)", - "p(1), q(2), q(3)", - "p(1), p(2), q(3)" - ); - } - - @Test - public void choiceProgram3Way() throws IOException { - assertAnswerSets( - "a :- not b, not c." + - "b :- not a, not c." + - "c :- not a, not b.", - - "a", - "b", - "c" - ); - } - - @Test - public void emptyProgramYieldsEmptyAnswerSet() throws IOException { - assertAnswerSets("", ""); - } - - @Test - public void chooseMultipleAnswerSets() throws IOException { - assertAnswerSets( - "a :- not nota." + - "nota :- not a." + - "b :- not notb." + - "notb :- not b." + - "c :- not notc." + - "notc :- not c." + - ":- nota,notb,notc.", - - "a, b, c", - "nota, b, c", - "a, notb, c", - "nota, notb, c", - "a, b, notc", - "nota, b, notc", - "a, notb, notc" - ); - } - - @Test - public void builtinAtoms() throws IOException { - assertAnswerSet( - "dom(1). dom(2). dom(3). dom(4). dom(5)." + - "p(X) :- dom(X), X = 4." + - "r(Y) :- dom(Y), Y <= 2.", - - "dom(1), dom(2), dom(3), dom(4), dom(5), p(4), r(1), r(2)" - ); - } - - @Test - public void builtinAtomsGroundRule() throws IOException { - assertAnswerSet( - "a :- 13 != 4." + - "b :- 2 != 3, 2 = 3." + - "c :- 2 <= 3, not 2 > 3.", - - "a, c" - ); - } - - - @Test - public void choiceProgramConstraintSimple() throws IOException { - assertAnswerSet( - "fact(a).\n" + - "choice(either, X) :- fact(X), not choice(or, X).\n" + - "choice(or, X) :- fact(X), not choice(either, X).\n" + - ":- choice(or, X).", - - "fact(a), choice(either, a)" - ); - } - - @Test - public void choiceProgramConstraintSimple2() throws IOException { - assertAnswerSet( - "fact(a).\n" + - "desired(either).\n" + - "choice(either, X) :- fact(X), not choice(or, X).\n" + - "choice(or, X) :- fact(X), not choice(either, X).\n" + - ":- choice(C, X), not desired(C).", - - "fact(a), desired(either), choice(either, a)" - ); - } - - @Test - public void choiceProgramConstraint() throws IOException { - assertAnswerSetsWithBase( - "eq(1,1)." + - "eq(2,2)." + - "eq(3,3)." + - "var(1)." + - "var(2)." + - "var(3)." + - "val(VAR,1):-var(VAR),not val(VAR,2),not val(VAR,3)." + - "val(VAR,2):-var(VAR),not val(VAR,1),not val(VAR,3)." + - "val(VAR,3):-var(VAR),not val(VAR,1),not val(VAR,2)." + - ":- eq(VAL1,VAL2), not eq(VAR1,VAR2), val(VAR1,VAL1), val(VAR2,VAL2).", - - "eq(1, 1), eq(2, 2), eq(3, 3), var(1), var(2), var(3)", - - "val(1, 1), val(2, 2), val(3, 3)", - "val(1, 1), val(3, 2), val(2, 3)", - "val(2, 1), val(1, 2), val(3, 3)", - "val(2, 1), val(3, 2), val(1, 3)", - "val(3, 1), val(1, 2), val(2, 3)", - "val(3, 1), val(2, 2), val(1, 3)" - ); - } - - @Test - public void choiceProgramConstraintPermutation() throws IOException { - assertAnswerSetsWithBase( - "eq(1,1)." + - "eq(2,2)." + - "eq(3,3)." + - "var(1)." + - "var(2)." + - "var(3)." + - "val(VAR,1):-var(VAR),not val(VAR,2),not val(VAR,3)." + - "val(VAR,2):-var(VAR),not val(VAR,1),not val(VAR,3)." + - "val(VAR,3):-var(VAR),not val(VAR,1),not val(VAR,2)." + - ":- val(VAR1,VAL1), val(VAR2,VAL2), eq(VAL1,VAL2), not eq(VAR1,VAR2).", - - "eq(1,1), eq(2,2), eq(3,3), var(1), var(2), var(3)", - - "val(1,1), val(2,2), val(3,3)", - "val(1,1), val(3,2), val(2,3)", - "val(2,1), val(1,2), val(3,3)", - "val(2,1), val(3,2), val(1,3)", - "val(3,1), val(1,2), val(2,3)", - "val(3,1), val(2,2), val(1,3)" - ); - } - - @Test - public void simpleNoPropagation() throws IOException { - assertAnswerSet( - "val(1,1)." + - "val(2,2)." + - "something:- val(VAR1,VAL1), val(VAR2,VAL2), anything(VAL1,VAL2).", - - "val(1, 1), val(2, 2)" - ); - } - - @Test - public void choiceAndPropagationAfterwards() throws IOException { - assertAnswerSetsWithBase( - "node(a)." + - "node(b)." + - "in(X) :- not out(X), node(X)." + - "out(X) :- not in(X), node(X)." + - "pair(X,Y) :- in(X), in(Y).", - - "node(a), node(b)", - - "in(a), in(b), pair(a,a), pair(a,b), pair(b,a), pair(b,b)", - "in(b), out(a), pair(b,b)", - "in(a), out(b), pair(a,a)", - "out(a), out(b)" - ); - } - - @Test - public void choiceAndConstraints() throws IOException { - assertAnswerSetsWithBase( - "node(a)." + - "node(b)." + - "edge(b,a)." + - "in(X) :- not out(X), node(X)." + - "out(X) :- not in(X), node(X)." + - ":- in(X), in(Y), edge(X,Y).", - - "node(a), node(b), edge(b,a)", - - "in(b), out(a)", - "in(a), out(b)", - "out(a), out(b)" - ); - } - - @Test - public void testUnsatisfiableProgram() throws IOException { - assertAnswerSets("p(a). p(b). :- p(a), p(b)."); - } - - @Test - public void testFunctionTermEquality() throws IOException { - assertAnswerSet( - "r1(f(a,b)). r2(f(a,b)). a :- r1(X), r2(Y), X = Y.", - - "r1(f(a,b)), r2(f(a,b)), a" - ); - } - - @Test - public void builtinInequality() throws IOException { - assertAnswerSetsWithBase( - "location(a1)." + - "region(r1)." + - "region(r2)." + - "assign(L,R) :- location(L), region(R), not nassign(L,R)." + - "nassign(L,R) :- location(L), region(R), not assign(L,R)." + - ":- assign(L,R1), assign(L,R2), R1 != R2." + - "aux_ext_assign(a1,r1)." + - "aux_ext_assign(a1,r2)." + - "aux_not_assign(L,R) :- aux_ext_assign(L,R), not assign(L,R)." + - ":- aux_not_assign(L,R), assign(L,R).", - - "location(a1), region(r1), region(r2), aux_ext_assign(a1,r1), aux_ext_assign(a1,r2)", - - "assign(a1,r2), nassign(a1,r1), aux_not_assign(a1,r1)", - "assign(a1,r1), nassign(a1,r2), aux_not_assign(a1,r2)", - "nassign(a1,r1), nassign(a1,r2), aux_not_assign(a1,r1), aux_not_assign(a1,r2)" - ); - } - - @Test - public void choiceConstraintsInequality() throws IOException { - assertAnswerSetsWithBase( - "assign(L, R) :- not nassign(L, R), possible(L, R)." + - "nassign(L, R) :- not assign(L, R), possible(L, R)." + - "assigned(L) :- assign(L, R)." + - ":- possible(L,_), not assigned(L)." + - ":- assign(L, R1), assign(L, R2), R1 != R2." + - "possible(l1, r1). possible(l3, r3). possible(l4, r1). possible(l4, r3). possible(l5, r4). possible(l6, r2). possible(l7, r3). possible(l8, r2). possible(l9, r1). possible(l9, r4).", - - "possible(l1,r1), " + - "possible(l3,r3), " + - "possible(l4,r1), " + - "possible(l4,r3), " + - "possible(l5,r4), " + - "possible(l6,r2), " + - "possible(l7,r3), " + - "possible(l8,r2), " + - "possible(l9,r1), " + - "possible(l9,r4), " + - "assign(l1,r1), " + - "assign(l3,r3), " + - "assign(l5,r4), " + - "assign(l6,r2), " + - "assign(l7,r3), " + - "assign(l8,r2), " + - "assigned(l1), " + - "assigned(l3), " + - "assigned(l4), " + - "assigned(l5), " + - "assigned(l6), " + - "assigned(l7), " + - "assigned(l8), " + - "assigned(l9)", - - "assign(l4,r1), " + - "assign(l9,r4), " + - "nassign(l4,r3), " + - "nassign(l9,r1)", - - "assign(l4,r1), " + - "assign(l9,r1), " + - "nassign(l4,r3), " + - "nassign(l9,r4)", - - "assign(l4,r3), " + - "assign(l9,r4), " + - "nassign(l4,r1), " + - "nassign(l9,r1)", - - "assign(l4,r3), " + - "assign(l9,r1), " + - "nassign(l4,r1), " + - "nassign(l9,r4)" - ); - } - @Test - public void sameVariableTwiceInAtom() throws IOException { - assertAnswerSets( - "p(a, a)." + - "q(X) :- p(X, X).", - - "p(a,a), q(a)" - ); - } - - @Test - public void sameVariableTwiceInAtomConstraint() throws IOException { - assertAnswerSets( - "p(a, a)." + - ":- p(X, X)." - ); - } - - @Test - public void noPositiveSelfFounding() throws IOException { - assertAnswerSets( - "a :- b." + - "b:- a." + - ":- not b." - ); - } - - @Test - public void noPositiveCycleSelfFoundingChoice() throws IOException { - assertAnswerSets( - "c :- not d." + - "d :- not c." + - "a :- b, not c." + - "b:- a." + - ":- not b." - ); - } - - @Test - public void conflictFromUnaryNoGood() throws IOException { - assertAnswerSet( - "d(b)." + - "sel(X) :- not nsel(X), d(X)." + - "nsel(X) :- not sel(X), d(X)." + - "t(a) :- sel(b)." + - ":- t(X).", - - "d(b), nsel(b)" - ); - } - - @Test - public void intervalsInFacts() throws IOException { - assertAnswerSets( - "a." + - "facta(1..3)." + - "factb(t, 5..8, u)." + - "factc(1..3, w, 2 .. 4)." + - "b(1,2)." + - "b(3,4).", - - "facta(1), " + - "facta(2), " + - "facta(3), " + - - "factb(t, 5, u)," + - "factb(t, 6, u)," + - "factb(t, 7, u)," + - "factb(t, 8, u)," + - - "factc(1, w, 2)," + - "factc(2, w, 2)," + - "factc(3, w, 2)," + - "factc(1, w, 3)," + - "factc(2, w, 3)," + - "factc(3, w, 3)," + - "factc(1, w, 4)," + - "factc(2, w, 4)," + - "factc(3, w, 4)," + - - "a," + - - "b(1, 2)," + - "b(3, 4)" - ); - } - - @Test - public void intervalInRules() throws IOException { - assertAnswerSets( - "a :- 3 = 1..4 ." + - "p(X, 1..X) :- dom(X), X != 2." + - "dom(1). dom(2). dom(3).", - - "dom(1)," + - "dom(2)," + - "dom(3)," + - - "p(1, 1)," + - "p(3, 1)," + - "p(3, 2)," + - "p(3, 3)," + - - "a" - ); - } - - @Test - public void emptyIntervals() throws IOException { - assertAnswerSets( - "p(3..1)." + - "dom(5)." + - "p(X) :- dom(X), X = 7..2 .", - "dom(5)" - ); - } - - @Test - public void intervalInFunctionTermsInRules() throws IOException { - assertAnswerSets( - "a :- q(f(1..3,g(4..5)))." + - "q(f(2,g(4)))." + - "q(f(1,g(5)))." + - "p(f(1..3,g(4..5))) :- b." + - "b.", - - "a, " + - "b, " + - - "q(f(2,g(4))), " + - "q(f(1,g(5))), " + - - "p(f(1,g(4))), " + - "p(f(1,g(5))), " + - "p(f(2,g(4))), " + - "p(f(2,g(5))), " + - "p(f(3,g(4))), " + - "p(f(3,g(5)))" - ); - } - - @Test - public void groundAtomInRule() throws IOException { - assertAnswerSet( - "p :- dom(X), q, q2." + - "dom(1)." + - "q :- not nq." + - "nq :- not q." + - "q2 :- not nq2." + - "nq2 :- not q2." + - ":- not p.", - - "dom(1), p, q, q2" - ); - } - - @Test - public void simpleChoiceRule() throws IOException { - assertAnswerSetsWithBase( - "{ a; b; c} :- d." + - "d.", - - "d", - "", - "a", - "a, b", - "a, c", - "a, b, c", - "b", - "b, c", - "c" - ); - } - - @Test - public void conditionalChoiceRule() throws IOException { - assertAnswerSetsWithBase( - "dom(1..3)." + - "{ p(X): not q(X); r(Y): p(Y)} :- dom(X), q(Y)." + - "q(2).", - - "dom(1)," + - "dom(2)," + - "dom(3)," + - "q(2)", - - "p(1)," + - "p(3)", - - "", - - "p(3)", - - "p(1)" - ); - } - - @Test - public void doubleChoiceRule() throws IOException { - Solver solver = getInstance("{ a }. { a }."); - // Make sure that no superfluous answer sets that only differ on hidden atoms occur. - List actual = solver.collectList(); - assertEquals(2, actual.size()); - assertEquals(AnswerSetsParser.parse("{} { a }"), new HashSet<>(actual)); - } - - @Test - public void simpleArithmetics() throws IOException { - assertAnswerSet("eight(X) :- X = 4 + 5 - 1." + - "three(X) :- X = Z, Y = 1..10, Z = Y / 3, Z > 2, Z < 4.", - - "eight(8), three(3)"); - } - - @Test - public void arithmeticsMultiplicationBeforeAddition() throws IOException { - assertAnswerSet("seven(X) :- 1+2 * 3 = X.", - - "seven(7)"); - } - - /** - * Tests the fix for issue #101 - */ - @Test - public void involvedUnsatisfiableProgram() throws IOException { - assertAnswerSets("x :- c1, c2, not x." + - "c1 :- not a1." + - "c1 :- not b1." + - "c2 :- not a2." + - "c2 :- not b2." + - "a1 :- not b1." + - "b1 :- not a1." + - "a2 :- not b2." + - "b2 :- not a2."); - } - - @Test - public void instanceEnumerationAtom() throws IOException { - Set answerSets = getInstance("# enumeration_predicate_is enum." + - "dom(1). dom(2). dom(3)." + - "p(X) :- dom(X)." + - "q(Y) :- p(Y)." + - "unique_position(Term,Pos) :- q(Term), enum(id0,Term,Pos)." + - "wrong_double_occurrence :- unique_position(T1,P), unique_position(T2,P), T1 != T2.").collectSet(); - // Since enumeration depends on evaluation, we do not know which unique_position is actually assigned. - // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. - assertEquals(1, answerSets.size()); - AnswerSet answerSet = answerSets.iterator().next(); - assertEquals(null, answerSet.getPredicateInstances(Predicate.getInstance("wrong_double_occurrence", 0))); - SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position", 2)); - assertEnumerationPositions(positions, 3); - } - - @Test - public void instanceEnumerationArbitraryTerms() throws IOException { - Set answerSets = getInstance("# enumeration_predicate_is enum." + - "dom(a). dom(f(a,b)). dom(d)." + - "p(X) :- dom(X)." + - "q(Y) :- p(Y)." + - "unique_position(Term,Pos) :- q(Term), enum(id0,Term,Pos)." + - "wrong_double_occurrence :- unique_position(T1,P), unique_position(T2,P), T1 != T2.").collectSet(); - // Since enumeration depends on evaluation, we do not know which unique_position is actually assigned. - // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. - assertEquals(1, answerSets.size()); - AnswerSet answerSet = answerSets.iterator().next(); - assertPropositionalPredicateFalse(answerSet, Predicate.getInstance("wrong_double_occurrence", 0)); - SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position", 2)); - assertEnumerationPositions(positions, 3); - } - - @Test - public void instanceEnumerationMultipleIdentifiers() throws IOException { - Set answerSets = getInstance("# enumeration_predicate_is enum." + - "dom(a). dom(b). dom(c). dom(d)." + - "p(X) :- dom(X)." + - "unique_position1(Term,Pos) :- p(Term), enum(id,Term,Pos)." + - "unique_position2(Term,Pos) :- p(Term), enum(otherid,Term,Pos)." + - "wrong_double_occurrence :- unique_position(T1,P), unique_position(T2,P), T1 != T2." + - "wrong_double_occurrence :- unique_position2(T1,P), unique_position(T2,P), T1 != T2.").collectSet(); - // Since enumeration depends on evaluation, we do not know which unique_position is actually assigned. - // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. - assertEquals(1, answerSets.size()); - AnswerSet answerSet = answerSets.iterator().next(); - assertPropositionalPredicateFalse(answerSet, Predicate.getInstance("wrong_double_occurrence", 0)); - SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position1", 2)); - assertEnumerationPositions(positions, 4); - SortedSet positions2 = answerSet.getPredicateInstances(Predicate.getInstance("unique_position2", 2)); - assertEnumerationPositions(positions2, 4); - } - - private void assertPropositionalPredicateFalse(AnswerSet answerSet, Predicate predicate) { - assertEquals(null, answerSet.getPredicateInstances(predicate)); - } - - private void assertEnumerationPositions(SortedSet positions, int numPositions) { - assertEquals(numPositions, positions.size()); - boolean usedPositions[] = new boolean[numPositions]; - for (Atom position : positions) { - @SuppressWarnings("unchecked") - Integer atomPos = ((ConstantTerm) position.getTerms().get(1)).getObject() - 1; - assertTrue(atomPos < numPositions); - usedPositions[atomPos] = true; - } - for (int i = 0; i < numPositions; i++) { - assertTrue(usedPositions[i]); - } - } - - @Test - public void smallCardinalityAggregate() throws IOException { - assertAnswerSetsWithBase( - "dom(1..3)." + - "bound(1..4)." + - "{ value(X) : dom(X) }." + - "num(K) :- K <= #count {X : value(X) }, bound(K).", - - "dom(1), dom(2), dom(3), bound(1), bound(2), bound(3), bound(4)", - "", - "", - "value(1), num(1)", - "value(1), value(2), num(1), num(2)", - "value(1), value(2), value(3), num(1), num(2), num(3)", - "value(1), value(3), num(1), num(2)", - "value(2), num(1)", - "value(2), value(3), num(1), num(2)", - "value(3), num(1)" - ); - } - - @Test - public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { - final ProgramParser parser = new ProgramParser(); - InputProgram.Builder bld = InputProgram.builder(); - bld.accumulate(parser.parse(CharStreams.fromPath(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp")))); - bld.accumulate(parser.parse(CharStreams.fromPath(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp")))); - InputProgram parsedProgram = bld.build(); - - SystemConfig config = new SystemConfig(); - config.setSolverName("default"); - config.setNogoodStoreName("alpharoaming"); - config.setSeed(0); - config.setBranchingHeuristic(BranchingHeuristicFactory.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 Alpha(config); - Optional answerSet = alpha.solve(parsedProgram).findFirst(); - assertTrue(answerSet.isPresent()); - } - - - @Test - public void dummyGrounder() { - AtomStore atomStore = new AtomStoreImpl(); - TestCase.assertEquals(DummyGrounder.EXPECTED, getInstance(atomStore, new DummyGrounder(atomStore)).collectSet()); - } - - @Test - public void choiceGrounder() { - AtomStore atomStore = new AtomStoreImpl(); - TestCase.assertEquals(ChoiceGrounder.EXPECTED, getInstance(atomStore, new ChoiceGrounder(atomStore)).collectSet()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java deleted file mode 100644 index d8923a166..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/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.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/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java deleted file mode 100644 index 27b34d7ee..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Random; - -import org.junit.Ignore; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -public class ThreeColouringRandomGraphTest extends AbstractSolverTests { - @Test(timeout = 1000) - public void testV3E3() throws IOException { - testThreeColouring(3, 3); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testV10E18() throws IOException { - testThreeColouring(10, 18); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testV20E38() throws IOException { - testThreeColouring(20, 38); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testV30E48() throws IOException { - testThreeColouring(30, 48); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testV200E300() throws IOException { - testThreeColouring(200, 300); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testV300E200() throws IOException { - testThreeColouring(300, 200); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testV300E300() throws IOException { - testThreeColouring(300, 300); - } - - private void testThreeColouring(int nVertices, int nEdges) throws IOException { - InputProgram tmpPrg = new ProgramParser().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); - prgBuilder.addFacts(createVertices(nVertices)); - prgBuilder.addFacts(createEdges(nVertices, nEdges)); - InputProgram program = prgBuilder.build(); - maybeShuffle(program); - - Optional answerSet = getInstance(program).stream().findAny(); - //System.out.println(answerSet); - - // TODO: check correctness of answer set - } - - 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 - // Collections.reverse(program.getRules()); - // Collections.shuffle(program.getRules()); - // Collections.reverse(program.getFacts()); - // Collections.shuffle(program.getFacts()); - } - - private List createVertices(int n) { - List facts = new ArrayList<>(n); - for (int i = 0; i < n; i++) { - facts.add(fact("v", i)); - } - return facts; - } - - private List createEdges(int vertices, int edges) { - Random rand = new Random(0); - List facts = new ArrayList<>(edges); - for (int i = 0; i < edges; i++) { - int v1 = 0; - int v2 = 0; - while (v1 == v2) { - v1 = rand.nextInt(vertices); - v2 = rand.nextInt(vertices); - } - facts.add(fact("e", v1, v2)); - facts.add(fact("e", v2, v1)); - } - return facts; - } - - private Atom fact(String predicateName, int... iTerms) { - List terms = new ArrayList<>(1); - for (int i : iTerms) { - terms.add(ConstantTerm.getInstance(i)); - } - return new BasicAtom(Predicate.getInstance(predicateName, iTerms.length), terms); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java deleted file mode 100644 index 6d51ffc5a..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import org.junit.Ignore; -import org.junit.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.Random; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Tests {@link AbstractSolver} 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: - * 10.1017/S1471068416000569 - */ -public class ThreeColouringTestWithRandom extends AbstractSolverTests { - @Test(timeout = 3000) - public void testN3() throws IOException { - testThreeColouring(3, false, 0); - } - - @Test(timeout = 4000) - public void testN4() throws IOException { - testThreeColouring(4, false, 0); - } - - @Test(timeout = 5000) - @Ignore("disabled to save resources during CI") - public void testN5() throws IOException { - testThreeColouring(5, false, 0); - } - - @Test(timeout = 6000) - @Ignore("disabled to save resources during CI") - public void testN6() throws IOException { - testThreeColouring(6, false, 0); - } - - @Test(timeout = 7000) - @Ignore("disabled to save resources during CI") - public void testN7() throws IOException { - testThreeColouring(7, false, 0); - } - - @Test(timeout = 8000) - @Ignore("disabled to save resources during CI") - public void testN8() throws IOException { - testThreeColouring(8, false, 0); - } - - @Test(timeout = 9000) - @Ignore("disabled to save resources during CI") - public void testN9() throws IOException { - testThreeColouring(9, false, 0); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testN10() throws IOException { - testThreeColouring(10, false, 0); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testN10Random0() throws IOException { - testThreeColouring(10, true, 0); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testN10Random1() throws IOException { - testThreeColouring(10, true, 1); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testN10Random2() throws IOException { - testThreeColouring(10, true, 2); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testN10Random3() throws IOException { - testThreeColouring(10, true, 3); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN19() throws IOException { - testThreeColouring(19, false, 0); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN19Random0() throws IOException { - testThreeColouring(19, true, 0); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN19Random1() throws IOException { - testThreeColouring(19, true, 1); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN19Random2() throws IOException { - testThreeColouring(19, true, 2); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN19Random3() throws IOException { - testThreeColouring(19, true, 3); - } - - @Test(timeout = 10000) - @Ignore("disabled to save resources during CI") - public void testN101() throws IOException { - testThreeColouring(101, false, 0); - } - - private void testThreeColouring(int n, boolean shuffle, int seed) throws IOException { - InputProgram tmpPrg = new ProgramParser() - .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); - prgBuilder.addFacts(createColors("1", "2", "3")); - prgBuilder.addFacts(createVertices(n)); - prgBuilder.addFacts(createEdges(n, shuffle, seed)); - InputProgram program = prgBuilder.build(); - - Solver solver = getInstance(program); - Optional answerSet = solver.stream().findAny(); - // System.out.println(answerSet); - // TODO: check correctness of answer set - } - - private List createColors(String... colours) { - List facts = new ArrayList<>(colours.length); - for (String colour : colours) { - List terms = new ArrayList<>(1); - terms.add(ConstantTerm.getInstance(colour)); - facts.add(new BasicAtom(Predicate.getInstance("c", 1), terms)); - } - return facts; - } - - private List createVertices(int n) { - List facts = new ArrayList<>(n); - for (int i = 1; i <= n; i++) { - facts.add(fact("v", i)); - } - return facts; - } - - /** - * - * @param n - * @param shuffle if true, the vertex indices are shuffled with the given seed - * @param seed - * @return - */ - private List createEdges(int n, boolean shuffle, int seed) { - List facts = new ArrayList<>(n); - List indices = new ArrayList<>(); - for (int i = 1; i <= n; i++) { - indices.add(i); - } - if (shuffle) { - Collections.shuffle(indices, new Random(seed)); - } - - for (int i = 1; i < n; i++) { - facts.add(fact("e", indices.get(0), indices.get(i))); - } - for (int i = 1; i < n - 1; i++) { - facts.add(fact("e", indices.get(i), indices.get(i + 1))); - } - facts.add(fact("e", indices.get(1), indices.get(n - 1))); - return facts; - } - - private Atom fact(String predicateName, int... iTerms) { - List terms = new ArrayList<>(iTerms.length); - Predicate predicate = Predicate.getInstance(predicateName, iTerms.length); - for (int i : iTerms) { - terms.add(ConstantTerm.getInstance(i)); - } - return new BasicAtom(predicate, terms); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java deleted file mode 100644 index 4f74be75d..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Copyright (c) 2017 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.solver; - -import org.junit.Ignore; -import org.junit.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; - -/** - * Tests {@link AbstractSolver} 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: 10.1017/S1471068416000569 - */ -public class ThreeColouringWheelTest extends AbstractSolverTests { - @Test(timeout = 1000) - public void testN4() throws IOException { - testThreeColouring(4); - } - - @Test(timeout = 1000) - public void testN5() throws IOException { - testThreeColouring(5); - } - - @Test(timeout = 6000) - @Ignore("disabled to save resources during CI") - public void testN6() throws IOException { - testThreeColouring(6); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN3() throws IOException { - testThreeColouring(3); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN7() throws IOException { - testThreeColouring(7); - } - - @Test(timeout = 60000) - @Ignore("disabled to save resources during CI") - public void testN11() throws IOException { - testThreeColouring(11); - } - - private void testThreeColouring(int n) throws IOException { - InputProgram tmpPrg = new ProgramParser().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); - prgBuilder.addFacts(createColors("red", "blue", "green")); - prgBuilder.addFacts(createVertices(n)); - prgBuilder.addFacts(createEdges(n)); - InputProgram program = prgBuilder.build(); - - maybeShuffle(program); - - Solver solver = getInstance(program); - - Optional answerSet = solver.stream().findAny(); - //System.out.println(answerSet); - - // TODO: check correctness of answer set - } - - private void maybeShuffle(InputProgram program) { - // FIXME since InputProgram is immutable this needs to be reworked a bit if used - // No shuffling here. - } - - private List createColors(String... colours) { - List facts = new ArrayList<>(colours.length); - Predicate predicate = Predicate.getInstance("c", 1); - for (String colour : colours) { - List terms = new ArrayList<>(1); - terms.add(ConstantTerm.getInstance(colour)); - facts.add(new BasicAtom(predicate, terms)); - } - return facts; - } - - private List createVertices(int n) { - List facts = new ArrayList<>(n); - for (int i = 1; i <= n; i++) { - facts.add(fact("v", i)); - } - return facts; - } - - private List createEdges(int n) { - List facts = new ArrayList<>(n); - for (int i = 2; i <= n; i++) { - facts.add(fact("e", 1, i)); - } - for (int i = 2; i <= n - 1; i++) { - facts.add(fact("e", i, i + 1)); - } - facts.add(fact("e", n, 2)); - return facts; - } - - private Atom fact(String predicateName, int... iTerms) { - List terms = new ArrayList<>(1); - Predicate predicate = Predicate.getInstance(predicateName, iTerms.length); - for (int i : iTerms) { - terms.add(ConstantTerm.getInstance(i)); - } - return new BasicAtom(predicate, terms); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java deleted file mode 100644 index 9cbda2250..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java +++ /dev/null @@ -1,260 +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.solver; - -import at.ac.tuwien.kr.alpha.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; - -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -/** - * Copyright (c) 2018-2020, the Alpha Team. - */ -public class TrailAssignmentTest { - private final TrailAssignment assignment; - - public TrailAssignmentTest() { - AtomStore atomStore = new AtomStoreImpl(); - AtomStoreTest.fillAtomStore(atomStore, 20); - assignment = new TrailAssignment(atomStore); - } - - @Before - public void setUp() { - assignment.clear(); - assignment.growForMaxAtomId(); - } - - @Test(expected = IllegalArgumentException.class) - public void assign() throws Exception { - assignment.assign(0, null); - } - - @Test(expected = IllegalArgumentException.class) - public void negativeAtomThrows() throws Exception { - assignment.assign(-1, null); - } - - @Test - public void alreadyAssignedThrows() throws Exception { - assertNull(assignment.assign(1, MBT)); - assertNotNull(assignment.assign(1, FALSE)); - } - - @Test - public void initializeDecisionLevelState() throws Exception { - assignment.assign(1, MBT); - assignment.choose(2, MBT); - assignment.choose(1, TRUE); - } - - @Test - public void checkToString() { - assignment.assign(1, FALSE); - assertEquals("[F_a(0)@0]", assignment.toString()); - - assignment.assign(2, TRUE); - assertEquals("[F_a(0)@0, T_a(1)@0]", assignment.toString()); - } - - @Test - public void reassignGracefully() { - assignment.assign(1, FALSE); - assignment.assign(1, FALSE); - } - - @Test - public void assignAndBacktrack() { - assignment.assign(1, MBT); - assignment.assign(2, FALSE); - assignment.assign(3, TRUE); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(FALSE, assignment.getTruth(2)); - assertEquals(TRUE, assignment.getTruth(3)); - assertEquals(assignment.getTrueAssignments(), new HashSet<>(Collections.singletonList(3))); - assertEquals(1, assignment.getMBTCount()); - - assignment.choose(1, TRUE); - - assertEquals(TRUE, assignment.getTruth(1)); - assertEquals(assignment.getTrueAssignments(), new HashSet<>(Arrays.asList(3, 1))); - assertEquals(0, assignment.getMBTCount()); - - assignment.backtrack(); - - assertEquals(MBT, assignment.getTruth(1)); - assertEquals(FALSE, assignment.getTruth(2)); - assertEquals(TRUE, assignment.getTruth(3)); - assertEquals(assignment.getTrueAssignments(), new HashSet<>(Collections.singletonList(3))); - assertEquals(1, assignment.getMBTCount()); - - assignment.choose(4, MBT); - assignment.assign(5, MBT); - - assertEquals(MBT, assignment.getTruth(4)); - assertEquals(MBT, assignment.getTruth(5)); - - assignment.backtrack(); - - assertFalse(assignment.isAssigned(4)); - assertFalse(assignment.isAssigned(5)); - - assignment.choose(4, TRUE); - - assertEquals(TRUE, assignment.getTruth(4)); - - assignment.backtrack(); - - assertNull(assignment.getTruth(4)); - } - - @Test - public void assignmentsToProcess() throws Exception { - assignment.assign(1, MBT); - - Assignment.Pollable queue = assignment.getAssignmentsToProcess(); - assertEquals(1, queue.remove()); - - assignment.choose(2, MBT); - assignment.choose(1, TRUE); - - assertEquals(2, queue.remove()); - assertEquals(1, queue.peek()); - - queue = assignment.getAssignmentsToProcess(); - assertEquals(1, queue.remove()); - } - - @Test - public void newAssignmentsIteratorAndBacktracking() throws Exception { - IntIterator newAssignmentsIterator; - - assignment.assign(1, MBT); - assignment.choose(2, MBT); - - newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - - assertEquals(1, (int)newAssignmentsIterator.next()); - assertEquals(2, (int)newAssignmentsIterator.next()); - assertFalse(newAssignmentsIterator.hasNext()); - - - assignment.choose(1, TRUE); - assignment.backtrack(); - assignment.assign(3, FALSE); - - newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(3, (int)newAssignmentsIterator.next()); - assertFalse(newAssignmentsIterator.hasNext()); - } - - @Test - public void newAssignmentsIteratorLowerDecisionLevelAndBacktracking() throws Exception { - IntIterator newAssignmentsIterator; - - assignment.choose(1, MBT); - assignment.choose(2, MBT); - assignment.assign(3, MBT, null, 1); - assignment.backtrack(); - - newAssignmentsIterator = assignment.getNewPositiveAssignmentsIterator(); - assertEquals(1, (int)newAssignmentsIterator.next()); - assertEquals(3, (int)newAssignmentsIterator.next()); - assertFalse(newAssignmentsIterator.hasNext()); - } - - @Test - public void iteratorAndBacktracking() throws Exception { - Assignment.Pollable assignmentsToProcess = assignment.getAssignmentsToProcess(); - - assignment.assign(1, MBT); - assertEquals(1, assignmentsToProcess.remove()); - - assignment.choose(2, MBT); - assertEquals(2, assignmentsToProcess.remove()); - - assignment.choose(1, TRUE); - assertEquals(1, assignmentsToProcess.remove()); - - assignment.backtrack(); - - assignment.assign(3, FALSE); - assertEquals(3, assignmentsToProcess.remove()); - } - - @Test - public void mbtCounterAssignMbtToFalseOnLowerDecisionLevel() { - assertNull(assignment.choose(1, TRUE)); - assertNull(assignment.choose(2, FALSE)); - - assertNull(assignment.assign(3, MBT, null, 2)); - assertEquals(1, assignment.getMBTCount()); - - assertNull(assignment.choose(4, TRUE)); - - assertNotNull(assignment.assign(3, FALSE, null, 1)); - - assignment.backtrack(); - assignment.backtrack(); - - assertEquals(0, assignment.getMBTCount()); - } - - @Test - public void numberOfAssignedAtoms() throws Exception { - assignment.assign(1, MBT); - assertEquals(1, assignment.getNumberOfAssignedAtoms()); - assignment.assign(2, FALSE); - assertEquals(2, assignment.getNumberOfAssignedAtoms()); - assignment.assign(3, MBT); - assignment.assign(3, TRUE); - assertEquals(3, assignment.getNumberOfAssignedAtoms()); - assignment.choose(1, TRUE); - assertEquals(3, assignment.getNumberOfAssignedAtoms()); - assertEquals(1, assignment.getNumberOfAtomsAssignedSinceLastDecision()); - assignment.assign(5, MBT); - assignment.assign(5, TRUE); - assertEquals(2, assignment.getNumberOfAtomsAssignedSinceLastDecision()); - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java deleted file mode 100644 index 16d8bf14e..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java +++ /dev/null @@ -1,170 +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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.grounder.Grounder; -import at.ac.tuwien.kr.alpha.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.solver.NaiveNoGoodStore; -import at.ac.tuwien.kr.alpha.solver.TestableChoiceManager; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Tests assumptions made by {@link DependencyDrivenHeuristic} and other domain-independent heuristics. - * Even if these test cases do not test {@link DependencyDrivenHeuristic} directly, - * it will break if these test cases break. - * - * Copyright (c) 2017-2018 Siemens AG - * - */ -public class AlphaHeuristicTestAssumptions { - private Grounder grounder; - private WritableAssignment assignment; - private TestableChoiceManager choiceManager; - private AtomStore atomStore; - - @Before - public void setUp() { - Alpha system = new Alpha(); - String testProgram = "" - + "b1." - + "b2." - + "{b3}." - + "{b4}." - + "h :- b1, b2, not b3, not b4."; - InputProgram parsedProgram = new ProgramParser().parse(testProgram); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); - atomStore = new AtomStoreImpl(); - grounder = new NaiveGrounder(internalProgram, atomStore, true); - assignment = new TrailAssignment(atomStore); - choiceManager = new TestableChoiceManager(assignment, new NaiveNoGoodStore(assignment)); - } - - @Test - public void testNumbersOfNoGoods_GrounderIsAtomChoicePoint() { - testNumbersOfNoGoods(atomStore::isAtomChoicePoint); - } - - @Test - public void testNumbersOfNoGoods_ChoiceManagerIsAtomChoice() { - testNumbersOfNoGoods(choiceManager::isAtomChoice); - } - - private void testNumbersOfNoGoods(Predicate isRuleBody) { - int n = 0; - int bodyNotHead = 0; - int bodyElementsNotBody = 0; - int noHead = 0; - int other = 0; - - Collection noGoods = getNoGoods(); - assignment.growForMaxAtomId(); - choiceManager.growForMaxAtomId(atomStore.getMaxAtomId()); - choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); - for (NoGood noGood : noGoods) { - n++; - boolean knownType = false; - if (DependencyDrivenHeuristic.isBodyNotHead(noGood, isRuleBody)) { - bodyNotHead++; - knownType = true; - } - if (DependencyDrivenHeuristic.isBodyElementsNotBody(noGood, isRuleBody)) { - bodyElementsNotBody++; - knownType = true; - } - if (!noGood.hasHead()) { - noHead++; - knownType = true; - } - if (!knownType) { - other++; - } - } - - System.out.println(noGoods.stream().map(atomStore::noGoodToString).collect(Collectors.joining(", "))); - - assertEquals("Unexpected number of bodyNotHead nogoods", 5, bodyNotHead); - assertEquals("Unexpected number of bodyElementsNotBody nogoods", 5, bodyElementsNotBody); - assertGreaterThan("Unexpected number of nogoods without head", 4, noHead); - - // there may be other nogoods (e.g. for ChoiceOn, ChoiceOff) which we do not care for here - System.out.println("Total number of NoGoods: " + n); - System.out.println("Number of NoGoods of unknown type: " + other); - } - - @Test - public void testIsAtomChoice_GrounderIsAtomChoicePoint() { - testIsAtomChoice(atomStore::isAtomChoicePoint); - } - - @Test - public void testIsAtomChoice_ChoiceManagerIsAtomChoice() { - testIsAtomChoice(choiceManager::isAtomChoice); - } - - private void testIsAtomChoice(Predicate isRuleBody) { - Collection noGoods = getNoGoods(); - assignment.growForMaxAtomId(); - choiceManager.growForMaxAtomId(atomStore.getMaxAtomId()); - choiceManager.addChoiceInformation(grounder.getChoiceAtoms(), grounder.getHeadsToBodies()); - for (NoGood noGood : noGoods) { - for (Integer literal : noGood) { - int atom = atomOf(literal); - String atomToString = atomStore.atomToString(atom); - if (atomToString.startsWith("_R_")) { - assertTrue("Atom not choice: " + atomToString, isRuleBody.test(atom)); - } - } - } - } - - private Collection getNoGoods() { - return grounder.getNoGoods(null).values(); - } - - private void assertGreaterThan(String message, long expected, long actual) { - assertTrue(message, actual > expected); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java deleted file mode 100644 index 29227058f..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java +++ /dev/null @@ -1,193 +0,0 @@ -/** - * Copyright (c) 2016-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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.NaiveNoGoodStore; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.Collections; -import java.util.Random; - -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static org.junit.Assert.assertEquals; - -/** - * Tests {@link BerkMin}. - * - * Copyright (c) 2016 Siemens AG - * - */ -public class BerkMinTest { - - /** - * The tolerable epsilon for double comparisons - */ - private static final double DOUBLE_COMPARISON_EPSILON = 0.000001; - - private BerkMin berkmin; - - @Before - public void setUp() { - AtomStore atomStore = new AtomStoreImpl(); - AtomStoreTest.fillAtomStore(atomStore, 2); - WritableAssignment assignment = new TrailAssignment(atomStore); - assignment.growForMaxAtomId(); - this.berkmin = new BerkMin( - assignment, - new PseudoChoiceManager(assignment, new NaiveNoGoodStore(assignment)), - new Random() - ); - } - - @Test - public void countPositiveLiteralsOnce() { - NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void countNegativeLiteralsOnce() { - NoGood violatedNoGood = new NoGood(fromOldLiterals(-1, -2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(1, berkmin.getActivity(fromOldLiterals(-1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(1, berkmin.getActivity(fromOldLiterals(-2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void countPositiveLiteralsTwice() { - NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(2, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void countNegativeLiteralsTwice() { - NoGood violatedNoGood = new NoGood(fromOldLiterals(-1, -2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(2, berkmin.getActivity(fromOldLiterals(-1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(2, berkmin.getActivity(fromOldLiterals(-2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void countMixedLiteralsTwice() { - NoGood violatedNoGood = new NoGood(fromOldLiterals(1, -2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(2, berkmin.getActivity(fromOldLiterals(-2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void countPositiveLiteralsThenNegativeLiterals() { - NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - violatedNoGood = new NoGood(fromOldLiterals(-1, -2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(2, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void reachDecayPeriodOnce() { - berkmin.setDecayPeriod(3); - berkmin.setDecayFactor(1.0 / 3); - NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(2, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(2, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void reachDecayPeriodTwice() { - berkmin.setDecayPeriod(2); - berkmin.setDecayFactor(0.75); - NoGood violatedNoGood = new NoGood(fromOldLiterals(1, 2)); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(1, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(1, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(1.5, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(1.5, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(2.5, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(2.5, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - berkmin.violatedNoGood(violatedNoGood); - berkmin.analyzedConflict(pseudo(violatedNoGood)); - assertEquals(2.625, berkmin.getActivity(fromOldLiterals(1)), DOUBLE_COMPARISON_EPSILON); - assertEquals(2.625, berkmin.getActivity(fromOldLiterals(2)), DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void learnNoGood() { - NoGood learnedNoGood = NoGood.learnt(fromOldLiterals(1, 2)); - int backjumpLevel = 1; - boolean clearLastChoiceAfterBackjump = true; - Collection resolutionAtoms = Collections.emptySet(); - berkmin.analyzedConflict(new ConflictAnalysisResult(learnedNoGood, backjumpLevel, - resolutionAtoms)); - assertEquals(learnedNoGood, berkmin.getCurrentTopClause()); - } - - private static ConflictAnalysisResult pseudo(NoGood noGood) { - return new ConflictAnalysisResult(noGood, 0, Collections.emptySet()); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java deleted file mode 100644 index 519f14169..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (c) 2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.solver.*; -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Tests {@link BranchingHeuristicFactory} - */ -public class BranchingHeuristicFactoryTest { - - private final BranchingHeuristicFactory factory = new BranchingHeuristicFactory(); - private final boolean debugInternalChecks = true; - private ChoiceManager choiceManager; - - @Before - public void setUp() { - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - NoGoodStore store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); - this.choiceManager = new ChoiceManager(assignment, store); - } - - @Test - public void testChainedHeuristicWithReplay() { - HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(BranchingHeuristicFactory.Heuristic.VSIDS).setReplayChoices(Arrays.asList(1, 2, 3)); - BranchingHeuristic branchingHeuristic = factory.getInstance(builder.build(), null, null, choiceManager, null); - assertEquals(ChainedBranchingHeuristics.class, branchingHeuristic.getClass()); - assertTrue("Unexpected type of branchingHeuristic: " + branchingHeuristic.getClass(), branchingHeuristic instanceof ChainedBranchingHeuristics); - assertEquals(ChainedBranchingHeuristics.class.getSimpleName() + "[" + ReplayHeuristic.class.getSimpleName() + ", " + VSIDS.class.getSimpleName() + "]", branchingHeuristic.toString()); - } - - @Test - public void testChainedHeuristicWithoutReplay() { - HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(BranchingHeuristicFactory.Heuristic.VSIDS).setReplayChoices(null); - BranchingHeuristic branchingHeuristic = factory.getInstance(builder.build(), null, null, choiceManager, null); - assertEquals(VSIDS.class, branchingHeuristic.getClass()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java deleted file mode 100644 index a73882ed5..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Tests {@link HeapOfActiveAtoms}, including initial heuristic scores computed by {@link MOMs}. - * - */ -public class HeapOfActiveAtomsTest { - - private static final double DOUBLE_COMPARISON_EPSILON = 0.001; - - private AtomStore atomStore; - private WritableAssignment assignment; - private VSIDS vsids; - private NoGoodStoreAlphaRoaming noGoodStore; - - @Before - public void setUp() { - atomStore = new AtomStoreImpl(); - assignment = new TrailAssignment(atomStore); - noGoodStore = new NoGoodStoreAlphaRoaming(assignment); - ChoiceManager choiceManager = new PseudoChoiceManager(assignment, noGoodStore); - this.vsids = new VSIDS(assignment, choiceManager, MOMs.DEFAULT_STRATEGY); - } - - @Test - public void testAllAtomsEqualScore() { - int lit1 = Literals.atomToLiteral(1); - int lit2 = Literals.atomToLiteral(2); - int lit3 = Literals.atomToLiteral(3); - HeuristicTestUtils.addNoGoods(atomStore, assignment, noGoodStore, vsids, new NoGood(lit1, lit2), new NoGood(lit2, lit3), - new NoGood(lit1, lit3)); - double activity1 = vsids.heapOfActiveAtoms.getActivity(lit1); - double activity2 = vsids.heapOfActiveAtoms.getActivity(lit2); - double activity3 = vsids.heapOfActiveAtoms.getActivity(lit3); - assertEquals(activity1, activity2, DOUBLE_COMPARISON_EPSILON); - assertEquals(activity2, activity3, DOUBLE_COMPARISON_EPSILON); - } - - @Test - public void testOneAtomHigherScore() { - int lit1 = Literals.atomToLiteral(1); - int lit2 = Literals.atomToLiteral(2); - int lit3 = Literals.atomToLiteral(3); - int lit1Neg = Literals.atomToLiteral(1, false); - int lit2Neg = Literals.atomToLiteral(2, false); - int lit3Neg = Literals.atomToLiteral(3, false); - HeuristicTestUtils.addNoGoods(atomStore, assignment, noGoodStore, vsids, new NoGood(lit1, lit2Neg), new NoGood(lit1Neg, lit2), - new NoGood(lit2, lit3Neg), new NoGood(lit2Neg, lit3)); - double activity1 = vsids.heapOfActiveAtoms.getActivity(lit1); - double activity2 = vsids.heapOfActiveAtoms.getActivity(lit2); - double activity3 = vsids.heapOfActiveAtoms.getActivity(lit3); - assertLessThan(activity1, activity2); - assertLessThan(activity3, activity2); - } - - private static void assertLessThan(double d1, double d2) { - assertTrue(d1 < d2 + DOUBLE_COMPARISON_EPSILON); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java deleted file mode 100644 index 680dc6131..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; - -public class HeuristicTestUtils { - - static void addNoGoods(AtomStore atomStore, WritableAssignment assignment, NoGoodStoreAlphaRoaming noGoodStore, VSIDS vsids, NoGood... noGoods) { - int numberOfAtoms = Arrays.stream(noGoods).flatMapToInt(NoGood::stream).map(Literals::atomOf).max().getAsInt(); - AtomStoreTest.fillAtomStore(atomStore, numberOfAtoms); - assignment.growForMaxAtomId(); - noGoodStore.growForMaxAtomId(numberOfAtoms); - vsids.growForMaxAtomId(numberOfAtoms); - Collection setOfNoGoods = new HashSet<>(); - int noGoodId = 1; - for (NoGood noGood : noGoods) { - setOfNoGoods.add(noGood); - noGoodStore.add(noGoodId++, noGood); - } - vsids.heapOfActiveAtoms.newNoGoods(setOfNoGoods); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java deleted file mode 100644 index 55c95ccb0..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java +++ /dev/null @@ -1,51 +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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.NoGoodStore; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; - -/** - * A {@link ChoiceManager} for testing purposes that regards all atoms as active choice atoms. - * - */ -class PseudoChoiceManager extends ChoiceManager { - - public PseudoChoiceManager(WritableAssignment assignment, NoGoodStore store) { - super(assignment, store); - } - - @Override - public boolean isAtomChoice(int atom) { - return true; - } - - @Override - public boolean isActiveChoiceAtom(int atom) { - return true; - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java deleted file mode 100644 index 81ec7bbd1..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.solver.*; -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.List; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static org.junit.Assert.assertEquals; - -/** - * Tests {@link ReplayHeuristic} - */ -public class ReplayHeuristicTest { - - private final boolean debugInternalChecks = true; - private ChoiceManager choiceManager; - - @Before - public void setUp() { - AtomStore atomStore = new AtomStoreImpl(); - WritableAssignment assignment = new TrailAssignment(atomStore); - NoGoodStore store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); - this.choiceManager = new PseudoChoiceManager(assignment, store); - } - - @Test - public void testBasicChoiceSequence() { - final int literal1 = atomToLiteral(2); - final int signedAtom1 = 2; - - final int literal2 = atomToLiteral(4, false); - final int signedAtom2 = -4; - - final int literal3 = atomToLiteral(7); - final int signedAtom3 = 7; - - final List chosenSignedAtoms = Arrays.asList(signedAtom1, signedAtom2, signedAtom3); - final ReplayHeuristic replayHeuristic = new ReplayHeuristic(chosenSignedAtoms, choiceManager); - assertEquals(literal1, replayHeuristic.chooseLiteral()); - assertEquals(literal2, replayHeuristic.chooseLiteral()); - assertEquals(literal3, replayHeuristic.chooseLiteral()); - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java deleted file mode 100644 index e4f4f714f..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright (c) 2018-2019 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.*; -import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collection; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Tests {@link VSIDS}. - * - */ -public class VSIDSTest { - - /** - * The tolerable epsilon for double comparisons - */ - private static final double DOUBLE_COMPARISON_EPSILON = 0.000001; - - private VSIDS vsids; - private AtomStore atomStore; - private WritableAssignment assignment; - private NoGoodStoreAlphaRoaming noGoodStore; - - private int lit1Neg = Literals.atomToLiteral(1, false); - private int lit2Neg = Literals.atomToLiteral(2, false); - private int lit3Neg = Literals.atomToLiteral(3, false); - private int lit4Neg = Literals.atomToLiteral(4, false); - private int lit1 = Literals.atomToLiteral(1); - private int lit2 = Literals.atomToLiteral(2); - private int lit3 = Literals.atomToLiteral(3); - private int lit4 = Literals.atomToLiteral(4); - - @Before - public void setUp() { - atomStore = new AtomStoreImpl(); - AtomStoreTest.fillAtomStore(atomStore, 4); - assignment = new TrailAssignment(atomStore); - assignment.growForMaxAtomId(); - noGoodStore = new NoGoodStoreAlphaRoaming(assignment); - this.vsids = new VSIDS( - assignment, - new PseudoChoiceManager(assignment, noGoodStore), - null); - } - - /** - * Tests the following artificial situation: - * Static nogoods: { {-1, -2}, {-3, -4}} - * Learnt nogood: { 2, 3 } - * Atoms resolved out during conflict analysis: { 1 } - */ - @Test - public void testConflict() { - HeuristicTestUtils.addNoGoods(atomStore, assignment, noGoodStore, vsids, new NoGood(lit1Neg, lit2Neg), new NoGood(lit3Neg, lit4Neg)); - vsids.chooseLiteral(); // to make VSIDS ingest buffered nogoods - assertEquals(vsids.getActivity(lit1), vsids.getActivity(lit2), DOUBLE_COMPARISON_EPSILON); - assertEquals(vsids.getActivity(lit2), vsids.getActivity(lit3), DOUBLE_COMPARISON_EPSILON); - assertEquals(vsids.getActivity(lit3), vsids.getActivity(lit4), DOUBLE_COMPARISON_EPSILON); - - NoGood learnedNoGood = new NoGood(lit2, lit3); - Collection resolutionAtoms = Arrays.asList(1); - ConflictAnalysisResult analysisResult = new ConflictAnalysisResult(learnedNoGood, 1, resolutionAtoms); - vsids.analyzedConflict(analysisResult); - assertEquals(vsids.getActivity(lit1), vsids.getActivity(lit2), DOUBLE_COMPARISON_EPSILON); - assertEquals(vsids.getActivity(lit2), vsids.getActivity(lit3), DOUBLE_COMPARISON_EPSILON); - assertLessThan(vsids.getActivity(lit4), vsids.getActivity(lit3)); - - assertEquals(0, vsids.getSignBalance(1)); - assertEquals(1, vsids.getSignBalance(2)); - assertEquals(1, vsids.getSignBalance(3)); - assertEquals(0, vsids.getSignBalance(4)); - } - - /** - * First, calls {@link #testConflict()}. - * Then, simulates a second conflict, learning { -1, 4 } with resolved atoms { 2 }. - * Due to decay, scores of atoms { 1, 4, 2 } must increase by the increased activity delta of {@link VSIDS#DEFAULT_DECAY_FACTOR}. - * - */ - @Test - public void testTwoConflicts() { - testConflict(); - - double activity1 = vsids.getActivity(lit1); - double activity2 = vsids.getActivity(lit2); - double activity3 = vsids.getActivity(lit3); - double activity4 = vsids.getActivity(lit4); - - NoGood learnedNoGood = new NoGood(lit1Neg, lit4); - Collection resolutionAtoms = Arrays.asList(2); - ConflictAnalysisResult analysisResult = new ConflictAnalysisResult(learnedNoGood, 1, resolutionAtoms); - vsids.analyzedConflict(analysisResult); - assertEquals(activity1 + VSIDS.DEFAULT_DECAY_FACTOR, vsids.getActivity(lit1), DOUBLE_COMPARISON_EPSILON); - assertEquals(activity2 + VSIDS.DEFAULT_DECAY_FACTOR, vsids.getActivity(lit2), DOUBLE_COMPARISON_EPSILON); - assertEquals(activity3, vsids.getActivity(lit3), DOUBLE_COMPARISON_EPSILON); - assertEquals(activity4 + VSIDS.DEFAULT_DECAY_FACTOR, vsids.getActivity(lit4), DOUBLE_COMPARISON_EPSILON); - - assertEquals(-1, vsids.getSignBalance(1)); - assertEquals(1, vsids.getSignBalance(2)); - assertEquals(1, vsids.getSignBalance(3)); - assertEquals(1, vsids.getSignBalance(4)); - } - - private static void assertLessThan(double d1, double d2) { - assertTrue(d1 < d2 + DOUBLE_COMPARISON_EPSILON); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java b/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java deleted file mode 100644 index 238894bbd..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver.learning; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.*; -import org.junit.Ignore; -import org.junit.Test; - -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; -import static org.junit.Assert.*; - -/** - * Copyright (c) 2016-2019, the Alpha Team. - */ -public class GroundConflictNoGoodLearnerTest { - - private final WritableAssignment assignment; - private final NoGoodStore store; - private AtomStore atomStore; - - public GroundConflictNoGoodLearnerTest() { - atomStore = new AtomStoreImpl(); - AtomStoreTest.fillAtomStore(atomStore, 20); - this.assignment = new TrailAssignment(atomStore); - this.assignment.growForMaxAtomId(); - this.store = new NoGoodStoreAlphaRoaming(assignment); - this.store.growForMaxAtomId(20); - } - - @Test - public void smallConflictNonTrivial1UIP() { - GroundConflictNoGoodLearner learner = new GroundConflictNoGoodLearner(assignment, atomStore); - - NoGood n1 = new NoGood(fromOldLiterals(2, -8, 1)); - NoGood n2 = new NoGood(fromOldLiterals(-1, -7)); - NoGood n3 = new NoGood(fromOldLiterals(-3, 1)); - NoGood n4 = new NoGood(fromOldLiterals(5, 3)); - NoGood n5 = new NoGood(fromOldLiterals(6, -5)); - NoGood n6 = new NoGood(fromOldLiterals(4, -2)); - NoGood n7 = new NoGood(fromOldLiterals(-6, -4)); - store.add(10, n1); - store.add(11, n2); - store.add(12, n3); - store.add(13, n4); - store.add(14, n5); - store.add(15, n6); - store.add(16, n7); - - assignment.choose(9, ThriceTruth.TRUE); - assignment.choose(8, ThriceTruth.FALSE); - assertNull(store.propagate()); - assertFalse(store.didPropagate()); - assignment.choose(7, ThriceTruth.FALSE); - ConflictCause conflictCause = store.propagate(); - assertTrue(store.didPropagate()); - - assertNotNull(conflictCause); - Antecedent violatedNoGood = conflictCause.getAntecedent(); - assertNotNull(violatedNoGood); - assertTrue(antecedentsEquals(violatedNoGood, n5.asAntecedent()) || antecedentsEquals(violatedNoGood, n7.asAntecedent())); - GroundConflictNoGoodLearner.ConflictAnalysisResult analysisResult = learner.analyzeConflictingNoGood(conflictCause.getAntecedent()); - NoGood learnedNoGood = analysisResult.learnedNoGood; - assertEquals(new NoGood(fromOldLiterals(1, -8)), learnedNoGood); - int backjumpingDecisionLevel = analysisResult.backjumpLevel; - assertEquals(backjumpingDecisionLevel, 2); - } - - @Ignore // TrailAssignment no longer propagates at lower decision level. - @Test - public void subCurrentDLPropagationWithChoiceCauseOfConflict() { - GroundConflictNoGoodLearner learner = new GroundConflictNoGoodLearner(assignment, atomStore); - NoGood n1 = new NoGood(fromOldLiterals(1, -2)); - NoGood n2 = new NoGood(fromOldLiterals(2, 3)); - store.add(10, n1); - assignment.choose(1, ThriceTruth.TRUE); - assignment.choose(3, ThriceTruth.TRUE); - store.propagate(); - assertEquals(ThriceTruth.MBT, assignment.get(2).getTruth()); - assertEquals(1, assignment.get(2).getDecisionLevel()); - ConflictCause conflictCause = store.add(11, n2); - assertNotNull(conflictCause); - assertNotNull(conflictCause.getAntecedent()); - GroundConflictNoGoodLearner.ConflictAnalysisResult conflictAnalysisResult = learner.analyzeConflictingNoGood(conflictCause.getAntecedent()); - assertNull(conflictAnalysisResult.learnedNoGood); - assertEquals(2, conflictAnalysisResult.backjumpLevel); - - } -} \ No newline at end of file diff --git a/src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java b/src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java deleted file mode 100644 index e4e623a41..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/test/util/DependencyGraphUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -package at.ac.tuwien.kr.alpha.test.util; - -import at.ac.tuwien.kr.alpha.common.depgraph.DependencyGraph; -import at.ac.tuwien.kr.alpha.common.depgraph.Edge; -import at.ac.tuwien.kr.alpha.common.depgraph.Node; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * - * Copyright (c) 2019-2020, the Alpha Team. - */ -public final class DependencyGraphUtils { - - private DependencyGraphUtils() { - - } - - public static boolean isReachableFrom(Node dest, Node src, DependencyGraph dg) { - return DependencyGraphUtils.isReachableFrom(dest, src, dg, new HashSet<>()); - } - - private static boolean isReachableFrom(Node dest, Node src, DependencyGraph dg, Set discovered) { - List outgoingEdges; - if (src.equals(dest)) { - return true; - } - if ((outgoingEdges = dg.getAdjancencyMap().get(src)) == null) { - return false; - } - discovered.add(src); - // Checking all edges first before descending deeper. - for (Edge edge : outgoingEdges) { - if (edge.getTarget().equals(dest)) { - return true; - } - } - for (Edge tmp : outgoingEdges) { - if (discovered.contains(tmp.getTarget())) { - // Cycle found, do not descend deeper. - continue; - } - if (DependencyGraphUtils.isReachableFrom(dest, tmp.getTarget(), dg, discovered)) { - return true; - } - } - return false; - } - - /** - * Checks whether the given nodes are strongly connected within the given dependency graph. Strongly connected - * means every node in the given list is reachable from every other node in the list and vice versa. - * - * @param connectedNodes the nodes to check. - * @param dg the dependency graph in which to check. - * @return true if the given nodes are strongly connected, false otherwise. - */ - public static boolean areStronglyConnected(List connectedNodes, DependencyGraph dg) { - for (Node n1 : connectedNodes) { - for (Node n2 : connectedNodes) { - if (!(DependencyGraphUtils.isReachableFrom(n2, n1, dg) && DependencyGraphUtils.isReachableFrom(n1, n2, dg))) { - return false; - } - } - } - return true; - } - - public static boolean isStronglyConnectedComponent(List componentNodes, DependencyGraph dg) { - if (!DependencyGraphUtils.areStronglyConnected(componentNodes, dg)) { - return false; - } - // Check if the given set is maximal. - List lst = new ArrayList<>(componentNodes); - for (Node n : dg.getAdjancencyMap().keySet()) { - if (lst.contains(n)) { - continue; - } - lst.add(n); - if (DependencyGraphUtils.areStronglyConnected(lst, dg)) { - // Not a strongly connected component if there is a bigger set which is strongly connected. - return false; - } - } - return true; - } - -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java b/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java deleted file mode 100644 index df0526ea5..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (c) 2016-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.test.util; - -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.grounder.Substitution; - -public class SubstitutionTestUtil { - - public static String groundAndPrintRule(InternalRule rule, Substitution substitution) { - StringBuilder ret = new StringBuilder(); - if (!rule.isConstraint()) { - Atom groundHead = rule.getHeadAtom().substitute(substitution); - ret.append(groundHead.toString()); - } - ret.append(" :- "); - boolean isFirst = true; - for (Literal lit : rule.getBody()) { - ret.append(groundLiteralToString(lit, substitution, isFirst)); - isFirst = false; - } - ret.append("."); - return ret.toString(); - } - - public static String groundLiteralToString(Literal literal, Substitution substitution, boolean isFirst) { - Literal groundLiteral = literal.substitute(substitution); - return (isFirst ? "" : ", ") + groundLiteral.toString(); - } -} diff --git a/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java deleted file mode 100644 index 296b3e4c7..000000000 --- a/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java +++ /dev/null @@ -1,98 +0,0 @@ -package at.ac.tuwien.kr.alpha.test.util; - -import at.ac.tuwien.kr.alpha.AnswerSetsParser; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.AbstractProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import org.junit.Assert; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.StringJoiner; - -import static java.util.Collections.emptySet; - -public class TestUtils { - - 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 { - Assert.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) { - TestUtils.assertAnswerSetsEqual(emptySet(), actual); - return; - } - StringJoiner joiner = new StringJoiner("} {", "{", "}"); - Arrays.stream(expected).forEach(joiner::add); - TestUtils.assertAnswerSetsEqual(AnswerSetsParser.parse(joiner.toString()), actual); - } - - public static void assertAnswerSetsEqual(String expectedAnswerSet, Set actual) { - TestUtils.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); - } - } - TestUtils.assertAnswerSetsEqual(expectedAnswerSets, actual); - } - - public static void assertFactsContainedInProgram(AbstractProgram prog, Atom... facts) { - for (Atom fact : facts) { - Assert.assertTrue(prog.getFacts().contains(fact)); - } - } - - public static Atom basicAtomWithStringTerms(String predicate, String... terms) { - Predicate pred = Predicate.getInstance(predicate, terms.length); - List trms = new ArrayList<>(); - for (String str : terms) { - trms.add(ConstantTerm.getInstance(str)); - } - return new BasicAtom(pred, trms); - } - - public static Atom basicAtomWithSymbolicTerms(String predicate, String... constantSymbols) { - Predicate pred = Predicate.getInstance(predicate, constantSymbols.length); - List trms = new ArrayList<>(); - for (String str : constantSymbols) { - trms.add(ConstantTerm.getSymbolicInstance(str)); - } - return new BasicAtom(pred, trms); - } - -} diff --git a/src/test/resources/HanoiTower_Alpha.asp b/src/test/resources/HanoiTower_Alpha.asp deleted file mode 100644 index 922962744..000000000 --- a/src/test/resources/HanoiTower_Alpha.asp +++ /dev/null @@ -1,98 +0,0 @@ -% HanoiTower -% Source: ASP Competition 2013 Official (disjunction shifted by ASP Shifter) -% ADAPTIONS FOR ALPHA: -% - replaced "TP1 = T + 1" by "succ(T,TP1)" because arithmetics are not supported -% - replaced "TM1 = T - 1" by "succ(TM1,T)" for the same reason - -peg(1). -peg(2). -peg(3). -peg(4). - -% Read in data -on(0, N1, N) :- on0(N, N1). -onG(K, N1, N) :- ongoal(N, N1), steps(K). - -% Specify valid arrangements of disks -% Basic condition. Smaller disks are on larger ones -:- time(T), on(T, N1, N), N1 >= N. - -% Specify a valid move (only for T - - - - %5relative %.-1level %20.20logger %msg %n - - - - junit.log - false - - - %-4r %-5level %logger{35}: %msg%n - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/partial-eval/pup_topological_order.asp b/src/test/resources/partial-eval/pup_topological_order.asp deleted file mode 100644 index b8aacc3fd..000000000 --- a/src/test/resources/partial-eval/pup_topological_order.asp +++ /dev/null @@ -1,34 +0,0 @@ -maxPU(2). - -comUnit(1). comUnit(2). - -% relation between zones and door sensors -zone2sensor(1,1). -zone2sensor(1,2). -zone2sensor(2,1). -zone2sensor(2,3). -zone2sensor(2,4). -zone2sensor(3,3). - -% helpers for QUICKPUP heuristics, inspired by quickpup.ascass by Erich Teppan: -sensor(S):-zone2sensor(Z,S). -zone(Z):-zone2sensor(Z,S). - -numZones(N) :- zone(N), not zone(N+1). -numSensors(N) :- sensor(N), not sensor(N+1). -numElems(M):-numZones(E),numSensors(F),M=E+F. - -numUnits(N) :- comUnit(N), not comUnit(N+1). - -%-------topological order--- -startZone(1). -zoneDist(Z0,0):-startZone(Z0). - -sensorDist(S,Dz+1):-zoneDist(Z,Dz),zone2sensor(Z,S),numElems(M),Dz Date: Fri, 5 Feb 2021 19:42:49 +0100 Subject: [PATCH 020/111] WIP: adapt unit tests to modularized setup --- .../alpha/api/grounder/RuleGroundingInfo.java | 2 + .../api/grounder/RuleGroundingOrder.java | 2 + .../kr/alpha/api/grounder/Substitution.java | 2 + .../kr/alpha/api/rules/CompiledRule.java | 1 + .../core/grounder/RuleGroundingInfoImpl.java | 5 +- .../core/grounder/RuleGroundingOrderTest.java | 75 ++++---- .../alpha/core/grounder/RuleToStringTest.java | 26 +-- .../alpha/core/grounder/SubstitutionTest.java | 99 +++++----- .../kr/alpha/core/grounder/UnifierTest.java | 38 ++-- .../solver/AbstractSolverTests.java | 89 ++++----- ...AggregatesCardinalityCountingGridTest.java | 2 +- ...gregatesCardinalitySortingCircuitTest.java | 2 +- .../{ => core}/solver/AggregatesTest.java | 32 ++-- .../{ => core}/solver/AntecedentTest.java | 4 +- .../{ => core}/solver/AtomCounterTests.java | 57 +++--- .../{ => core}/solver/ChoiceManagerTests.java | 38 ++-- .../{ => core}/solver/HanoiTowerTest.java | 55 +++--- .../solver/HeadBodyTransformationTests.java | 23 +-- .../solver/LearnedNoGoodDeletionTest.java | 22 ++- .../solver/NaiveNoGoodStoreTest.java | 27 ++- .../solver/NoGoodStoreAlphaRoamingTest.java | 27 ++- .../solver/OmigaBenchmarksTest.java | 17 +- .../solver/PartSubpartConfigurationTest.java | 2 +- .../{ => core}/solver/PigeonHoleTest.java | 29 +-- .../kr/alpha/{ => core}/solver/RacksTest.java | 20 +- .../solver/SolverStatisticsTests.java | 19 +- .../alpha/{ => core}/solver/SolverTests.java | 63 +++--- .../solver/TestableChoiceManager.java | 2 +- .../solver/ThreeColouringRandomGraphTest.java | 2 +- .../solver/ThreeColouringTestWithRandom.java | 2 +- .../solver/ThreeColouringWheelTest.java | 2 +- .../solver/TrailAssignmentTest.java | 8 +- .../GrounderHeuristicConfigurationTest.java | 10 +- .../LiteralInstantiationStrategyTest.java | 118 ++++++------ .../LiteralInstantiatorTest.java | 111 ++++++----- .../structure/AnalyzeUnjustifiedTest.java | 91 +++++---- .../StratifiedEvaluationRegressionTest.java | 128 +++++++------ .../StratifiedEvaluationTest.java | 180 +++++++++--------- .../alpha/solver/HanoiTowerDetailedTest.java | 44 ----- .../AlphaHeuristicTestAssumptions.java | 9 +- .../alpha/solver/heuristics/BerkMinTest.java | 9 +- .../BranchingHeuristicFactoryTest.java | 3 +- .../heuristics/HeapOfActiveAtomsTest.java | 9 +- .../solver/heuristics/HeuristicTestUtils.java | 4 +- .../heuristics/PseudoChoiceManager.java | 6 +- .../heuristics/ReplayHeuristicTest.java | 3 +- .../kr/alpha/solver/heuristics/VSIDSTest.java | 9 +- .../GroundConflictNoGoodLearnerTest.java | 5 +- .../alpha/test/util/SubstitutionTestUtil.java | 10 +- .../tuwien/kr/alpha/test/util/TestUtils.java | 33 ++-- 50 files changed, 802 insertions(+), 774 deletions(-) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AbstractSolverTests.java (80%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AggregatesCardinalityCountingGridTest.java (97%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AggregatesCardinalitySortingCircuitTest.java (97%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AggregatesTest.java (88%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AntecedentTest.java (89%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/AtomCounterTests.java (70%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ChoiceManagerTests.java (76%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/HanoiTowerTest.java (77%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/HeadBodyTransformationTests.java (93%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/LearnedNoGoodDeletionTest.java (92%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/NaiveNoGoodStoreTest.java (94%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/NoGoodStoreAlphaRoamingTest.java (94%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/OmigaBenchmarksTest.java (89%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/PartSubpartConfigurationTest.java (98%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/PigeonHoleTest.java (89%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/RacksTest.java (85%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/SolverStatisticsTests.java (95%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/SolverTests.java (90%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/TestableChoiceManager.java (97%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ThreeColouringRandomGraphTest.java (99%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ThreeColouringTestWithRandom.java (99%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/ThreeColouringWheelTest.java (99%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/TrailAssignmentTest.java (97%) delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java index 30881011c..21820ce61 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java @@ -14,5 +14,7 @@ public interface RuleGroundingInfo { List getStartingLiterals(); RuleGroundingOrder orderStartingFrom(Literal startingLiteral); + + void computeGroundingOrders(); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java index a55a00c57..116b7227d 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java @@ -12,5 +12,7 @@ public interface RuleGroundingOrder { RuleGroundingOrder pushBack(int pos); void considerUntilCurrentEnd(); + + int getPositionFromWhichAllVarsAreBound(); } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java index 4d008e1ee..664b6ee6b 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Substitution.java @@ -13,4 +13,6 @@ public interface Substitution { > Term put(VariableTerm variableTerm, Term groundTerm); + boolean isVariableSet(VariableTerm var); + } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java index 2eeb6dbbd..c200ec45b 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java @@ -15,4 +15,5 @@ public interface CompiledRule extends Rule { CompiledRule renameVariables(String str); + boolean isGround(); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java index d50c333ab..137d80880 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java @@ -40,6 +40,7 @@ import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; @@ -63,7 +64,7 @@ * literal (whose interpretation is not fixed) is a starting literal, at least for the current grounding procedure. */ public class RuleGroundingInfoImpl implements RuleGroundingInfo { - private final InternalRule internalRule; + private final CompiledRule internalRule; HashMap groundingOrders; private HashMap literalSelectivity; private List startingLiterals; @@ -71,7 +72,7 @@ public class RuleGroundingInfoImpl implements RuleGroundingInfo { private final boolean fixedGroundingInstantiation; private RuleGroundingOrderImpl fixedGroundingOrder; - public RuleGroundingInfoImpl(InternalRule internalRule) { + public RuleGroundingInfoImpl(CompiledRule internalRule) { this.internalRule = internalRule; this.literalSelectivity = new HashMap<>(); resetLiteralSelectivity(); 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 index 2f69d8055..12ae3d392 100644 --- 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 @@ -32,20 +32,31 @@ import static org.junit.Assert.fail; import java.io.IOException; +import java.util.function.Function; import org.junit.Test; -import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +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.InternalProgram; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; /** * 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(false); + 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(); @@ -54,51 +65,43 @@ public void groundingOrder() throws IOException { 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."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - InternalRule rule0 = internalPrg.getRules().get(0); - RuleGroundingOrders rgo0 = new RuleGroundingOrders(rule0); + 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()); - InternalRule rule1 = internalPrg.getRules().get(1); - RuleGroundingOrders rgo1 = new RuleGroundingOrders(rule1); + CompiledRule rule1 = prog.getRules().get(1); + RuleGroundingInfo rgo1 = new RuleGroundingInfoImpl(rule1); rgo1.computeGroundingOrders(); assertEquals(4, rgo1.getStartingLiterals().size()); - InternalRule rule2 = internalPrg.getRules().get(2); - RuleGroundingOrders rgo2 = new RuleGroundingOrders(rule2); + CompiledRule rule2 = prog.getRules().get(2); + RuleGroundingInfo rgo2 = new RuleGroundingInfoImpl(rule2); rgo2.computeGroundingOrders(); - assertTrue(rgo2.fixedInstantiation()); + assertTrue(rgo2.hasFixedInstantiation()); } @Test(expected = RuntimeException.class) public void groundingOrderUnsafe() throws IOException { String aspStr = "h(X,C) :- X = Y, Y = C .. 3, C = X."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - computeGroundingOrdersForRule(internalPrg, 0); + CompiledProgram prog = PARSE_AND_PREPROCESS.apply(aspStr); + computeGroundingOrdersForRule(prog, 0); } @Test public void testPositionFromWhichAllVarsAreBound_ground() { String aspStr = "a :- b, not c."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders rgo0 = computeGroundingOrdersForRule(internalPrg, 0); + 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)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders rgo0 = computeGroundingOrdersForRule(internalPrg, 0); + 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()); @@ -108,10 +111,8 @@ public void testPositionFromWhichAllVarsAreBound_simpleNonGround() { @Test public void testPositionFromWhichAllVarsAreBound_longerSimpleNonGround() { String aspStr = "a(X) :- b(X), c(X), d(X), not e(X)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders rgo0 = computeGroundingOrdersForRule(internalPrg, 0); + 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()); @@ -121,10 +122,8 @@ public void testPositionFromWhichAllVarsAreBound_longerSimpleNonGround() { @Test public void testToString_longerSimpleNonGround() { String aspStr = "a(X) :- b(X), c(X), d(X), not e(X)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders rgo0 = computeGroundingOrdersForRule(internalPrg, 0); + 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()) { @@ -139,10 +138,8 @@ public void testToString_longerSimpleNonGround() { @Test public void testPositionFromWhichAllVarsAreBound_joinedNonGround() { String aspStr = "a(X) :- b(X), c(X,Y), d(X,Z), not e(X)."; - Alpha system = new Alpha(); - system.getConfig().setEvaluateStratifiedPart(false); - InternalProgram internalPrg = InternalProgram.fromNormalProgram(system.normalizeProgram(system.readProgramString(aspStr))); - RuleGroundingOrders rgo0 = computeGroundingOrdersForRule(internalPrg, 0); + 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)"); @@ -151,9 +148,9 @@ public void testPositionFromWhichAllVarsAreBound_joinedNonGround() { assertTrue(1 <= rgo0.orderStartingFrom(litDXZ).getPositionFromWhichAllVarsAreBound()); } - private RuleGroundingOrders computeGroundingOrdersForRule(InternalProgram program, int ruleIndex) { - InternalRule rule = program.getRules().get(ruleIndex); - RuleGroundingOrders rgo = new RuleGroundingOrders(rule); + 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/RuleToStringTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java index 54be5d18a..20f7cf988 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/RuleToStringTest.java @@ -31,17 +31,21 @@ import org.junit.Test; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +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.NormalRule; /** * Tests {@link BasicRule#toString()} and {@link InternalRule#toString()}. */ public class RuleToStringTest { - private final ProgramParser parser = new ProgramParser(); + private final ProgramParser parser = new ProgramParserImpl(); @Test public void positiveRuleToString() { @@ -84,18 +88,18 @@ public void nonGroundConstraintToString() { } private void parseSingleRuleAndCheckToString(String rule) { - BasicRule parsedRule = parseSingleRule(rule); + Rule parsedRule = parseSingleRule(rule); assertEquals(rule, parsedRule.toString()); } private void constructNonGroundRuleAndCheckToString(String textualRule) { - InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(parseSingleRule(textualRule))); + CompiledRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(parseSingleRule(textualRule))); assertEquals(textualRule, nonGroundRule.toString()); } - private BasicRule parseSingleRule(String rule) { - InputProgram program = parser.parse(rule); - List rules = program.getRules(); + private Rule parseSingleRule(String rule) { + ASPCore2Program program = parser.parse(rule); + List> rules = program.getRules(); assertEquals("Number of rules", 1, rules.size()); return rules.get(0); } 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 88dfcb9ec..df447a253 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 @@ -27,64 +27,73 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.rule.BasicRule; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.NormalRule; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.test.util.SubstitutionTestUtil; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.util.Arrays; -import static org.junit.Assert.assertEquals; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.grounder.Instance; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.rules.Head; +import at.ac.tuwien.kr.alpha.api.rules.Rule; +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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.NormalRule; +import at.ac.tuwien.kr.alpha.test.util.SubstitutionTestUtil; public class SubstitutionTest { - private static final ProgramParser PARSER = new ProgramParser(); + private static final ProgramParser PARSER = new ProgramParserImpl(); - private static final ConstantTerm A = ConstantTerm.getSymbolicInstance("a"); - private static final ConstantTerm B = ConstantTerm.getSymbolicInstance("b"); - private static final ConstantTerm C = ConstantTerm.getSymbolicInstance("c"); + private static final ConstantTerm A = CoreConstantTerm.getSymbolicInstance("a"); + private static final ConstantTerm B = CoreConstantTerm.getSymbolicInstance("b"); + private static final ConstantTerm C = CoreConstantTerm.getSymbolicInstance("c"); - private static final VariableTerm X = VariableTerm.getInstance("X"); - private static final VariableTerm Y = VariableTerm.getInstance("Y"); - private static final BasicAtom PX = new BasicAtom(Predicate.getInstance("p", 1), X); - private static final BasicAtom PY = new BasicAtom(Predicate.getInstance("p", 1), Y); + private static final VariableTerm X = VariableTermImpl.getInstance("X"); + private static final VariableTerm Y = VariableTermImpl.getInstance("Y"); + private static final BasicAtom PX = new BasicAtom(CorePredicate.getInstance("p", 1), X); + private static final BasicAtom PY = new BasicAtom(CorePredicate.getInstance("p", 1), Y); private static final Instance PA = new Instance(A); private static final Instance PB = new Instance(B); @Test public void putSimpleBinding() { - Substitution substitution = new Substitution(); + Substitution substitution = new SubstitutionImpl(); substitution.put(Y, A); assertEquals(A, substitution.eval(Y)); } @Test public void specializeTermsSimpleBinding() { - Substitution substitution = Substitution.specializeSubstitution(PY, PA, Substitution.EMPTY_SUBSTITUTION); + Substitution substitution = SubstitutionImpl.specializeSubstitution(PY, PA, SubstitutionImpl.EMPTY_SUBSTITUTION); assertEquals(A, substitution.eval(Y)); } @Test public void specializeTermsFunctionTermBinding() { - Substitution substitution = new Substitution(); + Substitution substitution = new SubstitutionImpl(); substitution.put(Y, A); FunctionTerm groundFunctionTerm = FunctionTerm.getInstance("f", B, C); Instance qfBC = new Instance(groundFunctionTerm); Term nongroundFunctionTerm = FunctionTerm.getInstance("f", B, X); - BasicAtom qfBX = new BasicAtom(Predicate.getInstance("q", 2), nongroundFunctionTerm); + BasicAtom qfBX = new BasicAtom(CorePredicate.getInstance("q", 2), nongroundFunctionTerm); - Substitution substitution1 = Substitution.specializeSubstitution(qfBX, qfBC, substitution); + Substitution substitution1 = SubstitutionImpl.specializeSubstitution(qfBX, qfBC, substitution); assertEquals(C, substitution1.eval(X)); assertEquals(A, substitution1.eval(Y)); @@ -102,20 +111,20 @@ public void substituteNegativeBasicAtom() { @Test public void groundAndPrintRule() { - BasicRule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); - InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); - Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); - Substitution substitution2 = Substitution.specializeSubstitution(PY, PB, substitution1); + Rule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); + CompiledRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); + Substitution substitution1 = SubstitutionImpl.specializeSubstitution(PX, PA, SubstitutionImpl.EMPTY_SUBSTITUTION); + Substitution substitution2 = SubstitutionImpl.specializeSubstitution(PY, PB, substitution1); String printedString = SubstitutionTestUtil.groundAndPrintRule(nonGroundRule, substitution2); assertEquals("x :- p(a, b), not q(a, b).", printedString); } @Test public void specializeBasicAtom() { - Predicate p = Predicate.getInstance("p", 2); + Predicate p = CorePredicate.getInstance("p", 2); BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); Instance instance = new Instance(A, B); - Substitution substitution = Substitution.specializeSubstitution(atom, instance, Substitution.EMPTY_SUBSTITUTION); + Substitution substitution = SubstitutionImpl.specializeSubstitution(atom, instance, SubstitutionImpl.EMPTY_SUBSTITUTION); BasicAtom substituted = atom.substitute(substitution); assertEquals(p, substituted.getPredicate()); assertEquals(A, substituted.getTerms().get(0)); @@ -123,10 +132,10 @@ public void specializeBasicAtom() { } private void substituteBasicAtomLiteral(boolean negated) { - Predicate p = Predicate.getInstance("p", 2); + Predicate p = CorePredicate.getInstance("p", 2); BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); Literal literal = new BasicLiteral(atom, !negated); - Substitution substitution = new Substitution(); + Substitution substitution = new SubstitutionImpl(); substitution.put(X, A); substitution.put(Y, B); literal = literal.substitute(substitution); @@ -147,23 +156,23 @@ public void groundLiteralToString_NegativeBasicAtom() { } private void groundLiteralToString(boolean negated) { - Predicate p = Predicate.getInstance("p", 2); + Predicate p = CorePredicate.getInstance("p", 2); BasicAtom atom = new BasicAtom(p, Arrays.asList(X, Y)); - Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); - Substitution substitution = Substitution.specializeSubstitution(PY, PB, substitution1); + Substitution substitution1 = SubstitutionImpl.specializeSubstitution(PX, PA, SubstitutionImpl.EMPTY_SUBSTITUTION); + Substitution substitution = SubstitutionImpl.specializeSubstitution(PY, PB, substitution1); String printedString = SubstitutionTestUtil.groundLiteralToString(atom.toLiteral(!negated), substitution, true); assertEquals((negated ? "not " : "") + "p(a, b)", printedString); } @Test public void substitutionFromString() { - BasicRule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); - InternalRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); - Substitution substitution1 = Substitution.specializeSubstitution(PX, PA, Substitution.EMPTY_SUBSTITUTION); - Substitution substitution = Substitution.specializeSubstitution(PY, PB, substitution1); + Rule rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0); + CompiledRule nonGroundRule = InternalRule.fromNormalRule(NormalRule.fromBasicRule(rule)); + Substitution substitution1 = SubstitutionImpl.specializeSubstitution(PX, PA, SubstitutionImpl.EMPTY_SUBSTITUTION); + Substitution substitution = SubstitutionImpl.specializeSubstitution(PY, PB, substitution1); RuleAtom ruleAtom = new RuleAtom(nonGroundRule, substitution); String substitutionString = (String) ((ConstantTerm) ruleAtom.getTerms().get(1)).getObject(); - Substitution fromString = Substitution.fromString(substitutionString); + Substitution fromString = SubstitutionImpl.fromString(substitutionString); assertEquals(substitution, fromString); } } 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 9031d619e..772b40dc1 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 @@ -28,42 +28,44 @@ package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import static org.junit.Assert.assertEquals; import org.junit.Test; -import static org.junit.Assert.assertEquals; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; public class UnifierTest extends SubstitutionTest { @Test public void extendUnifier() { - VariableTerm varX = VariableTerm.getInstance("X"); - VariableTerm varY = VariableTerm.getInstance("Y"); + VariableTerm varX = VariableTermImpl.getInstance("X"); + VariableTerm varY = VariableTermImpl.getInstance("Y"); Unifier sub1 = new Unifier(); sub1.put(varX, varY); Unifier sub2 = new Unifier(); - sub2.put(varY, ConstantTerm.getInstance("a")); + sub2.put(varY, CoreConstantTerm.getInstance("a")); sub1.extendWith(sub2); BasicAtom atom1 = parseAtom("p(X)"); Atom atomSubstituted = atom1.substitute(sub1); - assertEquals(ConstantTerm.getInstance("a"), atomSubstituted.getTerms().get(0)); + assertEquals(CoreConstantTerm.getInstance("a"), atomSubstituted.getTerms().get(0)); } @Test public void mergeUnifierIntoLeft() { - VariableTerm varX = VariableTerm.getInstance("X"); - VariableTerm varY = VariableTerm.getInstance("Y"); - VariableTerm varZ = VariableTerm.getInstance("Z"); - Term constA = ConstantTerm.getInstance("a"); + VariableTerm varX = VariableTermImpl.getInstance("X"); + VariableTerm varY = VariableTermImpl.getInstance("Y"); + VariableTerm varZ = VariableTermImpl.getInstance("Z"); + Term constA = CoreConstantTerm.getInstance("a"); Unifier left = new Unifier(); left.put(varX, varY); left.put(varZ, varY); @@ -75,8 +77,8 @@ public void mergeUnifierIntoLeft() { } private BasicAtom parseAtom(String atom) { - ProgramParser programParser = new ProgramParser(); - InputProgram program = programParser.parse(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/solver/AbstractSolverTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java similarity index 80% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java index d237fb548..936f98dfe 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AbstractSolverTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java @@ -25,33 +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.solver; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.config.SystemConfig; -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.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic; -import at.ac.tuwien.kr.alpha.test.util.TestUtils; -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; -import org.slf4j.LoggerFactory; +package at.ac.tuwien.kr.alpha.core.solver; -import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; @@ -59,6 +35,31 @@ import java.util.Random; import java.util.Set; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +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.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; +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.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; +import at.ac.tuwien.kr.alpha.test.util.TestUtils; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; + @RunWith(Parameterized.class) public abstract class AbstractSolverTests { @@ -70,10 +71,10 @@ public abstract class AbstractSolverTests { nonDeprecatedHeuristicsNames.add(field.getName()); } } - NON_DEPRECATED_HEURISTICS_NAMES = nonDeprecatedHeuristicsNames.toArray(new String[]{}); + NON_DEPRECATED_HEURISTICS_NAMES = nonDeprecatedHeuristicsNames.toArray(new String[] {}); } - private final ProgramParser parser = new ProgramParser(); + private final ProgramParser parser = new ProgramParserImpl(); /** * Sets the logging level to TRACE. Useful for debugging; call at beginning of test case. @@ -102,7 +103,7 @@ void ignoreTestForNaiveSolver() { * (which are not tuned for good performance as well as VSIDS). */ void ignoreNonDefaultDomainIndependentHeuristics() { - org.junit.Assume.assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + org.junit.Assume.assumeTrue(heuristic == Heuristic.VSIDS); } private static String[] getProperty(String subKey, String def) { @@ -124,10 +125,10 @@ public static Collection parameters() { // "ALL" is a magic value that will be expanded to contain all heuristics. if ("ALL".equals(heuristics[0])) { - BranchingHeuristicFactory.Heuristic[] values = BranchingHeuristicFactory.Heuristic.values(); + Heuristic[] values = Heuristic.values(); heuristics = new String[values.length]; int i = 0; - for (BranchingHeuristicFactory.Heuristic heuristic : values) { + for (Heuristic heuristic : values) { heuristics[i++] = heuristic.toString(); } } @@ -156,8 +157,8 @@ public static Collection parameters() { for (String gtc : gtcValues) { for (String gtr : gtrValues) { for (String dir : dirValues) { - factories.add(new Object[]{ - solver, grounder, store, BranchingHeuristicFactory.Heuristic.valueOf(heuristic), seed, checks, gtc, gtr, Boolean.valueOf(dir) + factories.add(new Object[] { + solver, grounder, store, Heuristic.valueOf(heuristic), seed, checks, gtc, gtr, Boolean.valueOf(dir) }); } } @@ -180,7 +181,7 @@ public static Collection parameters() { public String storeName; @Parameter(3) - public BranchingHeuristicFactory.Heuristic heuristic; + public Heuristic heuristic; @Parameter(4) public long seed; @@ -212,35 +213,29 @@ private SystemConfig buildSystemConfig() { return config; } - protected Solver getInstance(InputProgram program) { - Alpha system = new Alpha(); + protected Solver getInstance(ASPCore2Program program) { AtomStore atomStore = new AtomStoreImpl(); - NormalProgram normalized = system.normalizeProgram(program); - InternalProgram preprocessed = InternalProgram.fromNormalProgram(normalized); + CompiledProgram preprocessed = InternalProgram.fromNormalProgram(new NormalizeProgramTransformation(false).apply(program)); return getInstance(atomStore, GrounderFactory.getInstance(grounderName, preprocessed, atomStore, true)); } protected Solver getInstance(String program) { - return getInstance(CharStreams.fromString(program)); + return getInstance(parser.parse(program)); } - protected Solver getInstance(CharStream program) { - try { - return getInstance(parser.parse(program)); - } catch (IOException e) { - throw new RuntimeException(e); - } + protected Solver getInstance(InputStream program) { + return getInstance(parser.parse(program)); } protected Set collectSet(String program) { return getInstance(program).collectSet(); } - protected Set collectSet(InputProgram program) { + protected Set collectSet(ASPCore2Program program) { return getInstance(program).collectSet(); } - protected Set collectSet(CharStream program) { + protected Set collectSet(InputStream program) { return getInstance(program).collectSet(); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesCardinalityCountingGridTest.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesCardinalityCountingGridTest.java index c21d5e971..4df815209 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalityCountingGridTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesCardinalityCountingGridTest.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; /** * Executes {@link AggregatesTest} with {@code normalizationCountingGrid=true}. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesCardinalitySortingCircuitTest.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesCardinalitySortingCircuitTest.java index 9f0558e35..6554141df 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesCardinalitySortingCircuitTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesCardinalitySortingCircuitTest.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; /** * Executes {@link AggregatesTest} with {@code normalizationCountingGrid=false}. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java similarity index 88% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java index 107e1790a..28c5e8d21 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AggregatesTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java @@ -23,22 +23,23 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.core.grounder.transformation.CardinalityNormalization; -import at.ac.tuwien.kr.alpha.core.grounder.transformation.SumNormalization; +import java.io.IOException; import org.junit.Test; -import java.io.IOException; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +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.GrounderFactory; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.CardinalityNormalization; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.SumNormalization; /** * Tests if correct answer sets for programs containing aggregates are computed. @@ -168,12 +169,9 @@ public void testAggregate_Sum_GlobalVariable() throws IOException { } @Override - protected Solver getInstance(InputProgram program) { - Alpha system = new Alpha(); - system.getConfig().setUseNormalizationGrid(useCountingGridNormalization()); + protected Solver getInstance(ASPCore2Program program) { AtomStore atomStore = new AtomStoreImpl(); - NormalProgram normal = system.normalizeProgram(program); - InternalProgram preprocessed = InternalProgram.fromNormalProgram(normal); + CompiledProgram preprocessed = InternalProgram.fromNormalProgram(new NormalizeProgramTransformation(useCountingGridNormalization()).apply(program)); return super.getInstance(atomStore, GrounderFactory.getInstance(grounderName, preprocessed, atomStore, p->true, new GrounderHeuristicsConfiguration(), true)); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AntecedentTest.java similarity index 89% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AntecedentTest.java index 0dce2db91..b7b2755b4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AntecedentTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AntecedentTest.java @@ -1,7 +1,9 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; import java.util.HashSet; +import at.ac.tuwien.kr.alpha.core.solver.Antecedent; + public class AntecedentTest { /** diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java similarity index 70% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java index 9aae4b601..5fa9da8e8 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/AtomCounterTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java @@ -23,32 +23,35 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Test; - import java.util.Arrays; import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.AggregateAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.common.rule.head.NormalHead; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; -import at.ac.tuwien.kr.alpha.core.grounder.atoms.ChoiceAtom; -import at.ac.tuwien.kr.alpha.core.grounder.atoms.RuleAtom; +import org.junit.Before; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; +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.ComparisonOperatorImpl; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; +import at.ac.tuwien.kr.alpha.core.rules.InternalRule; +import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; +import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; public class AtomCounterTests { @@ -97,19 +100,19 @@ public void testGetStatsByType() throws NoSuchMethodException { } private void createBasicAtom1() { - atomStore.putIfAbsent(new BasicAtom(Predicate.getInstance("p", 0))); + atomStore.putIfAbsent(new BasicAtom(CorePredicate.getInstance("p", 0))); } private void createBasicAtom2() { - atomStore.putIfAbsent(new BasicAtom(Predicate.getInstance("q", 1), ConstantTerm.getInstance(1))); + atomStore.putIfAbsent(new BasicAtom(CorePredicate.getInstance("q", 1), CoreConstantTerm.getInstance(1))); } private void createAggregateAtom() { - final ConstantTerm c1 = ConstantTerm.getInstance(1); - final ConstantTerm c2 = ConstantTerm.getInstance(2); - final ConstantTerm c3 = ConstantTerm.getInstance(3); + final ConstantTerm c1 = CoreConstantTerm.getInstance(1); + final ConstantTerm c2 = CoreConstantTerm.getInstance(2); + final ConstantTerm c3 = CoreConstantTerm.getInstance(3); List basicTerms = Arrays.asList(c1, c2, c3); - AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, Collections.singletonList(new BasicAtom(Predicate.getInstance("p", 3), c1, c2, c3).toLiteral())); + AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, Collections.singletonList(new BasicAtom(CorePredicate.getInstance("p", 3), c1, c2, c3).toLiteral())); atomStore.putIfAbsent(new AggregateAtom(ComparisonOperatorImpl.LE, c1, null, null, AggregateAtom.AGGREGATEFUNCTION.COUNT, Collections.singletonList(aggregateElement))); } @@ -118,9 +121,9 @@ private void createChoiceAtom() { } private void createRuleAtom() { - Atom atomAA = new BasicAtom(Predicate.getInstance("aa", 0)); - InternalRule ruleAA = new InternalRule(new NormalHead(atomAA), Collections.singletonList(new BasicAtom(Predicate.getInstance("bb", 0)).toLiteral(false))); - atomStore.putIfAbsent(new RuleAtom(ruleAA, new Substitution())); + Atom atomAA = new BasicAtom(CorePredicate.getInstance("aa", 0)); + CompiledRule ruleAA = new InternalRule(new NormalHeadImpl(atomAA), Collections.singletonList(new BasicAtom(CorePredicate.getInstance("bb", 0)).toLiteral(false))); + atomStore.putIfAbsent(new RuleAtom(ruleAA, new SubstitutionImpl())); } private void expectGetNumberOfAtoms(AtomCounter atomCounter, Class classOfAtoms, int expectedNumber) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java similarity index 76% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java index 7327bea6e..d3e1029e4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ChoiceManagerTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ChoiceManagerTests.java @@ -23,27 +23,27 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -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.grounder.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; import org.junit.Before; import org.junit.Test; -import java.util.Collection; - -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static org.junit.Assert.assertTrue; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +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.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; public class ChoiceManagerTests extends AbstractSolverTests { private Grounder grounder; @@ -52,11 +52,9 @@ public class ChoiceManagerTests extends AbstractSolverTests { @Before public void setUp() { - Alpha system = new Alpha(); String testProgram = "h :- b1, b2, not b3, not b4."; - InputProgram parsedProgram = new ProgramParser().parse(testProgram); - NormalProgram normalProgram = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normalProgram); + ASPCore2Program parsedProgram = new ProgramParserImpl().parse(testProgram); + CompiledProgram internalProgram = InternalProgram.fromNormalProgram(new NormalizeProgramTransformation(false).apply(parsedProgram)); atomStore = new AtomStoreImpl(); grounder = new NaiveGrounder(internalProgram, atomStore, true); WritableAssignment assignment = new TrailAssignment(atomStore); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java similarity index 77% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java index 3b8c8a9c7..46b4f0df1 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java @@ -23,29 +23,31 @@ * 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.solver; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +package at.ac.tuwien.kr.alpha.core.solver; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.nio.file.Paths; import java.util.Optional; import java.util.SortedSet; -import static org.junit.Assert.assertTrue; +import org.junit.Ignore; +import org.junit.Test; +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.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; /** * Tests {@link AbstractSolver} using some hanoi tower test cases (see https://en.wikipedia.org/wiki/Tower_of_Hanoi). @@ -55,7 +57,7 @@ public class HanoiTowerTest extends AbstractSolverTests { private static final Logger LOGGER = LoggerFactory.getLogger(HanoiTowerTest.class); - private final ProgramParser parser = new ProgramParser(); + private final ProgramParser parser = new ProgramParserImpl(); @Test(timeout = 10000) @Ignore("disabled to save resources during CI") @@ -93,8 +95,8 @@ private void testHanoiTower(int instance) throws IOException { } private void testHanoiTower(String instance) throws IOException { - Alpha system = new Alpha(); - InputProgram prog = system.readProgramFiles(false, null, Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), + ASPCore2Program prog = new ProgramParserImpl().parse( + Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); Solver solver = getInstance(prog); Optional answerSet = solver.stream().findFirst(); @@ -103,27 +105,28 @@ private void testHanoiTower(String instance) throws IOException { } /** - * Conducts a very simple, non-comprehensive goal check (i.e. it may classify answer sets as correct that are actually wrong) by checking if for every goal/3 + * Conducts a very simple, non-comprehensive goal check (i.e. it may classify answer sets as correct that are actually wrong) by checking if + * for every goal/3 * fact in the input there is a corresponding on/3 atom in the output. */ - private void checkGoal(InputProgram parsedProgram, AnswerSet answerSet) { - Predicate ongoal = Predicate.getInstance("ongoal", 2); - Predicate on = Predicate.getInstance("on", 3); + private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { + Predicate ongoal = CorePredicate.getInstance("ongoal", 2); + Predicate on = CorePredicate.getInstance("on", 3); int steps = getSteps(parsedProgram); SortedSet onInstancesInAnswerSet = answerSet.getPredicateInstances(on); for (Atom atom : parsedProgram.getFacts()) { if (atom.getPredicate().getName().equals(ongoal.getName()) && atom.getPredicate().getArity() == ongoal.getArity()) { Term expectedTop = atom.getTerms().get(0); Term expectedBottom = atom.getTerms().get(1); - Term expectedSteps = ConstantTerm.getInstance(steps); + Term expectedSteps = CoreConstantTerm.getInstance(steps); Atom expectedAtom = new BasicAtom(on, expectedSteps, expectedBottom, expectedTop); assertTrue("Answer set does not contain " + expectedAtom, onInstancesInAnswerSet.contains(expectedAtom)); } } } - private int getSteps(InputProgram parsedProgram) { - Predicate steps = Predicate.getInstance("steps", 1); + private int getSteps(ASPCore2Program parsedProgram) { + Predicate steps = CorePredicate.getInstance("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()); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java similarity index 93% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java index f038ec0ba..38e2a2387 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HeadBodyTransformationTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -39,9 +39,10 @@ import org.junit.Ignore; import org.junit.Test; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; /** * Tests rule transformations described in the following research paper, and their effects on performance: @@ -161,7 +162,7 @@ public void testProgramA_Transformed_N16() throws IOException { test(constructProgramA_TransformationA(16)); } - private void test(InputProgram program) { + private void test(ASPCore2Program program) { Solver solver = getInstance(program); Optional answerSet = solver.stream().findFirst(); assertFalse(answerSet.isPresent()); @@ -172,7 +173,7 @@ private void test(InputProgram program) { * * @param n */ - private InputProgram constructProgramB(int n) { + private ASPCore2Program constructProgramB(int n) { int numberOfRules = 3 * n + 1; List strRules = new ArrayList<>(numberOfRules); strRules.add("x :- not x."); @@ -186,7 +187,7 @@ private InputProgram constructProgramB(int n) { * * @param n */ - private InputProgram constructProgramB_TransformationB(int n) { + private ASPCore2Program constructProgramB_TransformationB(int n) { int numberOfRules = 6 * n + 2; List strRules = new ArrayList<>(numberOfRules); strRules.add("b_notX :- not x."); @@ -201,7 +202,7 @@ private InputProgram constructProgramB_TransformationB(int n) { * * @param n */ - private InputProgram constructProgramA(int n) { + private ASPCore2Program constructProgramA(int n) { int numberOfRules = 4 * n + 1; List strRules = new ArrayList<>(numberOfRules); strRules.add(createXCRule(n)); @@ -215,7 +216,7 @@ private InputProgram constructProgramA(int n) { * * @param n */ - private InputProgram constructProgramA_TransformationA(int n) { + private ASPCore2Program constructProgramA_TransformationA(int n) { int numberOfRules = 7 * n + 2; List strRules = new ArrayList<>(numberOfRules); strRules.addAll(createXCRules_TransformationA(n)); @@ -224,10 +225,10 @@ private InputProgram constructProgramA_TransformationA(int n) { return checkNumberOfRulesAndParse(strRules, numberOfRules); } - private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { + private ASPCore2Program checkNumberOfRulesAndParse(List strRules, int numberOfRules) { assertEquals(numberOfRules, strRules.size()); String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - InputProgram parsedProgram = new ProgramParser().parse(strProgram); + ASPCore2Program 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/solver/LearnedNoGoodDeletionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/LearnedNoGoodDeletionTest.java similarity index 92% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/LearnedNoGoodDeletionTest.java index ab6afb5eb..056ebf995 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/LearnedNoGoodDeletionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/LearnedNoGoodDeletionTest.java @@ -25,20 +25,26 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.*; -import org.junit.Before; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type; +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.List; import java.util.Map; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +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.common.NoGoodInterface.Type; public class LearnedNoGoodDeletionTest { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStoreTest.java similarity index 94% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStoreTest.java index 33a069469..0c315027a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NaiveNoGoodStoreTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NaiveNoGoodStoreTest.java @@ -1,16 +1,27 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; + +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +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.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; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; -import at.ac.tuwien.kr.alpha.common.*; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import static at.ac.tuwien.kr.alpha.common.NoGood.fact; -import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; -import static org.junit.Assert.*; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +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; /** * Copyright (c) 2017, the Alpha Team. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoamingTest.java similarity index 94% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoamingTest.java index 0f6d73acf..8895ad6f6 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/NoGoodStoreAlphaRoamingTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/NoGoodStoreAlphaRoamingTest.java @@ -1,16 +1,27 @@ -package at.ac.tuwien.kr.alpha.solver; +package at.ac.tuwien.kr.alpha.core.solver; + +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +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.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; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; -import at.ac.tuwien.kr.alpha.common.*; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import static at.ac.tuwien.kr.alpha.common.NoGood.fact; -import static at.ac.tuwien.kr.alpha.common.NoGood.headFirst; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.*; -import static org.junit.Assert.*; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +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; /** * Copyright (c) 2017, the Alpha Team. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java similarity index 89% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java index 2e3b97f8c..9fc272e4f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/OmigaBenchmarksTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java @@ -23,19 +23,19 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.nio.file.Paths; -import java.util.Optional; +import at.ac.tuwien.kr.alpha.api.AnswerSet; /** * Tests {@link AbstractSolver} using Omiga benchmark problems. @@ -91,8 +91,7 @@ public void testReach_4() throws IOException { } private void test(String folder, String aspFileName) throws IOException { - CharStream programInputStream = CharStreams.fromPath(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName)); - Optional answerSet = getInstance(programInputStream).stream().findFirst(); + Optional answerSet = getInstance(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))).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/solver/PartSubpartConfigurationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java similarity index 98% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java index f5a34eefd..909cedff0 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PartSubpartConfigurationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import org.junit.Ignore; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java similarity index 89% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java index 48c9857b9..55d54da81 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/PigeonHoleTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java @@ -23,12 +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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; -import org.junit.Ignore; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; import java.io.IOException; import java.util.ArrayList; @@ -36,8 +34,11 @@ import java.util.Set; import java.util.stream.Collectors; -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; /** * Tests {@link AbstractSolver} using some pigeon-hole test cases (see https://en.wikipedia.org/wiki/Pigeonhole_principle). @@ -45,43 +46,43 @@ public class PigeonHoleTest extends AbstractSolverTests { @Test(timeout = 5000) public void test2Pigeons2Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + assumeTrue(heuristic == Heuristic.VSIDS); testPigeonsHoles(2, 2); } @Test(timeout = 5000) public void test3Pigeons2Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + assumeTrue(heuristic == Heuristic.VSIDS); testPigeonsHoles(3, 2); } @Test(timeout = 5000) public void test2Pigeons3Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + assumeTrue(heuristic == Heuristic.VSIDS); testPigeonsHoles(2, 3); } @Test(timeout = 10000) public void test3Pigeons3Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + assumeTrue(heuristic == Heuristic.VSIDS); testPigeonsHoles(3, 3); } @Test(timeout = 10000) public void test4Pigeons3Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + assumeTrue(heuristic == Heuristic.VSIDS); testPigeonsHoles(4, 3); } @Test(timeout = 10000) public void test3Pigeons4Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + assumeTrue(heuristic == Heuristic.VSIDS); testPigeonsHoles(3, 4); } @Test(timeout = 10000) public void test4Pigeons4Holes() throws IOException { - assumeTrue(heuristic == BranchingHeuristicFactory.Heuristic.VSIDS); + assumeTrue(heuristic == Heuristic.VSIDS); testPigeonsHoles(4, 4); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java similarity index 85% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java index 4125dc5a7..06704ff42 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/RacksTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java @@ -23,18 +23,19 @@ * 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.solver; - -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.junit.Ignore; -import org.junit.Test; +package at.ac.tuwien.kr.alpha.core.solver; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Paths; import java.util.Optional; +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; + /** * Tests {@link AbstractSolver} using a racks configuration problem. * @@ -47,10 +48,7 @@ public void testRacks() throws IOException { } private void test() throws IOException { - CharStream programInputStream = CharStreams.fromPath( - Paths.get("benchmarks", "siemens", "racks", "racks.lp") - ); - Solver solver = getInstance(programInputStream); + Solver solver = getInstance(Files.newInputStream(Paths.get("benchmarks", "siemens", "racks", "racks.lp"))); Optional answerSet = solver.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/solver/SolverStatisticsTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java similarity index 95% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java index cbd25f394..885c8ee83 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverStatisticsTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java @@ -23,20 +23,21 @@ * 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.solver; +package at.ac.tuwien.kr.alpha.core.solver; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.DummyGrounder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +import java.util.Set; import org.junit.Before; import org.junit.Test; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; +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; public class SolverStatisticsTests extends AbstractSolverTests { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java similarity index 90% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java index 9cd3085c3..7427a5aa5 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/SolverTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java @@ -25,15 +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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import static java.util.Collections.singleton; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.antlr.v4.runtime.CharStreams; -import org.junit.Test; - import java.io.IOException; import java.nio.file.Paths; import java.util.Arrays; @@ -44,23 +41,29 @@ import java.util.Set; import java.util.SortedSet; +import org.junit.Test; + import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.AnswerSetBuilder; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.config.SystemConfig; +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.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; 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.parser.InlineDirectives; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +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.util.AnswerSetsParser; -import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory; import junit.framework.TestCase; public class SolverTests extends AbstractSolverTests { @@ -80,12 +83,12 @@ public int compareTo(Thingy o) { public void testObjectProgram() throws IOException { final Thingy thingy = new Thingy(); - final Atom fact = new BasicAtom(Predicate.getInstance("foo", 1), ConstantTerm.getInstance(thingy)); + final Atom fact = new BasicAtom(CorePredicate.getInstance("foo", 1), CoreConstantTerm.getInstance(thingy)); final InputProgram program = new InputProgram( Collections.emptyList(), Collections.singletonList(fact), - new InlineDirectives() + new InlineDirectivesImpl() ); assertEquals(singleton(new AnswerSetBuilder() @@ -686,8 +689,8 @@ public void instanceEnumerationAtom() throws IOException { // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.iterator().next(); - assertEquals(null, answerSet.getPredicateInstances(Predicate.getInstance("wrong_double_occurrence", 0))); - SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position", 2)); + assertEquals(null, answerSet.getPredicateInstances(CorePredicate.getInstance("wrong_double_occurrence", 0))); + SortedSet positions = answerSet.getPredicateInstances(CorePredicate.getInstance("unique_position", 2)); assertEnumerationPositions(positions, 3); } @@ -703,8 +706,8 @@ public void instanceEnumerationArbitraryTerms() throws IOException { // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.iterator().next(); - assertPropositionalPredicateFalse(answerSet, Predicate.getInstance("wrong_double_occurrence", 0)); - SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position", 2)); + assertPropositionalPredicateFalse(answerSet, CorePredicate.getInstance("wrong_double_occurrence", 0)); + SortedSet positions = answerSet.getPredicateInstances(CorePredicate.getInstance("unique_position", 2)); assertEnumerationPositions(positions, 3); } @@ -721,10 +724,10 @@ public void instanceEnumerationMultipleIdentifiers() throws IOException { // Check manually that there is one answer set, wrong_double_occurrence has not been derived, and enum yielded a unique position for each term. assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.iterator().next(); - assertPropositionalPredicateFalse(answerSet, Predicate.getInstance("wrong_double_occurrence", 0)); - SortedSet positions = answerSet.getPredicateInstances(Predicate.getInstance("unique_position1", 2)); + assertPropositionalPredicateFalse(answerSet, CorePredicate.getInstance("wrong_double_occurrence", 0)); + SortedSet positions = answerSet.getPredicateInstances(CorePredicate.getInstance("unique_position1", 2)); assertEnumerationPositions(positions, 4); - SortedSet positions2 = answerSet.getPredicateInstances(Predicate.getInstance("unique_position2", 2)); + SortedSet positions2 = answerSet.getPredicateInstances(CorePredicate.getInstance("unique_position2", 2)); assertEnumerationPositions(positions2, 4); } @@ -769,17 +772,17 @@ public void smallCardinalityAggregate() throws IOException { @Test public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { - final ProgramParser parser = new ProgramParser(); + final ProgramParser parser = new ProgramParserImpl(); InputProgram.Builder bld = InputProgram.builder(); - bld.accumulate(parser.parse(CharStreams.fromPath(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp")))); - bld.accumulate(parser.parse(CharStreams.fromPath(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp")))); + bld.accumulate(parser.parse(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"))); + bld.accumulate(parser.parse(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"))); InputProgram parsedProgram = bld.build(); SystemConfig config = new SystemConfig(); config.setSolverName("default"); config.setNogoodStoreName("alpharoaming"); config.setSeed(0); - config.setBranchingHeuristic(BranchingHeuristicFactory.Heuristic.valueOf("VSIDS")); + config.setBranchingHeuristic(Heuristic.valueOf("VSIDS")); config.setDebugInternalChecks(true); config.setDisableJustificationSearch(false); config.setEvaluateStratifiedPart(false); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TestableChoiceManager.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TestableChoiceManager.java index d8923a166..50eaa2443 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TestableChoiceManager.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TestableChoiceManager.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import org.apache.commons.lang3.tuple.Pair; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java similarity index 99% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java index 4dffa1968..b5832a2fe 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringRandomGraphTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import java.io.IOException; import java.util.ArrayList; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java similarity index 99% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java index 93eec197d..261b91c9c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringTestWithRandom.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import org.junit.Ignore; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java similarity index 99% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java index a2882cd06..1912da4d4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/ThreeColouringWheelTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import org.junit.Ignore; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.java index 9cbda2250..6158cf120 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/TrailAssignmentTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/TrailAssignmentTest.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.solver; +package at.ac.tuwien.kr.alpha.core.solver; import at.ac.tuwien.kr.alpha.common.Assignment; import at.ac.tuwien.kr.alpha.common.AtomStore; @@ -39,9 +39,9 @@ import java.util.Collections; import java.util.HashSet; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.FALSE; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.MBT; -import static at.ac.tuwien.kr.alpha.solver.ThriceTruth.TRUE; +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; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java index bb57ea6c8..d31fbc701 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/heuristics/GrounderHeuristicConfigurationTest.java @@ -25,14 +25,16 @@ */ package at.ac.tuwien.kr.alpha.grounder.heuristics; -import org.junit.Test; - -import static at.ac.tuwien.kr.alpha.core.grounder.heuristics.GrounderHeuristicsConfiguration.PERMISSIVE_STRING; -import static at.ac.tuwien.kr.alpha.core.grounder.heuristics.GrounderHeuristicsConfiguration.STRICT_STRING; +import static at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration.PERMISSIVE_STRING; +import static at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration.STRICT_STRING; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; + /** * Tests {@link GrounderHeuristicsConfiguration} */ diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java index 2a7580ce2..8f2884da1 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java @@ -8,51 +8,57 @@ import org.junit.Assert; import org.junit.Test; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.DefaultLazyGroundingInstantiationStrategy; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationStrategy; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy; +import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; public class LiteralInstantiationStrategyTest { @Test public void workingMemoryBasedInstantiationAcceptLiteral() { - Predicate p = Predicate.getInstance("p", 1); + Predicate p = CorePredicate.getInstance("p", 1); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); + workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), true); LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); Literal positiveAcceptedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); + new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), true); Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(positiveAcceptedLiteral)); Literal negativeAcceptedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("b")), false); + new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("b")), false); Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(negativeAcceptedLiteral)); } @Test public void workingMemoryBasedInstantiationRejectLiteral() { - Predicate p = Predicate.getInstance("p", 1); + Predicate p = CorePredicate.getInstance("p", 1); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), true); + workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), true); LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); Literal positiveRejectedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("b")), true); + new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("b")), true); Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(positiveRejectedLiteral)); Literal negativeRejectedLiteral = new BasicLiteral( - new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")), false); + new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), false); Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(negativeRejectedLiteral)); } @@ -68,8 +74,8 @@ public void workingMemoryBasedInstantiationRejectLiteral() { */ @Test public void defaultLazyGroundingNoAssignmentGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + Predicate p = CorePredicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); WorkingMemory workingMemory = new WorkingMemory(); LinkedHashSet staleSet = new LinkedHashSet<>(); DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), @@ -96,11 +102,11 @@ public void defaultLazyGroundingNoAssignmentGroundLiteral() { */ @Test public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + Predicate q = CorePredicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); LinkedHashSet staleSet = new LinkedHashSet<>(); DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), Collections.emptyMap()); @@ -108,14 +114,14 @@ public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { strategy.setCurrentAssignment(null); List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); + new SubstitutionImpl()); Assert.assertEquals(1, result.size()); ImmutablePair substitutionInfo = result.get(0); Substitution substitution = substitutionInfo.left; AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); - Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); + Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); + Assert.assertEquals(CoreConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTermImpl.getInstance("X"))); Assert.assertTrue(staleSet.isEmpty()); } @@ -131,8 +137,8 @@ public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { */ @Test public void defaultLazyGroundingCheckUnassignedGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + Predicate p = CorePredicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -161,8 +167,8 @@ public void defaultLazyGroundingCheckUnassignedGroundLiteral() { */ @Test public void defaultLazyGroundingCheckFalseGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + Predicate p = CorePredicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -194,8 +200,8 @@ public void defaultLazyGroundingCheckFalseGroundLiteral() { */ @Test public void defaultLazyGroundingCheckTrueGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + Predicate p = CorePredicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -226,8 +232,8 @@ public void defaultLazyGroundingCheckTrueGroundLiteral() { */ @Test public void defaultLazyGroundingCheckMustBeTrueGroundLiteral() { - Predicate p = Predicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, ConstantTerm.getSymbolicInstance("a")); + Predicate p = CorePredicate.getInstance("p", 1); + BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -259,11 +265,11 @@ public void defaultLazyGroundingCheckMustBeTrueGroundLiteral() { */ @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + Predicate q = CorePredicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); LinkedHashSet staleSet = new LinkedHashSet<>(); @@ -273,17 +279,17 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance strategy.setCurrentAssignment(assignment); List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); + new SubstitutionImpl()); Assert.assertEquals(1, result.size()); ImmutablePair substitutionInfo = result.get(0); Substitution substitution = substitutionInfo.left; AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.UNASSIGNED, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); - Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); + Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); + Assert.assertEquals(CoreConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTermImpl.getInstance("X"))); Assert.assertEquals(1, staleSet.size()); - Assert.assertTrue(staleSet.contains(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")))); + Assert.assertTrue(staleSet.contains(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")))); } /** @@ -298,14 +304,14 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance */ @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + Predicate q = CorePredicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); - BasicAtom groundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")); + BasicAtom groundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")); atomStore.putIfAbsent(groundAtom); assignment.growForMaxAtomId(); assignment.assign(atomStore.get(groundAtom), ThriceTruth.TRUE); @@ -316,14 +322,14 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { strategy.setCurrentAssignment(assignment); List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); + new SubstitutionImpl()); Assert.assertEquals(1, result.size()); ImmutablePair substitutionInfo = result.get(0); Substitution substitution = substitutionInfo.left; AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTerm.getInstance("X"))); - Assert.assertEquals(ConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTerm.getInstance("X"))); + Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); + Assert.assertEquals(CoreConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTermImpl.getInstance("X"))); Assert.assertTrue(staleSet.isEmpty()); } @@ -339,14 +345,14 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { */ @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithFalseInstance() { - Predicate q = Predicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), VariableTerm.getInstance("X")); + Predicate q = CorePredicate.getInstance("q", 2); + BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); - BasicAtom groundAtom = new BasicAtom(q, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getSymbolicInstance("b")); + BasicAtom groundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")); atomStore.putIfAbsent(groundAtom); assignment.growForMaxAtomId(); assignment.assign(atomStore.get(groundAtom), ThriceTruth.FALSE); @@ -357,7 +363,7 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithFalseInstance() { strategy.setCurrentAssignment(assignment); List> result = strategy.getAcceptedSubstitutions(new BasicLiteral(nonGroundAtom, true), - new Substitution()); + new SubstitutionImpl()); Assert.assertTrue(result.isEmpty()); Assert.assertEquals(1, staleSet.size()); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java index 1e160c184..430b57aa3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java @@ -1,34 +1,41 @@ package at.ac.tuwien.kr.alpha.grounder.instantiation; -import at.ac.tuwien.kr.alpha.common.ComparisonOperator; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonAtom; -import at.ac.tuwien.kr.alpha.common.atoms.ComparisonLiteral; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.common.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; -import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; -import at.ac.tuwien.kr.alpha.core.grounder.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.core.grounder.atoms.EnumerationLiteral; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.lang3.tuple.ImmutablePair; import org.junit.Assert; import org.junit.Test; -import java.util.ArrayList; -import java.util.List; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; +import at.ac.tuwien.kr.alpha.core.atoms.ComparisonLiteral; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; +import at.ac.tuwien.kr.alpha.core.atoms.EnumerationLiteral; +import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; +import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationResult; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiator; +import at.ac.tuwien.kr.alpha.core.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy; public class LiteralInstantiatorTest { @Test public void instantiateSatisfiedFixedInterpretationLiteral() { - ComparisonAtom equalsThree = new ComparisonAtom(ConstantTerm.getInstance(3), VariableTerm.getInstance("THREE"), ComparisonOperatorImpl.EQ); + ComparisonAtom equalsThree = new ComparisonAtom(CoreConstantTerm.getInstance(3), VariableTermImpl.getInstance("THREE"), ComparisonOperatorImpl.EQ); Literal lit = new ComparisonLiteral(equalsThree, true); - Substitution substitution = new Substitution(); + Substitution substitution = new SubstitutionImpl(); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); @@ -36,17 +43,17 @@ public void instantiateSatisfiedFixedInterpretationLiteral() { Assert.assertEquals(1, resultSubstitutions.size()); Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitutions.get(0).right); Substitution extendedSubstitution = resultSubstitutions.get(0).left; - Assert.assertTrue(extendedSubstitution.isVariableSet(VariableTerm.getInstance("THREE"))); - Assert.assertEquals(ConstantTerm.getInstance(3), extendedSubstitution.eval(VariableTerm.getInstance("THREE"))); + Assert.assertTrue(extendedSubstitution.isVariableSet(VariableTermImpl.getInstance("THREE"))); + Assert.assertEquals(CoreConstantTerm.getInstance(3), extendedSubstitution.eval(VariableTermImpl.getInstance("THREE"))); } @Test public void instantiateUnsatisfiedFixedInterpretationLiteral() { - ComparisonAtom fiveEqualsThree = new ComparisonAtom(VariableTerm.getInstance("FIVE"), VariableTerm.getInstance("THREE"), ComparisonOperatorImpl.EQ); + ComparisonAtom fiveEqualsThree = new ComparisonAtom(VariableTermImpl.getInstance("FIVE"), VariableTermImpl.getInstance("THREE"), ComparisonOperatorImpl.EQ); Literal lit = new ComparisonLiteral(fiveEqualsThree, true); - Substitution substitution = new Substitution(); - substitution.put(VariableTerm.getInstance("FIVE"), ConstantTerm.getInstance(5)); - substitution.put(VariableTerm.getInstance("THREE"), ConstantTerm.getInstance(3)); + Substitution substitution = new SubstitutionImpl(); + substitution.put(VariableTermImpl.getInstance("FIVE"), CoreConstantTerm.getInstance(5)); + substitution.put(VariableTermImpl.getInstance("THREE"), CoreConstantTerm.getInstance(3)); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.STOP_BINDING, result.getType()); @@ -54,18 +61,18 @@ public void instantiateUnsatisfiedFixedInterpretationLiteral() { @Test public void instantiateEnumLiteral() { - VariableTerm enumTerm = VariableTerm.getInstance("E"); - VariableTerm idTerm = VariableTerm.getInstance("X"); - VariableTerm indexTerm = VariableTerm.getInstance("I"); + VariableTerm enumTerm = VariableTermImpl.getInstance("E"); + VariableTerm idTerm = VariableTermImpl.getInstance("X"); + VariableTerm indexTerm = VariableTermImpl.getInstance("I"); List termList = new ArrayList<>(); termList.add(enumTerm); termList.add(idTerm); termList.add(indexTerm); EnumerationAtom enumAtom = new EnumerationAtom(termList); EnumerationLiteral lit = new EnumerationLiteral(enumAtom); - Substitution substitution = new Substitution(); - substitution.put(enumTerm, ConstantTerm.getSymbolicInstance("enum1")); - substitution.put(idTerm, ConstantTerm.getSymbolicInstance("someElement")); + Substitution substitution = new SubstitutionImpl(); + substitution.put(enumTerm, CoreConstantTerm.getSymbolicInstance("enum1")); + substitution.put(idTerm, CoreConstantTerm.getSymbolicInstance("someElement")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); @@ -77,16 +84,16 @@ public void instantiateEnumLiteral() { @Test public void workingMemoryBasedVerifyPositiveGroundLiteralSatisfied() { - Predicate p = Predicate.getInstance("p", 2); + Predicate p = CorePredicate.getInstance("p", 2); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("y")), true); - VariableTerm x = VariableTerm.getInstance("X"); - VariableTerm y = VariableTerm.getInstance("Y"); + workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("x"), CoreConstantTerm.getSymbolicInstance("y")), true); + VariableTerm x = VariableTermImpl.getInstance("X"); + VariableTerm y = VariableTermImpl.getInstance("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); - Substitution substitution = new Substitution(); - substitution.put(x, ConstantTerm.getSymbolicInstance("x")); - substitution.put(y, ConstantTerm.getSymbolicInstance("y")); + Substitution substitution = new SubstitutionImpl(); + substitution.put(x, CoreConstantTerm.getSymbolicInstance("x")); + substitution.put(y, CoreConstantTerm.getSymbolicInstance("y")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); @@ -101,15 +108,15 @@ public void workingMemoryBasedVerifyPositiveGroundLiteralSatisfied() { @Test public void workingMemoryBasedVerifyPositiveGroundLiteralUnsatisfied() { - Predicate p = Predicate.getInstance("p", 2); + Predicate p = CorePredicate.getInstance("p", 2); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - VariableTerm x = VariableTerm.getInstance("X"); - VariableTerm y = VariableTerm.getInstance("Y"); + VariableTerm x = VariableTermImpl.getInstance("X"); + VariableTerm y = VariableTermImpl.getInstance("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); - Substitution substitution = new Substitution(); - substitution.put(x, ConstantTerm.getSymbolicInstance("x")); - substitution.put(y, ConstantTerm.getSymbolicInstance("y")); + Substitution substitution = new SubstitutionImpl(); + substitution.put(x, CoreConstantTerm.getSymbolicInstance("x")); + substitution.put(y, CoreConstantTerm.getSymbolicInstance("y")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); // With the given input substitution, lit is ground, but not satisfied - @@ -120,16 +127,16 @@ public void workingMemoryBasedVerifyPositiveGroundLiteralUnsatisfied() { @Test public void workingMemoryBasedInstantiatePositiveBasicLiteral() { - Predicate p = Predicate.getInstance("p", 2); + Predicate p = CorePredicate.getInstance("p", 2); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("y")), true); - workingMemory.addInstance(new BasicAtom(p, ConstantTerm.getSymbolicInstance("x"), ConstantTerm.getSymbolicInstance("z")), true); - VariableTerm x = VariableTerm.getInstance("X"); - VariableTerm y = VariableTerm.getInstance("Y"); + workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("x"), CoreConstantTerm.getSymbolicInstance("y")), true); + workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("x"), CoreConstantTerm.getSymbolicInstance("z")), true); + VariableTerm x = VariableTermImpl.getInstance("X"); + VariableTerm y = VariableTermImpl.getInstance("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); - Substitution substitution = new Substitution(); - substitution.put(x, ConstantTerm.getSymbolicInstance("x")); + Substitution substitution = new SubstitutionImpl(); + substitution.put(x, CoreConstantTerm.getSymbolicInstance("x")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); @@ -140,9 +147,9 @@ public void workingMemoryBasedInstantiatePositiveBasicLiteral() { for (ImmutablePair resultSubstitution : substitutions) { Assert.assertTrue(resultSubstitution.left.isVariableSet(y)); Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitution.right); - if (resultSubstitution.left.eval(y).equals(ConstantTerm.getSymbolicInstance("y"))) { + if (resultSubstitution.left.eval(y).equals(CoreConstantTerm.getSymbolicInstance("y"))) { ySubstituted = true; - } else if (resultSubstitution.left.eval(y).equals(ConstantTerm.getSymbolicInstance("z"))) { + } else if (resultSubstitution.left.eval(y).equals(CoreConstantTerm.getSymbolicInstance("z"))) { zSubstituted = true; } else { Assert.fail("Invalid substitution for variable Y"); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java index 4748e85ba..51ee7acf1 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java @@ -27,59 +27,63 @@ */ package at.ac.tuwien.kr.alpha.grounder.structure; -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.solver.ThriceTruth; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import org.junit.Test; +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertNotEquals; import java.util.Arrays; import java.util.Collections; import java.util.Set; +import java.util.function.Function; -import static junit.framework.TestCase.assertFalse; -import static org.junit.Assert.assertNotEquals; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +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.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 ProgramParser(); + private final ProgramParser parser = new ProgramParserImpl(); + private final NormalizeProgramTransformation normalize = new NormalizeProgramTransformation(false); + private final Function parseAndPreprocess = (str) -> { + return InternalProgram.fromNormalProgram(normalize.apply(parser.parse(str))); + }; @Test public void justifySimpleRules() { - Alpha system = new Alpha(); String program = "p(X) :- q(X)." + "q(X) :- p(X)." + "q(5) :- r." + "r :- not nr." + "nr :- not r." + ":- not p(5)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + 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(new BasicAtom(Predicate.getInstance("r", 0))); - int nrId = atomStore.get(new BasicAtom(Predicate.getInstance("nr", 0))); + int rId = atomStore.get(new BasicAtom(CorePredicate.getInstance("r", 0))); + int nrId = atomStore.get(new BasicAtom(CorePredicate.getInstance("nr", 0))); assignment.growForMaxAtomId(); assignment.assign(rId, ThriceTruth.FALSE); assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = new BasicAtom(Predicate.getInstance("p", 1), Collections.singletonList(ConstantTerm.getInstance(5))); + BasicAtom p5 = new BasicAtom(CorePredicate.getInstance("p", 1), Collections.singletonList(CoreConstantTerm.getInstance(5))); assignment.assign(atomStore.get(p5), ThriceTruth.MBT); Set reasons = grounder.justifyAtom(atomStore.get(p5), assignment); assertFalse(reasons.isEmpty()); @@ -87,7 +91,6 @@ public void justifySimpleRules() { @Test public void justifyLargerRules() { - Alpha system = new Alpha(); String program = "p(X) :- q(X,Y), r(Y), not s(X,Y)." + "{ q(1,X)} :- dom(X)." + "dom(1..3)." + @@ -95,9 +98,7 @@ public void justifyLargerRules() { "{r(2)}." + "{s(1,2)}." + ":- not p(1)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + CompiledProgram internalProgram = parseAndPreprocess.apply(program); AtomStore atomStore = new AtomStoreImpl(); NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); grounder.getNoGoods(null); @@ -128,16 +129,13 @@ public void justifyLargerRules() { @Test public void justifyMultipleReasons() { - Alpha system = new Alpha(); 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)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + CompiledProgram internalProgram = parseAndPreprocess.apply(program); AtomStore atomStore = new AtomStoreImpl(); NaiveGrounder grounder = new NaiveGrounder(internalProgram, atomStore, true); grounder.getNoGoods(null); @@ -160,12 +158,12 @@ public void justifyMultipleReasons() { assignment.assign(qdId, ThriceTruth.FALSE); assignment.assign(qeId, ThriceTruth.FALSE); - Predicate nq = Predicate.getInstance("_nq", 2, true); - Atom nqa = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("a"))); - Atom nqb = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("b"))); - Atom nqc = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("c"))); - Atom nqd = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("d"))); - Atom nqe = new BasicAtom(nq, Arrays.asList(ConstantTerm.getInstance("1"), ConstantTerm.getSymbolicInstance("e"))); + Predicate nq = CorePredicate.getInstance("_nq", 2, true); + Atom nqa = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("a"))); + Atom nqb = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("b"))); + Atom nqc = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("c"))); + Atom nqd = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("d"))); + Atom nqe = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("e"))); int nqaId = atomStore.get(nqa); int nqbId = atomStore.get(nqb); int nqcId = atomStore.get(nqc); @@ -186,7 +184,6 @@ public void justifyMultipleReasons() { @Test public void justifyNegatedFactsRemovedFromReasons() { - Alpha system = new Alpha(); String program = "forbidden(2,9). forbidden(1,9)." + "p(X) :- q(X)." + "q(X) :- p(X)." + @@ -194,25 +191,23 @@ public void justifyNegatedFactsRemovedFromReasons() { "r :- not nr, not forbidden(2,9), not forbidden(1,9)." + "nr :- not r." + ":- not p(5)."; - InputProgram parsedProgram = parser.parse(program); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + 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(new BasicAtom(Predicate.getInstance("r", 0))); - int nrId = atomStore.get(new BasicAtom(Predicate.getInstance("nr", 0))); + int rId = atomStore.get(new BasicAtom(CorePredicate.getInstance("r", 0))); + int nrId = atomStore.get(new BasicAtom(CorePredicate.getInstance("nr", 0))); assignment.growForMaxAtomId(); assignment.assign(rId, ThriceTruth.FALSE); assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = new BasicAtom(Predicate.getInstance("p", 1), Collections.singletonList(ConstantTerm.getInstance(5))); + BasicAtom p5 = new BasicAtom(CorePredicate.getInstance("p", 1), Collections.singletonList(CoreConstantTerm.getInstance(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(), Predicate.getInstance("forbidden", 2)); + assertNotEquals(literal.getPredicate(), CorePredicate.getInstance("forbidden", 2)); } } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java index b196005a4..e688cce72 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java @@ -1,5 +1,10 @@ package at.ac.tuwien.kr.alpha.grounder.transformation; +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.Assert; import org.junit.Test; @@ -9,21 +14,25 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; +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.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +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.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; +import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; import at.ac.tuwien.kr.alpha.test.util.TestUtils; @RunWith(Parameterized.class) @@ -51,32 +60,32 @@ public class StratifiedEvaluationRegressionTest { 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<>( + private static final ImmutablePair, Consumer>> BASIC_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramBasic, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasic); - private static final ImmutablePair, Consumer>> BASIC_MULTI_INSTANCE_VERIFIERS = new ImmutablePair<>( + 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<>( + private static final ImmutablePair, Consumer>> BASIC_NEGATION_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramBasicNegation, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicNegation); - private static final ImmutablePair, Consumer>> PART_STRATIFIED_VERIFIERS = new ImmutablePair<>( + private static final ImmutablePair, Consumer>> PART_STRATIFIED_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramPartStratified, StratifiedEvaluationRegressionTest::verifyAnswerSetsPartStratified); - private static final ImmutablePair, Consumer>> POSITIVE_RECURSIVE_VERIFIERS = new ImmutablePair<>( + private static final ImmutablePair, Consumer>> POSITIVE_RECURSIVE_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramPositiveRecursive, StratifiedEvaluationRegressionTest::verifyAnswerSetsPositiveRecursive); - private static final ImmutablePair, Consumer>> EMPTY_PROG_VERIFIERS = new ImmutablePair<>( + private static final ImmutablePair, Consumer>> EMPTY_PROG_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramEmptyProg, StratifiedEvaluationRegressionTest::verifyAnswerSetsEmptyProg); - private static final ImmutablePair, Consumer>> FACTS_ONLY_VERIFIERS = new ImmutablePair<>( + 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<>( + 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<>( + private static final ImmutablePair, Consumer>> STRATIFIED_W_FACTS_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramStratWithFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratWithFacts); - private static final ImmutablePair, Consumer>> EQUALITY_VERIFIERS = new ImmutablePair<>( + private static final ImmutablePair, Consumer>> EQUALITY_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramEquality, StratifiedEvaluationRegressionTest::verifyAnswerSetsEquality); - private static final ImmutablePair, Consumer>> EQUALITY_WITH_VAR_VERIFIERS = new ImmutablePair<>( + private static final ImmutablePair, Consumer>> EQUALITY_WITH_VAR_VERIFIERS = new ImmutablePair<>( StratifiedEvaluationRegressionTest::verifyProgramEqualityWithVar, StratifiedEvaluationRegressionTest::verifyAnswerSetsEqualityWithVar); @Parameters(name = "Run {index}: aspString={0}, programVerifier={1}, answerSetsVerifier={2}") public static Iterable params() { - List, Consumer>>>> testCases = new ArrayList<>(); + 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)); @@ -95,10 +104,10 @@ public static Iterable params() { } private String aspString; - private Consumer programVerifier; + private Consumer programVerifier; private Consumer> answerSetsVerifier; - public StratifiedEvaluationRegressionTest(String aspString, Consumer programVerifier, Consumer> answerSetsVerifier) { + public StratifiedEvaluationRegressionTest(String aspString, Consumer programVerifier, Consumer> answerSetsVerifier) { this.aspString = aspString; this.programVerifier = programVerifier; this.answerSetsVerifier = answerSetsVerifier; @@ -107,17 +116,22 @@ public StratifiedEvaluationRegressionTest(String aspString, Consumer answerSets = system.solve(evaluated).collect(Collectors.toSet()); + // 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(); this.answerSetsVerifier.accept(answerSets); } - private static void verifyProgramBasic(InternalProgram evaluated) { + private static void verifyProgramBasic(CompiledProgram evaluated) { TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("a"), TestUtils.basicAtomWithSymbolicTerms("b")); Assert.assertEquals(2, evaluated.getFacts().size()); Assert.assertTrue(evaluated.getRules().size() == 0); @@ -127,7 +141,7 @@ private static void verifyAnswerSetsBasic(Set answerSets) { TestUtils.assertAnswerSetsEqual("a, b", answerSets); } - private static void verifyProgramBasicMultiInstance(InternalProgram evaluated) { + private static void verifyProgramBasicMultiInstance(CompiledProgram evaluated) { TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("q", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "b")); Assert.assertTrue(evaluated.getRules().size() == 0); } @@ -136,7 +150,7 @@ private static void verifyAnswerSetsBasicMultiInstance(Set answerSets TestUtils.assertAnswerSetsEqual("p(a), p(b), q(a), q(b)", answerSets); } - private static void verifyProgramBasicNegation(InternalProgram evaluated) { + private static void verifyProgramBasicNegation(CompiledProgram evaluated) { TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("s", "a", "b"), TestUtils.basicAtomWithSymbolicTerms("s", "a", "d")); Assert.assertEquals(7, evaluated.getFacts().size()); @@ -147,7 +161,7 @@ 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(InternalProgram evaluated) { + 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"), @@ -162,15 +176,15 @@ private static void verifyAnswerSetsPartStratified(Set answerSets) { "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(InternalProgram evaluated) { - Predicate num = Predicate.getInstance("num", 1); - TestUtils.assertFactsContainedInProgram(evaluated, new BasicAtom(Predicate.getInstance("max_num", 1), ConstantTerm.getInstance(10)), - new BasicAtom(num, ConstantTerm.getInstance(0)), - new BasicAtom(num, ConstantTerm.getInstance(1)), new BasicAtom(num, ConstantTerm.getInstance(2)), - new BasicAtom(num, ConstantTerm.getInstance(3)), new BasicAtom(num, ConstantTerm.getInstance(4)), - new BasicAtom(num, ConstantTerm.getInstance(5)), new BasicAtom(num, ConstantTerm.getInstance(6)), - new BasicAtom(num, ConstantTerm.getInstance(7)), new BasicAtom(num, ConstantTerm.getInstance(8)), - new BasicAtom(num, ConstantTerm.getInstance(9)), new BasicAtom(num, ConstantTerm.getInstance(10))); + private static void verifyProgramPositiveRecursive(CompiledProgram evaluated) { + Predicate num = CorePredicate.getInstance("num", 1); + TestUtils.assertFactsContainedInProgram(evaluated, new BasicAtom(CorePredicate.getInstance("max_num", 1), CoreConstantTerm.getInstance(10)), + new BasicAtom(num, CoreConstantTerm.getInstance(0)), + new BasicAtom(num, CoreConstantTerm.getInstance(1)), new BasicAtom(num, CoreConstantTerm.getInstance(2)), + new BasicAtom(num, CoreConstantTerm.getInstance(3)), new BasicAtom(num, CoreConstantTerm.getInstance(4)), + new BasicAtom(num, CoreConstantTerm.getInstance(5)), new BasicAtom(num, CoreConstantTerm.getInstance(6)), + new BasicAtom(num, CoreConstantTerm.getInstance(7)), new BasicAtom(num, CoreConstantTerm.getInstance(8)), + new BasicAtom(num, CoreConstantTerm.getInstance(9)), new BasicAtom(num, CoreConstantTerm.getInstance(10))); LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); Assert.assertEquals(0, evaluated.getRules().size()); } @@ -179,7 +193,7 @@ 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(InternalProgram evaluated) { + private static void verifyProgramEmptyProg(CompiledProgram evaluated) { Assert.assertTrue(evaluated.getRules().isEmpty()); Assert.assertTrue(evaluated.getRulesById().isEmpty()); Assert.assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); @@ -192,7 +206,7 @@ private static void verifyAnswerSetsEmptyProg(Set answerSets) { Assert.assertTrue(answerSets.iterator().next().isEmpty()); } - private static void verifyProgramFactsOnly(InternalProgram evaluated) { + private static void verifyProgramFactsOnly(CompiledProgram evaluated) { Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("a"))); Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("b"))); Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("c"))); @@ -206,7 +220,7 @@ 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(InternalProgram evaluated) { + private static void verifyProgramStratNoFacts(CompiledProgram evaluated) { Assert.assertTrue(evaluated.getFacts().isEmpty()); } @@ -215,7 +229,7 @@ private static void verifyAnswerSetsStratNoFacts(Set answerSets) { Assert.assertTrue(answerSets.iterator().next().isEmpty()); } - private static void verifyProgramStratWithFacts(InternalProgram evaluated) { + private static void verifyProgramStratWithFacts(CompiledProgram evaluated) { // rules should all be taken care of at this point Assert.assertTrue(evaluated.getRules().isEmpty()); Assert.assertTrue(evaluated.getRulesById().isEmpty()); @@ -237,7 +251,7 @@ 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(InternalProgram evaluated) { + private static void verifyProgramEquality(CompiledProgram evaluated) { Assert.assertEquals(0, evaluated.getRules().size()); Assert.assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("equal"))); } @@ -246,11 +260,11 @@ private static void verifyAnswerSetsEquality(Set answerSets) { TestUtils.assertAnswerSetsEqual("equal", answerSets); } - private static void verifyProgramEqualityWithVar(InternalProgram evaluated) { + private static void verifyProgramEqualityWithVar(CompiledProgram evaluated) { Assert.assertEquals(0, evaluated.getRules().size()); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("a", 1), ConstantTerm.getInstance(1)))); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("c", 1), ConstantTerm.getInstance(2)))); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(Predicate.getInstance("d", 1), ConstantTerm.getInstance(3)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("a", 1), CoreConstantTerm.getInstance(1)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("c", 1), CoreConstantTerm.getInstance(2)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("d", 1), CoreConstantTerm.getInstance(3)))); } private static void verifyAnswerSetsEqualityWithVar(Set answerSets) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java index 9bb9842be..ba41fd408 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java @@ -30,45 +30,71 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.antlr.v4.runtime.CharStreams; -import org.junit.Assert; -import org.junit.Test; - 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.antlr.v4.runtime.CharStreams; +import org.junit.Assert; +import org.junit.Test; + import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.api.externals.Externals; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -import at.ac.tuwien.kr.alpha.common.program.Programs; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.config.InputConfig; -import at.ac.tuwien.kr.alpha.core.grounder.Instance; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +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.InputConfig; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.grounder.Instance; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +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.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +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; +import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.core.programs.Programs; +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.SolverFactory; import at.ac.tuwien.kr.alpha.test.util.TestUtils; public class StratifiedEvaluationTest { + private final ProgramParser parser = new ProgramParserImpl(); + private final NormalizeProgramTransformation normalizer = new NormalizeProgramTransformation(false); + 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(); + }; + @Test public void testDuplicateFacts() { String aspStr = "p(a). p(b). q(b). q(X) :- p(X)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(aspStr); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); Instance qOfB = new Instance(TestUtils.basicAtomWithSymbolicTerms("q", "b").getTerms()); - Set facts = evaluated.getFactsByPredicate().get(at.ac.tuwien.kr.alpha.common.Predicate.getInstance("q", 1)); + Set facts = evaluated.getFactsByPredicate().get(CorePredicate.getInstance("q", 1)); int numQOfB = 0; for (Instance at : facts) { if (at.equals(qOfB)) { @@ -81,11 +107,7 @@ public void testDuplicateFacts() { @Test public void testEqualityWithConstantTerms() { String aspStr = "equal :- 1 = 1."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(aspStr); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); Atom equal = TestUtils.basicAtomWithSymbolicTerms("equal"); assertTrue(evaluated.getFacts().contains(equal)); } @@ -93,48 +115,32 @@ public void testEqualityWithConstantTerms() { @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)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(aspStr); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + 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); } @Test public void testNonGroundableRule() { String asp = "p(a). q(a, b). s(X, Y) :- p(X), q(X, Y), r(Y)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + CompiledProgram evaluated = parseAndEvaluate.apply(asp); + Set answerSets = solveCompiledProg.apply(evaluated); TestUtils.assertAnswerSetsEqual("p(a), q(a,b)", answerSets); } @Test public void testCountAggregate() { String asp = "a. b :- 1 <= #count { 1 : a }."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + CompiledProgram evaluated = parseAndEvaluate.apply(asp); + Set answerSets = solveCompiledProg.apply(evaluated); TestUtils.assertAnswerSetsEqual("a, b", answerSets); } @Test public void testIntervalFact() { String asp = "a(1..3)."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + CompiledProgram evaluated = parseAndEvaluate.apply(asp); + Set answerSets = solveCompiledProg.apply(evaluated); TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); } @@ -144,26 +150,17 @@ 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."; - Alpha system = new Alpha(); - // system.getConfig().setUseNormalizationGrid(true); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + CompiledProgram evaluated = parseAndEvaluate.apply(asp); assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("allThings"))); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + Set answerSets = solveCompiledProg.apply(evaluated); TestUtils.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."; - Alpha system = new Alpha(); - InputProgram prg = system.readProgramString(asp); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = system.solve(evaluated).collect(Collectors.toSet()); + CompiledProgram evaluated = parseAndEvaluate.apply(asp); + Set answerSets = solveCompiledProg.apply(evaluated); TestUtils.assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); } @@ -175,14 +172,12 @@ public static boolean sayTrue(Object o) { @Test public void testNegatedExternalLiteral() throws Exception { String asp = "claimedTruth(bla). truth(X) :- claimedTruth(X), &sayTrue[X]. lie(X) :- claimedTruth(X), not &sayTrue[X]."; - Alpha alpha = new Alpha(); - InputConfig inputCfg = InputConfig.forString(asp); - inputCfg.addPredicateMethod("sayTrue", Externals.processPredicateMethod(this.getClass().getMethod("sayTrue", Object.class))); - InputProgram input = alpha.readProgram(inputCfg); - NormalProgram normal = alpha.normalizeProgram(input); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = alpha.solve(evaluated).collect(Collectors.toSet()); + Map externals = new HashMap<>(); + externals.put("sayTrue", Externals.processPredicateMethod(this.getClass().getMethod("sayTrue", Object.class))); + ProgramParser parserWithExternals = new ProgramParserImpl(externals); + AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parserWithExternals.parse(asp))); + CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); + Set answerSets = solveCompiledProg.apply(evaluated); TestUtils.assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); } @@ -192,11 +187,8 @@ public void testNegatedExternalLiteral() throws Exception { */ @Test public void testPartnerUnitsProblemTopologicalOrder() throws IOException { - Alpha system = new Alpha(); - InputProgram prg = new ProgramParser().parse(CharStreams.fromStream(this.getClass().getResourceAsStream("/partial-eval/pup_topological_order.asp"))); - NormalProgram normal = system.normalizeProgram(prg); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normal); - InternalProgram evaluated = new StratifiedEvaluation().apply(analyzed); + ASPCore2Program prg = parser.parse(StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp")); + CompiledProgram evaluated = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prg))); assertTrue("Not all rules eliminated by stratified evaluation", evaluated.getRules().isEmpty()); assertEquals(57, evaluated.getFacts().size()); } @@ -216,16 +208,18 @@ 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( + ASPCore2Program prog = Programs.fromInputStream( StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), new HashMap<>()); - Alpha systemStratified = new Alpha(); - systemStratified.getConfig().setEvaluateStratifiedPart(true); - Set asStrat = systemStratified.solve(prog).collect(Collectors.toSet()); + + // Run stratified evaluation and solve + CompiledProgram inputStratEval = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prog))); + Set asStrat = solveCompiledProg.apply(inputStratEval); TestUtils.assertAnswerSetsEqual(expectedAnswerSet, asStrat); - Alpha systemNoStratEval = new Alpha(); - systemNoStratEval.getConfig().setEvaluateStratifiedPart(false); - Set as = systemNoStratEval.solve(prog).collect(Collectors.toSet()); + + // Solve without stratified evaluation + CompiledProgram inputNoStratEval = InternalProgram.fromNormalProgram(normalizer.apply(prog)); + Set as = solveCompiledProg.apply(inputNoStratEval); TestUtils.assertAnswerSetsEqual(expectedAnswerSet, as); } @@ -258,15 +252,11 @@ public void testRecursiveRanking() { " thing_rank(Y, K),\n" + " R = K + 1."; //@formatter:on - Alpha alpha = new Alpha(); - InputProgram prog = alpha.readProgramString(asp); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(alpha.normalizeProgram(prog)); - StratifiedEvaluation evaluation = new StratifiedEvaluation(); - InternalProgram evaluated = evaluation.apply(analyzed); - Predicate rank = Predicate.getInstance("thing_rank", 2); - BasicAtom rank1 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("a"), ConstantTerm.getInstance(1)); - BasicAtom rank2 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("b"), ConstantTerm.getInstance(2)); - BasicAtom rank3 = new BasicAtom(rank, ConstantTerm.getSymbolicInstance("c"), ConstantTerm.getInstance(3)); + CompiledProgram evaluated = parseAndEvaluate.apply(asp); + Predicate rank = CorePredicate.getInstance("thing_rank", 2); + BasicAtom rank1 = new BasicAtom(rank, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getInstance(1)); + BasicAtom rank2 = new BasicAtom(rank, CoreConstantTerm.getSymbolicInstance("b"), CoreConstantTerm.getInstance(2)); + BasicAtom rank3 = new BasicAtom(rank, CoreConstantTerm.getSymbolicInstance("c"), CoreConstantTerm.getInstance(3)); List evaluatedFacts = evaluated.getFacts(); Assert.assertTrue(evaluatedFacts.contains(rank1)); Assert.assertTrue(evaluatedFacts.contains(rank2)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java deleted file mode 100644 index 5de21fbf0..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/HanoiTowerDetailedTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package at.ac.tuwien.kr.alpha.solver; - -import org.antlr.v4.runtime.CharStreams; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; - -/** - * A more fine-grained test, mostly intended for debugging purposes, of the "simple" instance of the Hanoi Tower - * problem. - * - * Copyright (c) 2020, the Alpha Team. - */ -public class HanoiTowerDetailedTest { - - private static final String HANOI_TOWER_SRC = "/HanoiTower_Alpha.asp"; - private static final String SIMPLE_INSTANCE = "/HanoiTower_instances/simple.asp"; - - @Test - public void testHanoiTower() throws IOException { - Alpha alpha = new Alpha(); - // alpha.getConfig().setEvaluateStratifiedPart(false); - InputProgram.Builder programBuilder = InputProgram.builder(); - ProgramParser parser = new ProgramParser(); - InputStream baseProgStream = HanoiTowerDetailedTest.class.getResourceAsStream(HANOI_TOWER_SRC); - InputStream instanceStream = HanoiTowerDetailedTest.class.getResourceAsStream(SIMPLE_INSTANCE); - programBuilder.accumulate(parser.parse(CharStreams.fromStream(baseProgStream))); - programBuilder.accumulate(parser.parse(CharStreams.fromStream(instanceStream))); - InputProgram prog = programBuilder.build(); - InternalProgram preprocessed = InternalProgram.fromNormalProgram(alpha.normalizeProgram(prog)); - Optional solveResult = alpha.solve(preprocessed).findFirst(); - Assert.assertTrue(solveResult.isPresent()); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java index ec2af6231..4e4730686 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java @@ -35,10 +35,11 @@ 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.grounder.parser.ProgramParser; -import at.ac.tuwien.kr.alpha.solver.NaiveNoGoodStore; -import at.ac.tuwien.kr.alpha.solver.TestableChoiceManager; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +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; + import org.junit.Before; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java index 29227058f..36d855a89 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java @@ -29,10 +29,11 @@ import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.common.AtomStoreTest; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.NaiveNoGoodStore; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import at.ac.tuwien.kr.alpha.core.solver.NaiveNoGoodStore; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; + import org.junit.Before; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java index 519f14169..1c639a01e 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java @@ -27,7 +27,8 @@ import at.ac.tuwien.kr.alpha.common.AtomStore; import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.solver.*; +import at.ac.tuwien.kr.alpha.core.solver.*; + import org.junit.Before; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java index a73882ed5..bcc751159 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java @@ -29,10 +29,11 @@ import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.common.Literals; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; + import org.junit.Before; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java index 680dc6131..48d3404de 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java @@ -29,8 +29,8 @@ import at.ac.tuwien.kr.alpha.common.AtomStoreTest; import at.ac.tuwien.kr.alpha.common.Literals; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; import java.util.Arrays; import java.util.Collection; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java index 55c95ccb0..c23816a5b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java @@ -25,9 +25,9 @@ */ package at.ac.tuwien.kr.alpha.solver.heuristics; -import at.ac.tuwien.kr.alpha.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.solver.NoGoodStore; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStore; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; /** * A {@link ChoiceManager} for testing purposes that regards all atoms as active choice atoms. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java index 81ec7bbd1..c210303b5 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java @@ -27,7 +27,8 @@ import at.ac.tuwien.kr.alpha.common.AtomStore; import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.solver.*; +import at.ac.tuwien.kr.alpha.core.solver.*; + import org.junit.Before; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java index e4f4f714f..c10999d40 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java @@ -26,10 +26,11 @@ package at.ac.tuwien.kr.alpha.solver.heuristics; import at.ac.tuwien.kr.alpha.common.*; -import at.ac.tuwien.kr.alpha.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; + import org.junit.Before; import org.junit.Test; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java index 238894bbd..aa53095e0 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java @@ -4,12 +4,13 @@ import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.common.AtomStoreTest; import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.solver.*; +import at.ac.tuwien.kr.alpha.core.solver.*; + import org.junit.Ignore; import org.junit.Test; import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.solver.AntecedentTest.antecedentsEquals; +import static at.ac.tuwien.kr.alpha.core.solver.AntecedentTest.antecedentsEquals; import static org.junit.Assert.*; /** diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java index bc95c1b8d..ffa510b11 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/SubstitutionTestUtil.java @@ -28,14 +28,14 @@ package at.ac.tuwien.kr.alpha.test.util; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.Literal; -import at.ac.tuwien.kr.alpha.common.rule.InternalRule; -import at.ac.tuwien.kr.alpha.core.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; public class SubstitutionTestUtil { - public static String groundAndPrintRule(InternalRule rule, Substitution substitution) { + public static String groundAndPrintRule(CompiledRule rule, Substitution substitution) { StringBuilder ret = new StringBuilder(); if (!rule.isConstraint()) { Atom groundHead = rule.getHeadAtom().substitute(substitution); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java index aa023207c..aff7371bf 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java @@ -1,15 +1,6 @@ package at.ac.tuwien.kr.alpha.test.util; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.AbstractProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; - -import org.junit.Assert; +import static java.util.Collections.emptySet; import java.util.ArrayList; import java.util.Arrays; @@ -18,7 +9,17 @@ import java.util.Set; import java.util.StringJoiner; -import static java.util.Collections.emptySet; +import org.junit.Assert; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; public class TestUtils { @@ -72,26 +73,26 @@ public static void assertAnswerSetsEqualWithBase(String base, String[] expectedA TestUtils.assertAnswerSetsEqual(expectedAnswerSets, actual); } - public static void assertFactsContainedInProgram(AbstractProgram prog, Atom... facts) { + public static void assertFactsContainedInProgram(Program prog, Atom... facts) { for (Atom fact : facts) { Assert.assertTrue(prog.getFacts().contains(fact)); } } public static Atom basicAtomWithStringTerms(String predicate, String... terms) { - Predicate pred = Predicate.getInstance(predicate, terms.length); + Predicate pred = CorePredicate.getInstance(predicate, terms.length); List trms = new ArrayList<>(); for (String str : terms) { - trms.add(ConstantTerm.getInstance(str)); + trms.add(CoreConstantTerm.getInstance(str)); } return new BasicAtom(pred, trms); } public static Atom basicAtomWithSymbolicTerms(String predicate, String... constantSymbols) { - Predicate pred = Predicate.getInstance(predicate, constantSymbols.length); + Predicate pred = CorePredicate.getInstance(predicate, constantSymbols.length); List trms = new ArrayList<>(); for (String str : constantSymbols) { - trms.add(ConstantTerm.getSymbolicInstance(str)); + trms.add(CoreConstantTerm.getSymbolicInstance(str)); } return new BasicAtom(pred, trms); } From f250c240f751ce070e64c538ca258e85067a5ae8 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Mon, 8 Feb 2021 10:58:29 +0100 Subject: [PATCH 021/111] modularize and fix compilation errors in unit tests --- alpha-core/junit.log | 0 .../core/grounder/RuleGroundingInfoImpl.java | 1 - .../kr/alpha/core/programs/InputProgram.java | 4 +- .../alpha/core/grounder/ChoiceGrounder.java | 2 - .../kr/alpha/core/grounder/DummyGrounder.java | 2 - .../grounder/IndexedInstanceStorageTest.java | 1 - .../core/solver/AbstractSolverTests.java | 28 ++++------ .../kr/alpha/core/solver/AntecedentTest.java | 2 - .../alpha/core/solver/AtomCounterTests.java | 1 - .../kr/alpha/core/solver/SolverTests.java | 34 ------------ .../solver/ThreeColouringRandomGraphTest.java | 23 ++++---- .../solver/ThreeColouringTestWithRandom.java | 35 ++++++------ .../core/solver/ThreeColouringWheelTest.java | 35 ++++++------ .../core/solver/TrailAssignmentTest.java | 25 +++++---- .../AlphaHeuristicTestAssumptions.java | 55 ++++++++++--------- .../solver/heuristics/BerkMinTest.java | 28 +++++----- .../BranchingHeuristicFactoryTest.java | 25 +++++---- .../heuristics/HeapOfActiveAtomsTest.java | 22 ++++---- .../solver/heuristics/HeuristicTestUtils.java | 16 +++--- .../heuristics/PseudoChoiceManager.java | 2 +- .../heuristics/ReplayHeuristicTest.java | 22 +++++--- .../solver/heuristics/VSIDSTest.java | 26 +++++---- .../StratifiedEvaluationTest.java | 6 -- .../GroundConflictNoGoodLearnerTest.java | 27 ++++++--- .../tuwien/kr/alpha/impl/AlphaImplTest.java | 32 +++++++++++ 25 files changed, 235 insertions(+), 219 deletions(-) create mode 100644 alpha-core/junit.log rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/AlphaHeuristicTestAssumptions.java (84%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/BerkMinTest.java (97%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/BranchingHeuristicFactoryTest.java (81%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/HeapOfActiveAtomsTest.java (93%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/HeuristicTestUtils.java (91%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/PseudoChoiceManager.java (97%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/ReplayHeuristicTest.java (83%) rename alpha-core/src/test/java/at/ac/tuwien/kr/alpha/{ => core}/solver/heuristics/VSIDSTest.java (94%) diff --git a/alpha-core/junit.log b/alpha-core/junit.log new file mode 100644 index 000000000..e69de29bb diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java index 137d80880..8198f0799 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java @@ -43,7 +43,6 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** * Provides the grounder with information on the order to ground the literals in the body of a rule. 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/InputProgram.java index f17c52f9f..ecb68b7b7 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/InputProgram.java @@ -59,7 +59,7 @@ public static Builder builder() { return new Builder(); } - public static Builder builder(InputProgram prog) { + public static Builder builder(ASPCore2Program prog) { return new Builder(prog); } @@ -72,7 +72,7 @@ public static class Builder { private List facts = new ArrayList<>(); private InlineDirectives inlineDirectives = new InlineDirectivesImpl(); - public Builder(InputProgram prog) { + public Builder(ASPCore2Program prog) { this.addRules(prog.getRules()); this.addFacts(prog.getFacts()); this.addInlineDirectives(prog.getInlineDirectives()); 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/ChoiceGrounder.java index 9ca9430d0..166dbb3cb 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/ChoiceGrounder.java @@ -60,8 +60,6 @@ import at.ac.tuwien.kr.alpha.core.common.CorePredicate; 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.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; 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.NormalRule; 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/DummyGrounder.java index 4c9b79ef1..8fbbfc9f5 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/DummyGrounder.java @@ -59,8 +59,6 @@ import at.ac.tuwien.kr.alpha.core.common.CorePredicate; 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.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; 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.NormalRule; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java index 59f131e1c..f7c03533c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java @@ -40,7 +40,6 @@ import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; /** * Copyright (c) 2016, the Alpha Team. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java index 936f98dfe..8dd9e392f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java @@ -39,7 +39,6 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; -import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; @@ -55,10 +54,7 @@ import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; 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 at.ac.tuwien.kr.alpha.test.util.TestUtils; -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; @RunWith(Parameterized.class) public abstract class AbstractSolverTests { @@ -76,18 +72,18 @@ public abstract class AbstractSolverTests { private final ProgramParser parser = new ProgramParserImpl(); - /** - * Sets the logging level to TRACE. Useful for debugging; call at beginning of test case. - */ - protected static void enableTracing() { - Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - root.setLevel(ch.qos.logback.classic.Level.TRACE); - } - - protected static void enableDebugLog() { - Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - root.setLevel(Level.DEBUG); - } +// /** +// * Sets the logging level to TRACE. Useful for debugging; call at beginning of test case. +// */ +// protected static void enableTracing() { +// Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); +// root.setLevel(ch.qos.logback.classic.Level.TRACE); +// } +// +// protected static void enableDebugLog() { +// Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); +// root.setLevel(Level.DEBUG); +// } /** * Calling this method in a test leads to the test being ignored for the naive solver. 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 index b7b2755b4..a2cb52826 100644 --- 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 @@ -2,8 +2,6 @@ import java.util.HashSet; -import at.ac.tuwien.kr.alpha.core.solver.Antecedent; - public class AntecedentTest { /** 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 5fa9da8e8..71b294498 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 @@ -51,7 +51,6 @@ import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; -import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; public class AtomCounterTests { 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 7427a5aa5..978557637 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 @@ -32,25 +32,18 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; -import java.nio.file.Paths; -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.SortedSet; import org.junit.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.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.api.program.ProgramParser; -import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; @@ -61,7 +54,6 @@ 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.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.util.AnswerSetsParser; import junit.framework.TestCase; @@ -770,32 +762,6 @@ public void smallCardinalityAggregate() throws IOException { ); } - @Test - public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { - final ProgramParser parser = new ProgramParserImpl(); - InputProgram.Builder bld = InputProgram.builder(); - bld.accumulate(parser.parse(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"))); - bld.accumulate(parser.parse(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"))); - 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 = new Alpha(config); - Optional answerSet = alpha.solve(parsedProgram).findFirst(); - assertTrue(answerSet.isPresent()); - } - - @Test public void dummyGrounder() { AtomStore atomStore = new AtomStoreImpl(); 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 b5832a2fe..17e348e8f 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 @@ -34,14 +34,15 @@ import org.junit.Ignore; import org.junit.Test; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; public class ThreeColouringRandomGraphTest extends AbstractSolverTests { @Test(timeout = 1000) @@ -86,7 +87,7 @@ public void testV300E300() throws IOException { } private void testThreeColouring(int nVertices, int nEdges) throws IOException { - InputProgram tmpPrg = new ProgramParser().parse( + ASPCore2Program 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)." + @@ -142,8 +143,8 @@ private List createEdges(int vertices, int edges) { private Atom fact(String predicateName, int... iTerms) { List terms = new ArrayList<>(1); for (int i : iTerms) { - terms.add(ConstantTerm.getInstance(i)); + terms.add(CoreConstantTerm.getInstance(i)); } - return new BasicAtom(Predicate.getInstance(predicateName, iTerms.length), terms); + return new BasicAtom(CorePredicate.getInstance(predicateName, iTerms.length), terms); } } 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 261b91c9c..97c1dbbd8 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 @@ -25,9 +25,6 @@ */ package at.ac.tuwien.kr.alpha.core.solver; -import org.junit.Ignore; -import org.junit.Test; - import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -35,14 +32,20 @@ import java.util.Optional; import java.util.Random; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: @@ -159,7 +162,7 @@ public void testN101() throws IOException { } private void testThreeColouring(int n, boolean shuffle, int seed) throws IOException { - InputProgram tmpPrg = new ProgramParser() + ASPCore2Program 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); prgBuilder.addFacts(createColors("1", "2", "3")); @@ -177,8 +180,8 @@ private List createColors(String... colours) { List facts = new ArrayList<>(colours.length); for (String colour : colours) { List terms = new ArrayList<>(1); - terms.add(ConstantTerm.getInstance(colour)); - facts.add(new BasicAtom(Predicate.getInstance("c", 1), terms)); + terms.add(CoreConstantTerm.getInstance(colour)); + facts.add(new BasicAtom(CorePredicate.getInstance("c", 1), terms)); } return facts; } @@ -220,9 +223,9 @@ private List createEdges(int n, boolean shuffle, int seed) { private Atom fact(String predicateName, int... iTerms) { List terms = new ArrayList<>(iTerms.length); - Predicate predicate = Predicate.getInstance(predicateName, iTerms.length); + Predicate predicate = CorePredicate.getInstance(predicateName, iTerms.length); for (int i : iTerms) { - terms.add(ConstantTerm.getInstance(i)); + terms.add(CoreConstantTerm.getInstance(i)); } return new BasicAtom(predicate, terms); } 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 1912da4d4..2ff699cbf 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 @@ -25,22 +25,25 @@ */ package at.ac.tuwien.kr.alpha.core.solver; -import org.junit.Ignore; -import org.junit.Test; - import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Optional; -import at.ac.tuwien.kr.alpha.common.AnswerSet; -import at.ac.tuwien.kr.alpha.common.Predicate; -import at.ac.tuwien.kr.alpha.common.atoms.Atom; -import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.common.terms.Term; -import at.ac.tuwien.kr.alpha.core.grounder.parser.ProgramParser; +import org.junit.Ignore; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.core.common.CorePredicate; +import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.InputProgram; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: @@ -85,7 +88,7 @@ public void testN11() throws IOException { } private void testThreeColouring(int n) throws IOException { - InputProgram tmpPrg = new ProgramParser().parse( + ASPCore2Program 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)."); @@ -112,10 +115,10 @@ private void maybeShuffle(InputProgram program) { private List createColors(String... colours) { List facts = new ArrayList<>(colours.length); - Predicate predicate = Predicate.getInstance("c", 1); + Predicate predicate = CorePredicate.getInstance("c", 1); for (String colour : colours) { List terms = new ArrayList<>(1); - terms.add(ConstantTerm.getInstance(colour)); + terms.add(CoreConstantTerm.getInstance(colour)); facts.add(new BasicAtom(predicate, terms)); } return facts; @@ -143,9 +146,9 @@ private List createEdges(int n) { private Atom fact(String predicateName, int... iTerms) { List terms = new ArrayList<>(1); - Predicate predicate = Predicate.getInstance(predicateName, iTerms.length); + Predicate predicate = CorePredicate.getInstance(predicateName, iTerms.length); for (int i : iTerms) { - terms.add(ConstantTerm.getInstance(i)); + terms.add(CoreConstantTerm.getInstance(i)); } return new BasicAtom(predicate, terms); } 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 6158cf120..8267fc7d0 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.common.Assignment; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.IntIterator; -import org.junit.Before; -import org.junit.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; @@ -47,6 +35,19 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +import org.junit.Before; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +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; + /** * Copyright (c) 2018-2020, the Alpha Team. */ diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java similarity index 84% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java index 4e4730686..063412e0f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/AlphaHeuristicTestAssumptions.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/AlphaHeuristicTestAssumptions.java @@ -23,33 +23,34 @@ * 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.api.Alpha; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.common.program.InputProgram; -import at.ac.tuwien.kr.alpha.common.program.InternalProgram; -import at.ac.tuwien.kr.alpha.common.program.NormalProgram; -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.grounder.parser.ProgramParser; -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; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import org.junit.Before; -import org.junit.Test; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.util.Collection; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; -import static at.ac.tuwien.kr.alpha.common.Literals.atomOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +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.InternalProgram; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +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; /** * Tests assumptions made by {@link DependencyDrivenHeuristic} and other domain-independent heuristics. @@ -60,6 +61,13 @@ * */ public class AlphaHeuristicTestAssumptions { + + private final ProgramParser parser = new ProgramParserImpl(); + private final NormalizeProgramTransformation normalizer = new NormalizeProgramTransformation(false); + private final Function parseAndPreprocess = (str) -> { + return InternalProgram.fromNormalProgram(normalizer.apply(parser.parse(str))); + }; + private Grounder grounder; private WritableAssignment assignment; private TestableChoiceManager choiceManager; @@ -67,16 +75,13 @@ public class AlphaHeuristicTestAssumptions { @Before public void setUp() { - Alpha system = new Alpha(); String testProgram = "" + "b1." + "b2." + "{b3}." + "{b4}." + "h :- b1, b2, not b3, not b4."; - InputProgram parsedProgram = new ProgramParser().parse(testProgram); - NormalProgram normal = system.normalizeProgram(parsedProgram); - InternalProgram internalProgram = InternalProgram.fromNormalProgram(normal); + CompiledProgram internalProgram = parseAndPreprocess.apply(testProgram); atomStore = new AtomStoreImpl(); grounder = new NaiveGrounder(internalProgram, atomStore, true); assignment = new TrailAssignment(atomStore); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMinTest.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMinTest.java index 36d855a89..0502d6095 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BerkMinTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BerkMinTest.java @@ -23,26 +23,26 @@ * 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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.core.solver.NaiveNoGoodStore; -import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; - -import org.junit.Before; -import org.junit.Test; +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static org.junit.Assert.assertEquals; import java.util.Collection; import java.util.Collections; import java.util.Random; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +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.solver.NaiveNoGoodStore; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; /** * Tests {@link BerkMin}. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactoryTest.java similarity index 81% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactoryTest.java index 1c639a01e..b2f22fa00 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/BranchingHeuristicFactoryTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/BranchingHeuristicFactoryTest.java @@ -23,19 +23,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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.solver.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; import org.junit.Before; import org.junit.Test; -import java.util.Arrays; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; +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.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStore; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; /** * Tests {@link BranchingHeuristicFactory} @@ -56,7 +61,7 @@ public void setUp() { @Test public void testChainedHeuristicWithReplay() { - HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(BranchingHeuristicFactory.Heuristic.VSIDS).setReplayChoices(Arrays.asList(1, 2, 3)); + HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(Heuristic.VSIDS).setReplayChoices(Arrays.asList(1, 2, 3)); BranchingHeuristic branchingHeuristic = factory.getInstance(builder.build(), null, null, choiceManager, null); assertEquals(ChainedBranchingHeuristics.class, branchingHeuristic.getClass()); assertTrue("Unexpected type of branchingHeuristic: " + branchingHeuristic.getClass(), branchingHeuristic instanceof ChainedBranchingHeuristics); @@ -65,7 +70,7 @@ public void testChainedHeuristicWithReplay() { @Test public void testChainedHeuristicWithoutReplay() { - HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(BranchingHeuristicFactory.Heuristic.VSIDS).setReplayChoices(null); + HeuristicsConfigurationBuilder builder = new HeuristicsConfigurationBuilder().setHeuristic(Heuristic.VSIDS).setReplayChoices(null); BranchingHeuristic branchingHeuristic = factory.getInstance(builder.build(), null, null, choiceManager, null); assertEquals(VSIDS.class, branchingHeuristic.getClass()); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtomsTest.java similarity index 93% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtomsTest.java index bcc751159..38af92f00 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeapOfActiveAtomsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeapOfActiveAtomsTest.java @@ -23,22 +23,22 @@ * 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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; -import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +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.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; /** * Tests {@link HeapOfActiveAtoms}, including initial heuristic scores computed by {@link MOMs}. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicTestUtils.java similarity index 91% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicTestUtils.java index 48d3404de..b0183e5ae 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/HeuristicTestUtils.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/HeuristicTestUtils.java @@ -23,19 +23,19 @@ * 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.solver.heuristics; - -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.Literals; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +import at.ac.tuwien.kr.alpha.core.common.AtomStore; +import at.ac.tuwien.kr.alpha.core.common.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; + public class HeuristicTestUtils { static void addNoGoods(AtomStore atomStore, WritableAssignment assignment, NoGoodStoreAlphaRoaming noGoodStore, VSIDS vsids, NoGood... noGoods) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/PseudoChoiceManager.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/PseudoChoiceManager.java index c23816a5b..7b081cfd5 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/PseudoChoiceManager.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/PseudoChoiceManager.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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; import at.ac.tuwien.kr.alpha.core.solver.ChoiceManager; import at.ac.tuwien.kr.alpha.core.solver.NoGoodStore; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ReplayHeuristicTest.java similarity index 83% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ReplayHeuristicTest.java index c210303b5..80485e155 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/ReplayHeuristicTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/ReplayHeuristicTest.java @@ -23,20 +23,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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.solver.*; - -import org.junit.Before; -import org.junit.Test; +import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; +import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.List; -import static at.ac.tuwien.kr.alpha.common.Literals.atomToLiteral; -import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; + +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.solver.ChoiceManager; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStore; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; /** * Tests {@link ReplayHeuristic} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDSTest.java similarity index 94% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java rename to alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDSTest.java index c10999d40..18ea7b87a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/heuristics/VSIDSTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/heuristics/VSIDSTest.java @@ -23,22 +23,26 @@ * 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.solver.heuristics; +package at.ac.tuwien.kr.alpha.core.solver.heuristics; -import at.ac.tuwien.kr.alpha.common.*; -import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; -import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; -import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; -import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; - -import org.junit.Before; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Collection; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +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.Literals; +import at.ac.tuwien.kr.alpha.core.common.NoGood; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult; /** * Tests {@link VSIDS}. diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java index ba41fd408..9bc4354ea 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java @@ -36,17 +36,13 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; -import java.util.stream.Collectors; -import org.antlr.v4.runtime.CharStreams; import org.junit.Assert; import org.junit.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.common.fixedinterpretations.PredicateInterpretation; -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.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; @@ -64,9 +60,7 @@ 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.InputProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.programs.Programs; import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java index aa53095e0..b368689e1 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/solver/learning/GroundConflictNoGoodLearnerTest.java @@ -1,17 +1,28 @@ package at.ac.tuwien.kr.alpha.solver.learning; -import at.ac.tuwien.kr.alpha.common.AtomStore; -import at.ac.tuwien.kr.alpha.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.common.AtomStoreTest; -import at.ac.tuwien.kr.alpha.common.NoGood; -import at.ac.tuwien.kr.alpha.core.solver.*; +import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; +import static at.ac.tuwien.kr.alpha.core.solver.AntecedentTest.antecedentsEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import org.junit.Ignore; import org.junit.Test; -import static at.ac.tuwien.kr.alpha.common.NoGoodTest.fromOldLiterals; -import static at.ac.tuwien.kr.alpha.core.solver.AntecedentTest.antecedentsEquals; -import static org.junit.Assert.*; +import at.ac.tuwien.kr.alpha.common.AtomStoreTest; +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.solver.Antecedent; +import at.ac.tuwien.kr.alpha.core.solver.ConflictCause; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStore; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodStoreAlphaRoaming; +import at.ac.tuwien.kr.alpha.core.solver.ThriceTruth; +import at.ac.tuwien.kr.alpha.core.solver.TrailAssignment; +import at.ac.tuwien.kr.alpha.core.solver.WritableAssignment; +import at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner; /** * Copyright (c) 2016-2019, the Alpha Team. diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java index ae2657725..2ac8e747f 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java @@ -34,13 +34,16 @@ import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -59,8 +62,10 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; @@ -72,6 +77,7 @@ 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.InputProgram; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -590,4 +596,30 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep ASPCore2Program prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).limit(limit).collect(Collectors.toList()).isEmpty()); } + + @Test + public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { + final ProgramParser parser = new ProgramParserImpl(); + InputProgram.Builder bld = InputProgram.builder(); + bld.accumulate(parser.parse(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"))); + bld.accumulate(parser.parse(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"))); + 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 = new AlphaImpl(config); + Optional answerSet = alpha.solve(parsedProgram).findFirst(); + assertTrue(answerSet.isPresent()); + } + } From f5e165a1a5f90b67ea6d3b8abb9b9cc66bf9b0c7 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 12 Feb 2021 13:45:30 +0100 Subject: [PATCH 022/111] tests for core module fixed --- .../kr/alpha/api/program/ProgramParser.java | 17 ++--- .../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-core/junit.log | 48 ++++++++++++++ .../alpha/core/parser/ProgramParserImpl.java | 61 ++++++++++-------- .../alpha/core/programs/InternalProgram.java | 3 + .../kr/alpha/core/programs/Programs.java | 7 +- .../core/rules/heads/NormalHeadImpl.java | 5 +- .../ac/tuwien/kr/alpha/antlr/ParserTest.java | 2 +- .../kr/alpha/common/atoms/AtomsTest.java | 17 ++--- ...LiteralBindingNonBindingVariablesTest.java | 6 +- .../core/solver/AbstractSolverTests.java | 7 +- .../StratifiedEvaluationTest.java | 4 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 10 +-- 22 files changed, 126 insertions(+), 61 deletions(-) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases.tar.gz (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/3col/3col-10-18.txt (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/3col/3col-20-38.txt (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/cutedge/cutedge-100-30.txt (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/cutedge/cutedge-100-50.txt (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/locstrat/locstrat-200.txt (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/locstrat/locstrat-400.txt (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/reach/reach-1.txt (100%) rename {benchmarks => alpha-core/benchmarks}/omiga/omiga-testcases/reach/reach-4.txt (100%) rename {benchmarks => alpha-core/benchmarks}/siemens/racks/racks.lp (100%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java index 84a793086..d280f527d 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java @@ -1,5 +1,6 @@ package at.ac.tuwien.kr.alpha.api.program; +import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.util.Collections; @@ -13,30 +14,30 @@ default ASPCore2Program parse(String programString) { return parse(programString, Collections.emptyMap()); } - default ASPCore2Program parse(InputStream programSource) { + default ASPCore2Program parse(InputStream programSource) throws IOException { return parse(programSource, Collections.emptyMap()); } - default ASPCore2Program parse(Path programPath) { + default ASPCore2Program parse(Path programPath) throws IOException { return parse(programPath, Collections.emptyMap()); } - default ASPCore2Program parse(Path... programSources) { + default ASPCore2Program parse(Path... programSources) throws IOException { return parse(Collections.emptyMap(), programSources); } - default ASPCore2Program parse(Iterable programSources) { + default ASPCore2Program parse(Iterable programSources) throws IOException { return parse(programSources, Collections.emptyMap()); } ASPCore2Program parse(String programString, Map externalPredicateDefinitions); - ASPCore2Program parse(InputStream programSource, Map externalPredicateDefinitions); + ASPCore2Program parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException; - ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions); + ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions) throws IOException; - ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources); + ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources) throws IOException; - ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions); + ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException; } diff --git a/benchmarks/omiga/omiga-testcases.tar.gz b/alpha-core/benchmarks/omiga/omiga-testcases.tar.gz similarity index 100% rename from benchmarks/omiga/omiga-testcases.tar.gz rename to alpha-core/benchmarks/omiga/omiga-testcases.tar.gz diff --git a/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt b/alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt diff --git a/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt b/alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt diff --git a/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt b/alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt diff --git a/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt b/alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt diff --git a/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt b/alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt diff --git a/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt b/alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt diff --git a/benchmarks/omiga/omiga-testcases/reach/reach-1.txt b/alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-1.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/reach/reach-1.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-1.txt diff --git a/benchmarks/omiga/omiga-testcases/reach/reach-4.txt b/alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-4.txt similarity index 100% rename from benchmarks/omiga/omiga-testcases/reach/reach-4.txt rename to alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-4.txt diff --git a/benchmarks/siemens/racks/racks.lp b/alpha-core/benchmarks/siemens/racks/racks.lp similarity index 100% rename from benchmarks/siemens/racks/racks.lp rename to alpha-core/benchmarks/siemens/racks/racks.lp diff --git a/alpha-core/junit.log b/alpha-core/junit.log index e69de29bb..ac63bdbd0 100644 --- a/alpha-core/junit.log +++ b/alpha-core/junit.log @@ -0,0 +1,48 @@ +6062 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.016s: 140 +6110 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 140 decisions in 1.016s or 137.79527 decisions per sec. Overall replayed assignments: 655. +7057 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.0s: 11 +7057 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 151 decisions in 2.016s or 74.900795 decisions per sec. Overall replayed assignments: 824. +9052 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.142s: 146 +9053 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 146 decisions in 1.142s or 127.84589 decisions per sec. Overall replayed assignments: 751. +10192 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.14s: 20 +10193 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 166 decisions in 2.282s or 72.7432 decisions per sec. Overall replayed assignments: 1012. +16095 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.0s: 183 +16095 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 183 decisions in 1.0s or 183.0 decisions per sec. Overall replayed assignments: 206. +18487 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.002s: 216 +18488 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 216 decisions in 1.002s or 215.56886 decisions per sec. Overall replayed assignments: 228. +20461 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.024s: 1 +20461 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.024s or 0.97656244 decisions per sec. Overall replayed assignments: 0. +22172 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.169s: 1 +22172 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.169s or 0.855432 decisions per sec. Overall replayed assignments: 0. +23207 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.035s: 0 +23211 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 2.204s or 0.4537205 decisions per sec. Overall replayed assignments: 0. +25040 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.063s: 1 +25041 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.063s or 0.9407338 decisions per sec. Overall replayed assignments: 0. +26937 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.056s: 1 +26937 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.056s or 0.9469697 decisions per sec. Overall replayed assignments: 0. +29335 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.053s: 0 +29335 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.053s or 0.0 decisions per sec. Overall replayed assignments: 0. +30376 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.041s: 0 +30376 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.094s or 0.0 decisions per sec. Overall replayed assignments: 0. +31382 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.006s: 0 +31382 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.1s or 0.0 decisions per sec. Overall replayed assignments: 0. +32421 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.039s: 0 +32422 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.139s or 0.0 decisions per sec. Overall replayed assignments: 0. +33426 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.005s: 0 +33428 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.144s or 0.0 decisions per sec. Overall replayed assignments: 0. +34453 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.027s: 0 +34453 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 6.171s or 0.0 decisions per sec. Overall replayed assignments: 0. +37118 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.128s: 1 +37118 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.128s or 0.8865248 decisions per sec. Overall replayed assignments: 0. +38610 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.002s: 0 +38610 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.002s or 0.0 decisions per sec. Overall replayed assignments: 0. +39643 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.033s: 0 +39643 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.035s or 0.0 decisions per sec. Overall replayed assignments: 0. +40683 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.04s: 0 +40683 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.075s or 0.0 decisions per sec. Overall replayed assignments: 0. +41712 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.029s: 0 +41713 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.104s or 0.0 decisions per sec. Overall replayed assignments: 0. +42733 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.021s: 0 +42734 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.125s or 0.0 decisions per sec. Overall replayed assignments: 0. +45215 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.073s: 1 +45215 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.073s or 0.9319665 decisions per sec. Overall replayed assignments: 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 6d399c310..393ed31a7 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 @@ -23,19 +23,22 @@ import at.ac.tuwien.kr.alpha.core.programs.InputProgram; public class ProgramParserImpl implements ProgramParser { - private final Map externals; +// private final Map externals; +// +// // TODO not sure if it makes sense to have this constructor... is it even used? +// public ProgramParserImpl(Map externals) { +// this.externals = externals; +// } - public ProgramParserImpl(Map externals) { - this.externals = externals; - } - - public ProgramParserImpl() { - this(Collections.emptyMap()); + @Override + public ASPCore2Program parse(String s) { + return parse(s, Collections.emptyMap()); } - public ASPCore2Program parse(String s) { + @Override + public ASPCore2Program parse(String s, Map externals) { try { - return parse(CharStreams.fromString(s)); + return parse(CharStreams.fromString(s), externals); } catch (IOException e) { // In this case we assume that something went fundamentally // wrong when using a String as input. The caller probably @@ -49,7 +52,11 @@ public ASPCore2Program parse(String s) { } } - public InputProgram parse(CharStream stream) throws IOException { + public ASPCore2Program parse(CharStream stream) throws IOException { + return parse(stream, Collections.emptyMap()); + } + + public ASPCore2Program parse(CharStream stream, Map externals) throws IOException { //@formatter:off /* * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. @@ -113,32 +120,30 @@ public InputProgram parse(CharStream stream) throws IOException { } @Override - public InputProgram parse(String programString, Map externalPredicateDefinitions) { - // TODO Auto-generated method stub - return null; - } - - @Override - public InputProgram parse(InputStream programSource, Map externalPredicateDefinitions) { - // TODO Auto-generated method stub - return null; + public ASPCore2Program parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException { + return parse(CharStreams.fromStream(programSource), externalPredicateDefinitions); } @Override - public InputProgram parse(Path programPath, Map externalPredicateDefinitions) { - // TODO Auto-generated method stub - return null; + public ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions) throws IOException { + return parse(CharStreams.fromPath(programPath), externalPredicateDefinitions); } @Override - public InputProgram parse(Map externalPredicateDefinitions, Path... programSources) { - // TODO Auto-generated method stub - return null; + public ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { + InputProgram.Builder bld = InputProgram.builder(); + for (Path src : programSources) { + bld.accumulate(parse(src, externalPredicateDefinitions)); + } + return bld.build(); } @Override - public InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) { - // TODO Auto-generated method stub - return null; + public ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { + InputProgram.Builder bld = InputProgram.builder(); + for (Path src : programSources) { + bld.accumulate(parse(src, externalPredicateDefinitions)); + } + return bld.build(); } } 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 1986471d3..69ad9988f 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 @@ -84,14 +84,17 @@ private void recordDefiningRule(Predicate headPredicate, CompiledRule rule) { predicateDefiningRules.get(headPredicate).add(rule); } + @Override public Map> getPredicateDefiningRules() { return Collections.unmodifiableMap(predicateDefiningRules); } + @Override public Map> getFactsByPredicate() { return Collections.unmodifiableMap(factsByPredicate); } + @Override public Map getRulesById() { return Collections.unmodifiableMap(rulesById); } 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 995a99c04..905228caf 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,6 +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.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; public class Programs { @@ -15,9 +16,9 @@ private Programs() { throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); } - public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { - ProgramParserImpl parser = new ProgramParserImpl(externals); - return parser.parse(CharStreams.fromStream(is)); + public static ASPCore2Program 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/rules/heads/NormalHeadImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java index ba6492305..56baca8b9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/heads/NormalHeadImpl.java @@ -16,11 +16,12 @@ public NormalHeadImpl(Atom atom) { } // Note that at some point in the future it might make sense to have this method directly in Head + @Override public boolean isGround() { - // return atom.isGround(); TODO - return false; + return atom.isGround(); } + @Override public Atom getAtom() { return atom; } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java index 789658c0c..7d4e5ae3d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java @@ -125,7 +125,7 @@ public void parseInterval() throws IOException { IntervalTerm factInterval = (IntervalTerm) parsedProgram.getFacts().get(0).getTerms().get(0); assertTrue(factInterval.equals(IntervalTerm.getInstance(CoreConstantTerm.getInstance(2), CoreConstantTerm.getInstance(5)))); IntervalTerm bodyInterval = (IntervalTerm) ((Literal) parsedProgram.getRules().get(0).getBody().stream().findFirst().get()).getTerms().get(1); - assertTrue(bodyInterval.equals(IntervalTerm.getInstance(CoreConstantTerm.getInstance(3), CoreConstantTerm.getInstance("X")))); + assertTrue(bodyInterval.equals(IntervalTerm.getInstance(CoreConstantTerm.getInstance(3), VariableTermImpl.getInstance("X")))); } @Test diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java index b861d8e6d..f16d68ce1 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java @@ -30,12 +30,13 @@ public class AtomsTest { private final ProgramParser parser; + private Map externals; public AtomsTest() throws NoSuchMethodException, SecurityException { - Map externals = new HashMap<>(); + 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(externals); + parser = new ProgramParserImpl(); } @Predicate @@ -97,13 +98,13 @@ public void testAreBasicAtomsEqual() { @Test public void testIsExternalAtomGround() { - ASPCore2Program p1 = parser.parse("a :- &isFoo[1]."); + 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)]."); + 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]."); + ASPCore2Program p3 = parser.parse("a :- &isFoo[BLA].", externals); Atom ext3 = p3.getRules().get(0).getBody().stream().findFirst().get().getAtom(); assertExternalAtomGround(ext3, false); } @@ -111,9 +112,9 @@ public void testIsExternalAtomGround() { @Test @SuppressWarnings("unlikely-arg-type") public void testAreExternalAtomsEqual() { - ASPCore2Program p1 = parser.parse("a :- &isFoo[1]."); + 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]."); + ASPCore2Program p2 = parser.parse("a :- &isFoo[1].", externals); Atom ext2 = p2.getRules().get(0).getBody().stream().findFirst().get().getAtom(); Assert.assertEquals(ext1, ext2); Assert.assertEquals(ext2, ext1); @@ -125,7 +126,7 @@ public void testAreExternalAtomsEqual() { @Test public void testExternalHasOutput() { - ASPCore2Program p = parser.parse("a:- &extWithOutput[1](OUT)."); + ASPCore2Program p = parser.parse("a:- &extWithOutput[1](OUT).", externals); Atom ext = p.getRules().get(0).getBody().stream().findFirst().get().getAtom(); assertExternalAtomGround(ext, false); Assert.assertTrue(((ExternalAtom) ext).hasOutput()); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java index 464eafca6..9176f687d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/LiteralBindingNonBindingVariablesTest.java @@ -56,7 +56,7 @@ public class LiteralBindingNonBindingVariablesTest { private final Map externals = new HashMap<>(); - private final ProgramParser parser = new ProgramParserImpl(externals); + private final ProgramParser parser = new ProgramParserImpl(); @Test public void testPositiveBasicLiteral() { @@ -182,7 +182,7 @@ 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).").getRules().get(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(); assertEquals(false, literal.isNegated()); expectVariables(literal.getBindingVariables(), "X"); @@ -192,7 +192,7 @@ 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).").getRules().get(0).getNegativeBody().stream().findFirst().get(); + Literal literal = parser.parse("p(X) :- q(Y), not &ext[Y](X).", externals).getRules().get(0).getNegativeBody().stream().findFirst().get(); 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/solver/AbstractSolverTests.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java index 8dd9e392f..9e33a8b32 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AbstractSolverTests.java @@ -27,6 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.solver; +import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; @@ -220,7 +221,11 @@ protected Solver getInstance(String program) { } protected Solver getInstance(InputStream program) { - return getInstance(parser.parse(program)); + try { + return getInstance(parser.parse(program)); + } catch (IOException ex) { + throw new RuntimeException("IOException in program parsing!"); + } } protected Set collectSet(String program) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java index 9bc4354ea..ffb505e08 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java @@ -168,8 +168,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(externals); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parserWithExternals.parse(asp))); + 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); 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 b89a4a286..b7040e817 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 @@ -104,9 +104,9 @@ public ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - ProgramParserImpl parser = new ProgramParserImpl(externals); + ProgramParserImpl parser = new ProgramParserImpl(); InputProgram.Builder prgBuilder = InputProgram.builder(); - InputProgram tmpProg; + ASPCore2Program tmpProg; for (Path path : paths) { CharStream stream; if (!literate) { @@ -114,7 +114,7 @@ public ASPCore2Program readProgramFiles(boolean literate, Map externals) { - ProgramParserImpl parser = new ProgramParserImpl(externals); - return parser.parse(aspString); + ProgramParserImpl parser = new ProgramParserImpl(); + return parser.parse(aspString, externals); } @Override From 4c333fb1e09a126e83c240735b4dcce6657c22dd Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Fri, 12 Feb 2021 20:12:00 +0100 Subject: [PATCH 023/111] fix unit tests in all modules --- .../AnswerSetToWorkbookMapperTest.java | 2 +- alpha-core/junit.log | 1686 ++++++++++++++++- .../alpha/core/parser/ProgramParserImpl.java | 25 +- .../core/depgraph/DependencyGraphTest.java | 2 +- .../depgraph/StratificationAlgorithmTest.java | 2 +- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 18 +- .../tuwien/kr/alpha/impl/AlphaImplTest.java | 2 +- .../src/test/resources/HanoiTower_Alpha.asp | 98 + .../test/resources/HanoiTower_instances/1.asp | 85 + .../test/resources/HanoiTower_instances/2.asp | 91 + .../test/resources/HanoiTower_instances/3.asp | 89 + .../test/resources/HanoiTower_instances/4.asp | 95 + .../HanoiTower_instances/instances.txt | 4 + .../resources/HanoiTower_instances/simple.asp | 24 + .../PreviouslyProblematic/3col-20-38.txt | 0 .../vehicle_normal_small.asp | 0 16 files changed, 2155 insertions(+), 68 deletions(-) create mode 100644 alpha-solver/src/test/resources/HanoiTower_Alpha.asp create mode 100644 alpha-solver/src/test/resources/HanoiTower_instances/1.asp create mode 100644 alpha-solver/src/test/resources/HanoiTower_instances/2.asp create mode 100644 alpha-solver/src/test/resources/HanoiTower_instances/3.asp create mode 100644 alpha-solver/src/test/resources/HanoiTower_instances/4.asp create mode 100644 alpha-solver/src/test/resources/HanoiTower_instances/instances.txt create mode 100644 alpha-solver/src/test/resources/HanoiTower_instances/simple.asp rename {alpha-core => alpha-solver}/src/test/resources/PreviouslyProblematic/3col-20-38.txt (100%) rename {alpha-core => alpha-solver}/src/test/resources/PreviouslyProblematic/vehicle_normal_small.asp (100%) 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 0c5a69b67..744ad2b3d 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 @@ -44,7 +44,7 @@ public void solveAndWriteWorkbookTest() { + "q(A, B) :- p(A), p(B)."; //@formatter:on Alpha alpha = new AlphaImpl(); - List answerSets = alpha.solve(alpha.readProgramString(progstr, null)).collect(Collectors.toList()); + List answerSets = alpha.solve(alpha.readProgramString(progstr)).collect(Collectors.toList()); Assert.assertEquals(1, answerSets.size()); AnswerSet as = answerSets.get(0); Workbook answerSetWorkbook = this.mapper.mapFromAnswerSet(as); diff --git a/alpha-core/junit.log b/alpha-core/junit.log index ac63bdbd0..7ce55a609 100644 --- a/alpha-core/junit.log +++ b/alpha-core/junit.log @@ -1,48 +1,1638 @@ -6062 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.016s: 140 -6110 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 140 decisions in 1.016s or 137.79527 decisions per sec. Overall replayed assignments: 655. -7057 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.0s: 11 -7057 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 151 decisions in 2.016s or 74.900795 decisions per sec. Overall replayed assignments: 824. -9052 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.142s: 146 -9053 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 146 decisions in 1.142s or 127.84589 decisions per sec. Overall replayed assignments: 751. -10192 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.14s: 20 -10193 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 166 decisions in 2.282s or 72.7432 decisions per sec. Overall replayed assignments: 1012. -16095 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.0s: 183 -16095 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 183 decisions in 1.0s or 183.0 decisions per sec. Overall replayed assignments: 206. -18487 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.002s: 216 -18488 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 216 decisions in 1.002s or 215.56886 decisions per sec. Overall replayed assignments: 228. -20461 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.024s: 1 -20461 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.024s or 0.97656244 decisions per sec. Overall replayed assignments: 0. -22172 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.169s: 1 -22172 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.169s or 0.855432 decisions per sec. Overall replayed assignments: 0. -23207 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.035s: 0 -23211 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 2.204s or 0.4537205 decisions per sec. Overall replayed assignments: 0. -25040 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.063s: 1 -25041 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.063s or 0.9407338 decisions per sec. Overall replayed assignments: 0. -26937 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.056s: 1 -26937 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.056s or 0.9469697 decisions per sec. Overall replayed assignments: 0. -29335 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.053s: 0 -29335 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.053s or 0.0 decisions per sec. Overall replayed assignments: 0. -30376 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.041s: 0 -30376 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.094s or 0.0 decisions per sec. Overall replayed assignments: 0. -31382 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.006s: 0 -31382 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.1s or 0.0 decisions per sec. Overall replayed assignments: 0. -32421 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.039s: 0 -32422 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.139s or 0.0 decisions per sec. Overall replayed assignments: 0. -33426 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.005s: 0 -33428 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.144s or 0.0 decisions per sec. Overall replayed assignments: 0. -34453 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.027s: 0 -34453 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 6.171s or 0.0 decisions per sec. Overall replayed assignments: 0. -37118 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.128s: 1 -37118 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.128s or 0.8865248 decisions per sec. Overall replayed assignments: 0. -38610 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.002s: 0 -38610 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.002s or 0.0 decisions per sec. Overall replayed assignments: 0. -39643 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.033s: 0 -39643 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.035s or 0.0 decisions per sec. Overall replayed assignments: 0. -40683 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.04s: 0 -40683 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.075s or 0.0 decisions per sec. Overall replayed assignments: 0. -41712 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.029s: 0 -41713 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.104s or 0.0 decisions per sec. Overall replayed assignments: 0. -42733 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.021s: 0 -42734 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.125s or 0.0 decisions per sec. Overall replayed assignments: 0. -45215 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.073s: 1 -45215 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.073s or 0.9319665 decisions per sec. Overall replayed assignments: 0. +880 INFO org.reflections.Reflections: Reflections took 183 ms to scan 1 urls, producing 1 keys and 8 values +1456 INFO org.reflections.Reflections: Reflections took 9 ms to scan 1 urls, producing 1 keys and 8 values +1539 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +1580 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values +1615 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values +1649 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values +1698 INFO org.reflections.Reflections: Reflections took 18 ms to scan 1 urls, producing 1 keys and 8 values +1730 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values +1757 INFO org.reflections.Reflections: Reflections took 10 ms to scan 1 urls, producing 1 keys and 8 values +1791 INFO org.reflections.Reflections: Reflections took 14 ms to scan 1 urls, producing 1 keys and 8 values +1811 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +1839 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +1863 INFO org.reflections.Reflections: Reflections took 13 ms to scan 1 urls, producing 1 keys and 8 values +1873 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +1880 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +1890 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +1899 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +1912 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +1925 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +1943 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +1950 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +1962 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2066 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2080 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2088 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2182 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2188 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2193 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2199 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2206 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2211 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2222 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2229 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2236 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2241 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2250 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2257 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2261 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2269 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2283 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +2290 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +2299 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2316 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2335 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2362 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2469 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2484 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2493 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +2513 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2529 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values +2537 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2543 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2554 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2557 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +2598 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2605 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2609 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2626 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +2643 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2647 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2652 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2657 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2664 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2670 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2727 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2733 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2738 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2745 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2751 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2756 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2762 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2768 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2774 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2782 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2789 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2794 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2807 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2813 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2820 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +2830 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2835 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2841 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2846 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2852 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2857 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2864 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2881 INFO org.reflections.Reflections: Reflections took 15 ms to scan 1 urls, producing 1 keys and 8 values +2886 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2892 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2898 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2903 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2911 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2916 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2923 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +2929 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2935 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2940 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2952 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2959 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2965 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2980 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +2987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2991 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +2998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3004 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3008 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3015 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3024 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +3029 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3049 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3054 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3060 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3065 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3070 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3075 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3081 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3086 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3099 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3108 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3112 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3121 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3125 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3133 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3138 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3144 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3149 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3157 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3161 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3169 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3173 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3180 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3185 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3191 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3195 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3207 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3213 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3218 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3225 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3229 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3236 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3241 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3247 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3252 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3258 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3263 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3269 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3274 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3283 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3287 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3293 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3298 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3305 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3310 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3318 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3335 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3341 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3346 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3351 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3355 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3361 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3366 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3372 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3377 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3385 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +3390 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3394 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3398 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3406 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +3409 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +3418 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3425 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +3438 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3442 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3445 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +3480 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3499 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3504 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3623 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +3636 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3641 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3758 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3766 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3770 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3855 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3862 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3867 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3969 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +3975 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3980 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +3993 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4006 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4011 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4016 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4028 INFO org.reflections.Reflections: Reflections took 11 ms to scan 1 urls, producing 1 keys and 8 values +4034 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4039 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4043 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4050 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4055 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4060 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4064 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4069 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4075 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4079 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4090 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4095 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4100 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4104 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4109 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4115 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4120 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4125 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4130 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4136 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4141 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4145 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4151 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4167 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4181 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4186 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4200 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4205 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4210 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4215 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4267 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4287 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4295 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4299 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4311 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4316 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4322 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4326 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4386 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4395 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4401 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4408 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +4424 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +4429 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4435 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4439 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4502 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4515 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4522 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +4527 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4540 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4546 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4551 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4556 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4616 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4625 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4629 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4635 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4640 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4645 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4667 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4672 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4676 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4681 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4686 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4691 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4698 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4704 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4710 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +4715 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4723 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +4727 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4734 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4739 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4743 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4749 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4756 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4760 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4766 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4772 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4776 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4782 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4787 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4790 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +4795 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4798 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +4801 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +4807 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4815 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4821 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4825 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4829 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +4832 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +4836 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4841 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4846 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4851 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4919 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4927 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4931 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4936 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4941 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4944 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4954 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4958 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4962 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +4967 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4973 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +4977 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4982 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4986 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4989 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +4997 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5001 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5004 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5013 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5019 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5026 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5034 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +5041 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5045 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5058 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5064 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5068 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5074 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5080 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5093 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5098 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5102 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5111 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5116 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5121 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5126 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5131 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5135 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5141 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5146 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5150 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5157 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5163 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5167 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5177 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5181 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5187 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5195 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5199 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5205 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5211 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5215 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5222 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5226 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5230 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5235 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5240 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5244 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5250 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5255 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5259 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5269 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5274 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5279 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5286 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +5291 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5294 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5297 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5313 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5317 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5322 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5328 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5333 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5338 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5348 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5398 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5403 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5407 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5412 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5416 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5421 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5426 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5429 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5432 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5440 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5443 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5446 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5456 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5463 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5468 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5475 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5479 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5482 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5502 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5507 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5512 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5516 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5522 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +5525 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5530 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5535 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5539 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5544 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5549 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5553 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5559 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5564 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5567 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5571 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5576 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5579 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5584 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5587 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5590 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5594 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5598 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5600 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5606 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5610 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5614 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5621 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5627 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5631 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5636 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5643 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5647 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5651 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5657 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5662 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5666 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5724 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +5727 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5730 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5734 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5738 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5741 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5747 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5750 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5753 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5756 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5760 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5763 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5767 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5770 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5773 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5779 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +5785 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5788 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5792 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5796 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5799 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5804 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5809 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5813 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5819 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5823 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5826 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5830 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5833 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5836 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5840 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5843 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5846 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5851 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5855 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5858 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5862 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5866 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5869 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5873 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5877 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5880 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5885 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5888 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5891 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5896 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5899 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5902 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5906 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5909 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5913 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5918 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5924 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5927 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5931 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5934 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5937 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5942 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5947 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5950 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5955 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5959 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5962 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +5969 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5973 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5978 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5982 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +5987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5991 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +5994 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6006 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6009 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6013 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6021 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6026 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6032 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6044 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6082 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6087 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6094 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +6101 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +6106 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6110 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6114 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6117 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6144 INFO org.reflections.Reflections: Reflections took 15 ms to scan 1 urls, producing 1 keys and 8 values +6167 INFO org.reflections.Reflections: Reflections took 18 ms to scan 1 urls, producing 1 keys and 8 values +6183 INFO org.reflections.Reflections: Reflections took 15 ms to scan 1 urls, producing 1 keys and 8 values +6187 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6218 INFO org.reflections.Reflections: Reflections took 9 ms to scan 1 urls, producing 1 keys and 8 values +6222 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6232 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6246 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6254 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +6258 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6301 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6307 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6310 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6316 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6322 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6326 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6338 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +6358 INFO org.reflections.Reflections: Reflections took 18 ms to scan 1 urls, producing 1 keys and 8 values +6369 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6377 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +6384 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6389 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6395 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6399 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6403 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6409 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6413 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6416 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6421 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6425 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6428 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6432 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6436 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6443 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6446 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6450 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6455 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6466 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +6473 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6476 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6482 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6489 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +6492 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6496 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6502 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6506 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6555 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6560 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6564 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6568 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6573 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6586 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6591 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6594 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6599 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6604 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6607 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6612 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6617 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6621 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6627 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6631 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6635 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6642 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6647 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6651 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6656 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6660 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6664 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6669 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6673 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6677 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6682 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6686 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6696 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6701 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6706 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6711 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6720 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6726 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6730 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6734 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6739 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6743 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6748 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6752 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6756 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6764 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6768 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6772 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6776 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6783 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +6786 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +6792 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6797 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6800 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6806 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6811 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6815 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6821 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6826 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +6829 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6834 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6839 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6843 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6848 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6852 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6856 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6865 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6869 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6873 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6877 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6883 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6888 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6892 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6910 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6919 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6929 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6934 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6939 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6947 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +6998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7003 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7007 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7012 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7017 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7023 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7028 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7033 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7037 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7044 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7049 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7053 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7062 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7066 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7070 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7075 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7080 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7102 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7106 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7110 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7114 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7119 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7123 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7129 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7133 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7137 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7141 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7146 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7150 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7155 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7160 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7163 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7166 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7171 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7175 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7181 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7185 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7189 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7194 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7198 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7208 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7213 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7217 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7222 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7227 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7231 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7236 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7241 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7246 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7250 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7256 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7260 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7264 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7306 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7310 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7314 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7319 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7323 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7331 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7335 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7339 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7344 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7348 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7351 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7354 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7359 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7362 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7367 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7372 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7376 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7383 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7388 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7392 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7397 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7401 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7406 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7411 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7417 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7422 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7427 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7431 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7440 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7444 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7448 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7455 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7459 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7463 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7469 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7473 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7478 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7482 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7488 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7491 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7498 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7501 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7504 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7509 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7513 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7516 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7522 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7527 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7531 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7536 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7541 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7544 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7549 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7555 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7559 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7563 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7567 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7572 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7581 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7584 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7599 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7603 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7608 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7612 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7618 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7623 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7625 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7637 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7642 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7646 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7654 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7659 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7664 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7671 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7713 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +7719 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +7724 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +7729 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7734 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7737 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7743 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7747 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7749 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +7761 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7765 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7770 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7846 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7853 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7857 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7861 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7901 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7912 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7916 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7922 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +7939 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +7945 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7949 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7956 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +7986 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +7990 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7995 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +7999 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8016 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +8021 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +8024 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +8026 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +8059 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8065 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8069 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8073 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8101 INFO org.reflections.Reflections: Reflections took 14 ms to scan 1 urls, producing 1 keys and 8 values +8106 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8111 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +8114 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8146 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8154 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +8160 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +8163 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8209 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +8218 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8223 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +8227 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +8230 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +8233 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +8249 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +8253 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +9333 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.077s: 148 +9339 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 148 decisions in 1.077s or 137.41875 decisions per sec. Overall replayed assignments: 787. +9770 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +9772 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +9776 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +9787 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +9790 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +10800 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.007s: 160 +10800 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 160 decisions in 1.007s or 158.88779 decisions per sec. Overall replayed assignments: 907. +11021 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11025 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11028 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11040 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +11044 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11046 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11051 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11054 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11057 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11062 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11065 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11067 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11076 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11080 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11084 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11091 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11548 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11553 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11557 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11562 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11581 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11586 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +11599 INFO org.reflections.Reflections: Reflections took 10 ms to scan 1 urls, producing 1 keys and 8 values +11609 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11613 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11618 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11624 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11641 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +11645 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11649 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11653 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11662 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +11666 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11670 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11677 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11712 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11721 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +11726 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +11731 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11797 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11802 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11806 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +11810 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11854 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11859 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11863 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11869 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11881 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11885 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11889 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11893 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11900 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11904 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11909 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +11915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12369 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +12374 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12378 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12384 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12405 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12410 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12415 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12423 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12433 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12440 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +12445 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12454 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12475 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12480 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12484 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12498 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12508 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12513 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12519 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12527 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12569 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12574 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12582 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12653 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12658 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12662 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12671 INFO org.reflections.Reflections: Reflections took 8 ms to scan 1 urls, producing 1 keys and 8 values +12732 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12737 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12741 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12748 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +12760 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12764 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12768 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12772 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12779 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12783 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12788 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +12797 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13206 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13211 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13214 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13219 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13240 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13244 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13249 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13258 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13266 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13270 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13275 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13282 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +13298 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13306 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13311 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +13320 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13324 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13329 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13336 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13366 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13371 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +13375 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13379 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13443 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13447 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13491 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13495 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13500 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13506 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13517 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13523 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +13526 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +13531 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13537 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13543 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +13549 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13555 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13944 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +13948 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13952 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13956 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13974 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13978 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13982 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13989 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +13998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14002 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14007 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14015 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +14030 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14034 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14038 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14042 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14051 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14056 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14060 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14067 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14101 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14106 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14109 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14115 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14167 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14176 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14180 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14231 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14236 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14240 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14247 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14259 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14264 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14267 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14271 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14287 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14292 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14297 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14350 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14354 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14358 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14362 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14377 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14385 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14390 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14394 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14402 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14408 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14412 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14417 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14427 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14431 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14448 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14453 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14457 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14464 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +14483 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14486 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +14490 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14495 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14550 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14554 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14558 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14562 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14605 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14609 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +14616 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +14623 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14629 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14634 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14638 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14641 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14648 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14652 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14657 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14661 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14710 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14715 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14719 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14724 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14740 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14744 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14747 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14751 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14757 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14761 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14765 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14769 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14777 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14781 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14785 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14789 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14803 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +14807 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14812 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14816 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14833 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14838 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14841 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14846 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14892 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14896 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14900 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14904 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14946 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14950 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14954 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14958 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14964 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14968 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14972 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14975 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +14982 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14991 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +14995 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15039 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15047 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +15050 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15054 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15069 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15072 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15076 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15080 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15085 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15089 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15094 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15098 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15104 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15108 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15112 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15116 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15124 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15128 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15132 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15136 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15150 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15154 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15157 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15161 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15206 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15209 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15214 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15252 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15256 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15260 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15264 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15270 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15274 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15278 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15282 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15288 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15294 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15300 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15304 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15350 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15354 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15357 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15362 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15378 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15385 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +15390 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15397 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +15407 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15411 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15416 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15421 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15429 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15433 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15437 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15441 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15449 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15453 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15459 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +15466 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15482 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15487 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15491 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15496 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15540 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15548 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values +15553 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15557 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15598 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15602 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15606 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15611 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15618 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15624 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15628 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15632 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15643 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15649 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +15654 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15658 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15664 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15671 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15675 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +15679 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15682 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15699 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +15704 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15708 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15712 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15719 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +15723 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15727 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15729 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15844 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15848 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +15851 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +16583 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16588 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16592 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16614 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16619 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16624 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16720 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16725 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16731 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +16972 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16976 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16980 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16993 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +16998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +17001 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +17033 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +17039 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +17043 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +17190 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +17196 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +17199 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18014 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18019 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +18022 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18045 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18052 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18055 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18136 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18141 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18145 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18389 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18397 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values +18400 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18413 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18419 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18423 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18469 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +18476 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +18480 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18500 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +18505 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18509 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18595 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18600 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18643 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +18646 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +19512 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +19569 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +19573 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +20636 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.059s: 1 +20637 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.059s or 0.94428706 decisions per sec. Overall replayed assignments: 0. +20842 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +20846 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +20849 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +20865 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +20870 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +20872 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +20922 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +20926 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +20950 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +20953 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +21508 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +21564 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +21567 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22618 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22624 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22627 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22637 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22642 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +22645 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22717 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22951 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +22954 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +23972 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.004s: 0 +23972 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.004s or 0.0 decisions per sec. Overall replayed assignments: 0. +24977 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.005s: 0 +24977 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.009s or 0.0 decisions per sec. Overall replayed assignments: 0. +25979 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.002s: 0 +25979 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.011s or 0.0 decisions per sec. Overall replayed assignments: 0. +27003 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.024s: 0 +27003 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.035s or 0.0 decisions per sec. Overall replayed assignments: 0. +28003 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.0s: 0 +28004 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.035s or 0.0 decisions per sec. Overall replayed assignments: 0. +28542 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +28573 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +28577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +29317 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +29390 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +29394 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +30459 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.059s: 1 +30459 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.059s or 0.94428706 decisions per sec. Overall replayed assignments: 0. +30759 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +30763 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +30767 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +30778 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +30783 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +30786 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +30833 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +31042 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +31045 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +32066 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.009s: 0 +32066 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.009s or 0.0 decisions per sec. Overall replayed assignments: 0. +33097 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.031s: 0 +33097 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.04s or 0.0 decisions per sec. Overall replayed assignments: 0. +34140 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.043s: 0 +34141 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.083s or 0.0 decisions per sec. Overall replayed assignments: 0. +35171 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.031s: 0 +35171 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.114s or 0.0 decisions per sec. Overall replayed assignments: 0. +36188 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.017s: 0 +36188 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.131s or 0.0 decisions per sec. Overall replayed assignments: 0. +36369 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +36455 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +36461 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +37047 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +37081 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +37085 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38175 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38178 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38180 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38185 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38189 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38192 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38194 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38200 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38203 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38206 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38208 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38214 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +38218 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38221 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38224 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38253 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38257 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38261 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38264 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38268 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38272 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38276 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38279 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38283 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38287 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38290 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38294 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38298 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38305 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38309 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38318 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38323 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38327 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38331 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38334 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38337 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38340 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38343 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38346 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38349 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38352 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38354 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38359 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38363 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38366 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38368 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38377 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38381 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38384 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38387 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38392 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +38395 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38398 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38401 INFO org.reflections.Reflections: Reflections took 1 ms to scan 1 urls, producing 1 keys and 8 values +38407 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38412 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38415 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38417 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38431 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38443 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38871 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38875 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38879 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38883 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +38888 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38891 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38894 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38897 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38902 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38905 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38908 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38911 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38930 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38933 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38936 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +38938 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39393 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +39396 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39400 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39402 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39406 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39409 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39412 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39414 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39418 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39421 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39424 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39426 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39433 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39438 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39442 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39447 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39457 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39462 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39464 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39467 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39471 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39475 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39478 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39480 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39486 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +39492 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39496 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39500 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39504 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39507 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39510 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39512 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39521 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +39524 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39527 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39529 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39533 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39536 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39538 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39541 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39547 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +39550 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39553 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39555 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39567 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39571 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39573 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39576 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39910 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39918 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39922 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39926 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39929 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39932 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39934 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39939 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39942 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39945 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39948 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +39963 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39966 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39969 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +39971 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40436 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40440 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40442 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40445 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40449 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40455 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40459 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40463 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40468 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40471 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40475 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40478 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40482 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40488 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +40491 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40494 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40501 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40504 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40506 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40509 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40512 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40516 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40520 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40523 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40527 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40530 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40533 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40535 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40539 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40544 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +40548 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40551 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40563 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +40566 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40568 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40571 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40575 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40578 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40581 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40583 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40588 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40591 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40594 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40597 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40638 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +40641 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40644 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +40646 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41013 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41016 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41019 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41021 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41026 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41029 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41032 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41034 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41040 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41043 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41046 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41048 INFO org.reflections.Reflections: Reflections took 1 ms to scan 1 urls, producing 1 keys and 8 values +41065 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41068 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41071 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41073 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41674 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41677 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41680 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41682 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41688 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +41693 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41696 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41699 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41704 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +41711 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41714 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41717 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41723 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +41727 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41731 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41733 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41741 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41744 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41747 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41749 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41753 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41756 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41759 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41761 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41765 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41768 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41771 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41774 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41779 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41782 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41785 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41787 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41795 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41799 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41802 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41805 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41809 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41812 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41815 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41818 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41825 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41828 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41830 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41833 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41845 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +41848 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41851 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +41853 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42200 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +42226 INFO org.reflections.Reflections: Reflections took 25 ms to scan 1 urls, producing 1 keys and 8 values +42229 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42231 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42235 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42239 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42242 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42244 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42251 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +42255 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42258 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42261 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42280 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +42283 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42286 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42289 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42877 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42881 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42883 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42886 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42889 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42892 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42895 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42897 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42901 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42904 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42907 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42910 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42920 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +42923 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42926 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42940 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42944 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42948 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42950 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42955 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42958 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42960 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42963 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42966 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42969 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42972 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42975 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42978 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42984 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42989 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +42995 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +42998 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43001 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43004 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43007 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43009 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43013 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43016 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43020 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +43023 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43026 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43029 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43033 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43037 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43040 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43043 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43046 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43049 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43053 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43055 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43058 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43075 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43079 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43094 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43098 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43102 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43105 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43109 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43118 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +43126 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values +43130 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43134 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values +43137 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43141 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values +43147 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values +43151 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values 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 393ed31a7..529a4d6cb 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 @@ -4,6 +4,7 @@ import java.io.InputStream; import java.nio.file.Path; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import org.antlr.v4.runtime.BailErrorStrategy; @@ -20,15 +21,16 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.core.externals.Externals; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; public class ProgramParserImpl implements ProgramParser { -// private final Map externals; -// -// // TODO not sure if it makes sense to have this constructor... is it even used? -// public ProgramParserImpl(Map externals) { -// this.externals = externals; -// } + + private final Map preloadedExternals; + + public ProgramParserImpl() { + this.preloadedExternals = Externals.getStandardLibraryExternals(); + } @Override public ASPCore2Program parse(String s) { @@ -114,8 +116,17 @@ public ASPCore2Program parse(CharStream stream, Map knownExternals; + if (externals != null && !externals.isEmpty()) { + knownExternals = new HashMap<>(preloadedExternals); + knownExternals.putAll(externals); + } else { + knownExternals = preloadedExternals; + } + // Construct internal program representation. - ParseTreeVisitor visitor = new ParseTreeVisitor(externals); + ParseTreeVisitor visitor = new ParseTreeVisitor(knownExternals); return visitor.translate(programContext); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java index 303c45bd5..51b76ef80 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraphTest.java @@ -159,7 +159,7 @@ public void stronglyConnectedComponentsSimpleTest() { bld.append("b :- a.").append("\n"); bld.append("a :- b.").append("\n"); - ASPCore2Program prog = parser.parse(bld.toString(), null); + ASPCore2Program prog = parser.parse(bld.toString()); NormalProgram normalProg = normalizeTransform.apply(prog); AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); DependencyGraph dg = analyzed.getDependencyGraph(); 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 index 709c5b904..d2d18c97b 100644 --- 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 @@ -41,7 +41,7 @@ private boolean predicateIsBeforePredicateInOrder(Predicate predBefore, Predicat @Test public void stratifyOneRuleTest() { - ASPCore2Program prog = parser.parse("a :- b.", null); + ASPCore2Program prog = parser.parse("a :- b."); NormalProgram normalProg = normalizeTransform.apply(prog); AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalProg); DependencyGraph dg = analyzed.getDependencyGraph(); 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 b7040e817..b60b7082f 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 @@ -28,17 +28,17 @@ package at.ac.tuwien.kr.alpha.api.impl; import java.io.IOException; -import java.nio.charset.CodingErrorAction; +import java.io.InputStream; +import java.nio.channels.Channels; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,6 +55,7 @@ import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.core.common.AtomStore; @@ -74,6 +75,7 @@ public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); private SystemConfig config = new SystemConfig(); // The config is initialized with default values. + private ProgramParser parser = new ProgramParserImpl(); public AlphaImpl(SystemConfig cfg) { this.config = cfg; @@ -104,15 +106,14 @@ public ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - ProgramParserImpl parser = new ProgramParserImpl(); InputProgram.Builder prgBuilder = InputProgram.builder(); ASPCore2Program tmpProg; for (Path path : paths) { - CharStream stream; + InputStream stream; if (!literate) { - stream = CharStreams.fromPath(path); + stream = Files.newInputStream(path); } else { - stream = CharStreams.fromChannel(Util.streamToChannel(Util.literate(Files.lines(path))), 4096, CodingErrorAction.REPLACE, path.toString()); + stream = Channels.newInputStream(Util.streamToChannel(Util.literate(Files.lines(path)))); } tmpProg = parser.parse(stream, externals); prgBuilder.accumulate(tmpProg); @@ -122,13 +123,12 @@ public ASPCore2Program readProgramFiles(boolean literate, Map externals) { - ProgramParserImpl parser = new ProgramParserImpl(); return parser.parse(aspString, externals); } @Override public ASPCore2Program readProgramString(String aspString) { - return readProgramString(aspString, null); + return readProgramString(aspString, Collections.emptyMap()); } // TODO make sure to adapt this without exposing internal imnplementation types diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java index 2ac8e747f..2892d1d69 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java @@ -477,7 +477,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, null); + ASPCore2Program prog = system.readProgramString(progstr); Set actual = system.solve(prog, (p) -> p.equals(CorePredicate.getInstance("a", 0)) || p.equals(CorePredicate.getInstance("e", 2))) .collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").predicate("e").symbolicInstance("a", "b").build())); diff --git a/alpha-solver/src/test/resources/HanoiTower_Alpha.asp b/alpha-solver/src/test/resources/HanoiTower_Alpha.asp new file mode 100644 index 000000000..922962744 --- /dev/null +++ b/alpha-solver/src/test/resources/HanoiTower_Alpha.asp @@ -0,0 +1,98 @@ +% HanoiTower +% Source: ASP Competition 2013 Official (disjunction shifted by ASP Shifter) +% ADAPTIONS FOR ALPHA: +% - replaced "TP1 = T + 1" by "succ(T,TP1)" because arithmetics are not supported +% - replaced "TM1 = T - 1" by "succ(TM1,T)" for the same reason + +peg(1). +peg(2). +peg(3). +peg(4). + +% Read in data +on(0, N1, N) :- on0(N, N1). +onG(K, N1, N) :- ongoal(N, N1), steps(K). + +% Specify valid arrangements of disks +% Basic condition. Smaller disks are on larger ones +:- time(T), on(T, N1, N), N1 >= N. + +% Specify a valid move (only for T Date: Tue, 16 Feb 2021 14:33:58 +0100 Subject: [PATCH 024/111] WIP: deploy jar files to local maven cache --- alpha-api/build.gradle | 18 +- .../kr/alpha/api/externals/Predicate.java | 12 +- .../GrounderHeuristicsConfiguration.java | 5 +- alpha-cli-app/build.gradle | 17 + alpha-core/build.gradle | 16 + alpha-core/junit.log | 1638 ----------------- alpha-solver/build.gradle | 17 + .../alpha.java-common-conventions.gradle | 2 +- junit.log | 82 + 9 files changed, 161 insertions(+), 1646 deletions(-) delete mode 100644 alpha-core/junit.log create mode 100644 junit.log diff --git a/alpha-api/build.gradle b/alpha-api/build.gradle index 130db84b2..c89678ddc 100644 --- a/alpha-api/build.gradle +++ b/alpha-api/build.gradle @@ -1,5 +1,6 @@ plugins { - id 'alpha.java-library-conventions' + id 'alpha.java-library-conventions' + id 'maven-publish' } dependencies { @@ -11,3 +12,18 @@ dependencies { testImplementation group: 'junit', name: 'junit', version: '4.12' } +java { + withSourcesJar() +} + +publishing { + publications { + maven(MavenPublication) { + groupId = 'at.ac.tuwien.kr.alpha' + artifactId = 'alpha-api' + version = '0.8-SNAPSHOT' + + from components.java + } + } +} \ No newline at end of file diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java index 928f2cf99..2b1b974c3 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/externals/Predicate.java @@ -5,15 +5,17 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** - * This annotation is used for discovery of method that represent - * external predicates at runtime. - * - * In order to have your method detected by Alpha, annotate it +/* TODO this should be javadoc, but has a problem with the ref to Externals + * * In order to have your method detected by Alpha, annotate it * with this annotation and call {@link Externals#scan}. * * @see Externals#scan */ + +/** + * This annotation is used for discovery of method that represent + * external predicates at runtime. + */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Predicate { diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/heuristics/GrounderHeuristicsConfiguration.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/heuristics/GrounderHeuristicsConfiguration.java index dec9e7334..a4012ed4e 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/heuristics/GrounderHeuristicsConfiguration.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/heuristics/GrounderHeuristicsConfiguration.java @@ -25,8 +25,11 @@ */ package at.ac.tuwien.kr.alpha.api.grounder.heuristics; +/* TODO this should be javadoc but has a problem with the ref to a component from core module: +* Contains configuration parameters for heuristics used by {@link at.ac.tuwien.kr.alpha.grounder.Grounder}s. +*/ + /** - * Contains configuration parameters for heuristics used by {@link at.ac.tuwien.kr.alpha.grounder.Grounder}s. * * Both parameters {@link #toleranceConstraints} and {@link #toleranceRules} are interpreted as follows: * A rule (or constraint) is grounded if the following conditions are satisfied: diff --git a/alpha-cli-app/build.gradle b/alpha-cli-app/build.gradle index 19907f7ce..a22d50f3c 100644 --- a/alpha-cli-app/build.gradle +++ b/alpha-cli-app/build.gradle @@ -1,5 +1,6 @@ plugins { id 'alpha.java-application-conventions' + id 'maven-publish' } dependencies { @@ -42,3 +43,19 @@ task bundledJar(type: Jar) { with jar } + +java { + withSourcesJar() +} + +publishing { + publications { + maven(MavenPublication) { + groupId = 'at.ac.tuwien.kr.alpha' + artifactId = 'alpha-cli-app' + version = '0.8-SNAPSHOT' + + from components.java + } + } +} diff --git a/alpha-core/build.gradle b/alpha-core/build.gradle index 9cdcf3d0b..5869bb4c9 100644 --- a/alpha-core/build.gradle +++ b/alpha-core/build.gradle @@ -1,6 +1,7 @@ plugins { id 'antlr' id 'alpha.java-library-conventions' + id 'maven-publish' } @@ -57,3 +58,18 @@ jacocoTestReport { } } +java { + withSourcesJar() +} + +publishing { + publications { + maven(MavenPublication) { + groupId = 'at.ac.tuwien.kr.alpha' + artifactId = 'alpha-core' + version = '0.8-SNAPSHOT' + + from components.java + } + } +} diff --git a/alpha-core/junit.log b/alpha-core/junit.log deleted file mode 100644 index 7ce55a609..000000000 --- a/alpha-core/junit.log +++ /dev/null @@ -1,1638 +0,0 @@ -880 INFO org.reflections.Reflections: Reflections took 183 ms to scan 1 urls, producing 1 keys and 8 values -1456 INFO org.reflections.Reflections: Reflections took 9 ms to scan 1 urls, producing 1 keys and 8 values -1539 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -1580 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values -1615 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values -1649 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values -1698 INFO org.reflections.Reflections: Reflections took 18 ms to scan 1 urls, producing 1 keys and 8 values -1730 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values -1757 INFO org.reflections.Reflections: Reflections took 10 ms to scan 1 urls, producing 1 keys and 8 values -1791 INFO org.reflections.Reflections: Reflections took 14 ms to scan 1 urls, producing 1 keys and 8 values -1811 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -1839 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -1863 INFO org.reflections.Reflections: Reflections took 13 ms to scan 1 urls, producing 1 keys and 8 values -1873 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -1880 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -1890 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -1899 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -1912 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -1925 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -1943 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -1950 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -1962 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2066 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2080 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2088 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2182 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2188 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2193 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2199 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2206 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2211 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2222 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2229 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2236 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2241 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2250 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2257 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2261 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2269 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2283 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -2290 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -2299 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2316 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2335 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2362 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2469 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2484 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2493 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -2513 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2529 INFO org.reflections.Reflections: Reflections took 12 ms to scan 1 urls, producing 1 keys and 8 values -2537 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2543 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2554 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2557 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -2598 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2605 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2609 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2626 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -2643 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2647 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2652 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2657 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2664 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2670 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2727 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2733 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2738 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2745 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2751 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2756 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2762 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2768 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2774 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2782 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2789 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2794 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2807 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2813 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2820 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -2830 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2835 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2841 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2846 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2852 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2857 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2864 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2881 INFO org.reflections.Reflections: Reflections took 15 ms to scan 1 urls, producing 1 keys and 8 values -2886 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2892 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2898 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2903 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2911 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2916 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2923 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -2929 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2935 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2940 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2952 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2959 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2965 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2980 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -2987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2991 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -2998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3004 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3008 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3015 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3024 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -3029 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3049 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3054 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3060 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3065 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3070 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3075 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3081 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3086 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3099 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3108 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3112 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3121 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3125 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3133 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3138 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3144 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3149 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3157 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3161 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3169 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3173 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3180 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3185 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3191 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3195 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3207 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3213 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3218 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3225 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3229 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3236 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3241 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3247 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3252 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3258 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3263 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3269 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3274 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3283 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3287 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3293 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3298 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3305 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3310 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3318 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3335 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3341 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3346 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3351 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3355 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3361 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3366 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3372 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3377 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3385 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -3390 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3394 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3398 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3406 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -3409 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -3418 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3425 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -3438 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3442 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3445 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -3480 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3499 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3504 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3623 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -3636 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3641 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3758 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3766 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3770 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3855 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3862 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3867 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3969 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -3975 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3980 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -3993 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4006 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4011 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4016 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4028 INFO org.reflections.Reflections: Reflections took 11 ms to scan 1 urls, producing 1 keys and 8 values -4034 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4039 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4043 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4050 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4055 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4060 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4064 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4069 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4075 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4079 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4090 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4095 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4100 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4104 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4109 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4115 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4120 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4125 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4130 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4136 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4141 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4145 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4151 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4167 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4181 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4186 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4200 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4205 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4210 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4215 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4267 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4287 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4295 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4299 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4311 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4316 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4322 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4326 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4386 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4395 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4401 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4408 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -4424 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -4429 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4435 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4439 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4502 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4515 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4522 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -4527 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4540 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4546 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4551 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4556 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4616 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4625 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4629 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4635 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4640 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4645 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4667 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4672 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4676 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4681 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4686 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4691 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4698 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4704 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4710 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -4715 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4723 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -4727 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4734 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4739 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4743 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4749 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4756 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4760 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4766 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4772 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4776 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4782 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4787 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4790 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -4795 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4798 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -4801 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -4807 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4815 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4821 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4825 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4829 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -4832 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -4836 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4841 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4846 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4851 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4919 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4927 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4931 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4936 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4941 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4944 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4954 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4958 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4962 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -4967 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4973 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -4977 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4982 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4986 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4989 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -4997 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5001 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5004 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5013 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5019 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5026 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5034 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -5041 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5045 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5058 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5064 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5068 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5074 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5080 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5093 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5098 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5102 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5111 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5116 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5121 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5126 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5131 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5135 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5141 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5146 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5150 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5157 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5163 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5167 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5177 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5181 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5187 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5195 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5199 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5205 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5211 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5215 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5222 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5226 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5230 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5235 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5240 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5244 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5250 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5255 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5259 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5269 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5274 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5279 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5286 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -5291 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5294 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5297 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5313 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5317 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5322 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5328 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5333 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5338 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5348 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5398 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5403 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5407 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5412 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5416 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5421 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5426 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5429 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5432 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5440 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5443 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5446 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5456 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5463 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5468 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5475 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5479 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5482 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5502 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5507 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5512 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5516 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5522 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -5525 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5530 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5535 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5539 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5544 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5549 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5553 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5559 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5564 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5567 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5571 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5576 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5579 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5584 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5587 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5590 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5594 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5598 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5600 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5606 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5610 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5614 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5621 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5627 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5631 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5636 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5643 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5647 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5651 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5657 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5662 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5666 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5724 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -5727 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5730 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5734 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5738 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5741 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5747 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5750 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5753 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5756 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5760 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5763 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5767 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5770 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5773 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5779 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -5785 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5788 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5792 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5796 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5799 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5804 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5809 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5813 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5819 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5823 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5826 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5830 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5833 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5836 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5840 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5843 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5846 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5851 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5855 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5858 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5862 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5866 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5869 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5873 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5877 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5880 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5885 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5888 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5891 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5896 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5899 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5902 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5906 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5909 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5913 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5918 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5924 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5927 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5931 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5934 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5937 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5942 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5947 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5950 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5955 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5959 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5962 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -5969 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5973 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5978 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5982 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -5987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5991 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -5994 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6006 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6009 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6013 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6021 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6026 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6032 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6044 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6082 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6087 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6094 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -6101 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -6106 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6110 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6114 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6117 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6144 INFO org.reflections.Reflections: Reflections took 15 ms to scan 1 urls, producing 1 keys and 8 values -6167 INFO org.reflections.Reflections: Reflections took 18 ms to scan 1 urls, producing 1 keys and 8 values -6183 INFO org.reflections.Reflections: Reflections took 15 ms to scan 1 urls, producing 1 keys and 8 values -6187 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6218 INFO org.reflections.Reflections: Reflections took 9 ms to scan 1 urls, producing 1 keys and 8 values -6222 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6232 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6246 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6254 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -6258 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6301 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6307 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6310 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6316 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6322 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6326 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6338 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -6358 INFO org.reflections.Reflections: Reflections took 18 ms to scan 1 urls, producing 1 keys and 8 values -6369 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6377 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -6384 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6389 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6395 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6399 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6403 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6409 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6413 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6416 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6421 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6425 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6428 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6432 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6436 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6443 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6446 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6450 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6455 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6466 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -6473 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6476 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6482 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6489 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -6492 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6496 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6502 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6506 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6555 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6560 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6564 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6568 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6573 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6586 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6591 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6594 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6599 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6604 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6607 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6612 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6617 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6621 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6627 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6631 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6635 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6642 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6647 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6651 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6656 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6660 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6664 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6669 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6673 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6677 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6682 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6686 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6696 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6701 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6706 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6711 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6720 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6726 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6730 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6734 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6739 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6743 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6748 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6752 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6756 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6764 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6768 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6772 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6776 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6783 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -6786 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -6792 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6797 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6800 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6806 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6811 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6815 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6821 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6826 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -6829 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6834 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6839 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6843 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6848 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6852 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6856 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6865 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6869 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6873 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6877 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6883 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6888 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6892 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6910 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6919 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6929 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6934 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6939 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6947 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -6998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7003 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7007 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7012 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7017 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7023 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7028 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7033 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7037 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7044 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7049 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7053 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7062 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7066 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7070 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7075 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7080 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7102 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7106 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7110 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7114 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7119 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7123 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7129 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7133 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7137 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7141 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7146 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7150 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7155 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7160 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7163 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7166 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7171 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7175 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7181 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7185 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7189 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7194 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7198 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7208 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7213 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7217 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7222 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7227 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7231 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7236 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7241 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7246 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7250 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7256 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7260 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7264 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7306 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7310 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7314 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7319 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7323 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7331 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7335 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7339 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7344 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7348 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7351 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7354 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7359 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7362 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7367 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7372 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7376 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7383 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7388 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7392 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7397 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7401 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7406 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7411 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7417 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7422 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7427 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7431 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7440 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7444 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7448 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7455 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7459 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7463 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7469 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7473 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7478 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7482 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7488 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7491 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7498 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7501 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7504 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7509 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7513 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7516 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7522 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7527 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7531 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7536 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7541 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7544 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7549 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7555 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7559 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7563 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7567 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7572 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7581 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7584 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7599 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7603 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7608 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7612 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7618 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7623 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7625 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7637 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7642 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7646 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7654 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7659 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7664 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7671 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7713 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -7719 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -7724 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -7729 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7734 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7737 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7743 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7747 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7749 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -7761 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7765 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7770 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7846 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7853 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7857 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7861 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7901 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7912 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7916 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7922 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -7939 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -7945 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7949 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7956 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -7986 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -7990 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7995 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -7999 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8016 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -8021 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -8024 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -8026 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -8059 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8065 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8069 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8073 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8101 INFO org.reflections.Reflections: Reflections took 14 ms to scan 1 urls, producing 1 keys and 8 values -8106 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8111 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -8114 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8146 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8154 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -8160 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -8163 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8209 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -8218 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8223 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -8227 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -8230 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -8233 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -8249 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -8253 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -9333 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.077s: 148 -9339 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 148 decisions in 1.077s or 137.41875 decisions per sec. Overall replayed assignments: 787. -9770 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -9772 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -9776 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -9787 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -9790 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -10800 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.007s: 160 -10800 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 160 decisions in 1.007s or 158.88779 decisions per sec. Overall replayed assignments: 907. -11021 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11025 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11028 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11040 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -11044 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11046 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11051 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11054 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11057 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11062 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11065 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11067 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11076 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11080 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11084 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11091 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11548 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11553 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11557 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11562 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11581 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11586 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -11599 INFO org.reflections.Reflections: Reflections took 10 ms to scan 1 urls, producing 1 keys and 8 values -11609 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11613 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11618 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11624 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11641 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -11645 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11649 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11653 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11662 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -11666 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11670 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11677 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11712 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11721 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -11726 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -11731 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11797 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11802 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11806 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -11810 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11854 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11859 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11863 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11869 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11881 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11885 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11889 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11893 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11900 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11904 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11909 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -11915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12369 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -12374 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12378 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12384 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12405 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12410 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12415 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12423 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12433 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12440 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -12445 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12454 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12475 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12480 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12484 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12498 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12508 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12513 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12519 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12527 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12569 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12574 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12582 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12653 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12658 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12662 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12671 INFO org.reflections.Reflections: Reflections took 8 ms to scan 1 urls, producing 1 keys and 8 values -12732 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12737 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12741 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12748 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -12760 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12764 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12768 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12772 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12779 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12783 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12788 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -12797 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13206 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13211 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13214 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13219 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13240 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13244 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13249 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13258 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13266 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13270 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13275 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13282 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -13298 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13306 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13311 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -13320 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13324 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13329 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13336 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13366 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13371 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -13375 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13379 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13443 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13447 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13491 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13495 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13500 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13506 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13517 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13523 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -13526 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -13531 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13537 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13543 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -13549 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13555 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13944 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -13948 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13952 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13956 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13974 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13978 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13982 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13989 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -13998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14002 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14007 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14015 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -14030 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14034 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14038 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14042 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14051 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14056 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14060 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14067 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14101 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14106 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14109 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14115 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14167 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14176 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14180 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14231 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14236 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14240 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14247 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14259 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14264 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14267 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14271 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14287 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14292 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14297 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14350 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14354 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14358 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14362 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14377 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14385 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14390 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14394 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14402 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14408 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14412 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14417 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14427 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14431 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14448 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14453 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14457 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14464 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -14483 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14486 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -14490 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14495 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14550 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14554 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14558 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14562 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14605 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14609 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -14616 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -14623 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14629 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14634 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14638 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14641 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14648 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14652 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14657 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14661 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14710 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14715 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14719 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14724 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14740 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14744 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14747 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14751 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14757 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14761 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14765 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14769 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14777 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14781 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14785 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14789 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14803 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -14807 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14812 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14816 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14833 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14838 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14841 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14846 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14892 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14896 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14900 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14904 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14946 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14950 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14954 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14958 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14964 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14968 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14972 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14975 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -14982 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14991 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -14995 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15039 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15047 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -15050 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15054 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15069 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15072 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15076 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15080 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15085 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15089 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15094 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15098 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15104 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15108 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15112 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15116 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15124 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15128 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15132 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15136 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15150 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15154 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15157 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15161 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15202 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15206 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15209 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15214 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15252 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15256 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15260 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15264 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15270 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15274 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15278 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15282 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15288 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15294 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15300 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15304 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15350 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15354 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15357 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15362 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15378 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15385 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -15390 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15397 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -15407 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15411 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15416 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15421 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15429 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15433 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15437 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15441 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15449 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15453 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15459 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -15466 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15482 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15487 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15491 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15496 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15540 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15548 INFO org.reflections.Reflections: Reflections took 7 ms to scan 1 urls, producing 1 keys and 8 values -15553 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15557 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15598 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15602 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15606 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15611 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15618 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15624 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15628 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15632 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15643 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15649 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -15654 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15658 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15664 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15671 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15675 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -15679 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15682 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15699 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -15704 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15708 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15712 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15719 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -15723 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15727 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15729 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15844 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15848 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -15851 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -16583 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16588 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16592 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16614 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16619 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16624 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16720 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16725 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16731 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -16972 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16976 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16980 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16993 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -16998 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -17001 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -17033 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -17039 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -17043 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -17190 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -17196 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -17199 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18014 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18019 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -18022 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18045 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18052 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18055 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18136 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18141 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18145 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18389 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18397 INFO org.reflections.Reflections: Reflections took 6 ms to scan 1 urls, producing 1 keys and 8 values -18400 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18413 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18419 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18423 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18469 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -18476 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -18480 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18500 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -18505 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18509 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18595 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18600 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18643 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -18646 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -19512 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -19569 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -19573 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -20636 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.059s: 1 -20637 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.059s or 0.94428706 decisions per sec. Overall replayed assignments: 0. -20842 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -20846 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -20849 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -20865 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -20870 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -20872 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -20922 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -20926 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -20950 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -20953 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -21508 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -21564 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -21567 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22618 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22624 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22627 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22637 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22642 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -22645 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22717 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22951 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -22954 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -23972 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.004s: 0 -23972 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.004s or 0.0 decisions per sec. Overall replayed assignments: 0. -24977 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.005s: 0 -24977 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.009s or 0.0 decisions per sec. Overall replayed assignments: 0. -25979 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.002s: 0 -25979 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.011s or 0.0 decisions per sec. Overall replayed assignments: 0. -27003 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.024s: 0 -27003 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.035s or 0.0 decisions per sec. Overall replayed assignments: 0. -28003 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.0s: 0 -28004 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.035s or 0.0 decisions per sec. Overall replayed assignments: 0. -28542 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -28573 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -28577 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -29317 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -29390 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -29394 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -30459 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.059s: 1 -30459 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 1 decisions in 1.059s or 0.94428706 decisions per sec. Overall replayed assignments: 0. -30759 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -30763 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -30767 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -30778 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -30783 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -30786 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -30833 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -31042 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -31045 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -32066 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.009s: 0 -32066 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 1.009s or 0.0 decisions per sec. Overall replayed assignments: 0. -33097 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.031s: 0 -33097 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 2.04s or 0.0 decisions per sec. Overall replayed assignments: 0. -34140 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.043s: 0 -34141 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 3.083s or 0.0 decisions per sec. Overall replayed assignments: 0. -35171 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.031s: 0 -35171 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 4.114s or 0.0 decisions per sec. Overall replayed assignments: 0. -36188 INFO a.a.t.k.a.core.solver.DefaultSolver: Decisions in 1.017s: 0 -36188 INFO a.a.t.k.a.core.solver.DefaultSolver: Overall performance: 0 decisions in 5.131s or 0.0 decisions per sec. Overall replayed assignments: 0. -36369 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -36455 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -36461 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -37047 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -37081 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -37085 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38172 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38175 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38178 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38180 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38185 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38189 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38192 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38194 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38200 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38203 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38206 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38208 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38214 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -38218 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38221 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38224 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38253 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38257 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38261 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38264 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38268 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38272 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38276 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38279 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38283 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38287 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38290 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38294 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38298 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38302 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38305 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38309 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38318 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38323 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38327 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38331 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38334 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38337 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38340 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38343 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38346 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38349 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38352 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38354 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38359 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38363 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38366 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38368 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38377 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38381 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38384 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38387 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38392 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -38395 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38398 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38401 INFO org.reflections.Reflections: Reflections took 1 ms to scan 1 urls, producing 1 keys and 8 values -38407 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38412 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38415 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38417 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38431 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38435 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38439 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38443 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38871 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38875 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38879 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38883 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -38888 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38891 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38894 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38897 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38902 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38905 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38908 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38911 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38930 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38933 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38936 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -38938 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39393 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -39396 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39400 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39402 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39406 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39409 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39412 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39414 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39418 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39421 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39424 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39426 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39433 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39438 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39442 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39447 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39457 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39462 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39464 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39467 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39471 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39475 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39478 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39480 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39486 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -39492 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39496 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39500 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39504 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39507 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39510 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39512 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39521 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -39524 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39527 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39529 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39533 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39536 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39538 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39541 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39547 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -39550 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39553 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39555 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39567 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39571 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39573 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39576 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39910 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39918 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39922 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39926 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39929 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39932 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39934 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39939 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39942 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39945 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39948 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -39963 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39966 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39969 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -39971 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40436 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40440 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40442 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40445 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40449 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40455 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40459 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40463 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40468 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40471 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40475 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40478 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40482 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40488 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -40491 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40494 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40501 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40504 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40506 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40509 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40512 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40516 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40520 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40523 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40527 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40530 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40533 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40535 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40539 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40544 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -40548 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40551 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40563 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -40566 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40568 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40571 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40575 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40578 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40581 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40583 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40588 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40591 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40594 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40597 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40638 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -40641 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40644 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -40646 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41013 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41016 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41019 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41021 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41026 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41029 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41032 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41034 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41040 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41043 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41046 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41048 INFO org.reflections.Reflections: Reflections took 1 ms to scan 1 urls, producing 1 keys and 8 values -41065 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41068 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41071 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41073 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41674 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41677 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41680 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41682 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41688 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -41693 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41696 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41699 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41704 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -41711 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41714 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41717 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41723 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -41727 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41731 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41733 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41741 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41744 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41747 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41749 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41753 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41756 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41759 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41761 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41765 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41768 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41771 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41774 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41779 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41782 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41785 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41787 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41795 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41799 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41802 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41805 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41809 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41812 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41815 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41818 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41825 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41828 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41830 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41833 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41845 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -41848 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41851 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -41853 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42200 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -42226 INFO org.reflections.Reflections: Reflections took 25 ms to scan 1 urls, producing 1 keys and 8 values -42229 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42231 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42235 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42239 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42242 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42244 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42251 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -42255 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42258 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42261 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42280 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -42283 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42286 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42289 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42877 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42881 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42883 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42886 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42889 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42892 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42895 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42897 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42901 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42904 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42907 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42910 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42915 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42920 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -42923 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42926 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42940 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42944 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42948 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42950 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42955 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42958 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42960 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42963 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42966 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42969 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42972 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42975 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42978 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42984 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42987 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42989 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -42995 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -42998 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43001 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43004 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43007 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43009 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43013 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43016 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43020 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -43023 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43026 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43029 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43033 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43037 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43040 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43043 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43046 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43049 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43053 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43055 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43058 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43075 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43079 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43084 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43094 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43098 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43102 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43105 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43109 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43118 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -43126 INFO org.reflections.Reflections: Reflections took 5 ms to scan 1 urls, producing 1 keys and 8 values -43130 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43134 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values -43137 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43141 INFO org.reflections.Reflections: Reflections took 2 ms to scan 1 urls, producing 1 keys and 8 values -43147 INFO org.reflections.Reflections: Reflections took 4 ms to scan 1 urls, producing 1 keys and 8 values -43151 INFO org.reflections.Reflections: Reflections took 3 ms to scan 1 urls, producing 1 keys and 8 values diff --git a/alpha-solver/build.gradle b/alpha-solver/build.gradle index ca47985af..86c0c006f 100644 --- a/alpha-solver/build.gradle +++ b/alpha-solver/build.gradle @@ -1,5 +1,6 @@ plugins { id 'alpha.java-library-conventions' + id 'maven-publish' } dependencies { @@ -11,3 +12,19 @@ dependencies { } +java { + withSourcesJar() +} + +publishing { + publications { + maven(MavenPublication) { + groupId = 'at.ac.tuwien.kr.alpha' + artifactId = 'alpha-solver' + version = '0.8-SNAPSHOT' + + from components.java + } + } +} + diff --git a/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle b/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle index e8efe3857..dbf9c1af5 100644 --- a/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle +++ b/buildSrc/src/main/groovy/alpha.java-common-conventions.gradle @@ -14,7 +14,7 @@ targetCompatibility = 1.8 dependencies { implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.1' - implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3' + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.9' implementation group: 'org.apache.commons', name: 'commons-text', version: '1.8' implementation group: 'org.reflections', name: 'reflections', version: '0.9.11' implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.20' diff --git a/junit.log b/junit.log new file mode 100644 index 000000000..a23dc718b --- /dev/null +++ b/junit.log @@ -0,0 +1,82 @@ +653 INFO org.reflections.Reflections: Reflections took 100 ms to scan 2 urls, producing 2 keys and 19 values +1096 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values +1107 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1119 INFO org.reflections.Reflections: Reflections took 6 ms to scan 2 urls, producing 2 keys and 19 values +1129 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1145 INFO org.reflections.Reflections: Reflections took 10 ms to scan 2 urls, producing 2 keys and 19 values +1160 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values +1175 INFO org.reflections.Reflections: Reflections took 8 ms to scan 2 urls, producing 2 keys and 19 values +1198 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values +1213 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values +1222 INFO org.reflections.Reflections: Reflections took 6 ms to scan 2 urls, producing 2 keys and 19 values +1230 INFO org.reflections.Reflections: Reflections took 6 ms to scan 2 urls, producing 2 keys and 19 values +1238 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1245 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +1252 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +1260 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1268 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1279 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1286 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1293 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1300 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +1349 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +1356 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +1365 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values +1372 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +1941 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values +3868 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.0s: 208 +3872 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 208 decisions in 1.0s or 208.0 decisions per sec. Overall replayed assignments: 551. +4868 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.0s: 24 +4868 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 232 decisions in 2.0s or 116.0 decisions per sec. Overall replayed assignments: 714. +6736 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.097s: 208 +6736 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 208 decisions in 1.097s or 189.60802 decisions per sec. Overall replayed assignments: 567. +7773 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.037s: 29 +7773 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 237 decisions in 2.134s or 111.059044 decisions per sec. Overall replayed assignments: 720. +9329 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.077s: 206 +9330 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 206 decisions in 1.077s or 191.27205 decisions per sec. Overall replayed assignments: 520. +10367 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.038s: 31 +10368 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 237 decisions in 2.115s or 112.05674 decisions per sec. Overall replayed assignments: 720. +11740 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.022s: 221 +11740 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 221 decisions in 1.022s or 216.24268 decisions per sec. Overall replayed assignments: 692. +20601 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.048s: 1 +20602 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 1 decisions in 1.048s or 0.9541985 decisions per sec. Overall replayed assignments: 0. +22781 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.059s: 1 +22781 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 1 decisions in 1.059s or 0.94428706 decisions per sec. Overall replayed assignments: 0. +24657 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.016s: 0 +24657 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 1.016s or 0.0 decisions per sec. Overall replayed assignments: 0. +25660 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.003s: 0 +25660 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 2.019s or 0.0 decisions per sec. Overall replayed assignments: 0. +26673 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.013s: 0 +26674 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 3.032s or 0.0 decisions per sec. Overall replayed assignments: 0. +27700 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.027s: 0 +27701 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 4.059s or 0.0 decisions per sec. Overall replayed assignments: 0. +28752 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.052s: 0 +28753 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 5.111s or 0.0 decisions per sec. Overall replayed assignments: 0. +32004 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.011s: 0 +32005 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 1.011s or 0.0 decisions per sec. Overall replayed assignments: 0. +33030 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.026s: 0 +33030 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 2.037s or 0.0 decisions per sec. Overall replayed assignments: 0. +34054 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.024s: 0 +34055 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 3.061s or 0.0 decisions per sec. Overall replayed assignments: 0. +35067 INFO a.a.t.kr.alpha.solver.DefaultSolver: Decisions in 1.012s: 0 +35067 INFO a.a.t.kr.alpha.solver.DefaultSolver: Overall performance: 0 decisions in 4.073s or 0.0 decisions per sec. Overall replayed assignments: 0. +51213 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51228 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +51249 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +51492 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +51502 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51511 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51519 INFO org.reflections.Reflections: Reflections took 6 ms to scan 2 urls, producing 2 keys and 19 values +51526 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51533 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51540 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51549 INFO org.reflections.Reflections: Reflections took 6 ms to scan 2 urls, producing 2 keys and 19 values +51556 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +51644 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51652 INFO org.reflections.Reflections: Reflections took 5 ms to scan 2 urls, producing 2 keys and 19 values +51662 INFO org.reflections.Reflections: Reflections took 6 ms to scan 2 urls, producing 2 keys and 19 values +51986 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values +51993 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +52002 INFO org.reflections.Reflections: Reflections took 4 ms to scan 2 urls, producing 2 keys and 19 values +52368 INFO org.reflections.Reflections: Reflections took 6 ms to scan 2 urls, producing 2 keys and 19 values +52378 INFO org.reflections.Reflections: Reflections took 7 ms to scan 2 urls, producing 2 keys and 19 values From 6ef295ee6c7af22c36bb3b973ebc6a5a097ff343 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 16 Feb 2021 14:34:29 +0100 Subject: [PATCH 025/111] ignore junit log --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index da0daf5a0..7c48f18f6 100644 --- a/.gitignore +++ b/.gitignore @@ -98,7 +98,7 @@ gradle-app.setting ### Custom additions ### /.checkstyle -/junit.log +*/junit.log .idea/modules/*.iml *.tokens /.dbeaver From 3000fdeda503c455cd1f1a5526506c8c0cfdd1a9 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Wed, 17 Feb 2021 12:22:31 +0100 Subject: [PATCH 026/111] new module alpha-commons --- alpha-commons/build.gradle | 29 +++++++++++++++++++ .../kr/alpha/core/atoms/AggregateAtom.java | 2 +- .../kr/alpha/core/atoms/AggregateLiteral.java | 2 +- settings.gradle | 2 +- 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 alpha-commons/build.gradle diff --git a/alpha-commons/build.gradle b/alpha-commons/build.gradle new file mode 100644 index 000000000..d1681b318 --- /dev/null +++ b/alpha-commons/build.gradle @@ -0,0 +1,29 @@ +plugins { + id 'alpha.java-library-conventions' + id 'maven-publish' +} + +dependencies { + + api project(":alpha-api") + + testImplementation group: 'junit', name: 'junit', version: '4.12' + +} + +java { + withSourcesJar() +} + +publishing { + publications { + maven(MavenPublication) { + groupId = 'at.ac.tuwien.kr.alpha' + artifactId = 'alpha-commons' + version = '0.8-SNAPSHOT' + + from components.java + } + } +} + diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index 736f6c366..79d045501 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -114,7 +114,7 @@ public List getAggregateVariables() { @Override public AggregateAtom substitute(Substitution substitution) { - return null; + throw new UnsupportedOperationException("Cannot substitute AggregateAtom!"); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index 74f8d48cb..dece62fb0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -19,7 +19,7 @@ public AggregateLiteral(AggregateAtom atom, boolean positive) { @Override public AggregateAtom getAtom() { - return (AggregateAtom)atom; + return (AggregateAtom) atom; } @Override diff --git a/settings.gradle b/settings.gradle index 8058001c5..19b643406 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ rootProject.name = "alpha" -include("alpha-api", "alpha-cli-app", "alpha-core", "alpha-solver") +include("alpha-api", "alpha-cli-app", "alpha-core", "alpha-solver", "alpha-commons") From 9c5733962dae227648ab23330ec87083056b9f23 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 23 Feb 2021 11:27:59 +0100 Subject: [PATCH 027/111] WIP: move terms to commons module --- .../kr/alpha/api/terms/FunctionTerm.java | 5 ++ .../tuwien/kr/alpha/commons/AbstractTerm.java | 19 ++++--- .../kr/alpha/commons}/ArithmeticTerm.java | 10 ++-- .../kr/alpha/commons/ConstantTermImpl.java | 30 +++++------ .../kr/alpha/commons/FunctionTermImpl.java | 31 +++++------ .../kr/alpha/commons}/IntervalTerm.java | 14 ++--- .../at/ac/tuwien/kr/alpha/commons}/Terms.java | 28 +++++++--- .../kr/alpha/commons}/VariableTermImpl.java | 10 ++-- .../alpha/commons/util}/IntIdGenerator.java | 2 +- .../kr/alpha/commons/util}/Interner.java | 2 +- .../ac/tuwien/kr/alpha/commons}/TermTest.java | 34 ++++++------ .../ac/tuwien/kr/alpha/commons/TermsTest.java | 32 +++++++++++ .../kr/alpha/commons}/TestMinusTerm.java | 10 ++-- alpha-core/build.gradle | 3 +- .../kr/alpha/core/atoms/AggregateAtom.java | 2 +- .../kr/alpha/core/atoms/AggregateLiteral.java | 2 +- .../tuwien/kr/alpha/core/atoms/BasicAtom.java | 2 +- .../kr/alpha/core/atoms/ChoiceAtom.java | 4 +- .../kr/alpha/core/atoms/ComparisonAtom.java | 2 +- .../alpha/core/atoms/ComparisonLiteral.java | 12 ++--- .../tuwien/kr/alpha/core/atoms/CoreAtom.java | 2 +- .../kr/alpha/core/atoms/EnumerationAtom.java | 6 +-- .../alpha/core/atoms/EnumerationLiteral.java | 2 +- .../kr/alpha/core/atoms/ExternalAtom.java | 2 +- .../kr/alpha/core/atoms/ExternalLiteral.java | 2 +- .../kr/alpha/core/atoms/IntervalAtom.java | 4 +- .../kr/alpha/core/atoms/IntervalLiteral.java | 11 ++-- .../tuwien/kr/alpha/core/atoms/RuleAtom.java | 7 ++- .../alpha/core/common/AnswerSetBuilder.java | 6 +-- .../kr/alpha/core/common/AtomStoreImpl.java | 2 +- .../kr/alpha/core/common/CorePredicate.java | 1 + .../core/externals/AspStandardLibrary.java | 2 +- .../kr/alpha/core/externals/Externals.java | 24 +++++---- .../alpha/core/grounder/BridgedGrounder.java | 1 + .../alpha/core/grounder/ChoiceRecorder.java | 1 + .../core/grounder/FactIntervalEvaluator.java | 13 +++-- .../alpha/core/grounder/NogoodRegistry.java | 1 + .../alpha/core/grounder/SubstitutionImpl.java | 21 ++++---- .../kr/alpha/core/grounder/Unification.java | 10 ++-- .../alpha/core/grounder/bridges/Bridge.java | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 53 +++++++++--------- .../alpha/core/parser/ProgramPartParser.java | 16 +++--- .../CardinalityNormalization.java | 14 ++--- .../transformation/ChoiceHeadToNormal.java | 6 +-- .../IntervalTermToIntervalAtom.java | 18 +++---- .../transformation/SumNormalization.java | 14 ++--- .../kr/alpha/core/rules/InternalRule.java | 4 +- .../kr/alpha/core/solver/DefaultSolver.java | 8 +-- .../java/at/ac/tuwien/kr/alpha/TestUtil.java | 8 +-- .../ac/tuwien/kr/alpha/antlr/ParserTest.java | 20 +++---- .../stdlib/AspStandardLibraryTest.java | 42 +++++++-------- .../tuwien/kr/alpha/common/AtomStoreTest.java | 4 +- .../kr/alpha/common/BasicAnswerSetTest.java | 8 +-- .../kr/alpha/common/atoms/AtomsTest.java | 4 +- .../kr/alpha/common/terms/TermsTest.java | 34 ------------ .../grounder/IndexedInstanceStorageTest.java | 14 ++--- .../core/grounder/NaiveGrounderTest.java | 8 +-- .../core/grounder/NoGoodGeneratorTest.java | 8 +-- .../alpha/core/grounder/SubstitutionTest.java | 16 +++--- .../kr/alpha/core/grounder/UnifierTest.java | 10 ++-- .../alpha/core/solver/AtomCounterTests.java | 10 ++-- .../kr/alpha/core/solver/HanoiTowerTest.java | 4 +- .../kr/alpha/core/solver/SolverTests.java | 4 +- .../solver/ThreeColouringRandomGraphTest.java | 4 +- .../solver/ThreeColouringTestWithRandom.java | 6 +-- .../core/solver/ThreeColouringWheelTest.java | 6 +-- .../LiteralInstantiationStrategyTest.java | 54 +++++++++---------- .../LiteralInstantiatorTest.java | 36 ++++++------- .../structure/AnalyzeUnjustifiedTest.java | 16 +++--- .../StratifiedEvaluationRegressionTest.java | 22 ++++---- .../StratifiedEvaluationTest.java | 8 +-- .../tuwien/kr/alpha/test/util/TestUtils.java | 6 +-- .../tuwien/kr/alpha/impl/AlphaImplTest.java | 16 +++--- .../impl/FixedInterpretationLiteralsTest.java | 20 +++---- .../tuwien/kr/alpha/test/util/TestUtils.java | 6 +-- 75 files changed, 466 insertions(+), 435 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AbstractTerm.java (90%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/ArithmeticTerm.java (96%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ConstantTermImpl.java (75%) rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java (73%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/IntervalTerm.java (91%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/Terms.java (54%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/VariableTermImpl.java (89%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util}/IntIdGenerator.java (93%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util}/Interner.java (93%) rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common => alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons}/TermTest.java (68%) create mode 100644 alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermsTest.java rename {alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms => alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons}/TestMinusTerm.java (84%) delete mode 100644 alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java new file mode 100644 index 000000000..d989d522b --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java @@ -0,0 +1,5 @@ +package at.ac.tuwien.kr.alpha.api.terms; + +public interface FunctionTerm extends Term{ + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AbstractTerm.java similarity index 90% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AbstractTerm.java index 440a0fa21..586392f5e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AbstractTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.common.terms; +package at.ac.tuwien.kr.alpha.commons; import java.util.HashMap; import java.util.Map; @@ -6,6 +6,7 @@ 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; @@ -34,8 +35,9 @@ * Copyright (c) 2016-2020, the Alpha Team. */ //@formatter:on -public abstract class CoreTerm implements Term { +abstract class AbstractTerm implements Term { + @Override public abstract Set getOccurringVariables(); /** @@ -44,16 +46,16 @@ public abstract class CoreTerm implements Term { * @param substitution the variable substitution to apply. * @return the non-substitute term where all variable substitutions have been applied. */ + @Override public abstract Term substitute(Substitution substitution); // TODO change this to work on interfaces and break out of this class private static int priority(Term term) { - final Class clazz = term.getClass(); - if (clazz.equals(CoreConstantTerm.class)) { + if (term instanceof ConstantTerm) { return 1; - } else if (clazz.equals(FunctionTerm.class)) { + } else if (term instanceof FunctionTerm) { return 2; - } else if (clazz.equals(VariableTermImpl.class)) { + } else if (term instanceof VariableTerm) { return 3; } throw new UnsupportedOperationException("Can only compare constant term, function terms and variable terms among each other."); @@ -64,6 +66,7 @@ public int compareTo(Term o) { return o == null ? 1 : Integer.compare(priority(this), priority(o)); } + @Override public abstract boolean isGround(); /** @@ -72,8 +75,10 @@ public int compareTo(Term o) { * @param renamePrefix the name to prefix all occurring variables. * @return the term with all variables renamed. */ + @Override public abstract Term renameVariables(String renamePrefix); + @Override public abstract Term normalizeVariables(String renamePrefix, Term.RenameCounter counter); public static class RenameCounterImpl implements Term.RenameCounter { @@ -85,10 +90,12 @@ public RenameCounterImpl(int startingValue) { renamedVariables = new HashMap<>(); } + @Override public Map getRenamedVariables() { return renamedVariables; } + @Override public int getAndIncrement() { int retVal = counter; counter++; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTerm.java similarity index 96% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTerm.java index 2cf163f5b..87fdd35e5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/ArithmeticTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTerm.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.terms; +package at.ac.tuwien.kr.alpha.commons; import java.util.LinkedHashSet; import java.util.Set; @@ -36,13 +36,13 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.commons.util.Interner; /** * This class represents an arithmetic expression occurring as a term. * Copyright (c) 2017-2019, the Alpha Team. */ -public class ArithmeticTerm extends CoreTerm { +public class ArithmeticTerm extends AbstractTerm { private static final Interner INTERNER = new Interner<>(); protected final Term left; private final ArithmeticOperator arithmeticOperator; @@ -58,7 +58,7 @@ public static Term getInstance(Term left, ArithmeticOperator arithmeticOperator, // Evaluate ground arithmetic terms immediately and return result. if (left.isGround() && right.isGround()) { Integer result = new ArithmeticTerm(left, arithmeticOperator, right).evaluateExpression(); - return CoreConstantTerm.getInstance(result); + return ConstantTermImpl.getInstance(result); } return INTERNER.intern(new ArithmeticTerm(left, arithmeticOperator, right)); } @@ -205,7 +205,7 @@ public static Term getInstance(Term term) { // Evaluate ground arithmetic terms immediately and return result. if (term.isGround()) { Integer result = evaluateGroundTermHelper(term) * -1; - return CoreConstantTerm.getInstance(result); + return ConstantTermImpl.getInstance(result); } return INTERNER.intern(new MinusTerm(term)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ConstantTermImpl.java similarity index 75% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ConstantTermImpl.java index c470e7555..1baef0a93 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/CoreConstantTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ConstantTermImpl.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.common.terms; +package at.ac.tuwien.kr.alpha.commons; import java.util.Collections; import java.util.Set; @@ -7,30 +7,30 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.commons.util.Interner; /** * Copyright (c) 2016-2020, the Alpha Team. */ -public class CoreConstantTerm> extends CoreTerm implements ConstantTerm { - private static final Interner> INTERNER = new Interner<>(); +class ConstantTermImpl> extends AbstractTerm implements ConstantTerm { + private static final Interner> INTERNER = new Interner<>(); private final T object; private final boolean symbolic; - private CoreConstantTerm(T object, boolean symbolic) { + private ConstantTermImpl(T object, boolean symbolic) { this.object = object; this.symbolic = symbolic; } @SuppressWarnings("unchecked") - public static > CoreConstantTerm getInstance(T symbol) { - return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, false)); + public static > ConstantTermImpl getInstance(T symbol) { + return (ConstantTermImpl) INTERNER.intern(new ConstantTermImpl<>(symbol, false)); } @SuppressWarnings("unchecked") - public static > CoreConstantTerm getSymbolicInstance(String symbol) { - return (CoreConstantTerm) INTERNER.intern(new CoreConstantTerm<>(symbol, true)); + public static > ConstantTermImpl getSymbolicInstance(String symbol) { + return (ConstantTermImpl) INTERNER.intern(new ConstantTermImpl<>(symbol, true)); } @Override @@ -70,7 +70,7 @@ public boolean equals(Object o) { return false; } - CoreConstantTerm that = (CoreConstantTerm) o; + ConstantTermImpl that = (ConstantTermImpl) o; if (this.symbolic != that.symbolic) { return false; } @@ -89,7 +89,7 @@ public int hashCode() { * Establishes "priority" for ordering of constant terms depending on the type * of the corresponding object according to ASP-Core-2.03c. */ - private static final int priority(final Class clazz, CoreConstantTerm term) { + private static final int priority(final Class clazz, ConstantTermImpl term) { if (clazz.equals(Integer.class)) { return 1; } else if (clazz.equals(String.class)) { @@ -105,11 +105,11 @@ public int compareTo(Term o) { return 0; } - if (!(o instanceof CoreConstantTerm)) { + if (!(o instanceof ConstantTermImpl)) { return super.compareTo(o); } - CoreConstantTerm other = (CoreConstantTerm) o; + ConstantTermImpl other = (ConstantTermImpl) o; // We will perform an unchecked cast. // Because of type erasure, we cannot know the exact type @@ -141,13 +141,13 @@ public int compareTo(Term o) { } @Override - public CoreTerm renameVariables(String renamePrefix) { + public AbstractTerm renameVariables(String renamePrefix) { // Constant contains no variables, hence stays the same. return this; } @Override - public CoreTerm normalizeVariables(String renamePrefix, Term.RenameCounter counter) { + public AbstractTerm normalizeVariables(String renamePrefix, Term.RenameCounter counter) { return this; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java similarity index 73% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java index 713bad3c5..9602fe4a9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/FunctionTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.common.terms; +package at.ac.tuwien.kr.alpha.commons; import java.util.ArrayList; import java.util.Arrays; @@ -9,21 +9,22 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +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.core.common.Interner; +import at.ac.tuwien.kr.alpha.commons.util.Interner; /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class FunctionTerm extends CoreTerm { - private static final Interner INTERNER = new Interner<>(); +public 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 FunctionTerm(String symbol, List terms) { + private FunctionTermImpl(String symbol, List terms) { if (symbol == null) { throw new IllegalArgumentException(); } @@ -41,11 +42,11 @@ private FunctionTerm(String symbol, List terms) { this.ground = ground; } - public static FunctionTerm getInstance(String functionSymbol, List termList) { - return INTERNER.intern(new FunctionTerm(functionSymbol, termList)); + public static FunctionTermImpl getInstance(String functionSymbol, List termList) { + return INTERNER.intern(new FunctionTermImpl(functionSymbol, termList)); } - public static FunctionTerm getInstance(String functionSymbol, Term... terms) { + public static FunctionTermImpl getInstance(String functionSymbol, Term... terms) { return getInstance(functionSymbol, Arrays.asList(terms)); } @@ -72,12 +73,12 @@ public Set getOccurringVariables() { } @Override - public FunctionTerm substitute(Substitution substitution) { + public FunctionTermImpl substitute(Substitution substitution) { List groundTermList = new ArrayList<>(terms.size()); for (Term term : terms) { groundTermList.add(term.substitute(substitution)); } - return FunctionTerm.getInstance(symbol, groundTermList); + return FunctionTermImpl.getInstance(symbol, groundTermList); } @Override @@ -98,7 +99,7 @@ public boolean equals(Object o) { return false; } - FunctionTerm that = (FunctionTerm) o; + FunctionTermImpl that = (FunctionTermImpl) o; if (!symbol.equals(that.symbol)) { return false; @@ -117,11 +118,11 @@ public int compareTo(Term o) { return 0; } - if (!(o instanceof FunctionTerm)) { + if (!(o instanceof FunctionTermImpl)) { return super.compareTo(o); } - FunctionTerm other = (FunctionTerm) o; + FunctionTermImpl other = (FunctionTermImpl) o; if (terms.size() != other.terms.size()) { return terms.size() - other.terms.size(); @@ -149,7 +150,7 @@ public Term renameVariables(String renamePrefix) { for (Term term : terms) { renamedTerms.add(term.renameVariables(renamePrefix)); } - return FunctionTerm.getInstance(symbol, renamedTerms); + return FunctionTermImpl.getInstance(symbol, renamedTerms); } @Override @@ -158,6 +159,6 @@ public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) for (Term term : terms) { normalizedTerms.add(term.normalizeVariables(renamePrefix, counter)); } - return FunctionTerm.getInstance(symbol, normalizedTerms); + return FunctionTermImpl.getInstance(symbol, normalizedTerms); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java index 5936b764a..f871af00a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/IntervalTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.common.terms; +package at.ac.tuwien.kr.alpha.commons; import java.util.LinkedHashSet; import java.util.Set; @@ -7,14 +7,14 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.Interner; +import at.ac.tuwien.kr.alpha.commons.util.Interner; /** * An IntervalTerm represents the shorthand notation for a set of rules where all elements in this interval occur once, e.g., fact(2..5). * An IntervalTerm is a meta-term and the grounder must replace it with its corresponding set of facts or rules. * Copyright (c) 2017, the Alpha Team. */ -public class IntervalTerm extends CoreTerm { +public class IntervalTerm extends AbstractTerm { private static final Interner INTERNER = new Interner<>(); private final Term lowerBoundTerm; private final Term upperBoundTerm; @@ -139,20 +139,20 @@ public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) public static boolean termContainsIntervalTerm(Term term) { if (term instanceof IntervalTerm) { return true; - } else if (term instanceof FunctionTerm) { - return functionTermContainsIntervals((FunctionTerm) term); + } else if (term instanceof FunctionTermImpl) { + return functionTermContainsIntervals((FunctionTermImpl) term); } else { return false; } } - public static boolean functionTermContainsIntervals(FunctionTerm functionTerm) { + public static boolean functionTermContainsIntervals(FunctionTermImpl functionTerm) { // Test whether a function term contains an interval term (recursively). for (Term term : functionTerm.getTerms()) { if (term instanceof IntervalTerm) { return true; } - if (term instanceof FunctionTerm && functionTermContainsIntervals((FunctionTerm) term)) { + if (term instanceof FunctionTermImpl && functionTermContainsIntervals((FunctionTermImpl) term)) { return true; } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java similarity index 54% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java index 6ad916486..045cc748d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java @@ -1,15 +1,16 @@ -package at.ac.tuwien.kr.alpha.core.common.terms; +package at.ac.tuwien.kr.alpha.commons; import java.util.ArrayList; import java.util.List; 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.terms.VariableTerm; /** - * Convenience methods for {@link CoreTerm}s. The methods provided here are an + * Convenience methods for {@link Term}s. The methods provided here are an * attempt to avoid repeating commonly used code snippets, like wrapping sets of - * values in {@link CoreTerm}s and creating lists of those terms, etc. + * values in {@link Term}s and creating lists of those terms, etc. * * Copyright (c) 2020, the Alpha Team. */ @@ -24,23 +25,38 @@ private Terms() { throw new AssertionError(Terms.class.getSimpleName() + " is a non-instantiable utility class!"); } + public static > ConstantTerm newConstant(T constantObject) { + return ConstantTermImpl.getInstance(constantObject); + } + + public static ConstantTerm newSymbolicConstant(String symbol) { + return ConstantTermImpl.getSymbolicInstance(symbol); + } + + public static VariableTerm newVariable(String varName) { + return VariableTermImpl.getInstance(varName); + } + + public static VariableTerm newAnonymousVariable() { + return VariableTermImpl.getAnonymousInstance(); + } + @SafeVarargs public static > List> asTermList(T... values) { List> retVal = new ArrayList<>(); for (T value : values) { - retVal.add(CoreConstantTerm.getInstance(value)); + retVal.add(ConstantTermImpl.getInstance(value)); } return retVal; } public static List renameTerms(List terms, String prefix, int counterStartingValue) { List renamedTerms = new ArrayList<>(terms.size()); - CoreTerm.RenameCounterImpl renameCounter = new CoreTerm.RenameCounterImpl(counterStartingValue); + AbstractTerm.RenameCounterImpl renameCounter = new AbstractTerm.RenameCounterImpl(counterStartingValue); for (Term term : terms) { renamedTerms.add(term.normalizeVariables(prefix, renameCounter)); } return renamedTerms; } - } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java similarity index 89% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java index 122b4ca55..99d471ae5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/terms/VariableTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.common.terms; +package at.ac.tuwien.kr.alpha.commons; import java.util.Collections; import java.util.Set; @@ -6,13 +6,13 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.Interner; -import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; +import at.ac.tuwien.kr.alpha.commons.util.Interner; /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class VariableTermImpl extends CoreTerm implements VariableTerm { +public class VariableTermImpl extends AbstractTerm implements VariableTerm { private static final Interner INTERNER = new Interner<>(); private static final String ANONYMOUS_VARIABLE_PREFIX = "_"; @@ -93,7 +93,7 @@ public int compareTo(Term o) { } @Override - public CoreTerm renameVariables(String renamePrefix) { + public AbstractTerm renameVariables(String renamePrefix) { return VariableTermImpl.getInstance(renamePrefix + variableName); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util/IntIdGenerator.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util/IntIdGenerator.java index 278268bb0..f6a6feada 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/IntIdGenerator.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util/IntIdGenerator.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.grounder; +package at.ac.tuwien.kr.alpha.commons.util; import static at.ac.tuwien.kr.alpha.api.Util.oops; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Interner.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util/Interner.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Interner.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util/Interner.java index 117191d79..b398507c8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Interner.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/util/Interner.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.common; +package at.ac.tuwien.kr.alpha.commons.util; import java.lang.ref.WeakReference; import java.util.WeakHashMap; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermTest.java similarity index 68% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermTest.java index 380fb1995..139e5b280 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/TermTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.common; +package at.ac.tuwien.kr.alpha.commons; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -15,13 +15,11 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; /** * Copyright (c) 2016, the Alpha Team. */ +// TODO maybe this should actually work against the AbstractTerm type since it tests properties of interned terms which is not part of the public Term interface public class TermTest { @Test @@ -29,26 +27,26 @@ public void testTermReferenceEquality() { // Terms must have a unique representation so that reference comparison is // sufficient to check // whether two terms are equal. - ConstantTerm ta1 = CoreConstantTerm.getInstance("a"); - ConstantTerm ta2 = CoreConstantTerm.getInstance("a"); + ConstantTerm ta1 = Terms.newConstant("a"); + ConstantTerm ta2 = Terms.newConstant("a"); assertTrue("Two instances of ConstantTerms for the same term symbol must be the same object", ta1 == ta2); List termList = new LinkedList<>(); termList.add(ta1); termList.add(ta2); - FunctionTerm ft1 = FunctionTerm.getInstance("f", termList); + FunctionTermImpl ft1 = FunctionTermImpl.getInstance("f", termList); List termList2 = new LinkedList<>(); termList2.add(ta1); termList2.add(ta2); - FunctionTerm ft2 = FunctionTerm.getInstance("f", termList2); + FunctionTermImpl ft2 = FunctionTermImpl.getInstance("f", termList2); assertTrue("Two instances of FunctionTerms for the same term symbol and equal term lists must be the same object", ft1 == ft2); } @Test public void testTermVariableOccurrences() { - ConstantTerm ta = CoreConstantTerm.getInstance("a"); + ConstantTerm ta = Terms.newConstant("a"); VariableTerm tx = VariableTermImpl.getInstance("X"); - FunctionTerm tf = FunctionTerm.getInstance("f", ta, tx); + FunctionTermImpl tf = FunctionTermImpl.getInstance("f", ta, tx); Set occurringVariables = tf.getOccurringVariables(); assertEquals("Variable occurring as subterm must be reported as occurring variable.", new ArrayList<>(occurringVariables).get(0), tx); @@ -56,10 +54,10 @@ public void testTermVariableOccurrences() { @Test public void testTermOrdering() throws Exception { - Term cts = CoreConstantTerm.getInstance("abc"); - Term cti = CoreConstantTerm.getInstance(2); - Term cto = CoreConstantTerm.getInstance(new UUID(0, 0)); - Term ft = FunctionTerm.getInstance("f", CoreConstantTerm.getInstance("a")); + Term cts = Terms.newConstant("abc"); + Term cti = Terms.newConstant(2); + Term cto = Terms.newConstant(new UUID(0, 0)); + Term ft = FunctionTermImpl.getInstance("f", Terms.newConstant("a")); assertTrue(cts.compareTo(cti) > 0); assertTrue(cti.compareTo(cts) < 0); @@ -77,12 +75,12 @@ public void testTermOrdering() throws Exception { @Test public void testStringVsConstantSymbolEquality() { String theString = "string"; - ConstantTerm stringConstant = CoreConstantTerm.getInstance(theString); - ConstantTerm constantSymbol = CoreConstantTerm.getSymbolicInstance(theString); + ConstantTerm stringConstant = Terms.newConstant(theString); + ConstantTerm constantSymbol = Terms.newSymbolicConstant(theString); // Reference equality must hold for both the string constant and the constant // symbol. - Assert.assertTrue(stringConstant == CoreConstantTerm.getInstance(theString)); - ConstantTerm sameConstantSymbol = CoreConstantTerm.getSymbolicInstance(theString); + Assert.assertTrue(stringConstant == Terms.newConstant(theString)); + ConstantTerm sameConstantSymbol = Terms.newSymbolicConstant(theString); Assert.assertTrue(constantSymbol == sameConstantSymbol); // Make sure both hashCode and equals understand that stringConstant and // constantSymbol are NOT the same thing! diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermsTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermsTest.java new file mode 100644 index 000000000..92f89f1c1 --- /dev/null +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermsTest.java @@ -0,0 +1,32 @@ +package at.ac.tuwien.kr.alpha.commons; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; + +public class TermsTest { + + @Test + public void integersAsTermList() { + List> intTerms = Terms.asTermList(1, 2, 3, 4, 5, 6); + Assert.assertEquals(6, intTerms.size()); + Assert.assertEquals(Terms.newConstant(1), intTerms.get(0)); + Assert.assertEquals(Terms.newConstant(2), intTerms.get(1)); + Assert.assertEquals(Terms.newConstant(3), intTerms.get(2)); + Assert.assertEquals(Terms.newConstant(4), intTerms.get(3)); + Assert.assertEquals(Terms.newConstant(5), intTerms.get(4)); + Assert.assertEquals(Terms.newConstant(6), intTerms.get(5)); + } + + @Test + public void stringsAsTermList() { + List> terms = Terms.asTermList("bla", "blubb"); + Assert.assertEquals(2, terms.size()); + Assert.assertEquals("\"bla\"", terms.get(0).toString()); + Assert.assertEquals("\"blubb\"", terms.get(1).toString()); + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java similarity index 84% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java index f3ac4b9ad..92fff66c3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TestMinusTerm.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.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.common.terms; +package at.ac.tuwien.kr.alpha.commons; import static org.junit.Assert.assertEquals; @@ -31,10 +31,8 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.Term.RenameCounter; -import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm.MinusTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm.RenameCounterImpl; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.AbstractTerm.RenameCounterImpl; +import at.ac.tuwien.kr.alpha.commons.ArithmeticTerm.MinusTerm; /** * Tests {@link MinusTerm} @@ -46,7 +44,7 @@ public class TestMinusTerm { @Test public void testNormalizeVariablesNoVariable() { - Term m2 = MinusTerm.getInstance(CoreConstantTerm.getInstance(2)); + Term m2 = MinusTerm.getInstance(ConstantTermImpl.getInstance(2)); assertEquals(m2, m2.normalizeVariables(renamePrefix, counter)); } diff --git a/alpha-core/build.gradle b/alpha-core/build.gradle index 5869bb4c9..0f1ccbf50 100644 --- a/alpha-core/build.gradle +++ b/alpha-core/build.gradle @@ -21,7 +21,8 @@ configurations { dependencies { - api project(":alpha-api") + api project(":alpha-api") // TODO does it make more sense to use implementation scope? + api project(":alpha-commons") // TODO does it make more sense to use implementation scope? // We need to give the ANTLR Plugin a hint. antlr group: 'org.antlr', name: 'antlr4', version: "${antlrVersion}" diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index 79d045501..b133f10eb 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -39,9 +39,9 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; 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.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; public class AggregateAtom extends CoreAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index dece62fb0..f6b681ced 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -6,8 +6,8 @@ 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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; /** * Copyright (c) 2018, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java index f1c56e698..68255a025 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java @@ -37,7 +37,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.core.common.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.Terms; /** * Represents ordinary ASP atoms. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java index fe615fc46..5062ad153 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java @@ -35,8 +35,8 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; public class ChoiceAtom extends CoreAtom { @@ -52,7 +52,7 @@ private ChoiceAtom(Predicate predicate, Term term) { } private ChoiceAtom(Predicate predicate, int id) { - this(predicate, CoreConstantTerm.getInstance(Integer.toString(id))); + this(predicate, Terms.newConstant(Integer.toString(id))); } public static ChoiceAtom on(int id) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java index 0a773777c..eadd72737 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java @@ -35,8 +35,8 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; -import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** * Represents a builtin comparison atom according to the standard. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index 48854da29..108e24bff 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -27,7 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm.evaluateGroundTerm; +import static at.ac.tuwien.kr.alpha.commons.ArithmeticTerm.evaluateGroundTerm; import java.util.Collections; import java.util.HashSet; @@ -39,10 +39,10 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; 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.ArithmeticTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; -import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** @@ -169,7 +169,7 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit if (result == null) { return Collections.emptyList(); } - resultTerm = CoreConstantTerm.getInstance(result); + resultTerm = Terms.newConstant(result); } else { // Ground term is another term (constant, or function term). resultTerm = groundTerm; @@ -192,7 +192,7 @@ private Term evaluateTerm(Term term) { if (result == null) { return null; } - return CoreConstantTerm.getInstance(result); + return Terms.newConstant(result); } return term; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index 1b353ecaf..821601080 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -36,7 +36,7 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 86b911072..6520a3640 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -7,9 +7,9 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** @@ -71,7 +71,7 @@ public Substitution addEnumerationIndexToSubstitution(Substitution substitution) } Integer enumerationIndex = getEnumerationIndex(idTerm, enumerationTerm); SubstitutionImpl retVal = new SubstitutionImpl(substitution); - retVal.put((VariableTermImpl) getTerms().get(2), CoreConstantTerm.getInstance(enumerationIndex)); + retVal.put((VariableTermImpl) getTerms().get(2), Terms.newConstant(enumerationIndex)); return retVal; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java index f36577640..7a5ff06d5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java @@ -7,7 +7,7 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; /** * Copyright (c) 2018, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index 6ba7a3b35..d1d8dd165 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.core.common.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.Terms; public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java index 54ce0fbe5..f86fb4116 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java @@ -38,7 +38,7 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java index 6cb15d9ab..0b393fb4b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java @@ -35,9 +35,9 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.Terms; /** * Helper for treating IntervalTerms in rules. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index 6d69467a1..bbdc25480 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java @@ -38,9 +38,9 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** @@ -72,7 +72,7 @@ private List getIntervalSubstitutions(Substitution partialSubstitu // Still a variable, generate all elements in the interval. for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) { Substitution ith = new SubstitutionImpl(partialSubstitution); - ith.put((VariableTermImpl) intervalRepresentingVariable, CoreConstantTerm.getInstance(i)); + ith.put((VariableTermImpl) intervalRepresentingVariable, Terms.newConstant(i)); substitutions.add(ith); } return substitutions; @@ -83,7 +83,8 @@ private List getIntervalSubstitutions(Substitution partialSubstitu // Term is not bound to an integer constant, not in the interval. return Collections.emptyList(); } - Integer integer = (Integer) ((CoreConstantTerm) intervalRepresentingVariable).getObject(); + // TODO to avoid that type of unchecked cast, we may want interval terms to not extend AbstractTerm + Integer integer = ((ConstantTerm) intervalRepresentingVariable).getObject(); if (intervalTerm.getLowerBound() <= integer && integer <= intervalTerm.getUpperBound()) { return Collections.singletonList(partialSubstitution); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java index a72a57813..1c2b67f84 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java @@ -27,8 +27,6 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm.getInstance; - import java.util.Arrays; import java.util.List; @@ -38,6 +36,7 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; 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; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; /** @@ -59,8 +58,8 @@ private RuleAtom(List> terms) { public RuleAtom(CompiledRule nonGroundRule, Substitution substitution) { this(Arrays.asList( - getInstance(Integer.toString(nonGroundRule.getRuleId())), - getInstance(substitution.toString()) + Terms.newConstant(Integer.toString(nonGroundRule.getRuleId())), + Terms.newConstant(substitution.toString()) ) ); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java index 6d7a146dc..2483edb6e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java @@ -13,8 +13,8 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; public class AnswerSetBuilder { private boolean firstInstance = true; @@ -76,7 +76,7 @@ public final > AnswerSetBuilder instance(final T... term // since we are only reading, not writing. List termList = Stream .of(terms) - .map(CoreConstantTerm::getInstance) + .map(Terms::newConstant) .collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); @@ -90,7 +90,7 @@ public AnswerSetBuilder symbolicInstance(String... terms) { predicates.add(predicate); } - List termList = Stream.of(terms).map(CoreConstantTerm::getSymbolicInstance).collect(Collectors.toList()); + List termList = Stream.of(terms).map(Terms::newSymbolicConstant).collect(Collectors.toList()); instances.add(new BasicAtom(predicate, termList)); return this; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java index 6d97681fe..9c7054ae3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java @@ -36,8 +36,8 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; -import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java index ff16f9163..408eb0cc5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java @@ -1,6 +1,7 @@ package at.ac.tuwien.kr.alpha.core.common; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.commons.util.Interner; /** * A predicate as used by the Alpha solver internally. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java index 62c7c8bd2..db7cba228 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java @@ -33,7 +33,7 @@ import at.ac.tuwien.kr.alpha.api.externals.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.Terms; /** * Collection of methods that can be used as external atoms from ASP programs. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java index 9ad964735..3d9444426 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java @@ -25,10 +25,23 @@ */ package at.ac.tuwien.kr.alpha.core.externals; -import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.*; +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; + +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.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BinaryPredicateInterpretation; import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BindingMethodPredicateInterpretation; @@ -37,13 +50,6 @@ 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 at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; - -import org.reflections.Reflections; -import org.reflections.scanners.MethodAnnotationsScanner; - -import java.lang.reflect.Method; -import java.util.*; public final class Externals { @@ -143,7 +149,7 @@ public static > List asFacts(Class classOfExtFa String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. for (T instance : extFacts) { // TODO use properly wrapped BasicAtoms here - retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.core.common.CorePredicate.getInstance(name, 1), CoreConstantTerm.getInstance(instance))); + retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.core.common.CorePredicate.getInstance(name, 1), Terms.newConstant(instance))); } return retVal; } 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 6914bb1c4..8dcd72822 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 @@ -4,6 +4,7 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.program.Predicate; +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.grounder.bridges.Bridge; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java index 322bc1e86..573d3da1b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java @@ -27,6 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; 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.NoGood; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index 4f11a409f..b98d36bb2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -7,10 +7,9 @@ import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; /** * Helper functions to evaluate facts potentially containing intervals. @@ -27,7 +26,7 @@ public class FactIntervalEvaluator { public static List constructFactInstances(Atom fact) { // Construct instance(s) from the fact. int arity = fact.getPredicate().getArity(); - Term[] currentTerms = new CoreTerm[arity]; + Term[] currentTerms = new Term[arity]; boolean containsIntervals = false; // Check if instance contains intervals at all. for (int i = 0; i < arity; i++) { @@ -35,7 +34,7 @@ public static List constructFactInstances(Atom fact) { currentTerms[i] = term; if (term instanceof IntervalTerm) { containsIntervals = true; - } else if (term instanceof FunctionTerm && IntervalTerm.functionTermContainsIntervals((FunctionTerm) term)) { + } else if (term instanceof FunctionTermImpl && IntervalTerm.functionTermContainsIntervals((FunctionTermImpl) term)) { containsIntervals = true; throw new UnsupportedOperationException("Intervals inside function terms in facts are not supported yet. Try turning the fact into a rule."); } @@ -64,7 +63,7 @@ private static List unrollInstances(Term[] currentTerms, int currentPo for (int i = lower; i <= upper; i++) { Term[] clonedTerms = currentTerms.clone(); - clonedTerms[currentPosition] = CoreConstantTerm.getInstance(i); + clonedTerms[currentPosition] = Terms.newConstant(i); instances.addAll(unrollInstances(clonedTerms, currentPosition + 1)); } return instances; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NogoodRegistry.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NogoodRegistry.java index be67855a6..970ab86e6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NogoodRegistry.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NogoodRegistry.java @@ -3,6 +3,7 @@ import java.util.LinkedHashMap; import java.util.Map; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.common.NoGood; public class NogoodRegistry { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java index 76f2cd19b..55aae6f32 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java @@ -38,12 +38,11 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; +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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Substitution { @@ -51,7 +50,7 @@ public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Subs private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); public static final Substitution EMPTY_SUBSTITUTION = new SubstitutionImpl() { @Override - public > CoreTerm put(VariableTerm variableTerm, Term groundTerm) { + public > Term put(VariableTerm variableTerm, Term groundTerm) { throw Util.oops("Should not be called on EMPTY_SUBSTITUTION"); } }; @@ -101,7 +100,7 @@ boolean unifyTerms(Term termNonGround, Term termGround, Substitution partialSubs if (termNonGround == termGround) { // Both terms are either the same constant or the same variable term return true; - } else if (termNonGround instanceof CoreConstantTerm) { + } else if (termNonGround instanceof ConstantTerm) { // Since right term is ground, both terms differ return false; } else if (termNonGround instanceof VariableTermImpl) { @@ -124,10 +123,10 @@ boolean unifyTerms(Term termNonGround, Term termGround, Substitution partialSubs } updatedSubstitution.put(variableTerm, termGround); return true; - } else if (termNonGround instanceof FunctionTerm && termGround instanceof FunctionTerm) { + } else if (termNonGround instanceof FunctionTermImpl && termGround instanceof FunctionTermImpl) { // Both terms are function terms - FunctionTerm ftNonGround = (FunctionTerm) termNonGround; - FunctionTerm ftGround = (FunctionTerm) termGround; + FunctionTermImpl ftNonGround = (FunctionTermImpl) termNonGround; + FunctionTermImpl ftGround = (FunctionTermImpl) termGround; if (!(ftNonGround.getSymbol().equals(ftGround.getSymbol()))) { return false; @@ -168,7 +167,7 @@ public static Substitution specializeSubstitution(Atom atom, Instance instance, } /** - * This method should be used to obtain the {@link CoreTerm} to be used in place of a given {@link VariableTermImpl} under this + * This method should be used to obtain the {@link AbstractTerm} to be used in place of a given {@link VariableTermImpl} under this * substitution. * * @param variableTerm the variable term to substitute, if possible @@ -231,7 +230,7 @@ public static SubstitutionImpl fromString(String substitution) { for (String assignment : assignments) { String[] keyVal = assignment.split("->"); VariableTermImpl variable = VariableTermImpl.getInstance(keyVal[0]); - CoreTerm assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); + Term assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); ret.put(variable, assignedTerm); } return ret; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index cf19df43c..1906b8755 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -34,8 +34,8 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; /** * Copyright (c) 2017, the Alpha Team. @@ -95,9 +95,9 @@ private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitu currentSubstitution.put((VariableTermImpl) rightSubs, leftSubs); return true; } - if (leftSubs instanceof FunctionTerm && rightSubs instanceof FunctionTerm) { - final FunctionTerm leftFunction = (FunctionTerm) leftSubs; - final FunctionTerm rightFunction = (FunctionTerm) rightSubs; + if (leftSubs instanceof FunctionTermImpl && rightSubs instanceof FunctionTermImpl) { + final FunctionTermImpl leftFunction = (FunctionTermImpl) leftSubs; + final FunctionTermImpl rightFunction = (FunctionTermImpl) rightSubs; if (!leftFunction.getSymbol().equals(rightFunction.getSymbol()) || leftFunction.getTerms().size() != rightFunction.getTerms().size()) { return false; 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 a4897eb34..2d0beedb2 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 @@ -1,8 +1,8 @@ package at.ac.tuwien.kr.alpha.core.grounder.bridges; +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.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import java.util.Collection; 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 8283ed3ba..88cc7aac9 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 @@ -58,6 +58,11 @@ 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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.ArithmeticTerm; +import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; @@ -70,12 +75,6 @@ import at.ac.tuwien.kr.alpha.core.common.BasicAnswerSet; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHeadImpl; @@ -333,7 +332,7 @@ public AggregateLiteral visitAggregate(ASPCore2Parser.AggregateContext ctx) { Term ut = null; ComparisonOperatorImpl uop = null; if (ctx.lt != null) { - lt = (CoreTerm) visit(ctx.lt); + lt = (Term) visit(ctx.lt); lop = visitBinop(ctx.lop); } if (ctx.ut != null) { @@ -390,16 +389,16 @@ public Term visitBasic_term(ASPCore2Parser.Basic_termContext ctx) { public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { // ground_term : ID | QUOTED_STRING | MINUS? NUMBER; if (ctx.ID() != null) { - return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); + return Terms.newSymbolicConstant(ctx.ID().getText()); } else if (ctx.QUOTED_STRING() != null) { String quotedString = ctx.QUOTED_STRING().getText(); - return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); + return Terms.newConstant(quotedString.substring(1, quotedString.length() - 1)); } else { int multiplier = 1; if (ctx.MINUS() != null) { multiplier = -1; } - return CoreConstantTerm.getInstance(multiplier * Integer.parseInt(ctx.NUMBER().getText())); + return Terms.newConstant(multiplier * Integer.parseInt(ctx.NUMBER().getText())); } } @@ -453,8 +452,8 @@ public ComparisonOperatorImpl visitBinop(ASPCore2Parser.BinopContext ctx) { public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { // builtin_atom : term binop term; return new ComparisonAtom( - (CoreTerm) visit(ctx.term(0)), - (CoreTerm) visit(ctx.term(1)), + (Term) visit(ctx.term(0)), + (Term) visit(ctx.term(1)), visitBinop(ctx.binop()) ); } @@ -501,24 +500,24 @@ public List visitTerms(ASPCore2Parser.TermsContext ctx) { } @Override - public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { - return CoreConstantTerm.getInstance(Integer.parseInt(ctx.NUMBER().getText())); + public ConstantTerm visitTerm_number(ASPCore2Parser.Term_numberContext ctx) { + return Terms.newConstant(Integer.parseInt(ctx.NUMBER().getText())); } @Override - public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { - return CoreConstantTerm.getSymbolicInstance(ctx.ID().getText()); + public ConstantTerm visitTerm_const(ASPCore2Parser.Term_constContext ctx) { + return Terms.newSymbolicConstant(ctx.ID().getText()); } @Override - public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { + public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext ctx) { String quotedString = ctx.QUOTED_STRING().getText().replace("\\\"", "\""); - return CoreConstantTerm.getInstance(quotedString.substring(1, quotedString.length() - 1)); + return Terms.newConstant(quotedString.substring(1, quotedString.length() - 1)); } @Override - public FunctionTerm visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { - return FunctionTerm.getInstance(ctx.ID().getText(), visitTerms(ctx.terms())); + public FunctionTermImpl visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { + return FunctionTermImpl.getInstance(ctx.ID().getText(), visitTerms(ctx.terms())); } @Override @@ -575,15 +574,15 @@ public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) ASPCore2Parser.IntervalContext ictx = ctx.interval(); String lowerText = ictx.lower.getText(); String upperText = ictx.upper.getText(); - CoreTerm lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(lowerText)) : VariableTermImpl.getInstance(lowerText); - CoreTerm upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? CoreConstantTerm.getInstance(Integer.parseInt(upperText)) : VariableTermImpl.getInstance(upperText); + Term lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? Terms.newConstant(Integer.parseInt(lowerText)) : VariableTermImpl.getInstance(lowerText); + Term upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? Terms.newConstant(Integer.parseInt(upperText)) : VariableTermImpl.getInstance(upperText); return IntervalTerm.getInstance(lower, upper); } @Override public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { // | MINUS term - return ArithmeticTerm.MinusTerm.getInstance((CoreTerm) visit(ctx.term())); + return ArithmeticTerm.MinusTerm.getInstance((Term) visit(ctx.term())); } @Override @@ -591,26 +590,26 @@ public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArit // | term (TIMES | DIV | MODULO) term ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); } @Override public Object visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { // | term (PLUS | MINUS) term ArithmeticTerm.ArithmeticOperator op = ctx.PLUS() != null ? ArithmeticTerm.ArithmeticOperator.PLUS : ArithmeticTerm.ArithmeticOperator.MINUS; - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); } @Override public Object visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { // | term POWER term ArithmeticTerm.ArithmeticOperator op = ArithmeticTerm.ArithmeticOperator.POWER; - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), op, (CoreTerm) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); } @Override public Object visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { // | term BITXOR term - return ArithmeticTerm.getInstance((CoreTerm) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (CoreTerm) visit(ctx.term(1))); + return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (Term) visit(ctx.term(1))); } } 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 c23623ef4..2e7687de4 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 @@ -28,11 +28,7 @@ package at.ac.tuwien.kr.alpha.core.parser; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreTerm; +import java.util.Collections; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -40,7 +36,11 @@ import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.misc.ParseCancellationException; -import java.util.Collections; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Lexer; +import at.ac.tuwien.kr.alpha.antlr.ASPCore2Parser; +import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; /** * A parser that, in contrast to {@link ProgramParserImpl}, does not parse full programs but only program parts like @@ -49,9 +49,9 @@ public class ProgramPartParser { private final ParseTreeVisitor visitor = new ParseTreeVisitor(Collections.emptyMap(), true); - public CoreTerm parseTerm(String s) { + public Term parseTerm(String s) { final ASPCore2Parser parser = getASPCore2Parser(s); - return (CoreTerm)parse(parser.term()); + return (Term)parse(parser.term()); } public BasicAtom parseBasicAtom(String s) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index 345dd1048..f163c177b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -13,13 +13,13 @@ import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; @@ -194,12 +194,12 @@ private List> rewriteAggregatesInRule(Rule rule) { Substitution aggregateSubstitution = new Unifier(); Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); + aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), Terms.newConstant(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); - globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); - aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); + globalVariableTermlist.add(Terms.newConstant(aggregateCount)); + aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); } aggregateSubstitution.put(VariableTermImpl.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); @@ -210,7 +210,7 @@ private List> rewriteAggregatesInRule(Rule rule) { for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. List elementTerms = aggregateElement.getElementTerms(); - FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); + FunctionTermImpl elementTuple = FunctionTermImpl.getInstance("element_tuple", elementTerms); Substitution elementSubstitution = new Unifier(aggregateSubstitution); elementSubstitution.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); 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 a9cbde0f3..59670bc6d 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 @@ -39,11 +39,11 @@ import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; import at.ac.tuwien.kr.alpha.core.rules.heads.ChoiceHeadImpl; @@ -99,7 +99,7 @@ public ASPCore2Program apply(ASPCore2Program inputProgram) { Predicate negPredicate = CorePredicate.getInstance(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true); List headTerms = new ArrayList<>(head.getTerms()); - headTerms.add(0, CoreConstantTerm.getInstance("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for + headTerms.add(0, Terms.newConstant("1")); // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for // classical negative atoms. CoreAtom negHead = new BasicAtom(negPredicate, headTerms); 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 f9379007a..5ce442e75 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 @@ -38,10 +38,10 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; 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.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; @@ -98,9 +98,9 @@ private static Literal rewriteLiteral(Literal lit, Map intervalReplacement) { + private static FunctionTermImpl rewriteFunctionTerm(FunctionTermImpl functionTerm, Map intervalReplacement) { List termList = new ArrayList<>(functionTerm.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { @@ -123,9 +123,9 @@ private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map> rewriteAggregatesInRule(Rule rule) { Unifier aggregateUnifier = new Unifier(); Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), CoreConstantTerm.getInstance(aggregateCount)); + aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), Terms.newConstant(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); - globalVariableTermlist.add(CoreConstantTerm.getInstance(aggregateCount)); - aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTerm.getInstance("agg", globalVariableTermlist)); + globalVariableTermlist.add(Terms.newConstant(aggregateCount)); + aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); } aggregateUnifier.put(VariableTermImpl.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); @@ -170,7 +170,7 @@ private List> rewriteAggregatesInRule(Rule rule) { for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. List elementTerms = aggregateElement.getElementTerms(); - FunctionTerm elementTuple = FunctionTerm.getInstance("element_tuple", elementTerms); + FunctionTermImpl elementTuple = FunctionTermImpl.getInstance("element_tuple", elementTerms); Unifier elementUnifier = new Unifier(aggregateUnifier); elementUnifier.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); elementUnifier.put(VariableTermImpl.getInstance("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); 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 cecb63498..d917bf26b 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 @@ -39,9 +39,9 @@ import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; -import at.ac.tuwien.kr.alpha.core.grounder.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfoImpl; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; 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 55c7e7ace..e09279094 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 @@ -27,6 +27,7 @@ */ package at.ac.tuwien.kr.alpha.core.solver; +import static at.ac.tuwien.kr.alpha.api.Util.oops; import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToNegatedLiteral; @@ -34,7 +35,6 @@ import static at.ac.tuwien.kr.alpha.core.solver.ThriceTruth.MBT; import static at.ac.tuwien.kr.alpha.core.solver.heuristics.BranchingHeuristic.DEFAULT_CHOICE_LITERAL; import static at.ac.tuwien.kr.alpha.core.solver.learning.GroundConflictNoGoodLearner.ConflictAnalysisResult.UNSAT; -import static at.ac.tuwien.kr.alpha.api.Util.oops; import java.util.ArrayList; import java.util.Iterator; @@ -55,13 +55,13 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; 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.NoGood; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.ProgramAnalyzingGrounder; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; @@ -367,9 +367,9 @@ private boolean treatConflictAfterClosing(Antecedent violatedNoGood) { } // For RuleAtoms in toJustify the corresponding ground body contains BasicAtoms that have been assigned FALSE in the closing. // First, translate RuleAtom back to NonGroundRule + Substitution. - String ruleId = (String) ((CoreConstantTerm)atom.getTerms().get(0)).getObject(); + String ruleId = (String) ((ConstantTerm)atom.getTerms().get(0)).getObject(); CompiledRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId)); - String substitution = (String) ((CoreConstantTerm)atom.getTerms().get(1)).getObject(); + String substitution = (String) ((ConstantTerm)atom.getTerms().get(1)).getObject(); SubstitutionImpl groundingSubstitution = SubstitutionImpl.fromString(substitution); // Find ground literals in the body that have been assigned false and justify those. for (Literal bodyLiteral : nonGroundRule.getBody()) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java index 21a3616f9..07965090c 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java @@ -32,12 +32,12 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.NoGood; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; /** * Provides utility methods for test cases @@ -54,7 +54,7 @@ public static Atom atom(String predicateName, String... termStrings) { if (StringUtils.isAllUpperCase(termString.substring(0, 1))) { terms[i] = VariableTermImpl.getInstance(termString); } else { - terms[i] = CoreConstantTerm.getInstance(termString); + terms[i] = Terms.newConstant(termString); } } return new BasicAtom(CorePredicate.getInstance(predicateName, terms.length), terms); @@ -63,7 +63,7 @@ public static Atom atom(String predicateName, String... termStrings) { public static Atom atom(String predicateName, int... termInts) { Term[] terms = new Term[termInts.length]; for (int i = 0; i < termInts.length; i++) { - terms[i] = CoreConstantTerm.getInstance(termInts[i]); + terms[i] = Terms.newConstant(termInts[i]); } return new BasicAtom(CorePredicate.getInstance(predicateName, terms.length), terms); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java index 7d4e5ae3d..b624f3961 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java @@ -52,15 +52,15 @@ import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; 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.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.IntervalTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; /** @@ -87,8 +87,8 @@ public void parseFactWithFunctionTerms() throws IOException { assertEquals("Program contains one fact.", 1, parsedProgram.getFacts().size()); assertEquals("Predicate name of fact is p.", "p", parsedProgram.getFacts().get(0).getPredicate().getName()); assertEquals("Fact has two terms.", 2, parsedProgram.getFacts().get(0).getPredicate().getArity()); - assertEquals("First term is function term f.", "f", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(0)).getSymbol()); - assertEquals("Second term is function term g.", "g", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(1)).getSymbol()); + assertEquals("First term is function term f.", "f", ((FunctionTermImpl) parsedProgram.getFacts().get(0).getTerms().get(0)).getSymbol()); + assertEquals("Second term is function term g.", "g", ((FunctionTermImpl) parsedProgram.getFacts().get(0).getTerms().get(1)).getSymbol()); } @Test @@ -123,9 +123,9 @@ public void parseProgramWithDisjunctionInHead() throws IOException { public void parseInterval() throws IOException { 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(CoreConstantTerm.getInstance(2), CoreConstantTerm.getInstance(5)))); + 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); - assertTrue(bodyInterval.equals(IntervalTerm.getInstance(CoreConstantTerm.getInstance(3), VariableTermImpl.getInstance("X")))); + assertTrue(bodyInterval.equals(IntervalTerm.getInstance(Terms.newConstant(3), VariableTermImpl.getInstance("X")))); } @Test @@ -150,9 +150,9 @@ public void parseChoiceRuleBounded() throws IOException { assertEquals(2, conditionalLiterals.size()); assertFalse(conditionalLiterals.get(0).isNegated()); assertTrue(conditionalLiterals.get(1).isNegated()); - assertEquals(CoreConstantTerm.getInstance(1), choiceHead.getLowerBound()); + assertEquals(Terms.newConstant(1), choiceHead.getLowerBound()); assertEquals(ComparisonOperatorImpl.LT, choiceHead.getLowerOperator()); - assertEquals(CoreConstantTerm.getInstance(13), choiceHead.getUpperBound()); + assertEquals(Terms.newConstant(13), choiceHead.getUpperBound()); assertEquals(ComparisonOperatorImpl.LE, choiceHead.getUpperOperator()); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java index cdde34fd1..316624e6b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; public class AspStandardLibraryTest { @@ -18,12 +18,12 @@ public void parseDateTime1() { Assert.assertEquals(1, dtSubstitution.size()); List> dtTerms = dtSubstitution.stream().findFirst().get(); Assert.assertEquals(6, dtTerms.size()); - Assert.assertEquals(CoreConstantTerm.getInstance(2020), dtTerms.get(0)); - Assert.assertEquals(CoreConstantTerm.getInstance(5), dtTerms.get(1)); - Assert.assertEquals(CoreConstantTerm.getInstance(20), dtTerms.get(2)); - Assert.assertEquals(CoreConstantTerm.getInstance(1), dtTerms.get(3)); - Assert.assertEquals(CoreConstantTerm.getInstance(19), dtTerms.get(4)); - Assert.assertEquals(CoreConstantTerm.getInstance(13), dtTerms.get(5)); + Assert.assertEquals(Terms.newConstant(2020), dtTerms.get(0)); + Assert.assertEquals(Terms.newConstant(5), dtTerms.get(1)); + Assert.assertEquals(Terms.newConstant(20), dtTerms.get(2)); + Assert.assertEquals(Terms.newConstant(1), dtTerms.get(3)); + Assert.assertEquals(Terms.newConstant(19), dtTerms.get(4)); + Assert.assertEquals(Terms.newConstant(13), dtTerms.get(5)); } @Test @@ -32,12 +32,12 @@ public void parseDateTime2() { Assert.assertEquals(1, dtSubstitution.size()); List> dtTerms = dtSubstitution.stream().findFirst().get(); Assert.assertEquals(6, dtTerms.size()); - Assert.assertEquals(CoreConstantTerm.getInstance(2123), dtTerms.get(0)); - Assert.assertEquals(CoreConstantTerm.getInstance(7), dtTerms.get(1)); - Assert.assertEquals(CoreConstantTerm.getInstance(18), dtTerms.get(2)); - Assert.assertEquals(CoreConstantTerm.getInstance(22), dtTerms.get(3)); - Assert.assertEquals(CoreConstantTerm.getInstance(37), dtTerms.get(4)); - Assert.assertEquals(CoreConstantTerm.getInstance(1), dtTerms.get(5)); + Assert.assertEquals(Terms.newConstant(2123), dtTerms.get(0)); + Assert.assertEquals(Terms.newConstant(7), dtTerms.get(1)); + Assert.assertEquals(Terms.newConstant(18), dtTerms.get(2)); + Assert.assertEquals(Terms.newConstant(22), dtTerms.get(3)); + Assert.assertEquals(Terms.newConstant(37), dtTerms.get(4)); + Assert.assertEquals(Terms.newConstant(1), dtTerms.get(5)); } @Test @@ -47,12 +47,12 @@ public void parseDateTime3() { Assert.assertEquals(1, dtSubstitution.size()); List> dtTerms = dtSubstitution.stream().findFirst().get(); Assert.assertEquals(6, dtTerms.size()); - Assert.assertEquals(CoreConstantTerm.getInstance(2019), dtTerms.get(0)); - Assert.assertEquals(CoreConstantTerm.getInstance(12), dtTerms.get(1)); - Assert.assertEquals(CoreConstantTerm.getInstance(3), dtTerms.get(2)); - Assert.assertEquals(CoreConstantTerm.getInstance(11), dtTerms.get(3)); - Assert.assertEquals(CoreConstantTerm.getInstance(0), dtTerms.get(4)); - Assert.assertEquals(CoreConstantTerm.getInstance(0), dtTerms.get(5)); + Assert.assertEquals(Terms.newConstant(2019), dtTerms.get(0)); + Assert.assertEquals(Terms.newConstant(12), dtTerms.get(1)); + Assert.assertEquals(Terms.newConstant(3), dtTerms.get(2)); + Assert.assertEquals(Terms.newConstant(11), dtTerms.get(3)); + Assert.assertEquals(Terms.newConstant(0), dtTerms.get(4)); + Assert.assertEquals(Terms.newConstant(0), dtTerms.get(5)); } @Test @@ -89,7 +89,7 @@ public void stringLength() { List> lengthTerms = result.stream().findFirst().get(); Assert.assertEquals(1, lengthTerms.size()); ConstantTerm lenTerm = lengthTerms.get(0); - Assert.assertEquals(CoreConstantTerm.getInstance(21), lenTerm); + Assert.assertEquals(Terms.newConstant(21), lenTerm); } @Test @@ -99,7 +99,7 @@ public void stringConcat() { List> concatTerms = result.stream().findFirst().get(); Assert.assertEquals(1, concatTerms.size()); ConstantTerm concat = concatTerms.get(0); - Assert.assertEquals(CoreConstantTerm.getInstance("Foobar"), concat); + Assert.assertEquals(Terms.newConstant("Foobar"), concat); } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java index 92cb6dfbf..f03858e3a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java @@ -1,10 +1,10 @@ package at.ac.tuwien.kr.alpha.common; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; /** * Copyright (c) 2018, the Alpha Team. @@ -15,7 +15,7 @@ public class AtomStoreTest { public static void fillAtomStore(AtomStore atomStore, int numberOfAtomsToFill) { Predicate predA = CorePredicate.getInstance("a", 1); for (int i = 0; i < numberOfAtomsToFill; i++) { - atomStore.putIfAbsent(new BasicAtom(predA, CoreConstantTerm.getInstance(i))); + atomStore.putIfAbsent(new BasicAtom(predA, Terms.newConstant(i))); } } } \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java index 80f27f8fb..397ab25f2 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java @@ -17,10 +17,10 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.BasicAnswerSet; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; /** * Copyright (c) 2016, the Alpha Team. @@ -36,8 +36,8 @@ public void areAnswerSetsEqual() throws Exception { Predicate p = CorePredicate.getInstance("p", 1); SortedSet qAndP = new TreeSet<>(asList(q, p)); - ConstantTerm bar = CoreConstantTerm.getInstance("bar"); - ConstantTerm baz = CoreConstantTerm.getInstance("baz"); + ConstantTerm bar = Terms.newConstant("bar"); + ConstantTerm baz = Terms.newConstant("baz"); Map> inst1 = new HashMap<>(); inst1.put(a, new TreeSet<>(singleton(new BasicAtom(a)))); @@ -68,7 +68,7 @@ public void areAnswerSetsEqual() throws Exception { inst4.put(foo, new TreeSet<>(asList( new BasicAtom(foo, bar), new BasicAtom(foo, baz), - new BasicAtom(foo, CoreConstantTerm.getInstance("batsinga")) + new BasicAtom(foo, Terms.newConstant("batsinga")) ))); // as4 = { a, foo(bar), foo(baz), foo(batsinga) } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java index f16d68ce1..01d43adf4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java @@ -16,9 +16,9 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.externals.Externals; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -48,7 +48,7 @@ public static final boolean isFoo(int bar) { public static final Set>> extWithOutput(int in) { Set>> retVal = new HashSet<>(); List> lst = new ArrayList<>(); - lst.add(CoreConstantTerm.getSymbolicInstance(Integer.toString(in))); + lst.add(Terms.newConstant(in)); retVal.add(lst); return retVal; } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java deleted file mode 100644 index ba36bbde1..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/terms/TermsTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.kr.alpha.common.terms; - -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; - -import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.Terms; - -public class TermsTest { - - @Test - public void integersAsTermList() { - List> intTerms = Terms.asTermList(1, 2, 3, 4, 5, 6); - Assert.assertEquals(6, intTerms.size()); - Assert.assertEquals(CoreConstantTerm.getInstance(1), intTerms.get(0)); - Assert.assertEquals(CoreConstantTerm.getInstance(2), intTerms.get(1)); - Assert.assertEquals(CoreConstantTerm.getInstance(3), intTerms.get(2)); - Assert.assertEquals(CoreConstantTerm.getInstance(4), intTerms.get(3)); - Assert.assertEquals(CoreConstantTerm.getInstance(5), intTerms.get(4)); - Assert.assertEquals(CoreConstantTerm.getInstance(6), intTerms.get(5)); - } - - @Test - public void stringsAsTermList() { - List> terms = Terms.asTermList("bla", "blubb"); - Assert.assertEquals(2, terms.size()); - Assert.assertEquals("\"bla\"", terms.get(0).toString()); - Assert.assertEquals("\"blubb\"", terms.get(1).toString()); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java index f7c03533c..1c3ddb583 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java @@ -38,8 +38,8 @@ import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; /** * Copyright (c) 2016, the Alpha Team. @@ -50,12 +50,12 @@ public void testIndexedInstanceStorage() { IndexedInstanceStorage storage = new IndexedInstanceStorage(CorePredicate.getInstance("p", 4), true); storage.addIndexPosition(0); storage.addIndexPosition(2); - ConstantTerm t0 = CoreConstantTerm.getInstance("0"); - ConstantTerm t1 = CoreConstantTerm.getInstance("1"); - ConstantTerm t2 = CoreConstantTerm.getInstance("2"); - ConstantTerm t3 = CoreConstantTerm.getInstance("3"); - ConstantTerm t4 = CoreConstantTerm.getInstance("4"); - ConstantTerm t5 = CoreConstantTerm.getInstance("5"); + ConstantTerm t0 = Terms.newConstant("0"); + ConstantTerm t1 = Terms.newConstant("1"); + ConstantTerm t2 = Terms.newConstant("2"); + ConstantTerm t3 = Terms.newConstant("3"); + ConstantTerm t4 = Terms.newConstant("4"); + ConstantTerm t5 = Terms.newConstant("5"); Instance badInst1 = new Instance(t1, t1, t0); Instance badInst2 = new Instance(t5, t5, t5, t5, t5); 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 5c97e1d00..17b5e4bfa 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 @@ -49,12 +49,12 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; +import at.ac.tuwien.kr.alpha.commons.Terms; 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.Literals; import at.ac.tuwien.kr.alpha.core.common.NoGood; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; 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; @@ -226,7 +226,7 @@ private void testDeadEnd(String predicateNameOfStartingLiteral, RuleGroundingOrd grounder.bootstrap(); TrailAssignment currentAssignment = new TrailAssignment(atomStore); - final Substitution subst1 = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(CoreConstantTerm.getInstance(1)), SubstitutionImpl.EMPTY_SUBSTITUTION); + final Substitution subst1 = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(1)), SubstitutionImpl.EMPTY_SUBSTITUTION); final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, groundingOrder, subst1, currentAssignment); assertEquals(expectNoGoods, bindingResult.size() > 0); @@ -285,7 +285,7 @@ private void testIfGrounderGroundsRule(ASPCore2Program program, int ruleID, Lite grounder.bootstrap(); final CompiledRule nonGroundRule = grounder.getNonGroundRule(ruleID); - final Substitution substStartingLiteral = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(CoreConstantTerm.getInstance(startingInstance)), SubstitutionImpl.EMPTY_SUBSTITUTION); + final Substitution substStartingLiteral = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(startingInstance)), SubstitutionImpl.EMPTY_SUBSTITUTION); final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingInfo().orderStartingFrom(startingLiteral), substStartingLiteral, currentAssignment); assertEquals(expectNoGoods, bindingResult.size() > 0); } @@ -396,7 +396,7 @@ private void testPermissiveGrounderHeuristicTolerance(ASPCore2Program program, i grounder.bootstrap(); final CompiledRule nonGroundRule = grounder.getNonGroundRule(ruleID); - final Substitution substStartingLiteral = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(CoreConstantTerm.getInstance(startingInstance)), SubstitutionImpl.EMPTY_SUBSTITUTION); + final Substitution substStartingLiteral = SubstitutionImpl.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(startingInstance)), SubstitutionImpl.EMPTY_SUBSTITUTION); final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingInfo().orderStartingFrom(startingLiteral), substStartingLiteral, currentAssignment); assertEquals(expectNoGoods, bindingResult.size() > 0); if (bindingResult.size() > 0) { 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 16473387d..4971c6411 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 @@ -38,11 +38,11 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; 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.Literals; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; @@ -57,8 +57,8 @@ public class NoGoodGeneratorTest { private static final ProgramParser PARSER = new ProgramParserImpl(); private static final NormalizeProgramTransformation NORMALIZE_TRANSFORM = new NormalizeProgramTransformation(false); - private static final ConstantTerm A = CoreConstantTerm.getSymbolicInstance("a"); - private static final ConstantTerm B = CoreConstantTerm.getSymbolicInstance("b"); + private static final ConstantTerm A = Terms.newSymbolicConstant("a"); + private static final ConstantTerm B = Terms.newSymbolicConstant("b"); private static final VariableTerm X = VariableTermImpl.getInstance("X"); private static final VariableTerm Y = VariableTermImpl.getInstance("Y"); 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 df447a253..0285bcc05 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 @@ -44,13 +44,13 @@ 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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.FunctionTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; @@ -59,9 +59,9 @@ public class SubstitutionTest { private static final ProgramParser PARSER = new ProgramParserImpl(); - private static final ConstantTerm A = CoreConstantTerm.getSymbolicInstance("a"); - private static final ConstantTerm B = CoreConstantTerm.getSymbolicInstance("b"); - private static final ConstantTerm C = CoreConstantTerm.getSymbolicInstance("c"); + private static final ConstantTerm A = Terms.newSymbolicConstant("a"); + private static final ConstantTerm B = Terms.newSymbolicConstant("b"); + private static final ConstantTerm C = Terms.newSymbolicConstant("c"); private static final VariableTerm X = VariableTermImpl.getInstance("X"); private static final VariableTerm Y = VariableTermImpl.getInstance("Y"); @@ -88,9 +88,9 @@ public void specializeTermsFunctionTermBinding() { Substitution substitution = new SubstitutionImpl(); substitution.put(Y, A); - FunctionTerm groundFunctionTerm = FunctionTerm.getInstance("f", B, C); + FunctionTermImpl groundFunctionTerm = FunctionTermImpl.getInstance("f", B, C); Instance qfBC = new Instance(groundFunctionTerm); - Term nongroundFunctionTerm = FunctionTerm.getInstance("f", B, X); + Term nongroundFunctionTerm = FunctionTermImpl.getInstance("f", B, X); BasicAtom qfBX = new BasicAtom(CorePredicate.getInstance("q", 2), nongroundFunctionTerm); Substitution substitution1 = SubstitutionImpl.specializeSubstitution(qfBX, qfBC, substitution); 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 772b40dc1..4b72ec8ee 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 @@ -37,9 +37,9 @@ import at.ac.tuwien.kr.alpha.api.program.ProgramParser; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; public class UnifierTest extends SubstitutionTest { @@ -51,13 +51,13 @@ public void extendUnifier() { Unifier sub1 = new Unifier(); sub1.put(varX, varY); Unifier sub2 = new Unifier(); - sub2.put(varY, CoreConstantTerm.getInstance("a")); + sub2.put(varY, Terms.newConstant("a")); sub1.extendWith(sub2); BasicAtom atom1 = parseAtom("p(X)"); Atom atomSubstituted = atom1.substitute(sub1); - assertEquals(CoreConstantTerm.getInstance("a"), atomSubstituted.getTerms().get(0)); + assertEquals(Terms.newConstant("a"), atomSubstituted.getTerms().get(0)); } @Test @@ -65,7 +65,7 @@ public void mergeUnifierIntoLeft() { VariableTerm varX = VariableTermImpl.getInstance("X"); VariableTerm varY = VariableTermImpl.getInstance("Y"); VariableTerm varZ = VariableTermImpl.getInstance("Z"); - Term constA = CoreConstantTerm.getInstance("a"); + Term constA = Terms.newConstant("a"); Unifier left = new Unifier(); left.put(varX, varY); left.put(varZ, varY); 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 71b294498..fe7cabcc0 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 @@ -39,6 +39,7 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; 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; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; @@ -47,7 +48,6 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; import at.ac.tuwien.kr.alpha.core.rules.heads.NormalHeadImpl; @@ -103,13 +103,13 @@ private void createBasicAtom1() { } private void createBasicAtom2() { - atomStore.putIfAbsent(new BasicAtom(CorePredicate.getInstance("q", 1), CoreConstantTerm.getInstance(1))); + atomStore.putIfAbsent(new BasicAtom(CorePredicate.getInstance("q", 1), Terms.newConstant(1))); } private void createAggregateAtom() { - final ConstantTerm c1 = CoreConstantTerm.getInstance(1); - final ConstantTerm c2 = CoreConstantTerm.getInstance(2); - final ConstantTerm c3 = CoreConstantTerm.getInstance(3); + final ConstantTerm c1 = Terms.newConstant(1); + final ConstantTerm c2 = Terms.newConstant(2); + final ConstantTerm c3 = Terms.newConstant(3); List basicTerms = Arrays.asList(c1, c2, c3); AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, Collections.singletonList(new BasicAtom(CorePredicate.getInstance("p", 3), c1, c2, c3).toLiteral())); atomStore.putIfAbsent(new AggregateAtom(ComparisonOperatorImpl.LE, c1, null, null, AggregateAtom.AGGREGATEFUNCTION.COUNT, Collections.singletonList(aggregateElement))); 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 46b4f0df1..e6e08b163 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 @@ -44,9 +44,9 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; /** @@ -118,7 +118,7 @@ private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { if (atom.getPredicate().getName().equals(ongoal.getName()) && atom.getPredicate().getArity() == ongoal.getArity()) { Term expectedTop = atom.getTerms().get(0); Term expectedBottom = atom.getTerms().get(1); - Term expectedSteps = CoreConstantTerm.getInstance(steps); + Term expectedSteps = Terms.newConstant(steps); Atom expectedAtom = new BasicAtom(on, expectedSteps, expectedBottom, expectedTop); assertTrue("Answer set does not contain " + expectedAtom, onInstancesInAnswerSet.contains(expectedAtom)); } 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 978557637..97f0a947d 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 @@ -45,12 +45,12 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; 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.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; 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.parser.InlineDirectivesImpl; @@ -75,7 +75,7 @@ public int compareTo(Thingy o) { public void testObjectProgram() throws IOException { final Thingy thingy = new Thingy(); - final Atom fact = new BasicAtom(CorePredicate.getInstance("foo", 1), CoreConstantTerm.getInstance(thingy)); + final Atom fact = new BasicAtom(CorePredicate.getInstance("foo", 1), Terms.newConstant(thingy)); final InputProgram program = new InputProgram( Collections.emptyList(), 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 17e348e8f..b92242ab1 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 @@ -38,9 +38,9 @@ import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; @@ -143,7 +143,7 @@ private List createEdges(int vertices, int edges) { private Atom fact(String predicateName, int... iTerms) { List terms = new ArrayList<>(1); for (int i : iTerms) { - terms.add(CoreConstantTerm.getInstance(i)); + terms.add(Terms.newConstant(i)); } return new BasicAtom(CorePredicate.getInstance(predicateName, iTerms.length), terms); } 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 97c1dbbd8..f1b170556 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 @@ -41,9 +41,9 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; @@ -180,7 +180,7 @@ private List createColors(String... colours) { List facts = new ArrayList<>(colours.length); for (String colour : colours) { List terms = new ArrayList<>(1); - terms.add(CoreConstantTerm.getInstance(colour)); + terms.add(Terms.newConstant(colour)); facts.add(new BasicAtom(CorePredicate.getInstance("c", 1), terms)); } return facts; @@ -225,7 +225,7 @@ private Atom fact(String predicateName, int... iTerms) { List terms = new ArrayList<>(iTerms.length); Predicate predicate = CorePredicate.getInstance(predicateName, iTerms.length); for (int i : iTerms) { - terms.add(CoreConstantTerm.getInstance(i)); + terms.add(Terms.newConstant(i)); } return new BasicAtom(predicate, terms); } 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 2ff699cbf..3584e4672 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 @@ -39,9 +39,9 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.InputProgram; @@ -118,7 +118,7 @@ private List createColors(String... colours) { Predicate predicate = CorePredicate.getInstance("c", 1); for (String colour : colours) { List terms = new ArrayList<>(1); - terms.add(CoreConstantTerm.getInstance(colour)); + terms.add(Terms.newConstant(colour)); facts.add(new BasicAtom(predicate, terms)); } return facts; @@ -148,7 +148,7 @@ private Atom fact(String predicateName, int... iTerms) { List terms = new ArrayList<>(1); Predicate predicate = CorePredicate.getInstance(predicateName, iTerms.length); for (int i : iTerms) { - terms.add(CoreConstantTerm.getInstance(i)); + terms.add(Terms.newConstant(i)); } return new BasicAtom(predicate, terms); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java index 8f2884da1..41570b427 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java @@ -12,13 +12,13 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; 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.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.NaiveGrounder; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; @@ -37,13 +37,13 @@ public void workingMemoryBasedInstantiationAcceptLiteral() { Predicate p = CorePredicate.getInstance("p", 1); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), true); + workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("a")), true); LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); Literal positiveAcceptedLiteral = new BasicLiteral( - new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), true); + new BasicAtom(p, Terms.newSymbolicConstant("a")), true); Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(positiveAcceptedLiteral)); Literal negativeAcceptedLiteral = new BasicLiteral( - new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("b")), false); + new BasicAtom(p, Terms.newSymbolicConstant("b")), false); Assert.assertEquals(AssignmentStatus.TRUE, strategy.getTruthForGroundLiteral(negativeAcceptedLiteral)); } @@ -52,13 +52,13 @@ public void workingMemoryBasedInstantiationRejectLiteral() { Predicate p = CorePredicate.getInstance("p", 1); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), true); + workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("a")), true); LiteralInstantiationStrategy strategy = new WorkingMemoryBasedInstantiationStrategy(workingMemory); Literal positiveRejectedLiteral = new BasicLiteral( - new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("b")), true); + new BasicAtom(p, Terms.newSymbolicConstant("b")), true); Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(positiveRejectedLiteral)); Literal negativeRejectedLiteral = new BasicLiteral( - new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")), false); + new BasicAtom(p, Terms.newSymbolicConstant("a")), false); Assert.assertEquals(AssignmentStatus.FALSE, strategy.getTruthForGroundLiteral(negativeRejectedLiteral)); } @@ -75,7 +75,7 @@ public void workingMemoryBasedInstantiationRejectLiteral() { @Test public void defaultLazyGroundingNoAssignmentGroundLiteral() { Predicate p = CorePredicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); + BasicAtom pOfA = new BasicAtom(p, Terms.newSymbolicConstant("a")); WorkingMemory workingMemory = new WorkingMemory(); LinkedHashSet staleSet = new LinkedHashSet<>(); DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), @@ -103,10 +103,10 @@ public void defaultLazyGroundingNoAssignmentGroundLiteral() { @Test public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); LinkedHashSet staleSet = new LinkedHashSet<>(); DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, new AtomStoreImpl(), Collections.emptyMap()); @@ -121,7 +121,7 @@ public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); - Assert.assertEquals(CoreConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTermImpl.getInstance("X"))); + Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(VariableTermImpl.getInstance("X"))); Assert.assertTrue(staleSet.isEmpty()); } @@ -138,7 +138,7 @@ public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { @Test public void defaultLazyGroundingCheckUnassignedGroundLiteral() { Predicate p = CorePredicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); + BasicAtom pOfA = new BasicAtom(p, Terms.newSymbolicConstant("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -168,7 +168,7 @@ public void defaultLazyGroundingCheckUnassignedGroundLiteral() { @Test public void defaultLazyGroundingCheckFalseGroundLiteral() { Predicate p = CorePredicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); + BasicAtom pOfA = new BasicAtom(p, Terms.newSymbolicConstant("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -201,7 +201,7 @@ public void defaultLazyGroundingCheckFalseGroundLiteral() { @Test public void defaultLazyGroundingCheckTrueGroundLiteral() { Predicate p = CorePredicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); + BasicAtom pOfA = new BasicAtom(p, Terms.newSymbolicConstant("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -233,7 +233,7 @@ public void defaultLazyGroundingCheckTrueGroundLiteral() { @Test public void defaultLazyGroundingCheckMustBeTrueGroundLiteral() { Predicate p = CorePredicate.getInstance("p", 1); - BasicAtom pOfA = new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("a")); + BasicAtom pOfA = new BasicAtom(p, Terms.newSymbolicConstant("a")); WorkingMemory workingMemory = new WorkingMemory(); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); @@ -266,10 +266,10 @@ public void defaultLazyGroundingCheckMustBeTrueGroundLiteral() { @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); LinkedHashSet staleSet = new LinkedHashSet<>(); @@ -286,10 +286,10 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.UNASSIGNED, assignmentStatus); Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); - Assert.assertEquals(CoreConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTermImpl.getInstance("X"))); + Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(VariableTermImpl.getInstance("X"))); Assert.assertEquals(1, staleSet.size()); - Assert.assertTrue(staleSet.contains(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")))); + Assert.assertTrue(staleSet.contains(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")))); } /** @@ -305,13 +305,13 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); - BasicAtom groundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")); + BasicAtom groundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")); atomStore.putIfAbsent(groundAtom); assignment.growForMaxAtomId(); assignment.assign(atomStore.get(groundAtom), ThriceTruth.TRUE); @@ -329,7 +329,7 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); - Assert.assertEquals(CoreConstantTerm.getSymbolicInstance("b"), substitution.eval(VariableTermImpl.getInstance("X"))); + Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(VariableTermImpl.getInstance("X"))); Assert.assertTrue(staleSet.isEmpty()); } @@ -346,13 +346,13 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithFalseInstance() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); - workingMemory.addInstance(new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")), true); + workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); AtomStore atomStore = new AtomStoreImpl(); WritableAssignment assignment = new TrailAssignment(atomStore); - BasicAtom groundAtom = new BasicAtom(q, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getSymbolicInstance("b")); + BasicAtom groundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")); atomStore.putIfAbsent(groundAtom); assignment.growForMaxAtomId(); assignment.assign(atomStore.get(groundAtom), ThriceTruth.FALSE); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java index 430b57aa3..d82909fe4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java @@ -12,6 +12,8 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; @@ -20,8 +22,6 @@ import at.ac.tuwien.kr.alpha.core.atoms.EnumerationLiteral; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; -import at.ac.tuwien.kr.alpha.core.common.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory; import at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus; @@ -33,7 +33,7 @@ public class LiteralInstantiatorTest { @Test public void instantiateSatisfiedFixedInterpretationLiteral() { - ComparisonAtom equalsThree = new ComparisonAtom(CoreConstantTerm.getInstance(3), VariableTermImpl.getInstance("THREE"), ComparisonOperatorImpl.EQ); + ComparisonAtom equalsThree = new ComparisonAtom(Terms.newConstant(3), VariableTermImpl.getInstance("THREE"), ComparisonOperatorImpl.EQ); Literal lit = new ComparisonLiteral(equalsThree, true); Substitution substitution = new SubstitutionImpl(); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); @@ -44,7 +44,7 @@ public void instantiateSatisfiedFixedInterpretationLiteral() { Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitutions.get(0).right); Substitution extendedSubstitution = resultSubstitutions.get(0).left; Assert.assertTrue(extendedSubstitution.isVariableSet(VariableTermImpl.getInstance("THREE"))); - Assert.assertEquals(CoreConstantTerm.getInstance(3), extendedSubstitution.eval(VariableTermImpl.getInstance("THREE"))); + Assert.assertEquals(Terms.newConstant(3), extendedSubstitution.eval(VariableTermImpl.getInstance("THREE"))); } @Test @@ -52,8 +52,8 @@ public void instantiateUnsatisfiedFixedInterpretationLiteral() { ComparisonAtom fiveEqualsThree = new ComparisonAtom(VariableTermImpl.getInstance("FIVE"), VariableTermImpl.getInstance("THREE"), ComparisonOperatorImpl.EQ); Literal lit = new ComparisonLiteral(fiveEqualsThree, true); Substitution substitution = new SubstitutionImpl(); - substitution.put(VariableTermImpl.getInstance("FIVE"), CoreConstantTerm.getInstance(5)); - substitution.put(VariableTermImpl.getInstance("THREE"), CoreConstantTerm.getInstance(3)); + substitution.put(VariableTermImpl.getInstance("FIVE"), Terms.newConstant(5)); + substitution.put(VariableTermImpl.getInstance("THREE"), Terms.newConstant(3)); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.STOP_BINDING, result.getType()); @@ -71,8 +71,8 @@ public void instantiateEnumLiteral() { EnumerationAtom enumAtom = new EnumerationAtom(termList); EnumerationLiteral lit = new EnumerationLiteral(enumAtom); Substitution substitution = new SubstitutionImpl(); - substitution.put(enumTerm, CoreConstantTerm.getSymbolicInstance("enum1")); - substitution.put(idTerm, CoreConstantTerm.getSymbolicInstance("someElement")); + substitution.put(enumTerm, Terms.newSymbolicConstant("enum1")); + substitution.put(idTerm, Terms.newSymbolicConstant("someElement")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); @@ -87,13 +87,13 @@ public void workingMemoryBasedVerifyPositiveGroundLiteralSatisfied() { Predicate p = CorePredicate.getInstance("p", 2); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("x"), CoreConstantTerm.getSymbolicInstance("y")), true); + workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("x"), Terms.newSymbolicConstant("y")), true); VariableTerm x = VariableTermImpl.getInstance("X"); VariableTerm y = VariableTermImpl.getInstance("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); Substitution substitution = new SubstitutionImpl(); - substitution.put(x, CoreConstantTerm.getSymbolicInstance("x")); - substitution.put(y, CoreConstantTerm.getSymbolicInstance("y")); + substitution.put(x, Terms.newSymbolicConstant("x")); + substitution.put(y, Terms.newSymbolicConstant("y")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); @@ -115,8 +115,8 @@ public void workingMemoryBasedVerifyPositiveGroundLiteralUnsatisfied() { VariableTerm y = VariableTermImpl.getInstance("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); Substitution substitution = new SubstitutionImpl(); - substitution.put(x, CoreConstantTerm.getSymbolicInstance("x")); - substitution.put(y, CoreConstantTerm.getSymbolicInstance("y")); + substitution.put(x, Terms.newSymbolicConstant("x")); + substitution.put(y, Terms.newSymbolicConstant("y")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); // With the given input substitution, lit is ground, but not satisfied - @@ -130,13 +130,13 @@ public void workingMemoryBasedInstantiatePositiveBasicLiteral() { Predicate p = CorePredicate.getInstance("p", 2); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("x"), CoreConstantTerm.getSymbolicInstance("y")), true); - workingMemory.addInstance(new BasicAtom(p, CoreConstantTerm.getSymbolicInstance("x"), CoreConstantTerm.getSymbolicInstance("z")), true); + workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("x"), Terms.newSymbolicConstant("y")), true); + workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("x"), Terms.newSymbolicConstant("z")), true); VariableTerm x = VariableTermImpl.getInstance("X"); VariableTerm y = VariableTermImpl.getInstance("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); Substitution substitution = new SubstitutionImpl(); - substitution.put(x, CoreConstantTerm.getSymbolicInstance("x")); + substitution.put(x, Terms.newSymbolicConstant("x")); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.CONTINUE, result.getType()); @@ -147,9 +147,9 @@ public void workingMemoryBasedInstantiatePositiveBasicLiteral() { for (ImmutablePair resultSubstitution : substitutions) { Assert.assertTrue(resultSubstitution.left.isVariableSet(y)); Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitution.right); - if (resultSubstitution.left.eval(y).equals(CoreConstantTerm.getSymbolicInstance("y"))) { + if (resultSubstitution.left.eval(y).equals(Terms.newSymbolicConstant("y"))) { ySubstituted = true; - } else if (resultSubstitution.left.eval(y).equals(CoreConstantTerm.getSymbolicInstance("z"))) { + } else if (resultSubstitution.left.eval(y).equals(Terms.newSymbolicConstant("z"))) { zSubstituted = true; } else { Assert.fail("Invalid substitution for variable Y"); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java index 51ee7acf1..214799634 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java @@ -42,11 +42,11 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; 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.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; 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.InternalProgram; @@ -83,7 +83,7 @@ public void justifySimpleRules() { assignment.growForMaxAtomId(); assignment.assign(rId, ThriceTruth.FALSE); assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = new BasicAtom(CorePredicate.getInstance("p", 1), Collections.singletonList(CoreConstantTerm.getInstance(5))); + BasicAtom p5 = new BasicAtom(CorePredicate.getInstance("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()); @@ -159,11 +159,11 @@ public void justifyMultipleReasons() { assignment.assign(qeId, ThriceTruth.FALSE); Predicate nq = CorePredicate.getInstance("_nq", 2, true); - Atom nqa = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("a"))); - Atom nqb = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("b"))); - Atom nqc = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("c"))); - Atom nqd = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("d"))); - Atom nqe = new BasicAtom(nq, Arrays.asList(CoreConstantTerm.getInstance("1"), CoreConstantTerm.getSymbolicInstance("e"))); + Atom nqa = new BasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("a"))); + Atom nqb = new BasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("b"))); + Atom nqc = new BasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("c"))); + Atom nqd = new BasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("d"))); + Atom nqe = new BasicAtom(nq, Arrays.asList(Terms.newConstant("1"), Terms.newSymbolicConstant("e"))); int nqaId = atomStore.get(nqa); int nqbId = atomStore.get(nqb); int nqcId = atomStore.get(nqc); @@ -201,7 +201,7 @@ public void justifyNegatedFactsRemovedFromReasons() { assignment.growForMaxAtomId(); assignment.assign(rId, ThriceTruth.FALSE); assignment.assign(nrId, ThriceTruth.TRUE); - BasicAtom p5 = new BasicAtom(CorePredicate.getInstance("p", 1), Collections.singletonList(CoreConstantTerm.getInstance(5))); + BasicAtom p5 = new BasicAtom(CorePredicate.getInstance("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()); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java index e688cce72..4d943360d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java @@ -21,11 +21,11 @@ import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; 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.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; 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; @@ -178,13 +178,13 @@ private static void verifyAnswerSetsPartStratified(Set answerSets) { private static void verifyProgramPositiveRecursive(CompiledProgram evaluated) { Predicate num = CorePredicate.getInstance("num", 1); - TestUtils.assertFactsContainedInProgram(evaluated, new BasicAtom(CorePredicate.getInstance("max_num", 1), CoreConstantTerm.getInstance(10)), - new BasicAtom(num, CoreConstantTerm.getInstance(0)), - new BasicAtom(num, CoreConstantTerm.getInstance(1)), new BasicAtom(num, CoreConstantTerm.getInstance(2)), - new BasicAtom(num, CoreConstantTerm.getInstance(3)), new BasicAtom(num, CoreConstantTerm.getInstance(4)), - new BasicAtom(num, CoreConstantTerm.getInstance(5)), new BasicAtom(num, CoreConstantTerm.getInstance(6)), - new BasicAtom(num, CoreConstantTerm.getInstance(7)), new BasicAtom(num, CoreConstantTerm.getInstance(8)), - new BasicAtom(num, CoreConstantTerm.getInstance(9)), new BasicAtom(num, CoreConstantTerm.getInstance(10))); + TestUtils.assertFactsContainedInProgram(evaluated, new BasicAtom(CorePredicate.getInstance("max_num", 1), Terms.newConstant(10)), + new BasicAtom(num, Terms.newConstant(0)), + new BasicAtom(num, Terms.newConstant(1)), new BasicAtom(num, Terms.newConstant(2)), + new BasicAtom(num, Terms.newConstant(3)), new BasicAtom(num, Terms.newConstant(4)), + new BasicAtom(num, Terms.newConstant(5)), new BasicAtom(num, Terms.newConstant(6)), + new BasicAtom(num, Terms.newConstant(7)), new BasicAtom(num, Terms.newConstant(8)), + new BasicAtom(num, Terms.newConstant(9)), new BasicAtom(num, Terms.newConstant(10))); LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); Assert.assertEquals(0, evaluated.getRules().size()); } @@ -262,9 +262,9 @@ private static void verifyAnswerSetsEquality(Set answerSets) { private static void verifyProgramEqualityWithVar(CompiledProgram evaluated) { Assert.assertEquals(0, evaluated.getRules().size()); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("a", 1), CoreConstantTerm.getInstance(1)))); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("c", 1), CoreConstantTerm.getInstance(2)))); - Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("d", 1), CoreConstantTerm.getInstance(3)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("a", 1), Terms.newConstant(1)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("c", 1), Terms.newConstant(2)))); + Assert.assertTrue(evaluated.getFacts().contains(new BasicAtom(CorePredicate.getInstance("d", 1), Terms.newConstant(3)))); } private static void verifyAnswerSetsEqualityWithVar(Set answerSets) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java index ffb505e08..b1c346430 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java @@ -50,11 +50,11 @@ import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; 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.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; 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; @@ -248,9 +248,9 @@ public void testRecursiveRanking() { //@formatter:on CompiledProgram evaluated = parseAndEvaluate.apply(asp); Predicate rank = CorePredicate.getInstance("thing_rank", 2); - BasicAtom rank1 = new BasicAtom(rank, CoreConstantTerm.getSymbolicInstance("a"), CoreConstantTerm.getInstance(1)); - BasicAtom rank2 = new BasicAtom(rank, CoreConstantTerm.getSymbolicInstance("b"), CoreConstantTerm.getInstance(2)); - BasicAtom rank3 = new BasicAtom(rank, CoreConstantTerm.getSymbolicInstance("c"), CoreConstantTerm.getInstance(3)); + BasicAtom rank1 = new BasicAtom(rank, Terms.newSymbolicConstant("a"), Terms.newConstant(1)); + BasicAtom rank2 = new BasicAtom(rank, Terms.newSymbolicConstant("b"), Terms.newConstant(2)); + BasicAtom rank3 = new BasicAtom(rank, Terms.newSymbolicConstant("c"), Terms.newConstant(3)); List evaluatedFacts = evaluated.getFacts(); Assert.assertTrue(evaluatedFacts.contains(rank1)); Assert.assertTrue(evaluatedFacts.contains(rank2)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java index aff7371bf..7944d108e 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java @@ -16,9 +16,9 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.Program; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; public class TestUtils { @@ -83,7 +83,7 @@ public static Atom basicAtomWithStringTerms(String predicate, String... terms) { Predicate pred = CorePredicate.getInstance(predicate, terms.length); List trms = new ArrayList<>(); for (String str : terms) { - trms.add(CoreConstantTerm.getInstance(str)); + trms.add(Terms.newConstant(str)); } return new BasicAtom(pred, trms); } @@ -92,7 +92,7 @@ public static Atom basicAtomWithSymbolicTerms(String predicate, String... consta Predicate pred = CorePredicate.getInstance(predicate, constantSymbols.length); List trms = new ArrayList<>(); for (String str : constantSymbols) { - trms.add(CoreConstantTerm.getSymbolicInstance(str)); + trms.add(Terms.newSymbolicConstant(str)); } return new BasicAtom(pred, trms); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java index 2892d1d69..4b6903405 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java @@ -67,13 +67,13 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.MethodPredicateInterpretation; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; 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; @@ -185,8 +185,8 @@ public void filterOutput() throws Exception { Alpha system = new AlphaImpl(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); inputCfg.addPredicateMethod("getLargeGraphEdges", - Externals.processPredicate(() -> new HashSet<>(asList(asList(CoreConstantTerm.getInstance(1), CoreConstantTerm.getInstance(2)), - asList(CoreConstantTerm.getInstance(2), CoreConstantTerm.getInstance(1)), asList(CoreConstantTerm.getInstance(13), CoreConstantTerm.getInstance(1)))))); + 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); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ node(1), node(2), outgoing13(1) }"); @@ -197,7 +197,7 @@ public void filterOutput() throws Exception { 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(CoreConstantTerm.getInstance(1))))); + cfg.addPredicateMethod("bestNode", Externals.processPredicate(() -> singleton(singletonList(Terms.newConstant(1))))); ASPCore2Program prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ node(1), a }"); @@ -207,7 +207,7 @@ public void supplier() throws Exception { @at.ac.tuwien.kr.alpha.api.externals.Predicate public static Set>> bestNode() { - return singleton(singletonList(CoreConstantTerm.getInstance(1))); + return singleton(singletonList(Terms.newConstant(1))); } @Test @@ -234,7 +234,7 @@ public void smallGraphWithWrongType() throws Exception { public static Set>> neighbors(int node) { if (node == 1) { - return new HashSet<>(asList(singletonList(CoreConstantTerm.getInstance(2)), singletonList(CoreConstantTerm.getInstance(3)))); + return new HashSet<>(asList(singletonList(Terms.newConstant(2)), singletonList(Terms.newConstant(3)))); } return emptySet(); } @@ -316,9 +316,9 @@ public void withExternalSubtype() throws Exception { SubThingy thingy = new SubThingy(); BasicRule rule = new BasicRule( - new NormalHeadImpl(new BasicAtom(CorePredicate.getInstance("p", 1), CoreConstantTerm.getInstance("x"))), + new NormalHeadImpl(new BasicAtom(CorePredicate.getInstance("p", 1), Terms.newConstant("x"))), singletonList(new ExternalLiteral(new ExternalAtom(CorePredicate.getInstance("thinger", 1), - new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(CoreConstantTerm.getInstance(thingy)), + new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true))); Alpha system = new AlphaImpl(); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java index 623809068..d8646cf71 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java @@ -18,9 +18,9 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; import at.ac.tuwien.kr.alpha.core.externals.Externals; @@ -42,12 +42,12 @@ public static Set>> connection(String dummy) { List> l1 = new ArrayList<>(); List> l2 = new ArrayList<>(); List> l3 = new ArrayList<>(); - l1.add(CoreConstantTerm.getInstance("Klagenfurt")); - l1.add(CoreConstantTerm.getInstance("Villach")); - l2.add(CoreConstantTerm.getInstance("Klagenfurt")); - l2.add(CoreConstantTerm.getInstance("Graz")); - l3.add(CoreConstantTerm.getInstance("Villach")); - l3.add(CoreConstantTerm.getInstance("Salzburg")); + l1.add(Terms.newConstant("Klagenfurt")); + l1.add(Terms.newConstant("Villach")); + l2.add(Terms.newConstant("Klagenfurt")); + l2.add(Terms.newConstant("Graz")); + l3.add(Terms.newConstant("Villach")); + l3.add(Terms.newConstant("Salzburg")); retVal.add(l1); retVal.add(l2); retVal.add(l3); @@ -187,9 +187,9 @@ public void positiveExternalBindingOutput() { Assert.assertTrue(answerSet.getPredicates().contains(pred)); Set instances = answerSet.getPredicateInstances(pred); Assert.assertEquals(3, instances.size()); - Assert.assertTrue(instances.contains(new BasicAtom(pred, CoreConstantTerm.getInstance("Klagenfurt"), CoreConstantTerm.getInstance("Villach")))); - Assert.assertTrue(instances.contains(new BasicAtom(pred, CoreConstantTerm.getInstance("Klagenfurt"), CoreConstantTerm.getInstance("Graz")))); - Assert.assertTrue(instances.contains(new BasicAtom(pred, CoreConstantTerm.getInstance("Villach"), CoreConstantTerm.getInstance("Salzburg")))); + Assert.assertTrue(instances.contains(new BasicAtom(pred, Terms.newConstant("Klagenfurt"), Terms.newConstant("Villach")))); + Assert.assertTrue(instances.contains(new BasicAtom(pred, Terms.newConstant("Klagenfurt"), Terms.newConstant("Graz")))); + Assert.assertTrue(instances.contains(new BasicAtom(pred, Terms.newConstant("Villach"), Terms.newConstant("Salzburg")))); } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java index 7b38eb746..726d94148 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java @@ -15,9 +15,9 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.common.terms.CoreConstantTerm; import at.ac.tuwien.kr.alpha.core.programs.AbstractProgram; import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; @@ -83,7 +83,7 @@ public static Atom basicAtomWithStringTerms(String predicate, String... terms) { Predicate pred = CorePredicate.getInstance(predicate, terms.length); List trms = new ArrayList<>(); for (String str : terms) { - trms.add(CoreConstantTerm.getInstance(str)); + trms.add(Terms.newConstant(str)); } return new BasicAtom(pred, trms); } @@ -92,7 +92,7 @@ public static Atom basicAtomWithSymbolicTerms(String predicate, String... consta Predicate pred = CorePredicate.getInstance(predicate, constantSymbols.length); List trms = new ArrayList<>(); for (String str : constantSymbols) { - trms.add(CoreConstantTerm.getSymbolicInstance(str)); + trms.add(Terms.newSymbolicConstant(str)); } return new BasicAtom(pred, trms); } From 1b4f116f0624f22feb6c1cbb1d90b412081f3043 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 23 Feb 2021 11:49:29 +0100 Subject: [PATCH 028/111] hide implementation details for VariableTerm, change implementation to package private --- .../kr/alpha/commons/VariableTermImpl.java | 2 +- .../kr/alpha/core/atoms/AggregateAtom.java | 5 ++- .../kr/alpha/core/atoms/AggregateLiteral.java | 11 +++---- .../alpha/core/atoms/ComparisonLiteral.java | 11 +++---- .../tuwien/kr/alpha/core/atoms/CoreAtom.java | 8 +++-- .../kr/alpha/core/atoms/EnumerationAtom.java | 6 ++-- .../alpha/core/atoms/EnumerationLiteral.java | 7 ++--- .../kr/alpha/core/atoms/ExternalLiteral.java | 5 ++- .../kr/alpha/core/atoms/IntervalLiteral.java | 6 ++-- .../alpha/core/grounder/SubstitutionImpl.java | 8 +++-- .../kr/alpha/core/grounder/Unification.java | 9 +++--- .../alpha/core/parser/ParseTreeVisitor.java | 13 ++++---- .../CardinalityNormalization.java | 9 +++--- .../IntervalTermToIntervalAtom.java | 6 ++-- .../transformation/SumNormalization.java | 11 +++---- .../kr/alpha/core/rules/InternalRule.java | 7 +++-- .../java/at/ac/tuwien/kr/alpha/TestUtil.java | 3 +- .../ac/tuwien/kr/alpha/antlr/ParserTest.java | 11 +++---- .../core/grounder/NoGoodGeneratorTest.java | 5 ++- .../alpha/core/grounder/SubstitutionTest.java | 5 ++- .../kr/alpha/core/grounder/UnifierTest.java | 11 +++---- .../LiteralInstantiationStrategyTest.java | 21 ++++++------- .../LiteralInstantiatorTest.java | 31 +++++++++---------- 23 files changed, 102 insertions(+), 109 deletions(-) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java index 99d471ae5..92e4faf0e 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java @@ -12,7 +12,7 @@ /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class VariableTermImpl extends AbstractTerm implements VariableTerm { +class VariableTermImpl extends AbstractTerm implements VariableTerm { private static final Interner INTERNER = new Interner<>(); private static final String ANONYMOUS_VARIABLE_PREFIX = "_"; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java index b133f10eb..1bb5a9b33 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java @@ -39,7 +39,6 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; 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.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; @@ -229,8 +228,8 @@ public boolean isGround() { public List getOccurringVariables() { List occurringVariables = new LinkedList<>(); for (Term term : elementTerms) { - if (term instanceof VariableTermImpl) { - occurringVariables.add((VariableTermImpl) term); + if (term instanceof VariableTerm) { + occurringVariables.add((VariableTerm) term); } } for (Literal literal : elementLiterals) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index f6b681ced..e0b149b29 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -6,7 +6,6 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; /** @@ -28,7 +27,7 @@ public AggregateLiteral negate() { } /** - * @see CoreAtom#substitute(SubstitutionImpl) + * @see CoreAtom#substitute(Substitution) */ @Override public AggregateLiteral substitute(Substitution substitution) { @@ -39,10 +38,10 @@ public AggregateLiteral substitute(Substitution substitution) { public Set getBindingVariables() { Set bindingVariables = new HashSet<>(); if (boundBindingVariable(getAtom().getLowerBoundOperator(), getAtom().getLowerBoundTerm(), positive) != null) { - bindingVariables.add((VariableTermImpl) getAtom().getLowerBoundTerm()); + bindingVariables.add((VariableTerm) getAtom().getLowerBoundTerm()); } if (boundBindingVariable(getAtom().getUpperBoundOperator(), getAtom().getUpperBoundTerm(), positive) != null) { - bindingVariables.add((VariableTermImpl) getAtom().getUpperBoundTerm()); + bindingVariables.add((VariableTerm) getAtom().getUpperBoundTerm()); } return bindingVariables; } @@ -56,8 +55,8 @@ public Set getNonBindingVariables() { private static VariableTerm boundBindingVariable(ComparisonOperatorImpl op, Term bound, boolean positive) { boolean isNormalizedEquality = op == ComparisonOperatorImpl.EQ && positive || op == ComparisonOperatorImpl.NE && !positive; - if (isNormalizedEquality && bound instanceof VariableTermImpl) { - return (VariableTermImpl) bound; + if (isNormalizedEquality && bound instanceof VariableTerm) { + return (VariableTerm) bound; } return null; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index 108e24bff..d25e31074 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -41,7 +41,6 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.ArithmeticTerm; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; @@ -84,7 +83,7 @@ public ComparisonLiteral substitute(Substitution substitution) { } private boolean assignable(Term term) { - return isNormalizedEquality && term instanceof VariableTermImpl; + return isNormalizedEquality && term instanceof VariableTerm; } @Override @@ -97,10 +96,10 @@ public Set getBindingVariables() { throw new RuntimeException("Builtin equality with left and right side being variables encountered. Should not happen."); } if (assignable(left)) { - return Collections.singleton((VariableTermImpl) left); + return Collections.singleton((VariableTerm) left); } if (assignable(right)) { - return Collections.singleton((VariableTermImpl) right); + return Collections.singleton((VariableTerm) right); } return Collections.emptySet(); } @@ -154,11 +153,11 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit VariableTerm variable = null; Term expression = null; if (leftAssigning) { - variable = (VariableTermImpl) left; + variable = (VariableTerm) left; expression = right; } if (rightAssigning) { - variable = (VariableTermImpl) right; + variable = (VariableTerm) right; expression = left; } Term groundTerm = expression.substitute(partialSubstitution); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index 821601080..7911b47dc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -36,7 +36,7 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; /** @@ -50,11 +50,13 @@ public abstract class CoreAtom implements Atom { * @param terms the terms to set. * @return a new Atom with the given terms set. */ + @Override public abstract Atom withTerms(List terms); /** * Returns the set of all variables occurring in the Atom. */ + @Override public Set getOccurringVariables() { return toLiteral().getOccurringVariables(); } @@ -66,6 +68,7 @@ public Set getOccurringVariables() { * @param substitution the variable substitution to apply. * @return the atom resulting from the application of the substitution. */ + @Override public abstract Atom substitute(Substitution substitution); @Override @@ -93,11 +96,12 @@ public Literal toLiteral() { @Override public abstract Literal toLiteral(boolean positive); + @Override public Atom renameVariables(String newVariablePrefix) { Unifier renamingSubstitution = new Unifier(); int counter = 0; for (VariableTerm variable : getOccurringVariables()) { - renamingSubstitution.put(variable, VariableTermImpl.getInstance(newVariablePrefix + counter++)); + renamingSubstitution.put(variable, Terms.newVariable(newVariablePrefix + counter++)); } return this.substitute(renamingSubstitution); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 6520a3640..354df5a42 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -7,8 +7,8 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; @@ -32,7 +32,7 @@ public EnumerationAtom(List terms) { if (terms.size() != 3) { throw new RuntimeException("EnumerationAtom must have arity three. Given terms are of wrong size: " + terms); } - if (!(getTerms().get(2) instanceof VariableTermImpl)) { + if (!(getTerms().get(2) instanceof VariableTerm)) { throw new RuntimeException("Third parameter of EnumerationAtom must be a variable: " + terms); } } @@ -71,7 +71,7 @@ public Substitution addEnumerationIndexToSubstitution(Substitution substitution) } Integer enumerationIndex = getEnumerationIndex(idTerm, enumerationTerm); SubstitutionImpl retVal = new SubstitutionImpl(substitution); - retVal.put((VariableTermImpl) getTerms().get(2), Terms.newConstant(enumerationIndex)); + retVal.put((VariableTerm) getTerms().get(2), Terms.newConstant(enumerationIndex)); return retVal; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java index 7a5ff06d5..c7024bc86 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationLiteral.java @@ -7,7 +7,6 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; /** * Copyright (c) 2018, the Alpha Team. @@ -35,7 +34,7 @@ public EnumerationLiteral substitute(Substitution substitution) { @Override public Set getBindingVariables() { - return Collections.singleton((VariableTermImpl)getTerms().get(2)); + return Collections.singleton((VariableTerm)getTerms().get(2)); } @Override @@ -44,10 +43,10 @@ public Set getNonBindingVariables() { Term idTerm = getTerms().get(0); Term enumTerm = getTerms().get(1); if (idTerm instanceof VariableTerm) { - ret.add((VariableTermImpl) idTerm); + ret.add((VariableTerm) idTerm); } if (enumTerm instanceof VariableTerm) { - ret.add((VariableTermImpl) enumTerm); + ret.add((VariableTerm) enumTerm); } return ret; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java index f86fb4116..e648c241d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java @@ -38,7 +38,6 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** @@ -87,8 +86,8 @@ public Set getBindingVariables() { Set binding = new HashSet<>(output.size()); for (Term out : output) { - if (out instanceof VariableTermImpl) { - binding.add((VariableTermImpl) out); + if (out instanceof VariableTerm) { + binding.add((VariableTerm) out); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index bbdc25480..c6830285a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java @@ -40,7 +40,6 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** @@ -56,7 +55,7 @@ public IntervalLiteral(IntervalAtom atom) { public IntervalAtom getAtom() { return (IntervalAtom) atom; } - + @Override public IntervalLiteral negate() { throw new UnsupportedOperationException("IntervalLiteral cannot be negated"); @@ -72,7 +71,7 @@ private List getIntervalSubstitutions(Substitution partialSubstitu // Still a variable, generate all elements in the interval. for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) { Substitution ith = new SubstitutionImpl(partialSubstitution); - ith.put((VariableTermImpl) intervalRepresentingVariable, Terms.newConstant(i)); + ith.put((VariableTerm) intervalRepresentingVariable, Terms.newConstant(i)); substitutions.add(ith); } return substitutions; @@ -84,6 +83,7 @@ private List getIntervalSubstitutions(Substitution partialSubstitu return Collections.emptyList(); } // TODO to avoid that type of unchecked cast, we may want interval terms to not extend AbstractTerm + @SuppressWarnings("unchecked") Integer integer = ((ConstantTerm) intervalRepresentingVariable).getObject(); if (intervalTerm.getLowerBound() <= integer && integer <= intervalTerm.getUpperBound()) { return Collections.singletonList(partialSubstitution); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java index 55aae6f32..233b997ca 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java @@ -42,7 +42,7 @@ 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.FunctionTermImpl; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Substitution { @@ -103,7 +103,7 @@ boolean unifyTerms(Term termNonGround, Term termGround, Substitution partialSubs } else if (termNonGround instanceof ConstantTerm) { // Since right term is ground, both terms differ return false; - } else if (termNonGround instanceof VariableTermImpl) { + } else if (termNonGround instanceof VariableTerm) { VariableTerm variableTerm = (VariableTerm) termNonGround; // Left term is variable, bind it to the right term. Use original substitution if it has // not been cloned yet. @@ -178,6 +178,7 @@ public Term eval(VariableTerm variableTerm) { return this.substitution.get(variableTerm); } + @Override public > Term put(VariableTerm variableTerm, Term groundTerm) { if (!groundTerm.isGround()) { throw Util.oops("Right-hand term is not ground."); @@ -194,6 +195,7 @@ public boolean isEmpty() { return substitution.isEmpty(); } + @Override public boolean isVariableSet(VariableTerm variable) { return substitution.get(variable) != null; } @@ -229,7 +231,7 @@ public static SubstitutionImpl fromString(String substitution) { SubstitutionImpl ret = new SubstitutionImpl(); for (String assignment : assignments) { String[] keyVal = assignment.split("->"); - VariableTermImpl variable = VariableTermImpl.getInstance(keyVal[0]); + VariableTerm variable = Terms.newVariable(keyVal[0]); Term assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); ret.put(variable, assignedTerm); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index 1906b8755..64496f3e4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -35,7 +35,6 @@ 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.FunctionTermImpl; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; /** * Copyright (c) 2017, the Alpha Team. @@ -87,12 +86,12 @@ private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitu if (leftSubs == rightSubs) { return true; } - if (!keepLeftAsIs && leftSubs instanceof VariableTermImpl && !currentSubstitution.isVariableSet((VariableTermImpl) leftSubs)) { - currentSubstitution.put((VariableTermImpl) leftSubs, rightSubs); + if (!keepLeftAsIs && leftSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) leftSubs)) { + currentSubstitution.put((VariableTerm) leftSubs, rightSubs); return true; } - if (rightSubs instanceof VariableTermImpl && !currentSubstitution.isVariableSet((VariableTermImpl) rightSubs)) { - currentSubstitution.put((VariableTermImpl) rightSubs, leftSubs); + if (rightSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) rightSubs)) { + currentSubstitution.put((VariableTerm) rightSubs, leftSubs); return true; } if (leftSubs instanceof FunctionTermImpl && rightSubs instanceof FunctionTermImpl) { 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 88cc7aac9..355c33a85 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 @@ -62,7 +62,6 @@ import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; @@ -406,9 +405,9 @@ public Term visitGround_term(ASPCore2Parser.Ground_termContext ctx) { public Term visitVariable_term(ASPCore2Parser.Variable_termContext ctx) { // variable_term : VARIABLE | ANONYMOUS_VARIABLE; if (ctx.VARIABLE() != null) { - return VariableTermImpl.getInstance(ctx.VARIABLE().getText()); + return Terms.newVariable(ctx.VARIABLE().getText()); } else { - return VariableTermImpl.getAnonymousInstance(); + return Terms.newAnonymousVariable(); } } @@ -526,7 +525,7 @@ public VariableTerm visitTerm_anonymousVariable(ASPCore2Parser.Term_anonymousVar throw notSupported(ctx); } - return VariableTermImpl.getAnonymousInstance(); + return Terms.newAnonymousVariable(); } @Override @@ -535,7 +534,7 @@ public VariableTerm visitTerm_variable(ASPCore2Parser.Term_variableContext ctx) throw notSupported(ctx); } - return VariableTermImpl.getInstance(ctx.VARIABLE().getText()); + return Terms.newVariable(ctx.VARIABLE().getText()); } @Override @@ -574,8 +573,8 @@ public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) ASPCore2Parser.IntervalContext ictx = ctx.interval(); String lowerText = ictx.lower.getText(); String upperText = ictx.upper.getText(); - Term lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? Terms.newConstant(Integer.parseInt(lowerText)) : VariableTermImpl.getInstance(lowerText); - Term upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? Terms.newConstant(Integer.parseInt(upperText)) : VariableTermImpl.getInstance(upperText); + Term lower = ictx.lower.getType() == ASPCore2Lexer.NUMBER ? Terms.newConstant(Integer.parseInt(lowerText)) : Terms.newVariable(lowerText); + Term upper = ictx.upper.getType() == ASPCore2Lexer.NUMBER ? Terms.newConstant(Integer.parseInt(upperText)) : Terms.newVariable(upperText); return IntervalTerm.getInstance(lower, upper); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index f163c177b..414a90cb5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -15,7 +15,6 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; @@ -194,14 +193,14 @@ private List> rewriteAggregatesInRule(Rule rule) { Substitution aggregateSubstitution = new Unifier(); Collection globalVariables = getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), Terms.newConstant(aggregateCount)); + aggregateSubstitution.put(Terms.newVariable("AGGREGATE_ID"), Terms.newConstant(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(Terms.newConstant(aggregateCount)); - aggregateSubstitution.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); + aggregateSubstitution.put(Terms.newVariable("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); } - aggregateSubstitution.put(VariableTermImpl.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); + aggregateSubstitution.put(Terms.newVariable("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); // Create new output atom for addition to rule body instead of the aggregate. aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateSubstitution).toLiteral()); @@ -212,7 +211,7 @@ private List> rewriteAggregatesInRule(Rule rule) { List elementTerms = aggregateElement.getElementTerms(); FunctionTermImpl elementTuple = FunctionTermImpl.getInstance("element_tuple", elementTerms); Substitution elementSubstitution = new Unifier(aggregateSubstitution); - elementSubstitution.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); + elementSubstitution.put(Terms.newVariable("ELEMENT_TUPLE"), elementTuple); // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementSubstitution); 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 5ce442e75..a37956e6b 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 @@ -40,7 +40,7 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom; import at.ac.tuwien.kr.alpha.core.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; @@ -93,7 +93,7 @@ private static Literal rewriteLiteral(Literal lit, Map> rewriteAggregatesInRule(Rule rule) { Unifier aggregateUnifier = new Unifier(); Collection globalVariables = CardinalityNormalization.getGlobalVariables(rewrittenBody, aggregateAtom); if (globalVariables.isEmpty()) { - aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), Terms.newConstant(aggregateCount)); + aggregateUnifier.put(Terms.newVariable("AGGREGATE_ID"), Terms.newConstant(aggregateCount)); } else { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(Terms.newConstant(aggregateCount)); - aggregateUnifier.put(VariableTermImpl.getInstance("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); + aggregateUnifier.put(Terms.newVariable("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); } - aggregateUnifier.put(VariableTermImpl.getInstance("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); + aggregateUnifier.put(Terms.newVariable("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); // Create new output atom for addition to rule body instead of the aggregate. aggregateOutputAtoms.add(aggregateOutputAtom.substitute(aggregateUnifier).toLiteral()); @@ -172,8 +171,8 @@ private List> rewriteAggregatesInRule(Rule rule) { List elementTerms = aggregateElement.getElementTerms(); FunctionTermImpl elementTuple = FunctionTermImpl.getInstance("element_tuple", elementTerms); Unifier elementUnifier = new Unifier(aggregateUnifier); - elementUnifier.put(VariableTermImpl.getInstance("ELEMENT_TUPLE"), elementTuple); - elementUnifier.put(VariableTermImpl.getInstance("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); + elementUnifier.put(Terms.newVariable("ELEMENT_TUPLE"), elementTuple); + elementUnifier.put(Terms.newVariable("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); // Create new rule for input. BasicAtom inputHeadAtom = aggregateInputAtom.substitute(elementUnifier); 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 d917bf26b..ee58bde24 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 @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfoImpl; @@ -104,6 +104,7 @@ public static CompiledRule fromNormalRule(Rule rule) { * @param newVariablePostfix * @return */ + @Override public InternalRule renameVariables(String newVariablePostfix) { List occurringVariables = new ArrayList<>(); Atom headAtom = this.getHeadAtom(); @@ -114,7 +115,7 @@ public InternalRule renameVariables(String newVariablePostfix) { Unifier variableReplacement = new Unifier(); for (VariableTerm occurringVariable : occurringVariables) { final String newVariableName = occurringVariable.toString() + newVariablePostfix; - variableReplacement.put(occurringVariable, VariableTermImpl.getInstance(newVariableName)); + variableReplacement.put(occurringVariable, Terms.newVariable(newVariableName)); } Atom renamedHeadAtom = headAtom.substitute(variableReplacement); ArrayList renamedBody = new ArrayList<>(this.getBody().size()); @@ -128,10 +129,12 @@ public InternalRule renameVariables(String newVariablePostfix) { * Returns the predicates occurring in this rule. * @return a list of all predicates occurring in the rule (may contain duplicates and builtin atoms). */ + @Override public List getOccurringPredicates() { return this.occurringPredicates; } + @Override public RuleGroundingInfoImpl getGroundingInfo() { return this.groundingOrders; } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java index 07965090c..5d7b486c6 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java @@ -33,7 +33,6 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; @@ -52,7 +51,7 @@ public static Atom atom(String predicateName, String... termStrings) { for (int i = 0; i < termStrings.length; i++) { String termString = termStrings[i]; if (StringUtils.isAllUpperCase(termString.substring(0, 1))) { - terms[i] = VariableTermImpl.getInstance(termString); + terms[i] = Terms.newVariable(termString); } else { terms[i] = Terms.newConstant(termString); } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java index b624f3961..88f3cc1f8 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java @@ -55,7 +55,6 @@ import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; @@ -125,7 +124,7 @@ public void parseInterval() throws IOException { 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); - assertTrue(bodyInterval.equals(IntervalTerm.getInstance(Terms.newConstant(3), VariableTermImpl.getInstance("X")))); + assertTrue(bodyInterval.equals(IntervalTerm.getInstance(Terms.newConstant(3), Terms.newVariable("X")))); } @Test @@ -202,13 +201,13 @@ public void cardinalityAggregate() throws IOException { assertTrue(optionalBodyElement.isPresent()); Literal bodyElement = optionalBodyElement.get(); AggregateLiteral parsedAggregate = (AggregateLiteral) bodyElement; - VariableTerm x = VariableTermImpl.getInstance("X"); - VariableTerm y = VariableTermImpl.getInstance("Y"); - VariableTerm z = VariableTermImpl.getInstance("Z"); + VariableTerm x = Terms.newVariable("X"); + VariableTerm y = Terms.newVariable("Y"); + VariableTerm z = Terms.newVariable("Z"); List basicTerms = Arrays.asList(x, y, z); AggregateAtom.AggregateElement aggregateElement = new AggregateAtom.AggregateElement(basicTerms, Collections.singletonList(new BasicAtom(CorePredicate.getInstance("p", 3), x, y, z).toLiteral())); - AggregateAtom expectedAggregate = new AggregateAtom(ComparisonOperatorImpl.LE, VariableTermImpl.getInstance("K"), null, null, + AggregateAtom expectedAggregate = new AggregateAtom(ComparisonOperatorImpl.LE, Terms.newVariable("K"), null, null, AggregateAtom.AGGREGATEFUNCTION.COUNT, Collections.singletonList(aggregateElement)); assertEquals(expectedAggregate, parsedAggregate.getAtom()); } 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 4971c6411..802044cd7 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 @@ -39,7 +39,6 @@ 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.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; 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.Literals; @@ -60,8 +59,8 @@ public class NoGoodGeneratorTest { private static final ConstantTerm A = Terms.newSymbolicConstant("a"); private static final ConstantTerm B = Terms.newSymbolicConstant("b"); - private static final VariableTerm X = VariableTermImpl.getInstance("X"); - private static final VariableTerm Y = VariableTermImpl.getInstance("Y"); + 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 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 0285bcc05..42a7fc21b 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 @@ -46,7 +46,6 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; @@ -63,8 +62,8 @@ public class SubstitutionTest { private static final ConstantTerm B = Terms.newSymbolicConstant("b"); private static final ConstantTerm C = Terms.newSymbolicConstant("c"); - private static final VariableTerm X = VariableTermImpl.getInstance("X"); - private static final VariableTerm Y = VariableTermImpl.getInstance("Y"); + private static final VariableTerm X = Terms.newVariable("X"); + private static final VariableTerm Y = Terms.newVariable("Y"); private static final BasicAtom PX = new BasicAtom(CorePredicate.getInstance("p", 1), X); private static final BasicAtom PY = new BasicAtom(CorePredicate.getInstance("p", 1), Y); private static final Instance PA = new Instance(A); 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 4b72ec8ee..b8f874a92 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 @@ -38,7 +38,6 @@ 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.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; @@ -46,8 +45,8 @@ public class UnifierTest extends SubstitutionTest { @Test public void extendUnifier() { - VariableTerm varX = VariableTermImpl.getInstance("X"); - VariableTerm varY = VariableTermImpl.getInstance("Y"); + VariableTerm varX = Terms.newVariable("X"); + VariableTerm varY = Terms.newVariable("Y"); Unifier sub1 = new Unifier(); sub1.put(varX, varY); Unifier sub2 = new Unifier(); @@ -62,9 +61,9 @@ public void extendUnifier() { @Test public void mergeUnifierIntoLeft() { - VariableTerm varX = VariableTermImpl.getInstance("X"); - VariableTerm varY = VariableTermImpl.getInstance("Y"); - VariableTerm varZ = VariableTermImpl.getInstance("Z"); + 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); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java index 41570b427..396c51f19 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java @@ -13,7 +13,6 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.commons.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.common.AtomStore; @@ -103,7 +102,7 @@ public void defaultLazyGroundingNoAssignmentGroundLiteral() { @Test public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newVariable("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); @@ -120,8 +119,8 @@ public void defaultLazyGroundingNoAssignmentSubstituteNonGroundLiteral() { Substitution substitution = substitutionInfo.left; AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); - Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(VariableTermImpl.getInstance("X"))); + Assert.assertTrue(substitution.isVariableSet(Terms.newVariable("X"))); + Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(Terms.newVariable("X"))); Assert.assertTrue(staleSet.isEmpty()); } @@ -266,7 +265,7 @@ public void defaultLazyGroundingCheckMustBeTrueGroundLiteral() { @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newVariable("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); @@ -285,8 +284,8 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance Substitution substitution = substitutionInfo.left; AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.UNASSIGNED, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); - Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(VariableTermImpl.getInstance("X"))); + Assert.assertTrue(substitution.isVariableSet(Terms.newVariable("X"))); + Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(Terms.newVariable("X"))); Assert.assertEquals(1, staleSet.size()); Assert.assertTrue(staleSet.contains(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")))); @@ -305,7 +304,7 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithUnassignedInstance @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newVariable("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); @@ -328,8 +327,8 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { Substitution substitution = substitutionInfo.left; AssignmentStatus assignmentStatus = substitutionInfo.right; Assert.assertEquals(AssignmentStatus.TRUE, assignmentStatus); - Assert.assertTrue(substitution.isVariableSet(VariableTermImpl.getInstance("X"))); - Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(VariableTermImpl.getInstance("X"))); + Assert.assertTrue(substitution.isVariableSet(Terms.newVariable("X"))); + Assert.assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(Terms.newVariable("X"))); Assert.assertTrue(staleSet.isEmpty()); } @@ -346,7 +345,7 @@ public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() { @Test public void defaultLazyGroundingSubstituteNonGroundLiteralWithFalseInstance() { Predicate q = CorePredicate.getInstance("q", 2); - BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), VariableTermImpl.getInstance("X")); + BasicAtom nonGroundAtom = new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newVariable("X")); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(q); workingMemory.addInstance(new BasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java index d82909fe4..141f0abef 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java @@ -13,7 +13,6 @@ 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.Terms; -import at.ac.tuwien.kr.alpha.commons.VariableTermImpl; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; @@ -33,7 +32,7 @@ public class LiteralInstantiatorTest { @Test public void instantiateSatisfiedFixedInterpretationLiteral() { - ComparisonAtom equalsThree = new ComparisonAtom(Terms.newConstant(3), VariableTermImpl.getInstance("THREE"), ComparisonOperatorImpl.EQ); + ComparisonAtom equalsThree = new ComparisonAtom(Terms.newConstant(3), Terms.newVariable("THREE"), ComparisonOperatorImpl.EQ); Literal lit = new ComparisonLiteral(equalsThree, true); Substitution substitution = new SubstitutionImpl(); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); @@ -43,17 +42,17 @@ public void instantiateSatisfiedFixedInterpretationLiteral() { Assert.assertEquals(1, resultSubstitutions.size()); Assert.assertEquals(AssignmentStatus.TRUE, resultSubstitutions.get(0).right); Substitution extendedSubstitution = resultSubstitutions.get(0).left; - Assert.assertTrue(extendedSubstitution.isVariableSet(VariableTermImpl.getInstance("THREE"))); - Assert.assertEquals(Terms.newConstant(3), extendedSubstitution.eval(VariableTermImpl.getInstance("THREE"))); + Assert.assertTrue(extendedSubstitution.isVariableSet(Terms.newVariable("THREE"))); + Assert.assertEquals(Terms.newConstant(3), extendedSubstitution.eval(Terms.newVariable("THREE"))); } @Test public void instantiateUnsatisfiedFixedInterpretationLiteral() { - ComparisonAtom fiveEqualsThree = new ComparisonAtom(VariableTermImpl.getInstance("FIVE"), VariableTermImpl.getInstance("THREE"), ComparisonOperatorImpl.EQ); + ComparisonAtom fiveEqualsThree = new ComparisonAtom(Terms.newVariable("FIVE"), Terms.newVariable("THREE"), ComparisonOperatorImpl.EQ); Literal lit = new ComparisonLiteral(fiveEqualsThree, true); Substitution substitution = new SubstitutionImpl(); - substitution.put(VariableTermImpl.getInstance("FIVE"), Terms.newConstant(5)); - substitution.put(VariableTermImpl.getInstance("THREE"), Terms.newConstant(3)); + substitution.put(Terms.newVariable("FIVE"), Terms.newConstant(5)); + substitution.put(Terms.newVariable("THREE"), Terms.newConstant(3)); LiteralInstantiator instantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(null)); LiteralInstantiationResult result = instantiator.instantiateLiteral(lit, substitution); Assert.assertEquals(LiteralInstantiationResult.Type.STOP_BINDING, result.getType()); @@ -61,9 +60,9 @@ public void instantiateUnsatisfiedFixedInterpretationLiteral() { @Test public void instantiateEnumLiteral() { - VariableTerm enumTerm = VariableTermImpl.getInstance("E"); - VariableTerm idTerm = VariableTermImpl.getInstance("X"); - VariableTerm indexTerm = VariableTermImpl.getInstance("I"); + VariableTerm enumTerm = Terms.newVariable("E"); + VariableTerm idTerm = Terms.newVariable("X"); + VariableTerm indexTerm = Terms.newVariable("I"); List termList = new ArrayList<>(); termList.add(enumTerm); termList.add(idTerm); @@ -88,8 +87,8 @@ public void workingMemoryBasedVerifyPositiveGroundLiteralSatisfied() { WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("x"), Terms.newSymbolicConstant("y")), true); - VariableTerm x = VariableTermImpl.getInstance("X"); - VariableTerm y = VariableTermImpl.getInstance("Y"); + VariableTerm x = Terms.newVariable("X"); + VariableTerm y = Terms.newVariable("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); Substitution substitution = new SubstitutionImpl(); substitution.put(x, Terms.newSymbolicConstant("x")); @@ -111,8 +110,8 @@ public void workingMemoryBasedVerifyPositiveGroundLiteralUnsatisfied() { Predicate p = CorePredicate.getInstance("p", 2); WorkingMemory workingMemory = new WorkingMemory(); workingMemory.initialize(p); - VariableTerm x = VariableTermImpl.getInstance("X"); - VariableTerm y = VariableTermImpl.getInstance("Y"); + VariableTerm x = Terms.newVariable("X"); + VariableTerm y = Terms.newVariable("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); Substitution substitution = new SubstitutionImpl(); substitution.put(x, Terms.newSymbolicConstant("x")); @@ -132,8 +131,8 @@ public void workingMemoryBasedInstantiatePositiveBasicLiteral() { workingMemory.initialize(p); workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("x"), Terms.newSymbolicConstant("y")), true); workingMemory.addInstance(new BasicAtom(p, Terms.newSymbolicConstant("x"), Terms.newSymbolicConstant("z")), true); - VariableTerm x = VariableTermImpl.getInstance("X"); - VariableTerm y = VariableTermImpl.getInstance("Y"); + VariableTerm x = Terms.newVariable("X"); + VariableTerm y = Terms.newVariable("Y"); Literal lit = new BasicLiteral(new BasicAtom(p, x, y), true); Substitution substitution = new SubstitutionImpl(); substitution.put(x, Terms.newSymbolicConstant("x")); From 7ac24aaec879b706bd3a73dabe0f72919a1f9e43 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 23 Feb 2021 12:10:13 +0100 Subject: [PATCH 029/111] hide implementation details for FunctionTerm, change implementation to package private --- .../ac/tuwien/kr/alpha/api/terms/FunctionTerm.java | 6 ++++++ .../tuwien/kr/alpha/commons/FunctionTermImpl.java | 4 +++- .../ac/tuwien/kr/alpha/commons/IntervalTerm.java | 5 +++-- .../java/at/ac/tuwien/kr/alpha/commons/Terms.java | 13 +++++++++++-- .../alpha/core/grounder/FactIntervalEvaluator.java | 4 ++-- .../kr/alpha/core/grounder/SubstitutionImpl.java | 8 ++++---- .../tuwien/kr/alpha/core/grounder/Unification.java | 8 ++++---- .../kr/alpha/core/parser/ParseTreeVisitor.java | 6 +++--- .../transformation/CardinalityNormalization.java | 6 +++--- .../transformation/IntervalTermToIntervalAtom.java | 14 +++++++------- .../programs/transformation/SumNormalization.java | 6 +++--- .../at/ac/tuwien/kr/alpha/antlr/ParserTest.java | 6 +++--- .../kr/alpha/core/grounder/SubstitutionTest.java | 6 +++--- 13 files changed, 55 insertions(+), 37 deletions(-) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java index d989d522b..52a2c89b3 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/FunctionTerm.java @@ -1,5 +1,11 @@ package at.ac.tuwien.kr.alpha.api.terms; +import java.util.List; + public interface FunctionTerm extends Term{ + List getTerms(); + + String getSymbol(); + } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java index 9602fe4a9..9b7420805 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java @@ -17,7 +17,7 @@ /** * Copyright (c) 2016-2017, the Alpha Team. */ -public class FunctionTermImpl extends AbstractTerm implements FunctionTerm { +class FunctionTermImpl extends AbstractTerm implements FunctionTerm { private static final Interner INTERNER = new Interner<>(); private final String symbol; @@ -50,10 +50,12 @@ public static FunctionTermImpl getInstance(String functionSymbol, Term... terms) return getInstance(functionSymbol, Arrays.asList(terms)); } + @Override public List getTerms() { return terms; } + @Override public String getSymbol() { return symbol; } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java index f871af00a..ea549bf8c 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java @@ -5,6 +5,7 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; +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.util.Interner; @@ -146,13 +147,13 @@ public static boolean termContainsIntervalTerm(Term term) { } } - public static boolean functionTermContainsIntervals(FunctionTermImpl functionTerm) { + public static boolean functionTermContainsIntervals(FunctionTerm functionTerm) { // Test whether a function term contains an interval term (recursively). for (Term term : functionTerm.getTerms()) { if (term instanceof IntervalTerm) { return true; } - if (term instanceof FunctionTermImpl && functionTermContainsIntervals((FunctionTermImpl) term)) { + if (term instanceof FunctionTermImpl && functionTermContainsIntervals((FunctionTerm) term)) { return true; } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java index 045cc748d..f7b0a8ba7 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java @@ -4,6 +4,7 @@ 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.api.terms.VariableTerm; @@ -32,15 +33,23 @@ public static > ConstantTerm newConstant(T constantOb public static ConstantTerm newSymbolicConstant(String symbol) { return ConstantTermImpl.getSymbolicInstance(symbol); } - + public static VariableTerm newVariable(String varName) { return VariableTermImpl.getInstance(varName); } - + public static VariableTerm newAnonymousVariable() { return VariableTermImpl.getAnonymousInstance(); } + public static FunctionTerm newFunctionTerm(String functionSymbol, List functionArgs) { + return FunctionTermImpl.getInstance(functionSymbol, functionArgs); + } + + public static FunctionTerm newFunctionTerm(String functionSmybol, Term... functionArgs) { + return FunctionTermImpl.getInstance(functionSmybol, functionArgs); + } + @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/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index b98d36bb2..0e67fdc8d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -6,8 +6,8 @@ import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.program.Atom; +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.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; @@ -34,7 +34,7 @@ public static List constructFactInstances(Atom fact) { currentTerms[i] = term; if (term instanceof IntervalTerm) { containsIntervals = true; - } else if (term instanceof FunctionTermImpl && IntervalTerm.functionTermContainsIntervals((FunctionTermImpl) term)) { + } else if (term instanceof FunctionTerm && IntervalTerm.functionTermContainsIntervals((FunctionTerm) term)) { containsIntervals = true; throw new UnsupportedOperationException("Intervals inside function terms in facts are not supported yet. Try turning the fact into a rule."); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java index 233b997ca..071950e85 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java @@ -39,9 +39,9 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; 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; -import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; @@ -123,10 +123,10 @@ boolean unifyTerms(Term termNonGround, Term termGround, Substitution partialSubs } updatedSubstitution.put(variableTerm, termGround); return true; - } else if (termNonGround instanceof FunctionTermImpl && termGround instanceof FunctionTermImpl) { + } else if (termNonGround instanceof FunctionTerm && termGround instanceof FunctionTerm) { // Both terms are function terms - FunctionTermImpl ftNonGround = (FunctionTermImpl) termNonGround; - FunctionTermImpl ftGround = (FunctionTermImpl) termGround; + FunctionTerm ftNonGround = (FunctionTerm) termNonGround; + FunctionTerm ftGround = (FunctionTerm) termGround; if (!(ftNonGround.getSymbol().equals(ftGround.getSymbol()))) { return false; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index 64496f3e4..bc0682996 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -32,9 +32,9 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.program.Atom; +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.FunctionTermImpl; /** * Copyright (c) 2017, the Alpha Team. @@ -94,9 +94,9 @@ private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitu currentSubstitution.put((VariableTerm) rightSubs, leftSubs); return true; } - if (leftSubs instanceof FunctionTermImpl && rightSubs instanceof FunctionTermImpl) { - final FunctionTermImpl leftFunction = (FunctionTermImpl) leftSubs; - final FunctionTermImpl rightFunction = (FunctionTermImpl) rightSubs; + if (leftSubs instanceof FunctionTerm && rightSubs instanceof FunctionTerm) { + final FunctionTerm leftFunction = (FunctionTerm) leftSubs; + final FunctionTerm rightFunction = (FunctionTerm) rightSubs; if (!leftFunction.getSymbol().equals(rightFunction.getSymbol()) || leftFunction.getTerms().size() != rightFunction.getTerms().size()) { return false; 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 355c33a85..bcedd8b8a 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 @@ -56,10 +56,10 @@ import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; 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; import at.ac.tuwien.kr.alpha.commons.ArithmeticTerm; -import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; @@ -515,8 +515,8 @@ public ConstantTerm visitTerm_string(ASPCore2Parser.Term_stringContext c } @Override - public FunctionTermImpl visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { - return FunctionTermImpl.getInstance(ctx.ID().getText(), visitTerms(ctx.terms())); + public FunctionTerm visitTerm_func(ASPCore2Parser.Term_funcContext ctx) { + return Terms.newFunctionTerm(ctx.ID().getText(), visitTerms(ctx.terms())); } @Override diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index 414a90cb5..f2eac9c51 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -12,8 +12,8 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; +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.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; @@ -198,7 +198,7 @@ private List> rewriteAggregatesInRule(Rule rule) { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(Terms.newConstant(aggregateCount)); - aggregateSubstitution.put(Terms.newVariable("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); + aggregateSubstitution.put(Terms.newVariable("AGGREGATE_ID"), Terms.newFunctionTerm("agg", globalVariableTermlist)); } aggregateSubstitution.put(Terms.newVariable("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); @@ -209,7 +209,7 @@ private List> rewriteAggregatesInRule(Rule rule) { for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. List elementTerms = aggregateElement.getElementTerms(); - FunctionTermImpl elementTuple = FunctionTermImpl.getInstance("element_tuple", elementTerms); + FunctionTerm elementTuple = Terms.newFunctionTerm("element_tuple", elementTerms); Substitution elementSubstitution = new Unifier(aggregateSubstitution); elementSubstitution.put(Terms.newVariable("ELEMENT_TUPLE"), elementTuple); 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 a37956e6b..7a2768b63 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 @@ -36,9 +36,9 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; +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.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom; @@ -98,9 +98,9 @@ private static Literal rewriteLiteral(Literal lit, Map intervalReplacement) { + private static FunctionTerm rewriteFunctionTerm(FunctionTerm functionTerm, Map intervalReplacement) { List termList = new ArrayList<>(functionTerm.getTerms()); boolean didChange = false; for (int i = 0; i < termList.size(); i++) { @@ -123,9 +123,9 @@ private static FunctionTermImpl rewriteFunctionTerm(FunctionTermImpl functionTer termList.set(i, replacementVariable); didChange = true; } - if (term instanceof FunctionTermImpl) { + if (term instanceof FunctionTerm) { // Recursively rewrite function terms. - FunctionTermImpl rewrittenFunctionTerm = rewriteFunctionTerm((FunctionTermImpl) term, intervalReplacement); + FunctionTerm rewrittenFunctionTerm = rewriteFunctionTerm((FunctionTerm) term, intervalReplacement); if (rewrittenFunctionTerm != term) { termList.set(i, rewrittenFunctionTerm); didChange = true; @@ -133,7 +133,7 @@ private static FunctionTermImpl rewriteFunctionTerm(FunctionTermImpl functionTer } } if (didChange) { - return FunctionTermImpl.getInstance(functionTerm.getSymbol(), termList); + return Terms.newFunctionTerm(functionTerm.getSymbol(), termList); } return functionTerm; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index 21f2053c3..aad6df663 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -11,8 +11,8 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; +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.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; @@ -158,7 +158,7 @@ private List> rewriteAggregatesInRule(Rule rule) { // In case some variables are not local to the aggregate, add them to the aggregate identifier ArrayList globalVariableTermlist = new ArrayList<>(globalVariables); globalVariableTermlist.add(Terms.newConstant(aggregateCount)); - aggregateUnifier.put(Terms.newVariable("AGGREGATE_ID"), FunctionTermImpl.getInstance("agg", globalVariableTermlist)); + aggregateUnifier.put(Terms.newVariable("AGGREGATE_ID"), Terms.newFunctionTerm("agg", globalVariableTermlist)); } aggregateUnifier.put(Terms.newVariable("LOWER_BOUND"), aggregateAtom.getLowerBoundTerm()); @@ -169,7 +169,7 @@ private List> rewriteAggregatesInRule(Rule rule) { for (AggregateAtom.AggregateElement aggregateElement : aggregateAtom.getAggregateElements()) { // Prepare element substitution. List elementTerms = aggregateElement.getElementTerms(); - FunctionTermImpl elementTuple = FunctionTermImpl.getInstance("element_tuple", elementTerms); + FunctionTerm elementTuple = Terms.newFunctionTerm("element_tuple", elementTerms); Unifier elementUnifier = new Unifier(aggregateUnifier); elementUnifier.put(Terms.newVariable("ELEMENT_TUPLE"), elementTuple); elementUnifier.put(Terms.newVariable("FIRST_VARIABLE"), elementTuple.getTerms().get(0)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java index 88f3cc1f8..5d57ce7aa 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java @@ -50,9 +50,9 @@ import at.ac.tuwien.kr.alpha.api.program.InlineDirectives; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead; +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.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; @@ -86,8 +86,8 @@ public void parseFactWithFunctionTerms() throws IOException { assertEquals("Program contains one fact.", 1, parsedProgram.getFacts().size()); assertEquals("Predicate name of fact is p.", "p", parsedProgram.getFacts().get(0).getPredicate().getName()); assertEquals("Fact has two terms.", 2, parsedProgram.getFacts().get(0).getPredicate().getArity()); - assertEquals("First term is function term f.", "f", ((FunctionTermImpl) parsedProgram.getFacts().get(0).getTerms().get(0)).getSymbol()); - assertEquals("Second term is function term g.", "g", ((FunctionTermImpl) parsedProgram.getFacts().get(0).getTerms().get(1)).getSymbol()); + assertEquals("First term is function term f.", "f", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(0)).getSymbol()); + assertEquals("Second term is function term g.", "g", ((FunctionTerm) parsedProgram.getFacts().get(0).getTerms().get(1)).getSymbol()); } @Test 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 42a7fc21b..90ad6606b 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 @@ -42,9 +42,9 @@ import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; 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; -import at.ac.tuwien.kr.alpha.commons.FunctionTermImpl; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; @@ -87,9 +87,9 @@ public void specializeTermsFunctionTermBinding() { Substitution substitution = new SubstitutionImpl(); substitution.put(Y, A); - FunctionTermImpl groundFunctionTerm = FunctionTermImpl.getInstance("f", B, C); + FunctionTerm groundFunctionTerm = Terms.newFunctionTerm("f", B, C); Instance qfBC = new Instance(groundFunctionTerm); - Term nongroundFunctionTerm = FunctionTermImpl.getInstance("f", B, X); + Term nongroundFunctionTerm = Terms.newFunctionTerm("f", B, X); BasicAtom qfBX = new BasicAtom(CorePredicate.getInstance("q", 2), nongroundFunctionTerm); Substitution substitution1 = SubstitutionImpl.specializeSubstitution(qfBX, qfBC, substitution); From e3ca893045a1b42ff1115779549d4be4110d6ca3 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 23 Feb 2021 14:24:36 +0100 Subject: [PATCH 030/111] hide implementation details for ArithmeticTerm, change implementation to package private --- .../alpha/api/terms/ArithmeticOperator.java | 46 +++++++ .../kr/alpha/api/terms/ArithmeticTerm.java | 13 ++ ...meticTerm.java => ArithmeticTermImpl.java} | 125 ++++++------------ .../at/ac/tuwien/kr/alpha/commons/Terms.java | 32 +++++ .../kr/alpha/commons/TestMinusTerm.java | 2 +- .../alpha/core/atoms/ComparisonLiteral.java | 8 +- .../alpha/core/parser/ParseTreeVisitor.java | 36 +++-- 7 files changed, 151 insertions(+), 111 deletions(-) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticOperator.java create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticTerm.java rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ArithmeticTerm.java => ArithmeticTermImpl.java} (66%) diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticOperator.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticOperator.java new file mode 100644 index 000000000..3d75ae7c0 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticOperator.java @@ -0,0 +1,46 @@ +package at.ac.tuwien.kr.alpha.api.terms; + +import com.google.common.math.IntMath; + +public enum ArithmeticOperator { + PLUS("+"), + MINUS("-"), + TIMES("*"), + DIV("/"), + POWER("**"), + MODULO("\\"), + BITXOR("^"); + + private String asString; + + ArithmeticOperator(String asString) { + this.asString = asString; + } + + @Override + public String toString() { + return asString; + } + + public Integer eval(Integer left, Integer right) { + switch (this) { + case PLUS: + return left + right; + case MINUS: + return left - right; + case TIMES: + return left * right; + case DIV: + return left / right; + case POWER: + return IntMath.checkedPow(left, right); + case MODULO: + return left % right; + case BITXOR: + return left ^ right; + default: + throw new RuntimeException("Unknown arithmetic operator encountered."); + + } + } +} \ No newline at end of file diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticTerm.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticTerm.java new file mode 100644 index 000000000..fec6747f1 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/terms/ArithmeticTerm.java @@ -0,0 +1,13 @@ +package at.ac.tuwien.kr.alpha.api.terms; + +public interface ArithmeticTerm extends Term { + + ArithmeticOperator getOperator(); + + Term getLeftOperand(); + + Term getRightOperand(); + + Integer evaluateExpression(); + +} diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTermImpl.java similarity index 66% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTermImpl.java index 87fdd35e5..df1f275a3 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTermImpl.java @@ -30,10 +30,9 @@ import java.util.LinkedHashSet; import java.util.Set; -import com.google.common.math.IntMath; - 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.ArithmeticOperator; +import at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm; 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.util.Interner; @@ -42,25 +41,25 @@ * This class represents an arithmetic expression occurring as a term. * Copyright (c) 2017-2019, the Alpha Team. */ -public class ArithmeticTerm extends AbstractTerm { - private static final Interner INTERNER = new Interner<>(); +class ArithmeticTermImpl extends AbstractTerm implements ArithmeticTerm { + private static final Interner INTERNER = new Interner<>(); protected final Term left; private final ArithmeticOperator arithmeticOperator; private final Term right; - private ArithmeticTerm(Term left, ArithmeticOperator arithmeticOperator, Term right) { + private ArithmeticTermImpl(Term left, ArithmeticOperator arithmeticOperator, Term right) { this.left = left; this.arithmeticOperator = arithmeticOperator; this.right = right; } - public static Term getInstance(Term left, ArithmeticOperator arithmeticOperator, Term right) { + static Term getInstance(Term left, ArithmeticOperator arithmeticOperator, Term right) { // Evaluate ground arithmetic terms immediately and return result. if (left.isGround() && right.isGround()) { - Integer result = new ArithmeticTerm(left, arithmeticOperator, right).evaluateExpression(); + Integer result = new ArithmeticTermImpl(left, arithmeticOperator, right).evaluateExpression(); return ConstantTermImpl.getInstance(result); } - return INTERNER.intern(new ArithmeticTerm(left, arithmeticOperator, right)); + return INTERNER.intern(new ArithmeticTermImpl(left, arithmeticOperator, right)); } @Override @@ -89,37 +88,8 @@ public Term renameVariables(String renamePrefix) { public Term normalizeVariables(String renamePrefix, Term.RenameCounter counter) { Term normalizedLeft = left.normalizeVariables(renamePrefix, counter); Term normalizedRight = right.normalizeVariables(renamePrefix, counter); - return ArithmeticTerm.getInstance(normalizedLeft, arithmeticOperator, normalizedRight); - - } - - public static Integer evaluateGroundTerm(Term term) { - if (!term.isGround()) { - throw new RuntimeException("Cannot evaluate arithmetic term since it is not ground: " + term); - } - return evaluateGroundTermHelper(term); - } - - private static Integer evaluateGroundTermHelper(Term term) { - if (term instanceof ConstantTerm - && ((ConstantTerm) term).getObject() instanceof Integer) { - // Extract integer from the constant. - return (Integer) ((ConstantTerm) term).getObject(); - } else if (term instanceof ArithmeticTerm) { - return ((ArithmeticTerm) term).evaluateExpression(); - } else { - // ASP Core 2 standard allows non-integer terms in arithmetic expressions, result is to simply ignore the ground instance. - return null; - } - } + return ArithmeticTermImpl.getInstance(normalizedLeft, arithmeticOperator, normalizedRight); - Integer evaluateExpression() { - Integer leftInt = evaluateGroundTermHelper(left); - Integer rightInt = evaluateGroundTermHelper(right); - if (leftInt == null || rightInt == null) { - return null; - } - return arithmeticOperator.eval(leftInt, rightInt); } @Override @@ -136,7 +106,7 @@ public boolean equals(Object o) { return false; } - ArithmeticTerm that = (ArithmeticTerm) o; + ArithmeticTermImpl that = (ArithmeticTermImpl) o; if (left != that.left) { return false; @@ -151,68 +121,51 @@ public boolean equals(Object o) { public int hashCode() { return 31 * (31 * left.hashCode() + arithmeticOperator.hashCode()) + right.hashCode(); } + + @Override + public ArithmeticOperator getOperator() { + return arithmeticOperator; + } + + @Override + public Term getLeftOperand() { + return left; + } + + @Override + public Term getRightOperand() { + return right; + } - public enum ArithmeticOperator { - PLUS("+"), - MINUS("-"), - TIMES("*"), - DIV("/"), - POWER("**"), - MODULO("\\"), - BITXOR("^"); - - private String asString; - - ArithmeticOperator(String asString) { - this.asString = asString; - } - - @Override - public String toString() { - return asString; - } - - public Integer eval(Integer left, Integer right) { - switch (this) { - case PLUS: - return left + right; - case MINUS: - return left - right; - case TIMES: - return left * right; - case DIV: - return left / right; - case POWER: - return IntMath.checkedPow(left, right); - case MODULO: - return left % right; - case BITXOR: - return left ^ right; - default: - throw new RuntimeException("Unknown arithmetic operator encountered."); - - } + @Override + public Integer evaluateExpression() { + Integer leftInt = Terms.evaluateGroundTermHelper(left); + Integer rightInt = Terms.evaluateGroundTermHelper(right); + if (leftInt == null || rightInt == null) { + return null; } + return arithmeticOperator.eval(leftInt, rightInt); } - - public static class MinusTerm extends ArithmeticTerm { + + // FIXME it doesn't seem like this class is really needed, could be handled by an if in ArithmeticTermImpl#getInstance + public static class MinusTerm extends ArithmeticTermImpl { private MinusTerm(Term term) { super(term, null, null); } - public static Term getInstance(Term term) { + static Term getInstance(Term term) { // Evaluate ground arithmetic terms immediately and return result. if (term.isGround()) { - Integer result = evaluateGroundTermHelper(term) * -1; + Integer result = Terms.evaluateGroundTerm(term) * -1; return ConstantTermImpl.getInstance(result); } return INTERNER.intern(new MinusTerm(term)); } @Override - Integer evaluateExpression() { - return evaluateGroundTermHelper(left) * -1; + public Integer evaluateExpression() { + return Terms.evaluateGroundTermHelper(left) * -1; } @Override diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java index f7b0a8ba7..46aa291e1 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java @@ -3,10 +3,13 @@ import java.util.ArrayList; import java.util.List; +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; 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.ArithmeticTermImpl.MinusTerm; /** * Convenience methods for {@link Term}s. The methods provided here are an @@ -50,6 +53,15 @@ public static FunctionTerm newFunctionTerm(String functionSmybol, Term... functi return FunctionTermImpl.getInstance(functionSmybol, functionArgs); } + public static Term newArithmeticTerm(Term leftOperand, ArithmeticOperator operator, Term rightOperand) { + return ArithmeticTermImpl.getInstance(leftOperand, operator, rightOperand); + } + + // TODO see comment in MinusTerm, should be merged with normal arithmetic term! + public static Term newMinusTerm(Term negatedTerm) { + return MinusTerm.getInstance(negatedTerm); + } + @SafeVarargs public static > List> asTermList(T... values) { List> retVal = new ArrayList<>(); @@ -68,4 +80,24 @@ public static List renameTerms(List terms, String prefix, int counte return renamedTerms; } + public static Integer evaluateGroundTerm(Term term) { + if (!term.isGround()) { + throw new RuntimeException("Cannot evaluate arithmetic term since it is not ground: " + term); + } + return evaluateGroundTermHelper(term); + } + + static Integer evaluateGroundTermHelper(Term term) { + if (term instanceof ConstantTerm + && ((ConstantTerm) term).getObject() instanceof Integer) { + // Extract integer from the constant. + return (Integer) ((ConstantTerm) term).getObject(); + } else if (term instanceof ArithmeticTerm) { + return ((ArithmeticTerm) term).evaluateExpression(); + } else { + // ASP Core 2 standard allows non-integer terms in arithmetic expressions, result is to simply ignore the ground instance. + return null; + } + } + } diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java index 92fff66c3..064405722 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java @@ -32,7 +32,7 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.Term.RenameCounter; import at.ac.tuwien.kr.alpha.commons.AbstractTerm.RenameCounterImpl; -import at.ac.tuwien.kr.alpha.commons.ArithmeticTerm.MinusTerm; +import at.ac.tuwien.kr.alpha.commons.ArithmeticTermImpl.MinusTerm; /** * Tests {@link MinusTerm} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index d25e31074..cd8c1c9f5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -27,8 +27,6 @@ */ package at.ac.tuwien.kr.alpha.core.atoms; -import static at.ac.tuwien.kr.alpha.commons.ArithmeticTerm.evaluateGroundTerm; - import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; @@ -37,9 +35,9 @@ import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm; 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.ArithmeticTerm; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; @@ -164,7 +162,7 @@ public List getSatisfyingSubstitutions(Substitution partialSubstit Term resultTerm = null; // Check if the groundTerm is an arithmetic expression and evaluate it if so. if (groundTerm instanceof ArithmeticTerm) { - Integer result = evaluateGroundTerm(groundTerm); + Integer result = Terms.evaluateGroundTerm(groundTerm); if (result == null) { return Collections.emptyList(); } @@ -187,7 +185,7 @@ public boolean isLeftOrRightAssigning() { private Term evaluateTerm(Term term) { // Evaluate arithmetics. if (term instanceof ArithmeticTerm) { - Integer result = ArithmeticTerm.evaluateGroundTerm(term); + Integer result = Terms.evaluateGroundTerm(term); if (result == null) { return null; } 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 bcedd8b8a..50d7bc1b6 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 @@ -55,11 +55,11 @@ import at.ac.tuwien.kr.alpha.api.rules.ChoiceHead.ChoiceElement; import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; +import at.ac.tuwien.kr.alpha.api.terms.ArithmeticOperator; 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; -import at.ac.tuwien.kr.alpha.commons.ArithmeticTerm; import at.ac.tuwien.kr.alpha.commons.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; @@ -451,10 +451,9 @@ public ComparisonOperatorImpl visitBinop(ASPCore2Parser.BinopContext ctx) { public ComparisonAtom visitBuiltin_atom(ASPCore2Parser.Builtin_atomContext ctx) { // builtin_atom : term binop term; return new ComparisonAtom( - (Term) visit(ctx.term(0)), - (Term) visit(ctx.term(1)), - visitBinop(ctx.binop()) - ); + (Term) visit(ctx.term(0)), + (Term) visit(ctx.term(1)), + visitBinop(ctx.binop())); } @Override @@ -560,11 +559,10 @@ public ExternalAtom visitExternal_atom(ASPCore2Parser.External_atomContext ctx) List outputTerms = visitTerms(ctx.output); return new ExternalAtom( - CorePredicate.getInstance(predicateName, outputTerms.size()), - interpretation, - visitTerms(ctx.input), - outputTerms - ); + CorePredicate.getInstance(predicateName, outputTerms.size()), + interpretation, + visitTerms(ctx.input), + outputTerms); } @Override @@ -581,34 +579,34 @@ public IntervalTerm visitTerm_interval(ASPCore2Parser.Term_intervalContext ctx) @Override public Object visitTerm_minusArithTerm(ASPCore2Parser.Term_minusArithTermContext ctx) { // | MINUS term - return ArithmeticTerm.MinusTerm.getInstance((Term) visit(ctx.term())); + return Terms.newMinusTerm((Term) visit(ctx.term())); } @Override public Object visitTerm_timesdivmodArithTerm(ASPCore2Parser.Term_timesdivmodArithTermContext ctx) { // | term (TIMES | DIV | MODULO) term - ArithmeticTerm.ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticTerm.ArithmeticOperator.TIMES - : ctx.DIV() != null ? ArithmeticTerm.ArithmeticOperator.DIV : ArithmeticTerm.ArithmeticOperator.MODULO; - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); + ArithmeticOperator op = ctx.TIMES() != null ? ArithmeticOperator.TIMES + : ctx.DIV() != null ? ArithmeticOperator.DIV : ArithmeticOperator.MODULO; + return Terms.newArithmeticTerm((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); } @Override public Object visitTerm_plusminusArithTerm(ASPCore2Parser.Term_plusminusArithTermContext ctx) { // | term (PLUS | MINUS) term - ArithmeticTerm.ArithmeticOperator op = ctx.PLUS() != null ? ArithmeticTerm.ArithmeticOperator.PLUS : ArithmeticTerm.ArithmeticOperator.MINUS; - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); + ArithmeticOperator op = ctx.PLUS() != null ? ArithmeticOperator.PLUS : ArithmeticOperator.MINUS; + return Terms.newArithmeticTerm((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); } @Override public Object visitTerm_powerArithTerm(ASPCore2Parser.Term_powerArithTermContext ctx) { // | term POWER term - ArithmeticTerm.ArithmeticOperator op = ArithmeticTerm.ArithmeticOperator.POWER; - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); + ArithmeticOperator op = ArithmeticOperator.POWER; + return Terms.newArithmeticTerm((Term) visit(ctx.term(0)), op, (Term) visit(ctx.term(1))); } @Override public Object visitTerm_bitxorArithTerm(ASPCore2Parser.Term_bitxorArithTermContext ctx) { // | term BITXOR term - return ArithmeticTerm.getInstance((Term) visit(ctx.term(0)), ArithmeticTerm.ArithmeticOperator.BITXOR, (Term) visit(ctx.term(1))); + return Terms.newArithmeticTerm((Term) visit(ctx.term(0)), ArithmeticOperator.BITXOR, (Term) visit(ctx.term(1))); } } From 82ad457e49161af9e44a5415f741b4cfb47c23bf Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 23 Feb 2021 14:26:36 +0100 Subject: [PATCH 031/111] separate package for terms in alpha-commons --- .../tuwien/kr/alpha/commons/{ => terms}/AbstractTerm.java | 2 +- .../kr/alpha/commons/{ => terms}/ArithmeticTermImpl.java | 2 +- .../kr/alpha/commons/{ => terms}/ConstantTermImpl.java | 2 +- .../kr/alpha/commons/{ => terms}/FunctionTermImpl.java | 2 +- .../tuwien/kr/alpha/commons/{ => terms}/IntervalTerm.java | 2 +- .../at/ac/tuwien/kr/alpha/commons/{ => terms}/Terms.java | 4 ++-- .../kr/alpha/commons/{ => terms}/VariableTermImpl.java | 2 +- .../ac/tuwien/kr/alpha/commons/{ => terms}/TermTest.java | 5 ++++- .../ac/tuwien/kr/alpha/commons/{ => terms}/TermsTest.java | 3 ++- .../kr/alpha/commons/{ => terms}/TestMinusTerm.java | 8 +++++--- .../java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java | 2 +- .../java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java | 2 +- .../at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java | 2 +- .../ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java | 2 +- .../java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java | 2 +- .../at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java | 2 +- .../at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java | 2 +- .../at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java | 4 ++-- .../at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java | 4 ++-- .../java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java | 2 +- .../ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java | 2 +- .../kr/alpha/core/externals/AspStandardLibrary.java | 2 +- .../at/ac/tuwien/kr/alpha/core/externals/Externals.java | 2 +- .../kr/alpha/core/grounder/FactIntervalEvaluator.java | 4 ++-- .../tuwien/kr/alpha/core/grounder/SubstitutionImpl.java | 2 +- .../ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java | 4 ++-- .../programs/transformation/CardinalityNormalization.java | 2 +- .../core/programs/transformation/ChoiceHeadToNormal.java | 4 ++-- .../transformation/IntervalTermToIntervalAtom.java | 4 ++-- .../core/programs/transformation/SumNormalization.java | 2 +- .../at/ac/tuwien/kr/alpha/core/rules/InternalRule.java | 2 +- .../src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java | 2 +- .../test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java | 4 ++-- .../api/externals/stdlib/AspStandardLibraryTest.java | 2 +- .../java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java | 2 +- .../at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java | 2 +- .../at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java | 2 +- .../alpha/core/grounder/IndexedInstanceStorageTest.java | 2 +- .../tuwien/kr/alpha/core/grounder/NaiveGrounderTest.java | 2 +- .../kr/alpha/core/grounder/NoGoodGeneratorTest.java | 2 +- .../tuwien/kr/alpha/core/grounder/SubstitutionTest.java | 2 +- .../at/ac/tuwien/kr/alpha/core/grounder/UnifierTest.java | 2 +- .../ac/tuwien/kr/alpha/core/solver/AtomCounterTests.java | 2 +- .../at/ac/tuwien/kr/alpha/core/solver/HanoiTowerTest.java | 2 +- .../at/ac/tuwien/kr/alpha/core/solver/SolverTests.java | 2 +- .../alpha/core/solver/ThreeColouringRandomGraphTest.java | 2 +- .../alpha/core/solver/ThreeColouringTestWithRandom.java | 2 +- .../kr/alpha/core/solver/ThreeColouringWheelTest.java | 2 +- .../instantiation/LiteralInstantiationStrategyTest.java | 2 +- .../grounder/instantiation/LiteralInstantiatorTest.java | 2 +- .../alpha/grounder/structure/AnalyzeUnjustifiedTest.java | 2 +- .../StratifiedEvaluationRegressionTest.java | 2 +- .../grounder/transformation/StratifiedEvaluationTest.java | 2 +- .../java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java | 2 +- .../java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java | 2 +- .../kr/alpha/impl/FixedInterpretationLiteralsTest.java | 2 +- .../java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java | 2 +- 57 files changed, 73 insertions(+), 67 deletions(-) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/AbstractTerm.java (98%) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/ArithmeticTermImpl.java (99%) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/ConstantTermImpl.java (98%) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/FunctionTermImpl.java (98%) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/IntervalTerm.java (99%) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/Terms.java (96%) rename alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/VariableTermImpl.java (98%) rename alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/TermTest.java (94%) rename alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/TermsTest.java (91%) rename alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/{ => terms}/TestMinusTerm.java (87%) diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AbstractTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/AbstractTerm.java similarity index 98% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AbstractTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/AbstractTerm.java index 586392f5e..03710c3b5 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/AbstractTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/AbstractTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.HashMap; import java.util.Map; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ArithmeticTermImpl.java similarity index 99% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTermImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ArithmeticTermImpl.java index df1f275a3..4b52b4113 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ArithmeticTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ArithmeticTermImpl.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.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.LinkedHashSet; import java.util.Set; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ConstantTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ConstantTermImpl.java similarity index 98% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ConstantTermImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ConstantTermImpl.java index 1baef0a93..830d6f482 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/ConstantTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/ConstantTermImpl.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.Collections; import java.util.Set; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java similarity index 98% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java index 9b7420805..b163bc808 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/FunctionTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/FunctionTermImpl.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.ArrayList; import java.util.Arrays; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/IntervalTerm.java similarity index 99% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/IntervalTerm.java index ea549bf8c..313bd15aa 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/IntervalTerm.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/IntervalTerm.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.LinkedHashSet; import java.util.Set; diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/Terms.java similarity index 96% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/Terms.java index 46aa291e1..f52fbd93d 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/Terms.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/Terms.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.ArrayList; import java.util.List; @@ -9,7 +9,7 @@ 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.ArithmeticTermImpl.MinusTerm; +import at.ac.tuwien.kr.alpha.commons.terms.ArithmeticTermImpl.MinusTerm; /** * Convenience methods for {@link Term}s. The methods provided here are an diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/VariableTermImpl.java similarity index 98% rename from alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/VariableTermImpl.java index 92e4faf0e..5e892b480 100644 --- a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/VariableTermImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/terms/VariableTermImpl.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.Collections; import java.util.Set; diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java similarity index 94% rename from alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java index 139e5b280..ae017869c 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -15,6 +15,9 @@ 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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.terms.FunctionTermImpl; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.VariableTermImpl; /** * Copyright (c) 2016, the Alpha Team. diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermsTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java similarity index 91% rename from alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermsTest.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java index 92f89f1c1..22d5b6108 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TermsTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import java.util.List; @@ -6,6 +6,7 @@ import org.junit.Test; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; public class TermsTest { diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.java similarity index 87% rename from alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java rename to alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.java index 064405722..d49f0a86d 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/TestMinusTerm.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.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.commons; +package at.ac.tuwien.kr.alpha.commons.terms; import static org.junit.Assert.assertEquals; @@ -31,8 +31,10 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.Term.RenameCounter; -import at.ac.tuwien.kr.alpha.commons.AbstractTerm.RenameCounterImpl; -import at.ac.tuwien.kr.alpha.commons.ArithmeticTermImpl.MinusTerm; +import at.ac.tuwien.kr.alpha.commons.terms.ConstantTermImpl; +import at.ac.tuwien.kr.alpha.commons.terms.VariableTermImpl; +import at.ac.tuwien.kr.alpha.commons.terms.AbstractTerm.RenameCounterImpl; +import at.ac.tuwien.kr.alpha.commons.terms.ArithmeticTermImpl.MinusTerm; /** * Tests {@link MinusTerm} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java index 68255a025..36ee94796 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java @@ -37,7 +37,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; /** * Represents ordinary ASP atoms. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java index 5062ad153..9d6deabff 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java @@ -35,7 +35,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; public class ChoiceAtom extends CoreAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java index eadd72737..e5f5476af 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java @@ -35,7 +35,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index cd8c1c9f5..dff106692 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java index 7911b47dc..68bd2452f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java @@ -36,7 +36,7 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.grounder.Unifier; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 354df5a42..28ce72122 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index d1d8dd165..84342a632 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java index 0b393fb4b..33ccb166e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java @@ -35,8 +35,8 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +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.common.CorePredicate; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index c6830285a..06609bd17 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java @@ -38,8 +38,8 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +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.grounder.SubstitutionImpl; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java index 1c2b67f84..cd254feb0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java @@ -36,7 +36,7 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; 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; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java index 2483edb6e..09664afb5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java @@ -13,7 +13,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; public class AnswerSetBuilder { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java index db7cba228..30aad5eed 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/AspStandardLibrary.java @@ -33,7 +33,7 @@ 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; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; /** * Collection of methods that can be used as external atoms from ASP programs. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java index 3d9444426..a7cdb8379 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java @@ -41,7 +41,7 @@ import at.ac.tuwien.kr.alpha.api.externals.Predicate; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BinaryPredicateInterpretation; import at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.BindingMethodPredicateInterpretation; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index 0e67fdc8d..3909dc7c9 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -8,8 +8,8 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; 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.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; /** * Helper functions to evaluate facts potentially containing intervals. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java index 071950e85..7c447271f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java @@ -42,7 +42,7 @@ 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.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Substitution { 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 50d7bc1b6..45b71f4e7 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 @@ -60,8 +60,8 @@ 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.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +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.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java index f2eac9c51..61b887ccd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/CardinalityNormalization.java @@ -14,7 +14,7 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; 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; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; 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 59670bc6d..2c2828a9c 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 @@ -39,8 +39,8 @@ import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +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.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; 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 7a2768b63..93006cb92 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 @@ -39,8 +39,8 @@ 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.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +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.NormalProgram; import at.ac.tuwien.kr.alpha.core.rules.NormalRule; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java index aad6df663..8a80e7b25 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/SumNormalization.java @@ -13,7 +13,7 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; 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; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; 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 ee58bde24..ea2bff955 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 @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfoImpl; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java index 5d7b486c6..92f50a9f8 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/TestUtil.java @@ -32,7 +32,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java index 5d57ce7aa..c72ddb95a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/antlr/ParserTest.java @@ -53,8 +53,8 @@ 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.IntervalTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +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.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java index 316624e6b..84a3ce882 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/api/externals/stdlib/AspStandardLibraryTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; public class AspStandardLibraryTest { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java index f03858e3a..301f7fee3 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/AtomStoreTest.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.common; import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java index 397ab25f2..8f80af2d7 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/BasicAnswerSetTest.java @@ -17,7 +17,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.BasicAnswerSet; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java index 01d43adf4..d1597274f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/common/atoms/AtomsTest.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.core.externals.Externals; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java index 1c3ddb583..e65962a2b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/grounder/IndexedInstanceStorageTest.java @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; /** 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 17b5e4bfa..ce8eb435a 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 @@ -49,7 +49,7 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; 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; 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 802044cd7..51dde68b8 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 @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; 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.Terms; +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.common.Literals; 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 90ad6606b..95f07781c 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 @@ -45,7 +45,7 @@ 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.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; 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 b8f874a92..e79c714e9 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 @@ -37,7 +37,7 @@ import at.ac.tuwien.kr.alpha.api.program.ProgramParser; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; 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 fe7cabcc0..9cb6dfb49 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 @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; 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; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; 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 e6e08b163..a54cfa1c7 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 @@ -44,7 +44,7 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; 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 97f0a947d..161e06d23 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 @@ -45,7 +45,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; import at.ac.tuwien.kr.alpha.core.common.AtomStore; 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 b92242ab1..a3e0925ce 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 @@ -38,7 +38,7 @@ import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; 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 f1b170556..57ecb6983 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 @@ -41,7 +41,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; 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 3584e4672..7ba22fa1b 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 @@ -39,7 +39,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java index 396c51f19..0367ea628 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiationStrategyTest.java @@ -12,7 +12,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.common.AtomStore; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java index 141f0abef..04034e5df 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/instantiation/LiteralInstantiatorTest.java @@ -12,7 +12,7 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; 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.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.BasicLiteral; import at.ac.tuwien.kr.alpha.core.atoms.ComparisonAtom; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java index 214799634..52325f54f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/structure/AnalyzeUnjustifiedTest.java @@ -42,7 +42,7 @@ import at.ac.tuwien.kr.alpha.api.program.Literal; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java index 4d943360d..184128e67 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationRegressionTest.java @@ -21,7 +21,7 @@ import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java index b1c346430..61594841d 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/grounder/transformation/StratifiedEvaluationTest.java @@ -50,7 +50,7 @@ import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.ProgramParser; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java index 7944d108e..7d1a3bd0b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.program.Program; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.util.AnswerSetsParser; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java index 4b6903405..c75a07fa3 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/AlphaImplTest.java @@ -67,7 +67,7 @@ import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.solver.heuristics.Heuristic; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalAtom; import at.ac.tuwien.kr.alpha.core.atoms.ExternalLiteral; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java index d8646cf71..f9fbe9a40 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/impl/FixedInterpretationLiteralsTest.java @@ -18,7 +18,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.externals.AspStandardLibrary; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java index 726d94148..5e1d5103d 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/test/util/TestUtils.java @@ -15,7 +15,7 @@ import at.ac.tuwien.kr.alpha.api.program.Atom; import at.ac.tuwien.kr.alpha.api.program.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; -import at.ac.tuwien.kr.alpha.commons.Terms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; import at.ac.tuwien.kr.alpha.core.programs.AbstractProgram; From fe97209dc0840721a686b1661cc574598c16c0ef Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Tue, 23 Feb 2021 14:30:06 +0100 Subject: [PATCH 032/111] fix checkstyle errors --- .../java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java | 3 --- .../java/at/ac/tuwien/kr/alpha/commons/terms/TermsTest.java | 1 - .../at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.java | 2 -- 3 files changed, 6 deletions(-) diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java index ae017869c..25d06ed36 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TermTest.java @@ -15,9 +15,6 @@ 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.commons.terms.FunctionTermImpl; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.commons.terms.VariableTermImpl; /** * Copyright (c) 2016, the Alpha Team. 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 22d5b6108..666817172 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 @@ -6,7 +6,6 @@ import org.junit.Test; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; public class TermsTest { diff --git a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.java b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.java index d49f0a86d..1407759cf 100644 --- a/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.java +++ b/alpha-commons/src/test/java/at/ac/tuwien/kr/alpha/commons/terms/TestMinusTerm.java @@ -31,8 +31,6 @@ import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.Term.RenameCounter; -import at.ac.tuwien.kr.alpha.commons.terms.ConstantTermImpl; -import at.ac.tuwien.kr.alpha.commons.terms.VariableTermImpl; import at.ac.tuwien.kr.alpha.commons.terms.AbstractTerm.RenameCounterImpl; import at.ac.tuwien.kr.alpha.commons.terms.ArithmeticTermImpl.MinusTerm; From 171f6b307da1945486925ccf0adbd1a22bb080e1 Mon Sep 17 00:00:00 2001 From: Michael Langowski Date: Thu, 1 Apr 2021 17:27:53 +0200 Subject: [PATCH 033/111] WIP: move AggregateAtom to alpha-commons --- .../java/at/ac/tuwien/kr/alpha/api/Alpha.java | 8 +-- .../at/ac/tuwien/kr/alpha/api/AnswerSet.java | 4 +- .../kr/alpha/api/config/InputConfig.java | 2 +- .../kr/alpha/api/grounder/Instance.java | 2 +- .../alpha/api/grounder/RuleGroundingInfo.java | 2 +- .../api/grounder/RuleGroundingOrder.java | 2 +- .../ASPCore2Program.java | 2 +- .../CompiledProgram.java | 2 +- .../InlineDirectives.java | 2 +- .../api/{program => programs}/Literal.java | 3 +- .../api/{program => programs}/Predicate.java | 2 +- .../api/{program => programs}/Program.java | 3 +- .../{program => programs}/ProgramParser.java | 2 +- .../programs}/VariableNormalizableAtom.java | 4 +- .../api/{program => programs/atoms}/Atom.java | 7 ++- .../alpha/api/programs/atoms/BasicAtom.java | 7 +++ .../tuwien/kr/alpha/api/rules/ChoiceHead.java | 4 +- .../kr/alpha/api/rules/CompiledRule.java | 2 +- .../tuwien/kr/alpha/api/rules/NormalHead.java | 3 +- .../at/ac/tuwien/kr/alpha/api/rules/Rule.java | 4 +- .../main/java/at/ac/tuwien/kr/alpha/Main.java | 6 +- .../mappers/AnswerSetToWorkbookMapper.java | 4 +- .../kr/alpha/AnswerSetToXlsxWriterTest.java | 4 +- .../AnswerSetToWorkbookMapperTest.java | 4 +- .../kr/alpha/commons/atoms/AbstractAtom.java | 12 ++-- .../alpha/commons}/atoms/AggregateAtom.java | 18 +++--- .../tuwien/kr/alpha/commons/atoms/Atoms.java | 35 ++++++++++++ .../kr/alpha/commons/atoms/BasicAtomImpl.java | 33 ++++++----- .../kr/alpha/commons/literals/Literals.java | 17 ++++++ .../substitutions}/SubstitutionImpl.java | 22 +------- .../alpha/commons/substitutions}/Unifier.java | 2 +- .../alpha/core/api/PublicToCoreApiMapper.java | 29 ---------- .../kr/alpha/core/atoms/AggregateLiteral.java | 4 +- .../kr/alpha/core/atoms/BasicLiteral.java | 12 ++-- .../kr/alpha/core/atoms/ChoiceAtom.java | 9 +-- .../kr/alpha/core/atoms/ComparisonAtom.java | 8 ++- .../alpha/core/atoms/ComparisonLiteral.java | 7 ++- .../kr/alpha/core/atoms/CoreLiteral.java | 15 ++--- .../kr/alpha/core/atoms/EnumerationAtom.java | 7 ++- .../kr/alpha/core/atoms/ExternalAtom.java | 8 ++- .../kr/alpha/core/atoms/ExternalLiteral.java | 7 ++- .../atoms/FixedInterpretationLiteral.java | 5 +- .../kr/alpha/core/atoms/IntervalAtom.java | 8 ++- .../kr/alpha/core/atoms/IntervalLiteral.java | 2 +- .../core/{common => atoms}/Literals.java | 2 +- .../tuwien/kr/alpha/core/atoms/RuleAtom.java | 9 +-- .../alpha/core/common/AnswerSetBuilder.java | 12 ++-- .../kr/alpha/core/common/Assignment.java | 4 +- .../kr/alpha/core/common/AtomStore.java | 6 +- .../kr/alpha/core/common/AtomStoreImpl.java | 2 +- .../kr/alpha/core/common/BasicAnswerSet.java | 4 +- .../core/common/ComparisonOperatorImpl.java | 2 +- .../kr/alpha/core/common/CoreAnswerSet.java | 4 +- .../kr/alpha/core/common/CorePredicate.java | 2 +- .../tuwien/kr/alpha/core/common/NoGood.java | 10 ++-- .../core/common/SimpleAnswerSetFormatter.java | 4 +- .../alpha/core/depgraph/DependencyGraph.java | 6 +- .../tuwien/kr/alpha/core/depgraph/Node.java | 2 +- .../kr/alpha/core/externals/Externals.java | 7 +-- .../alpha/core/grounder/AbstractGrounder.java | 2 +- .../alpha/core/grounder/BridgedGrounder.java | 2 +- .../alpha/core/grounder/ChoiceRecorder.java | 2 +- .../core/grounder/FactIntervalEvaluator.java | 2 +- .../alpha/core/grounder/GrounderFactory.java | 4 +- .../core/grounder/IndexedInstanceStorage.java | 4 +- .../kr/alpha/core/grounder/NaiveGrounder.java | 15 ++--- .../alpha/core/grounder/NoGoodGenerator.java | 14 ++--- .../grounder/ProgramAnalyzingGrounder.java | 4 +- .../core/grounder/RuleGroundingInfoImpl.java | 24 +++++--- .../core/grounder/RuleGroundingOrderImpl.java | 7 ++- .../kr/alpha/core/grounder/Unification.java | 3 +- .../kr/alpha/core/grounder/WorkingMemory.java | 6 +- .../AbstractLiteralInstantiationStrategy.java | 10 ++-- ...ultLazyGroundingInstantiationStrategy.java | 19 +++---- .../LiteralInstantiationResult.java | 4 +- .../LiteralInstantiationStrategy.java | 4 +- .../instantiation/LiteralInstantiator.java | 4 +- ...rkingMemoryBasedInstantiationStrategy.java | 4 +- .../structure/AnalyzeUnjustified.java | 25 ++++----- .../alpha/core/grounder/structure/LitSet.java | 6 +- .../core/parser/InlineDirectivesImpl.java | 2 +- .../alpha/core/parser/ParseTreeVisitor.java | 18 +++--- .../alpha/core/parser/ProgramParserImpl.java | 4 +- .../alpha/core/parser/ProgramPartParser.java | 6 +- .../alpha/core/programs/AbstractProgram.java | 6 +- .../alpha/core/programs/AnalyzedProgram.java | 4 +- .../kr/alpha/core/programs/InputProgram.java | 6 +- .../alpha/core/programs/InternalProgram.java | 8 +-- .../kr/alpha/core/programs/NormalProgram.java | 8 +-- .../kr/alpha/core/programs/Programs.java | 2 +- .../CardinalityNormalization.java | 15 ++--- .../transformation/ChoiceHeadToNormal.java | 17 +++--- .../transformation/EnumerationRewriting.java | 8 +-- .../IntervalTermToIntervalAtom.java | 4 +- .../NormalizeProgramTransformation.java | 2 +- .../transformation/PredicateInternalizer.java | 13 ++--- .../transformation/ProgramTransformation.java | 2 +- .../transformation/StratifiedEvaluation.java | 14 ++--- .../transformation/SumNormalization.java | 15 ++--- .../VariableEqualityRemoval.java | 6 +- .../kr/alpha/core/rules/AbstractRule.java | 2 +- .../tuwien/kr/alpha/core/rules/BasicRule.java | 4 +- .../kr/alpha/core/rules/InternalRule.java | 8 +-- .../kr/alpha/core/rules/NormalRule.java | 4 +- .../core/rules/heads/ChoiceHeadImpl.java | 4 +- .../core/rules/heads/DisjunctiveHeadImpl.java | 2 +- .../core/rules/heads/NormalHeadImpl.java | 2 +- .../kr/alpha/core/solver/AtomCounter.java | 5 +- .../tuwien/kr/alpha/core/solver/Choice.java | 4 +- .../kr/alpha/core/solver/ChoiceManager.java | 2 +- .../kr/alpha/core/solver/DefaultSolver.java | 17 +++--- .../core/solver/LearnedNoGoodDeletion.java | 2 +- .../alpha/core/solver/NaiveNoGoodStore.java | 2 +- .../kr/alpha/core/solver/NaiveSolver.java | 6 +- .../core/solver/NoGoodStoreAlphaRoaming.java | 10 ++-- .../kr/alpha/core/solver/TrailAssignment.java | 30 ++++++---- .../kr/alpha/core/solver/WatchedNoGood.java | 2 +- .../alpha/core/solver/WritableAssignment.java | 4 +- .../heuristics/AlphaActiveRuleHeuristic.java | 2 +- .../alpha/core/solver/heuristics/BerkMin.java | 6 +- .../solver/heuristics/BerkMinLiteral.java | 2 +- .../solver/heuristics/BranchingHeuristic.java | 2 +- .../heuristics/DependencyDrivenHeuristic.java | 4 +- .../GeneralizedDependencyDrivenHeuristic.java | 2 +- .../solver/heuristics/HeapOfActiveAtoms.java | 2 +- .../heuristics/HeapOfActiveChoicePoints.java | 2 +- .../solver/heuristics/NaiveHeuristic.java | 2 +- .../solver/heuristics/ReplayHeuristic.java | 2 +- .../alpha/core/solver/heuristics/VSIDS.java | 6 +- .../activity/BodyActivityProvider.java | 2 +- .../learning/GroundConflictNoGoodLearner.java | 2 +- .../kr/alpha/core/util/Substitutions.java | 31 +++++++++++ .../java/at/ac/tuwien/kr/alpha/TestUtil.java | 8 +-- .../ac/tuwien/kr/alpha/antlr/ParserTest.java | 14 ++--- .../tuwien/kr/alpha/common/AtomStoreTest.java | 6 +- .../kr/alpha/common/BasicAnswerSetTest.java | 32 +++++------ .../ac/tuwien/kr/alpha/common/NoGoodTest.java | 2 +- .../tuwien/kr/alpha/common/ProgramTest.java | 2 +- .../ac/tuwien/kr/alpha/common/RuleTest.java | 2 +- .../kr/alpha/common/atoms/AtomsTest.java | 8 +-- ...LiteralBindingNonBindingVariablesTest.java | 6 +- .../core/depgraph/DependencyGraphTest.java | 6 +- .../depgraph/StratificationAlgorithmTest.java | 6 +- .../alpha/core/grounder/ChoiceGrounder.java | 18 +++--- .../kr/alpha/core/grounder/DummyGrounder.java | 16 +++--- .../core/grounder/NaiveGrounderTest.java | 11 ++-- .../core/grounder/NoGoodGeneratorTest.java | 9 +-- .../grounder/ProgramTransformationTest.java | 6 +- .../core/grounder/RuleGroundingOrderTest.java | 6 +- .../alpha/core/grounder/RuleToStringTest.java | 4 +- .../alpha/core/grounder/SubstitutionTest.java | 28 ++++++---- .../kr/alpha/core/grounder/UnifierTest.java | 9 +-- .../core/solver/AbstractSolverTests.java | 6 +- .../kr/alpha/core/solver/AggregatesTest.java | 4 +- .../alpha/core/solver/AtomCounterTests.java | 19 ++++--- .../alpha/core/solver/ChoiceManagerTests.java | 6 +- .../kr/alpha/core/solver/HanoiTowerTest.java | 12 ++-- .../solver/HeadBodyTransformationTests.java | 2 +- .../kr/alpha/core/solver/SolverTests.java | 8 +-- .../solver/ThreeColouringRandomGraphTest.java | 8 +-- .../solver/ThreeColouringTestWithRandom.java | 12 ++-- .../core/solver/ThreeColouringWheelTest.java | 12 ++-- .../AlphaHeuristicTestAssumptions.java | 6 +- .../heuristics/HeapOfActiveAtomsTest.java | 2 +- .../solver/heuristics/HeuristicTestUtils.java | 2 +- .../heuristics/ReplayHeuristicTest.java | 2 +- .../core/solver/heuristics/VSIDSTest.java | 2 +- .../LiteralInstantiationStrategyTest.java | 55 ++++++++++--------- .../LiteralInstantiatorTest.java | 20 +++---- .../structure/AnalyzeUnjustifiedTest.java | 35 ++++++------ .../StratifiedEvaluationRegressionTest.java | 30 +++++----- .../StratifiedEvaluationTest.java | 19 ++++--- .../alpha/test/util/SubstitutionTestUtil.java | 4 +- .../tuwien/kr/alpha/test/util/TestUtils.java | 17 +++--- .../tuwien/kr/alpha/api/impl/AlphaImpl.java | 10 ++-- .../tuwien/kr/alpha/impl/AlphaImplTest.java | 14 ++--- .../impl/FixedInterpretationLiteralsTest.java | 12 ++-- .../tuwien/kr/alpha/test/util/TestUtils.java | 10 ++-- 178 files changed, 781 insertions(+), 670 deletions(-) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs}/ASPCore2Program.java (78%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs}/CompiledProgram.java (90%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs}/InlineDirectives.java (87%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs}/Literal.java (84%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs}/Predicate.java (89%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs}/Program.java (73%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs}/ProgramParser.java (97%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms => alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs}/VariableNormalizableAtom.java (85%) rename alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/{program => programs/atoms}/Atom.java (76%) create mode 100644 alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/BasicAtom.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/AbstractAtom.java (92%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons}/atoms/AggregateAtom.java (93%) create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/Atoms.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImpl.java (79%) create mode 100644 alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/literals/Literals.java rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions}/SubstitutionImpl.java (91%) rename {alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder => alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions}/Unifier.java (98%) delete mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java rename alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/{common => atoms}/Literals.java (98%) create mode 100644 alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/util/Substitutions.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 febda8b7c..8a0932d0b 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 @@ -9,10 +9,10 @@ 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.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; -import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; 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 10dfa6693..c3bf18791 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 @@ -2,8 +2,8 @@ import java.util.SortedSet; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; public interface AnswerSet extends Comparable { diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/InputConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/InputConfig.java index 11ec4a41c..a9189d07c 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/InputConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/InputConfig.java @@ -1,7 +1,7 @@ package at.ac.tuwien.kr.alpha.api.config; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; import java.util.*; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Instance.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Instance.java index aaa0c6a85..ea80f7b09 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Instance.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/Instance.java @@ -6,7 +6,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.Util; -import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; /** diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java index 21820ce61..6a7be2060 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingInfo.java @@ -2,7 +2,7 @@ import java.util.List; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; public interface RuleGroundingInfo { diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java index 116b7227d..2f0abb141 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/grounder/RuleGroundingOrder.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.api.grounder; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; // TODO should we really expose this?? pretty specific to how our grounder works public interface RuleGroundingOrder { diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ASPCore2Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java similarity index 78% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ASPCore2Program.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java index 822b4c046..f7be84126 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ASPCore2Program.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs; import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/CompiledProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/CompiledProgram.java similarity index 90% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/CompiledProgram.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/CompiledProgram.java index 24d882b63..0f1c12a4e 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/CompiledProgram.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/CompiledProgram.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs; import java.util.LinkedHashSet; import java.util.Map; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InlineDirectives.java similarity index 87% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InlineDirectives.java index 985b9bb4e..7d4fb362e 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/InlineDirectives.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InlineDirectives.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs; import java.util.Map; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Literal.java similarity index 84% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Literal.java index 4a6c81e3a..4f4e4f5ac 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Literal.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Literal.java @@ -1,9 +1,10 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs; 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.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Predicate.java similarity index 89% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Predicate.java index 9ddc0695f..301033902 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Predicate.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Predicate.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs; public interface Predicate extends Comparable { String getName(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Program.java similarity index 73% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Program.java index 6feaacc8f..565cff397 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Program.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/Program.java @@ -1,7 +1,8 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs; import java.util.List; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.rules.Head; import at.ac.tuwien.kr.alpha.api.rules.Rule; diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java similarity index 97% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java index d280f527d..cda6f6f95 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/ProgramParser.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs; import java.io.IOException; import java.io.InputStream; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/VariableNormalizableAtom.java similarity index 85% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/VariableNormalizableAtom.java index fc2e973c5..6a2efbba4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/VariableNormalizableAtom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/VariableNormalizableAtom.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.core.atoms; +package at.ac.tuwien.kr.alpha.api.programs; -import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; /** * Interface for atom whose variables can be normalized, i.e., enumerated from diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/Atom.java similarity index 76% rename from alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java rename to alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/Atom.java index 4cd81c93e..32747ab9b 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/program/Atom.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/Atom.java @@ -1,13 +1,16 @@ -package at.ac.tuwien.kr.alpha.api.program; +package at.ac.tuwien.kr.alpha.api.programs.atoms; 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.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; public interface Atom extends Comparable { + Predicate getPredicate(); List getTerms(); @@ -31,7 +34,7 @@ public interface Atom extends Comparable { Set getOccurringVariables(); - Atom substitute(Substitution substitution); + Atom substitute(Substitution substitution); // Introduce parameterized interface Substituable 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/BasicAtom.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/BasicAtom.java new file mode 100644 index 000000000..b66145847 --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/atoms/BasicAtom.java @@ -0,0 +1,7 @@ +package at.ac.tuwien.kr.alpha.api.programs.atoms; + +import at.ac.tuwien.kr.alpha.api.programs.VariableNormalizableAtom; + +public interface BasicAtom extends Atom, VariableNormalizableAtom { + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java index 54a2b06d9..39b2e23e8 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/ChoiceHead.java @@ -3,8 +3,8 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; public interface ChoiceHead extends Head { diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java index c200ec45b..ac0127d2b 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/CompiledRule.java @@ -3,7 +3,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; public interface CompiledRule extends Rule { diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java index d0c741941..d6d353cfc 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/NormalHead.java @@ -1,9 +1,10 @@ package at.ac.tuwien.kr.alpha.api.rules; -import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; public interface NormalHead extends Head{ + // TODO should this be a BasicAtom? Atom getAtom(); boolean isGround(); diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java index 572495d34..f2a1b8c79 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/rules/Rule.java @@ -2,8 +2,8 @@ import java.util.Set; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; public interface Rule { 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 c84b01383..e75de1fd7 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 @@ -49,9 +49,9 @@ 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.impl.AlphaImpl; -import at.ac.tuwien.kr.alpha.api.program.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; -import at.ac.tuwien.kr.alpha.api.program.Program; +import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.rules.NormalHead; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.app.ComponentGraphWriter; diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapper.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapper.java index 3102e58a3..4fc5e81ee 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapper.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapper.java @@ -41,8 +41,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.mapper.AnswerSetToObjectMapper; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +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; /** 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 ccd013ef3..0caf9a209 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 @@ -17,8 +17,8 @@ import org.junit.Test; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +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; import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; 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 744ad2b3d..59199dd40 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 @@ -14,8 +14,8 @@ 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.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +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; import at.ac.tuwien.kr.alpha.core.common.AnswerSetBuilder; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/AbstractAtom.java similarity index 92% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/AbstractAtom.java index 68bd2452f..0fa932cb2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreAtom.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/AbstractAtom.java @@ -25,24 +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.atoms; +package at.ac.tuwien.kr.alpha.commons.atoms; import java.util.List; import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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; 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.grounder.Unifier; /** * An Atom is the common superclass of all representations of ASP atoms used by Alpha. */ -public abstract class CoreAtom implements Atom { +abstract class AbstractAtom implements Atom { /** * Creates a new Atom that represents this Atom, but has the given term list instead. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/AggregateAtom.java similarity index 93% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/AggregateAtom.java index 1bb5a9b33..75b75a6fc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateAtom.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/AggregateAtom.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.atoms; +package at.ac.tuwien.kr.alpha.commons.atoms; import static at.ac.tuwien.kr.alpha.api.Util.join; import static at.ac.tuwien.kr.alpha.api.Util.oops; @@ -34,24 +34,26 @@ import java.util.LinkedList; import java.util.List; +import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.core.atoms.AggregateLiteral; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -public class AggregateAtom extends CoreAtom { +public class AggregateAtom extends AbstractAtom { - private final ComparisonOperatorImpl lowerBoundOperator; + private final ComparisonOperator lowerBoundOperator; private final Term lowerBoundTerm; - private final ComparisonOperatorImpl upperBoundOperator; + private final ComparisonOperator upperBoundOperator; private final Term upperBoundTerm; private final AGGREGATEFUNCTION aggregatefunction; private final List aggregateElements; - public AggregateAtom(ComparisonOperatorImpl lowerBoundOperator, Term lowerBoundTerm, ComparisonOperatorImpl upperBoundOperator, Term upperBoundTerm, + public AggregateAtom(ComparisonOperator lowerBoundOperator, Term lowerBoundTerm, ComparisonOperator upperBoundOperator, Term upperBoundTerm, AGGREGATEFUNCTION aggregatefunction, List aggregateElements) { this.lowerBoundOperator = lowerBoundOperator; this.lowerBoundTerm = lowerBoundTerm; @@ -59,7 +61,7 @@ public AggregateAtom(ComparisonOperatorImpl lowerBoundOperator, Term lowerBoundT this.upperBoundTerm = upperBoundTerm; this.aggregatefunction = aggregatefunction; this.aggregateElements = aggregateElements; - if (upperBoundOperator != null || lowerBoundOperator != ComparisonOperatorImpl.LE || lowerBoundTerm == null) { + if (upperBoundOperator != null || lowerBoundOperator != ComparisonOperator.LE || lowerBoundTerm == null) { throw new UnsupportedOperationException("Aggregate construct not yet supported: " + this); } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/Atoms.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/Atoms.java new file mode 100644 index 000000000..54bdfbbcd --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/Atoms.java @@ -0,0 +1,35 @@ +package at.ac.tuwien.kr.alpha.commons.atoms; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +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.terms.Term; + +public final class Atoms { + + private Atoms() { + throw new AssertionError("Cannot instantiate utility class"); + } + + /** + * Creates a positive BasicAtom over predicate and terms. + * + * @param predicate + * @param terms + */ + public static BasicAtom newBasicAtom(Predicate predicate, List terms) { + return new BasicAtomImpl(predicate, terms); + } + + public static BasicAtom newBasicAtom(Predicate predicate, Term... terms) { + return new BasicAtomImpl(predicate, Arrays.asList(terms)); + } + + public static BasicAtom newBasicAtom(Predicate predicate) { + return new BasicAtomImpl(predicate, Collections.emptyList()); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImpl.java similarity index 79% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImpl.java index 36ee94796..005f217b0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicAtom.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/atoms/BasicAtomImpl.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.atoms; +package at.ac.tuwien.kr.alpha.commons.atoms; import java.util.Arrays; import java.util.Collections; @@ -34,15 +34,18 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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.terms.Term; +import at.ac.tuwien.kr.alpha.commons.literals.Literals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; /** * Represents ordinary ASP atoms. */ -public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { +class BasicAtomImpl extends AbstractAtom implements BasicAtom { private final Predicate predicate; private final List terms; private final boolean ground; @@ -53,7 +56,7 @@ public class BasicAtom extends CoreAtom implements VariableNormalizableAtom { * @param predicate * @param terms */ - public BasicAtom(Predicate predicate, List terms) { + BasicAtomImpl(Predicate predicate, List terms) { this.predicate = predicate; this.terms = terms; @@ -68,11 +71,11 @@ public BasicAtom(Predicate predicate, List terms) { this.ground = ground; } - public BasicAtom(Predicate predicate, Term... terms) { + BasicAtomImpl(Predicate predicate, Term... terms) { this(predicate, Arrays.asList(terms)); } - public BasicAtom(Predicate predicate) { + BasicAtomImpl(Predicate predicate) { this(predicate, Collections.emptyList()); } @@ -92,21 +95,21 @@ public boolean isGround() { } @Override - public BasicAtom substitute(Substitution substitution) { - return new BasicAtom(predicate, terms.stream() + public BasicAtomImpl substitute(Substitution substitution) { + return new BasicAtomImpl(predicate, terms.stream() .map(t -> t.substitute(substitution)) .collect(Collectors.toList())); } @Override - public BasicAtom normalizeVariables(String prefix, int counterStartingValue) { + public BasicAtomImpl normalizeVariables(String prefix, int counterStartingValue) { List renamedTerms = Terms.renameTerms(terms, prefix, counterStartingValue); - return new BasicAtom(predicate, renamedTerms); + return new BasicAtomImpl(predicate, renamedTerms); } @Override - public CoreLiteral toLiteral(boolean positive) { - return new BasicLiteral(this, positive); + public Literal toLiteral(boolean positive) { + return Literals.fromAtom(this, positive); } @Override @@ -150,7 +153,7 @@ public boolean equals(Object o) { return false; } - BasicAtom that = (BasicAtom) o; + BasicAtomImpl that = (BasicAtomImpl) o; return predicate.equals(that.predicate) && terms.equals(that.terms); } @@ -162,6 +165,6 @@ public int hashCode() { @Override public Atom withTerms(List terms) { - return new BasicAtom(predicate, terms); + return new BasicAtomImpl(predicate, terms); } } diff --git a/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/literals/Literals.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/literals/Literals.java new file mode 100644 index 000000000..e33280046 --- /dev/null +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/literals/Literals.java @@ -0,0 +1,17 @@ +package at.ac.tuwien.kr.alpha.commons.literals; + +import at.ac.tuwien.kr.alpha.api.programs.Literal; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; + +public final class Literals { + + private Literals() { + throw new AssertionError("Cannot instantiate utility class"); + } + + public static Literal fromAtom(Atom atom, boolean positive) { + // TODO + return null; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions/SubstitutionImpl.java similarity index 91% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions/SubstitutionImpl.java index 7c447271f..3d73638b5 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/SubstitutionImpl.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions/SubstitutionImpl.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.commons.substitutions; import java.util.List; import java.util.Map; @@ -36,18 +36,15 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; 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; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.parser.ProgramPartParser; public class SubstitutionImpl implements at.ac.tuwien.kr.alpha.api.grounder.Substitution { - private static final ProgramPartParser PROGRAM_PART_PARSER = new ProgramPartParser(); public static final Substitution EMPTY_SUBSTITUTION = new SubstitutionImpl() { @Override public > Term put(VariableTerm variableTerm, Term groundTerm) { @@ -225,19 +222,6 @@ public String toString() { return ret.toString(); } - public static SubstitutionImpl fromString(String substitution) { - String bare = substitution.substring(1, substitution.length() - 1); - String[] assignments = bare.split(","); - SubstitutionImpl ret = new SubstitutionImpl(); - for (String assignment : assignments) { - String[] keyVal = assignment.split("->"); - VariableTerm variable = Terms.newVariable(keyVal[0]); - Term assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]); - ret.put(variable, assignedTerm); - } - return ret; - } - @Override public boolean equals(Object o) { if (this == o) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions/Unifier.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java rename to alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions/Unifier.java index 757e1040e..8564e5358 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unifier.java +++ b/alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/substitutions/Unifier.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.grounder; +package at.ac.tuwien.kr.alpha.commons.substitutions; import static at.ac.tuwien.kr.alpha.api.Util.oops; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java deleted file mode 100644 index 4cd3b887b..000000000 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/api/PublicToCoreApiMapper.java +++ /dev/null @@ -1,29 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.api; - -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; -import at.ac.tuwien.kr.alpha.core.common.CorePredicate; - -/** - * Maps between public (i.e. published) API types residing in the alpha-api module and implementations used by the solver - * internally. - * - * Copyright (c) 2020-2021, the Alpha Team. - */ -public class PublicToCoreApiMapper { - - public static CorePredicate mapPredicate(Predicate predicate) { - if (predicate instanceof CorePredicate) { - return (CorePredicate) predicate; - } else { - return CorePredicate.getInstance(predicate.getName(), predicate.getArity()); - } - } - - public static CoreAtom mapAtom(Atom atom) { - // TODO - return null; - } - -} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java index e0b149b29..04c222434 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/AggregateLiteral.java @@ -6,6 +6,8 @@ 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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.atoms.AbstractAtom; +import at.ac.tuwien.kr.alpha.commons.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; /** @@ -27,7 +29,7 @@ public AggregateLiteral negate() { } /** - * @see CoreAtom#substitute(Substitution) + * @see AbstractAtom#substitute(Substitution) */ @Override public AggregateLiteral substitute(Substitution substitution) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java index c42969a8d..ee5f2ab4c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/BasicLiteral.java @@ -32,16 +32,18 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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.SubstitutionImpl; /** - * Contains a potentially negated {@link BasicAtom}. + * Contains a potentially negated {@link BasicAtomImpl}. * * Copyright (c) 2017-2018, the Alpha Team. */ -public class BasicLiteral extends CoreLiteral { +public class BasicLiteral extends CoreLiteral { // TODO could we parameterize Literal with Atom type? public BasicLiteral(BasicAtom atom, boolean positive) { super(atom, positive); @@ -61,11 +63,11 @@ public BasicLiteral negate() { } /** - * @see CoreAtom#substitute(SubstitutionImpl) + * @see AbstractAtom#substitute(SubstitutionImpl) */ @Override public BasicLiteral substitute(Substitution substitution) { - return new BasicLiteral(getAtom().substitute(substitution), positive); + return new BasicLiteral((BasicAtom) getAtom().substitute(substitution), positive); } /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java index 9d6deabff..5cbff5525 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ChoiceAtom.java @@ -32,13 +32,14 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +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; +import at.ac.tuwien.kr.alpha.commons.atoms.AbstractAtom; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -public class ChoiceAtom extends CoreAtom { +public class ChoiceAtom extends AbstractAtom { public static final Predicate ON = CorePredicate.getInstance("ChoiceOn", 1, true, true); public static final Predicate OFF = CorePredicate.getInstance("ChoiceOff", 1, true, true); @@ -85,7 +86,7 @@ public CoreLiteral toLiteral(boolean negated) { } @Override - public CoreAtom substitute(Substitution substitution) { + public AbstractAtom substitute(Substitution substitution) { return this; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java index e5f5476af..30128fc80 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonAtom.java @@ -32,16 +32,18 @@ import java.util.stream.Collectors; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.VariableNormalizableAtom; +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.atoms.AbstractAtom; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; /** * Represents a builtin comparison atom according to the standard. */ -public class ComparisonAtom extends CoreAtom implements VariableNormalizableAtom { +public class ComparisonAtom extends AbstractAtom implements VariableNormalizableAtom { private final Predicate predicate; final ComparisonOperatorImpl operator; private final List terms; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java index dff106692..24549e9e2 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ComparisonLiteral.java @@ -34,13 +34,14 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; import at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm; 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.AbstractAtom; +import at.ac.tuwien.kr.alpha.commons.substitutions.SubstitutionImpl; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.ComparisonOperatorImpl; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Contains a potentially negated {@link ComparisonAtom}. @@ -73,7 +74,7 @@ public ComparisonLiteral negate() { } /** - * @see CoreAtom#substitute(SubstitutionImpl) + * @see AbstractAtom#substitute(SubstitutionImpl) */ @Override public ComparisonLiteral substitute(Substitution substitution) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java index 947f98926..8f7d9c10b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/CoreLiteral.java @@ -33,14 +33,15 @@ import org.apache.commons.collections4.SetUtils; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.atoms.AbstractAtom; /** - * A potentially negated {@link CoreAtom} + * A potentially negated {@link AbstractAtom} * * Copyright (c) 2017-2018, the Alpha Team. */ @@ -82,7 +83,7 @@ public Set getOccurringVariables() { } /** - * @see CoreAtom#getPredicate() + * @see AbstractAtom#getPredicate() */ @Override public Predicate getPredicate() { @@ -90,7 +91,7 @@ public Predicate getPredicate() { } /** - * @see CoreAtom#getTerms() + * @see AbstractAtom#getTerms() */ @Override public List getTerms() { @@ -98,7 +99,7 @@ public List getTerms() { } /** - * @see CoreAtom#isGround() + * @see AbstractAtom#isGround() */ @Override public boolean isGround() { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java index 28ce72122..bc165d161 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/EnumerationAtom.java @@ -5,12 +5,13 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; 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.BasicAtomImpl; +import at.ac.tuwien.kr.alpha.commons.substitutions.SubstitutionImpl; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; /** * Represents a ground-instance enumeration atom of form: @@ -23,7 +24,7 @@ * * Copyright (c) 2017, the Alpha Team. */ -public class EnumerationAtom extends BasicAtom { +public class EnumerationAtom extends BasicAtomImpl { public static final Predicate ENUMERATION_PREDICATE = CorePredicate.getInstance("_Enumeration", 3); private static final HashMap> ENUMERATIONS = new HashMap<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java index 84342a632..6479d2668 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalAtom.java @@ -35,12 +35,14 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.VariableNormalizableAtom; +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.atoms.AbstractAtom; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -public class ExternalAtom extends CoreAtom implements VariableNormalizableAtom { +public class ExternalAtom extends AbstractAtom implements VariableNormalizableAtom { private final List input; private final List output; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java index e648c241d..af35e330c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/ExternalLiteral.java @@ -34,11 +34,12 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; 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.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; +import at.ac.tuwien.kr.alpha.commons.atoms.AbstractAtom; +import at.ac.tuwien.kr.alpha.commons.substitutions.SubstitutionImpl; /** * Contains a potentially negated {@link ExternalAtom}. @@ -64,7 +65,7 @@ public ExternalLiteral negate() { } /** - * @see CoreAtom#substitute(SubstitutionImpl) + * @see AbstractAtom#substitute(SubstitutionImpl) */ @Override public ExternalLiteral substitute(Substitution substitution) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java index 1c39ed31b..a7584555b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/FixedInterpretationLiteral.java @@ -30,7 +30,8 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; +import at.ac.tuwien.kr.alpha.commons.atoms.AbstractAtom; +import at.ac.tuwien.kr.alpha.commons.substitutions.SubstitutionImpl; /** * Represents a literal whose ground truth value(s) are independent of the @@ -41,7 +42,7 @@ */ public abstract class FixedInterpretationLiteral extends CoreLiteral { - public FixedInterpretationLiteral(CoreAtom atom, boolean positive) { + public FixedInterpretationLiteral(AbstractAtom atom, boolean positive) { super(atom, positive); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java index 33ccb166e..814618d3f 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalAtom.java @@ -32,9 +32,11 @@ import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.VariableNormalizableAtom; +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.atoms.AbstractAtom; 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.common.CorePredicate; @@ -51,7 +53,7 @@ * * Copyright (c) 2017, the Alpha Team. */ -public class IntervalAtom extends CoreAtom implements VariableNormalizableAtom { +public class IntervalAtom extends AbstractAtom implements VariableNormalizableAtom { private static final CorePredicate PREDICATE = CorePredicate.getInstance("_interval", 2, true); private final List terms; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java index 06609bd17..6855c2f7e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/IntervalLiteral.java @@ -38,9 +38,9 @@ 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.terms.VariableTerm; +import at.ac.tuwien.kr.alpha.commons.substitutions.SubstitutionImpl; 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.grounder.SubstitutionImpl; /** * @see IntervalAtom diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Literals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/Literals.java similarity index 98% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Literals.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/Literals.java index aa13adce0..8c34bb1b0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Literals.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/Literals.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; +package at.ac.tuwien.kr.alpha.core.atoms; /** * Provides methods to convert atoms to literals and vice versa, diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java index cd254feb0..79d985f8e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/atoms/RuleAtom.java @@ -31,11 +31,12 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +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.rules.CompiledRule; 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.atoms.AbstractAtom; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; @@ -43,7 +44,7 @@ * Atoms corresponding to rule bodies use this predicate, first term is rule number, * second is a term containing variable substitutions. */ -public class RuleAtom extends CoreAtom { +public class RuleAtom extends AbstractAtom { public static final Predicate PREDICATE = CorePredicate.getInstance("_R_", 2, true, true); private final List> terms; @@ -86,7 +87,7 @@ public CoreLiteral toLiteral(boolean positive) { } @Override - public CoreAtom substitute(Substitution substitution) { + public AbstractAtom substitute(Substitution substitution) { return this; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java index 09664afb5..f99152eb0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AnswerSetBuilder.java @@ -10,11 +10,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +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; +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.atoms.BasicAtom; public class AnswerSetBuilder { private boolean firstInstance = true; @@ -42,7 +42,7 @@ private void flush() { if (firstInstance) { predicate = CorePredicate.getInstance(predicateSymbol, 0); predicates.add(predicate); - predicateInstances.put(predicate, new TreeSet<>(singletonList(new BasicAtom(predicate)))); + predicateInstances.put(predicate, new TreeSet<>(singletonList(Atoms.newBasicAtom(predicate)))); } else { SortedSet atoms = predicateInstances.get(predicate); if (atoms == null) { @@ -79,7 +79,7 @@ public final > AnswerSetBuilder instance(final T... term .map(Terms::newConstant) .collect(Collectors.toList()); - instances.add(new BasicAtom(predicate, termList)); + instances.add(Atoms.newBasicAtom(predicate, termList)); return this; } @@ -91,7 +91,7 @@ public AnswerSetBuilder symbolicInstance(String... terms) { } List termList = Stream.of(terms).map(Terms::newSymbolicConstant).collect(Collectors.toList()); - instances.add(new BasicAtom(predicate, termList)); + instances.add(Atoms.newBasicAtom(predicate, termList)); return this; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Assignment.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Assignment.java index 59d61370d..ae21aaeee 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Assignment.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/Assignment.java @@ -27,8 +27,8 @@ */ package at.ac.tuwien.kr.alpha.core.common; -import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.isNegated; import java.util.Set; 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 6e8f2dcf8..e55c6fcfb 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 @@ -27,12 +27,12 @@ */ package at.ac.tuwien.kr.alpha.core.common; -import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.isNegated; import java.util.Iterator; -import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java index 9c7054ae3..2d836bdea 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/AtomStoreImpl.java @@ -35,7 +35,7 @@ import java.util.Map; import at.ac.tuwien.kr.alpha.api.Util; -import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.commons.util.IntIdGenerator; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.solver.AtomCounter; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java index 52ca5c093..75b2f2aa6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/BasicAnswerSet.java @@ -10,8 +10,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Util; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; /** * Copyright (c) 2016, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperatorImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperatorImpl.java index 5b739d0a5..a6060fff6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperatorImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/ComparisonOperatorImpl.java @@ -2,7 +2,7 @@ import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.Util; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; public enum ComparisonOperatorImpl implements ComparisonOperator { EQ("="), diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java index a1964b70b..cdaebbce7 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CoreAnswerSet.java @@ -2,8 +2,8 @@ import java.util.SortedSet; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; public interface CoreAnswerSet extends Comparable { SortedSet getPredicates(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java index 408eb0cc5..44cc25e77 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/CorePredicate.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.common; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.commons.util.Interner; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java index 9b780b1d6..f770e636e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/NoGood.java @@ -27,11 +27,11 @@ */ package at.ac.tuwien.kr.alpha.core.common; -import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.core.common.Literals.isNegated; -import static at.ac.tuwien.kr.alpha.core.common.Literals.isPositive; -import static at.ac.tuwien.kr.alpha.core.common.Literals.negateLiteral; -import static at.ac.tuwien.kr.alpha.core.common.Literals.positiveLiteral; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.isNegated; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.isPositive; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.negateLiteral; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.positiveLiteral; import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.INTERNAL; import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.LEARNT; import static at.ac.tuwien.kr.alpha.core.common.NoGoodInterface.Type.STATIC; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java index 1c9d50a27..f4395110e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/common/SimpleAnswerSetFormatter.java @@ -6,8 +6,8 @@ import java.util.stream.Collectors; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; public class SimpleAnswerSetFormatter implements AnswerSetFormatter { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java index b672f2a01..fe81dd2e8 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/DependencyGraph.java @@ -35,9 +35,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; import at.ac.tuwien.kr.alpha.core.common.CorePredicate; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java index f969e45a1..6d968742e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/depgraph/Node.java @@ -25,7 +25,7 @@ */ package at.ac.tuwien.kr.alpha.core.depgraph; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; /** * A node in a dependency graph. One node references exactly one predicate. This means that all rule heads deriving the diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java index a7cdb8379..26167299e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/externals/Externals.java @@ -39,10 +39,10 @@ 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.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; +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.atoms.BasicAtom; 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; @@ -148,8 +148,7 @@ public static > List asFacts(Class classOfExtFa String javaName = classOfExtFacts.getSimpleName(); String name = javaName.substring(0, 1).toLowerCase() + javaName.substring(1); // Camel-cased, but starting with lower case letter. for (T instance : extFacts) { - // TODO use properly wrapped BasicAtoms here - retVal.add(new BasicAtom(at.ac.tuwien.kr.alpha.core.common.CorePredicate.getInstance(name, 1), Terms.newConstant(instance))); + retVal.add(Atoms.newBasicAtom(at.ac.tuwien.kr.alpha.core.common.CorePredicate.getInstance(name, 1), Terms.newConstant(instance))); } return retVal; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java index 1280e5728..7c5cdd7cd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/AbstractGrounder.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.core.grounder; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; /** * Copyright (c) 2016, the Alpha Team. 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 8dcd72822..406ced3b0 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 @@ -3,7 +3,7 @@ import java.util.HashSet; import java.util.Set; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; 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; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java index 573d3da1b..19b012b41 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ChoiceRecorder.java @@ -39,7 +39,7 @@ import static at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom.off; import static at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom.on; -import static at.ac.tuwien.kr.alpha.core.common.Literals.*; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.*; import static java.util.Collections.emptyList; public class ChoiceRecorder { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java index 3909dc7c9..e9b4b7303 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/FactIntervalEvaluator.java @@ -5,7 +5,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.grounder.Instance; -import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; 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.IntervalTerm; 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 039a4265c..796c6207d 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 @@ -29,8 +29,8 @@ import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.grounder.bridges.Bridge; 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 f9748a0c5..6e8c1eaea 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 @@ -37,8 +37,8 @@ import java.util.Set; import at.ac.tuwien.kr.alpha.api.grounder.Instance; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +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; /** 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 4e0ae6320..1af4bdd47 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 @@ -28,7 +28,7 @@ package at.ac.tuwien.kr.alpha.core.grounder; import static at.ac.tuwien.kr.alpha.api.Util.oops; -import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; +import static at.ac.tuwien.kr.alpha.core.atoms.Literals.atomOf; import java.util.ArrayList; import java.util.Collection; @@ -54,13 +54,14 @@ import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.grounder.heuristics.GrounderHeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.substitutions.SubstitutionImpl; import at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom; import at.ac.tuwien.kr.alpha.core.atoms.RuleAtom; import at.ac.tuwien.kr.alpha.core.common.Assignment; @@ -278,7 +279,7 @@ public AnswerSet assignmentToAnswerSet(Iterable trueAtoms) { predicateInstances.putIfAbsent(factPredicate, new TreeSet<>()); for (Instance factInstance : facts.getValue()) { SortedSet instances = predicateInstances.get(factPredicate); - instances.add(new BasicAtom(factPredicate, factInstance.terms)); + instances.add(Atoms.newBasicAtom(factPredicate, factInstance.terms)); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java index a4ef6675a..3f2ee36ef 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NoGoodGenerator.java @@ -27,9 +27,9 @@ */ package at.ac.tuwien.kr.alpha.core.grounder; -import static at.ac.tuwien.kr.alpha.core.common.Literals.atomOf; -import static at.ac.tuwien.kr.alpha.core.common.Literals.atomToLiteral; -import static at.ac.tuwien.kr.alpha.core.common.Literals.negateLiteral; +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.negateLiteral; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -42,10 +42,10 @@ import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.CompiledProgram; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.CompiledProgram; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.atoms.FixedInterpretationLiteral; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java index a76ab3202..645c5d825 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/ProgramAnalyzingGrounder.java @@ -2,8 +2,8 @@ import java.util.Set; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.core.common.Assignment; diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java index 8198f0799..1d611c2e4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/RuleGroundingInfoImpl.java @@ -39,10 +39,9 @@ import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingInfo; import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; import at.ac.tuwien.kr.alpha.api.rules.CompiledRule; import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; -import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; /** * Provides the grounder with information on the order to ground the literals in the body of a rule. @@ -107,15 +106,23 @@ private boolean computeStartingLiterals() { if (literal.getNonBindingVariables().size() != 0) { continue; } - - if (literal.getAtom() instanceof BasicAtom && !literal.isNegated()) { - // Positive BasicAtom is the main/ordinary case. + if(literal.getBindingVariables().size() > 0) { + // Literals that can bind variables (i.e. positive basic literals) are the most common case ordinaryStartingLiterals.add(literal); } else { - // If literal is no positive BasicAtom but requires no bound variables, - // it can be the starting literal for some (fixed) instantiation. + // Literal does not need any variables bound (i.e. is ground or has a fixed interpretation), + // it is therefore an eligible starting literal for a fixed grounding order fixedStartingLiterals.add(literal); } + // TODO make sure above if is correct, then remove this +// if (literal.getAtom() instanceof BasicAtom && !literal.isNegated()) { +// // Positive BasicAtom is the main/ordinary case. +// ordinaryStartingLiterals.add(literal); +// } else { +// // If literal is no positive BasicAtom but requires no bound variables, +// // it can be the starting literal for some (fixed) instantiation. +// fixedStartingLiterals.add(literal); +// } } // If there are no positive BasicAtoms, the rule only contains fixed ground // instantiation literals and those are starting for the one-time grounding. @@ -130,6 +137,7 @@ private boolean computeStartingLiterals() { } } + @Override public List getStartingLiterals() { return Collections.unmodifiableList(startingLiterals); } @@ -138,6 +146,7 @@ public void updateLiteralSelectivity(Literal literal, int numGivenTuples, int nu // TODO: add old selectivity (with a decay factor) and new selectivity. } + @Override public RuleGroundingOrderImpl orderStartingFrom(Literal startingLiteral) { return groundingOrders.get(startingLiteral); } @@ -157,6 +166,7 @@ public boolean hasFixedInstantiation() { return fixedGroundingInstantiation; } + @Override public void computeGroundingOrders() { if (fixedGroundingInstantiation) { // Fixed grounding is only evaluated once and not depending on a starting variable, just use the first. 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 b0d1320b7..6824aa821 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,7 +29,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.grounder.RuleGroundingOrder; -import at.ac.tuwien.kr.alpha.api.program.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Literal; import at.ac.tuwien.kr.alpha.core.rules.InternalRule; /** @@ -67,6 +67,7 @@ private RuleGroundingOrderImpl(RuleGroundingOrderImpl otherRuleGroundingOrder) { * @param orderPosition zero-based index into list of literals except the starting literal * @return the literal at the given position, or {@code null} if it is already known that this literal is not able to yield new bindings */ + @Override public Literal getLiteralAtOrderPosition(int orderPosition) { if (orderPosition >= stopBindingAtOrderPosition) { return null; @@ -77,6 +78,7 @@ public Literal getLiteralAtOrderPosition(int orderPosition) { /** * @return the zero-based position from which on all variables are bound in list of literals except the starting literal */ + @Override public int getPositionFromWhichAllVarsAreBound() { return positionLastVarBound + 1; } @@ -113,6 +115,7 @@ public String toString() { * @return a new grounding order in which the atom is pushed back, * or {@code null} if the position of the grounding order after which no new bindings can be found has been reached. */ + @Override public RuleGroundingOrderImpl pushBack(int orderPosition) { if (orderPosition >= stopBindingAtOrderPosition - 1) { return null; @@ -122,10 +125,12 @@ public RuleGroundingOrderImpl pushBack(int orderPosition) { return reorderedGroundingOrder; } + @Override public void considerUntilCurrentEnd() { this.stopBindingAtOrderPosition = this.otherLiterals.size(); } + @Override public Literal getStartingLiteral() { return this.startingLiteral; } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java index bc0682996..a37a1d58b 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/Unification.java @@ -31,10 +31,11 @@ import java.util.Set; -import at.ac.tuwien.kr.alpha.api.program.Atom; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; 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.substitutions.Unifier; /** * Copyright (c) 2017, the Alpha Team. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java index 51d4a4e3e..2101714dc 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/WorkingMemory.java @@ -35,9 +35,9 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import at.ac.tuwien.kr.alpha.api.grounder.Instance; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.program.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; public class WorkingMemory { protected HashMap> workingMemory = new HashMap<>(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java index 2b19d2adf..529d204e6 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/AbstractLiteralInstantiationStrategy.java @@ -32,10 +32,10 @@ import at.ac.tuwien.kr.alpha.api.grounder.Instance; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.core.atoms.BasicAtom; -import at.ac.tuwien.kr.alpha.core.grounder.SubstitutionImpl; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.substitutions.SubstitutionImpl; /** * Abstract base implementation of {@link LiteralInstantiationStrategy} that outlines a basic workflow for @@ -114,7 +114,7 @@ protected final List> buildSubstit } // At this point, we know that the substitution works out. // Now check whether the resulting Atom has an acceptable AssignmentStatus. - atomForCurrentInstance = new BasicAtom(atomToSubstitute.getPredicate(), atomToSubstitute.getTerms()) + atomForCurrentInstance = Atoms.newBasicAtom(atomToSubstitute.getPredicate(), atomToSubstitute.getTerms()) .substitute(currentInstanceSubstitution); AssignmentStatus assignmentStatus = this.getAssignmentStatusForAtom(atomForCurrentInstance); if (!this.assignmentStatusAccepted(assignmentStatus)) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java index 13ed4511b..156489c77 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/instantiation/DefaultLazyGroundingInstantiationStrategy.java @@ -31,10 +31,9 @@ import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.Util; import at.ac.tuwien.kr.alpha.api.grounder.Instance; -import at.ac.tuwien.kr.alpha.api.program.Atom; -import at.ac.tuwien.kr.alpha.api.program.Literal; -import at.ac.tuwien.kr.alpha.api.program.Predicate; -import at.ac.tuwien.kr.alpha.core.atoms.CoreAtom; +import at.ac.tuwien.kr.alpha.api.programs.Literal; +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.core.common.Assignment; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage; @@ -46,7 +45,7 @@ * Implementation of {@link AbstractLiteralInstantiationStrategy} designed for use in {@link NaiveGrounder}. * * The instantiation strategy shares a {@link WorkingMemory}, an {@link AtomStore}, an {@link Assignment}, a {@link Map} of atoms that were - * facts of the currently grounded program, as well as a list of {@link CoreAtom}s that should be lazily deleted from the working memory, + * facts of the currently grounded program, as well as a list of {@link AbstractAtom}s that should be lazily deleted from the working memory, * with * the grounder. * @@ -56,11 +55,11 @@ * are added by the instantiation strategy. The {@link Assignment} reflects the {@link Solver}s "current view of the world". It is used by * {@link DefaultLazyGroundingInstantiationStrategy} to determine {@link AssignmentStatus}es for atoms. * - * A specialty of this implementation is that - since deletion of obsolete {@link CoreAtom}s from {@link NaiveGrounder}s + * A specialty of this implementation is that - since deletion of obsolete {@link AbstractAtom}s from {@link NaiveGrounder}s * {@link WorkingMemory} * happens lazily (i.e. at the end of each run of {@link NaiveGrounder#getNoGoods(Assignment)}) - it maintains a set of "stale" atoms that * is shared with the grounder. Specifically, whenever {@link DefaultLazyGroundingInstantiationStrategy#getAssignmentStatusForAtom(Atom)} - * determines that an {@link CoreAtom} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link CoreAtom} is + * determines that an {@link AbstractAtom} is {@link AssignmentStatus#UNASSIGNED} or {@link AssignmentStatus#FALSE}, that {@link AbstractAtom} is * added to * the stale atom set, which in turn is processed by the grounder, which then deletes the respective atoms from the working memory. * @@ -89,7 +88,7 @@ protected Iterable computeCandidateInstances(Atom partiallyGroundAtom) //@formatter:off /** - * Computes the {@link AssignmentStatus} for a given {@link CoreAtom} a. + * Computes the {@link AssignmentStatus} for a given {@link AbstractAtom} a. * * The atom a is {@link AssignmentStatus#TRUE} iff *