diff --git a/.gitattributes b/.gitattributes index 6d809091d..4adffdef2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,4 +16,4 @@ *.gpg filter=lfs diff=lfs merge=lfs binary *.bin filter=lfs diff=lfs merge=lfs binary -alpha-core/benchmarks/** linguist-vendored +alpha-solver/benchmarks/** linguist-vendored diff --git a/.gitignore b/.gitignore index 7f953ccdb..748e63db9 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,4 @@ gradle-app.setting /.dbeaver /Scripts /.vscode/ +*.code-workspace diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java index d1b37b00c..60dd0a236 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/Alpha.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.config.InputConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; @@ -27,7 +27,7 @@ public interface Alpha { * @return an {@link ASPCore2Program} representing the parsed ASP code from all sources referenced in the given {@link InputConfig} * @throws IOException in case one or more program sources (e.g. files) cannot be read, or parsing fails */ - ASPCore2Program readProgram(InputConfig cfg) throws IOException; + InputProgram readProgram(InputConfig cfg) throws IOException; /** * Reads and parses an {@link ASPCore2Program} from a list of {@link String}s representing paths. @@ -38,12 +38,12 @@ public interface Alpha { * @return an {@link ASPCore2Program} representing the parsed ASP code from all given path strings * @throws IOException in case one or more program sources cannot be read, or parsing fails */ - ASPCore2Program readProgramFiles(boolean literate, Map externals, List paths) throws IOException; + InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException; /** * see {@link Alpha#readProgramFiles(boolean, Map, List)} */ - ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; + InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException; /** * Parses a given String into an {@link ASPCore2Program}, using a map of custom {@link PredicateInterpretation}s to resolve external atoms @@ -53,19 +53,19 @@ public interface Alpha { * @param externals a map of custom {@link PredicateInterpretation}s against which external atoms in the given code are resolved * @return an {@link ASPCore2Program} representing the parsed ASP code */ - ASPCore2Program readProgramString(String aspString, Map externals); + InputProgram readProgramString(String aspString, Map externals); /** * Convenience method to parse ASP strings not containing any user-defined external atoms, see {@link Alpha#readProgramString(String, Map)}. */ - ASPCore2Program readProgramString(String aspString); + InputProgram readProgramString(String aspString); /** * Prepares a {@link DebugSolvingContext} for the given {@link ASPCore2Program} to debug program preprocessing. * * @return a {@link DebugSolvingContext} holding debug information for the given program */ - DebugSolvingContext prepareDebugSolve(final ASPCore2Program program); + DebugSolvingContext prepareDebugSolve(final InputProgram program); /** * Prepares a {@link DebugSolvingContext} for the given {@link NormalProgram} to debug program preprocessing. @@ -80,7 +80,7 @@ public interface Alpha { * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link DebugSolvingContext} holding debug information for the given program */ - DebugSolvingContext prepareDebugSolve(final ASPCore2Program program, java.util.function.Predicate filter); + DebugSolvingContext prepareDebugSolve(final InputProgram program, java.util.function.Predicate filter); /** * Prepares a {@link DebugSolvingContext} for the given {@link NormalProgram} to debug program preprocessing. @@ -95,7 +95,7 @@ public interface Alpha { * @param program an input program * @return a {@link Stream} of {@link AnswerSet}s of the given program */ - Stream solve(ASPCore2Program program); + Stream solve(InputProgram program); /** * Solves the given {@link ASPCore2Program}. @@ -103,7 +103,7 @@ public interface Alpha { * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Stream} of {@link AnswerSet}s of the given program */ - Stream solve(ASPCore2Program program, java.util.function.Predicate filter); + Stream solve(InputProgram program, java.util.function.Predicate filter); /** * Solves the given {@link NormalProgram}. @@ -126,7 +126,7 @@ public interface Alpha { * @param program An {@link ASPCore2Program} to normalize * @return a {@link NormalProgram} that is a semantic equivalent to the given input program */ - NormalProgram normalizeProgram(ASPCore2Program program); + NormalProgram normalizeProgram(InputProgram program); /** * Constructs a @{link Solver} pre-loaded with the given {@link ASPCore2Program} from which {@link AnswerSet}s can be obtained via {@link Solver#stream()}. @@ -135,7 +135,7 @@ public interface Alpha { * @param filter a {@link java.util.function.Predicate} against which {@link Predicate}s of answer sets are tested. * @return a {@link Solver} pre-loaded withthe given program */ - Solver prepareSolverFor(ASPCore2Program program, java.util.function.Predicate filter); + Solver prepareSolverFor(InputProgram program, java.util.function.Predicate filter); /** * Constructs a @{link Solver} pre-loaded with the given {@link NormalProgram} from which {@link AnswerSet}s can be obtained via {@link Solver#stream()}. diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java index b6cbfb168..7b8343b8e 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/ComparisonOperator.java @@ -1,11 +1,11 @@ package at.ac.tuwien.kr.alpha.api; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.terms.Term; /** - * A comparison operator that can be used in {@link ASPCore2Program}s. + * A comparison operator that can be used in {@link InputProgram}s. * * Copyright (c) 2021, the Alpha Team. */ diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java index 60966193a..2f9ab8fcf 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/DebugSolvingContext.java @@ -1,6 +1,6 @@ package at.ac.tuwien.kr.alpha.api; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; @@ -13,13 +13,13 @@ public interface DebugSolvingContext { /** - * The normalized version of the {@link ASPCore2Program} that is being solved. - * See {@link Alpha#normalizeProgram(ASPCore2Program)}. + * The normalized version of the {@link InputProgram} that is being solved. + * See {@link Alpha#normalizeProgram(InputProgram)}. */ NormalProgram getNormalizedProgram(); /** - * The fully preprocessed version of the {@link ASPCore2Program} that is being solved. + * The fully preprocessed version of the {@link InputProgram} that is being solved. * This differs from the value of {@link DebugSolvingContext#getNormalizedProgram()} in the stratified part of the normalized program may * already be evaluated depending on the respective configuration of {@link Alpha}. */ diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java index 27019ce10..e5c94fefd 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/config/SystemConfig.java @@ -44,13 +44,11 @@ public class SystemConfig { // initializing from those values in order to have the values accessible in // contexts where no AlphaConfig instance exists (e.g. argument parsing from // command line) - public static final String DEFAULT_GROUNDER_NAME = "naive"; public static final String DEFAULT_SOLVER_NAME = "default"; public static final String DEFAULT_NOGOOD_STORE_NAME = "alphaRoaming"; public static final Heuristic DEFAULT_BRANCHING_HEURISTIC = Heuristic.VSIDS; public static final BinaryNoGoodPropagationEstimationStrategy DEFAULT_MOMS_STRATEGY = BinaryNoGoodPropagationEstimationStrategy.CountBinaryWatches; public static final long DEFAULT_SEED = System.nanoTime(); - public static final boolean DEFAULT_DETERMINISTIC = false; public static final boolean DEFAULT_PRINT_STATS = false; public static final boolean DEFAULT_QUIET = false; public static final boolean DEFAULT_DISABLE_JUSTIFICATION_SEARCH = false; @@ -65,10 +63,8 @@ public class SystemConfig { public static final String DEFAULT_ATOM_SEPARATOR = ", "; public static final AggregateRewritingConfig DEFAULT_AGGREGATE_REWRITING_CONFIG = new AggregateRewritingConfig(); - private String grounderName = DEFAULT_GROUNDER_NAME; private String solverName = DEFAULT_SOLVER_NAME; private String nogoodStoreName = DEFAULT_NOGOOD_STORE_NAME; - private boolean deterministic = DEFAULT_DETERMINISTIC; private long seed = DEFAULT_SEED; private boolean debugInternalChecks = DEFAULT_DEBUG_INTERNAL_CHECKS; private Heuristic branchingHeuristic = DEFAULT_BRANCHING_HEURISTIC; @@ -86,17 +82,6 @@ public class SystemConfig { private String atomSeparator = DEFAULT_ATOM_SEPARATOR; private AggregateRewritingConfig aggregateRewritingConfig = DEFAULT_AGGREGATE_REWRITING_CONFIG; - public String getGrounderName() { - return this.grounderName; - } - - /** - * Sets the name of the grounder implementation to use. - */ - public void setGrounderName(String grounderName) { - this.grounderName = grounderName; - } - public String getSolverName() { return this.solverName; } @@ -119,18 +104,6 @@ public void setNogoodStoreName(String nogoodStoreName) { this.nogoodStoreName = nogoodStoreName; } - public boolean isDeterministic() { - return this.deterministic; - } - - /** - * If set, 0 will be used as random seed for solver-internal branching heuristics, resulting in answer sets of the same program being found - * in a fixed sequence. - */ - public void setDeterministic(boolean deterministic) { - this.deterministic = deterministic; - } - public long getSeed() { return this.seed; } diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java deleted file mode 100644 index 00d11f974..000000000 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ASPCore2Program.java +++ /dev/null @@ -1,13 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.programs; - -import at.ac.tuwien.kr.alpha.api.rules.Rule; -import at.ac.tuwien.kr.alpha.api.rules.heads.Head; - -/** - * A {@link Program} that conforms to Alphas implementation of the ASP-Core2-Standard. - * - * Copyright (c) 2021, the Alpha Team. - */ -public interface ASPCore2Program extends Program> { - -} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java new file mode 100644 index 000000000..c7be5bd2f --- /dev/null +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/InputProgram.java @@ -0,0 +1,9 @@ +package at.ac.tuwien.kr.alpha.api.programs; + +import at.ac.tuwien.kr.alpha.api.rules.Rule; +import at.ac.tuwien.kr.alpha.api.rules.heads.Head; + +// TODO javadoc +public interface InputProgram extends Program> { + +} diff --git a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java index 39f23cae8..d8195a9f6 100644 --- a/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java +++ b/alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/ProgramParser.java @@ -9,40 +9,40 @@ import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; /** - * A parser for {@link ASPCore2Program}s. + * A parser for {@link InputProgram}s. * * Copyright (c) 2021, the Alpha Team. */ public interface ProgramParser { - default ASPCore2Program parse(String programString) { + default InputProgram parse(String programString) { return parse(programString, Collections.emptyMap()); } - default ASPCore2Program parse(InputStream programSource) throws IOException { + default InputProgram parse(InputStream programSource) throws IOException { return parse(programSource, Collections.emptyMap()); } - default ASPCore2Program parse(Path programPath) throws IOException { + default InputProgram parse(Path programPath) throws IOException { return parse(programPath, Collections.emptyMap()); } - default ASPCore2Program parse(Path... programSources) throws IOException { + default InputProgram parse(Path... programSources) throws IOException { return parse(Collections.emptyMap(), programSources); } - default ASPCore2Program parse(Iterable programSources) throws IOException { + default InputProgram parse(Iterable programSources) throws IOException { return parse(programSources, Collections.emptyMap()); } - ASPCore2Program parse(String programString, Map externalPredicateDefinitions); + InputProgram parse(String programString, Map externalPredicateDefinitions); - ASPCore2Program parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException; + InputProgram parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException; - ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions) throws IOException; + InputProgram parse(Path programPath, Map externalPredicateDefinitions) throws IOException; - ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources) throws IOException; + InputProgram parse(Map externalPredicateDefinitions, Path... programSources) throws IOException; - ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException; + InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException; } diff --git a/alpha-cli-app/build.gradle.kts b/alpha-cli-app/build.gradle.kts index a62227309..c96c15b31 100644 --- a/alpha-cli-app/build.gradle.kts +++ b/alpha-cli-app/build.gradle.kts @@ -69,5 +69,6 @@ tasks.create("bundledJar") { } tasks.test { + dependsOn(":alpha-solver:test") useJUnitPlatform() } diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java index 487e25099..4fd32e07e 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/Main.java @@ -50,8 +50,8 @@ import at.ac.tuwien.kr.alpha.api.config.AlphaConfig; import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; @@ -80,9 +80,9 @@ public static void main(String[] args) { Main.exitWithMessage(commandLineParser.getUsageMessage(), 1); } - Alpha alpha = new AlphaImpl(cfg.getSystemConfig()); + Alpha alpha = AlphaFactory.newAlpha(cfg.getSystemConfig()); - ASPCore2Program program = null; + InputProgram program = null; try { program = alpha.readProgram(cfg.getInputConfig()); } catch (FileNotFoundException e) { diff --git a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java index 4b3ccf1f5..b8a27f880 100644 --- a/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java +++ b/alpha-cli-app/src/main/java/at/ac/tuwien/kr/alpha/app/config/CommandLineParser.java @@ -90,16 +90,12 @@ public class CommandLineParser { .desc("Write answer sets to excel files, i.e. xlsx workbooks (one workbook per answer set)").build(); // general system-wide config - private static final Option OPT_GROUNDER = Option.builder("g").longOpt("grounder").hasArg(true).argName("grounder") - .desc("the grounder implementation to use (default: " + SystemConfig.DEFAULT_GROUNDER_NAME + ")").build(); private static final Option OPT_SOLVER = Option.builder("s").longOpt("solver").hasArg(true).argName("solver") .desc("the solver implementation to use (default: " + SystemConfig.DEFAULT_SOLVER_NAME + ")").build(); private static final Option OPT_NOGOOD_STORE = Option.builder("r").longOpt("store").hasArg(true).argName("store") .desc("the nogood store to use (default: " + SystemConfig.DEFAULT_NOGOOD_STORE_NAME + ")").build(); private static final Option OPT_SORT = Option.builder("sort").longOpt("sort").hasArg(false) .desc("sort answer sets (default: " + SystemConfig.DEFAULT_SORT_ANSWER_SETS + ")").build(); - private static final Option OPT_DETERMINISTIC = Option.builder("d").longOpt("deterministic").hasArg(false) - .desc("disables randomness (default: " + SystemConfig.DEFAULT_DETERMINISTIC + ")").build(); private static final Option OPT_SEED = Option.builder("e").longOpt("seed").hasArg(true).argName("seed").type(Integer.class) .desc("set seed (default: System.nanoTime())").build(); private static final Option OPT_DEBUG_INTERNAL_CHECKS = Option.builder("dbgs").longOpt("DebugEnableInternalChecks") @@ -167,11 +163,9 @@ public class CommandLineParser { CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_DEBUG_PREPROCESSING); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_WRITE_XSLX); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_SOLVER); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_NOGOOD_STORE); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_SORT); - CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_DETERMINISTIC); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_SEED); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_DEBUG_INTERNAL_CHECKS); CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_BRANCHING_HEURISTIC); @@ -225,11 +219,9 @@ private void initializeGlobalOptionHandlers() { */ // help is handled separately, therefore dummy handler this.globalOptionHandlers.put(CommandLineParser.OPT_HELP.getOpt(), (o, c) -> { }); - this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER.getOpt(), this::handleGrounder); this.globalOptionHandlers.put(CommandLineParser.OPT_SOLVER.getOpt(), this::handleSolver); this.globalOptionHandlers.put(CommandLineParser.OPT_NOGOOD_STORE.getOpt(), this::handleNogoodStore); this.globalOptionHandlers.put(CommandLineParser.OPT_SORT.getOpt(), this::handleSort); - this.globalOptionHandlers.put(CommandLineParser.OPT_DETERMINISTIC.getOpt(), this::handleDeterministic); this.globalOptionHandlers.put(CommandLineParser.OPT_SEED.getOpt(), this::handleSeed); this.globalOptionHandlers.put(CommandLineParser.OPT_DEBUG_INTERNAL_CHECKS.getOpt(), this::handleInternalChecks); this.globalOptionHandlers.put(CommandLineParser.OPT_BRANCHING_HEURISTIC.getOpt(), this::handleBranchingHeuristic); @@ -335,10 +327,6 @@ private void handleInput(Option opt, InputConfig cfg) { cfg.getFiles().add(optVal); } - private void handleGrounder(Option opt, SystemConfig cfg) { - cfg.setGrounderName(opt.getValue(SystemConfig.DEFAULT_GROUNDER_NAME)); - } - private void handleSolver(Option opt, SystemConfig cfg) { cfg.setSolverName(opt.getValue(SystemConfig.DEFAULT_SOLVER_NAME)); } @@ -362,12 +350,10 @@ private void handleSort(Option opt, SystemConfig cfg) { } private void handleDeterministic(Option opt, SystemConfig cfg) { - cfg.setDeterministic(true); cfg.setSeed(0); } private void handleSeed(Option opt, SystemConfig cfg) { - cfg.setDeterministic(false); String optVal = opt.getValue(); long seed; if (optVal != null) { diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java index 97fec5bee..35ef774fc 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/MainTest.java @@ -49,10 +49,10 @@ public class MainTest { private static Stream provideCommandLineArguments() { return Stream.of( - Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-e", "1119654162577372", "-n", "20", "-str", INPUT}), - Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "0", "-str", INPUT}), - Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-g", "naive", "-s", "default", "-n", "1", "-str", INPUT}), - Arguments.of((Object) new String[]{"-g", "naive", "-s", "default", "-r", "naive", "-e", "1119654162577372", "--numAS", "1", "-str", INPUT})); + Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-s", "default", "-e", "1119654162577372", "-n", "20", "-str", INPUT}), + Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-s", "default", "-n", "0", "-str", INPUT}), + Arguments.of((Object) new String[]{"-DebugEnableInternalChecks", "-s", "default", "-n", "1", "-str", INPUT}), + Arguments.of((Object) new String[]{"-s", "default", "-r", "naive", "-e", "1119654162577372", "--numAS", "1", "-str", INPUT})); } /** diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java index 39273cf20..23655f106 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/ComponentGraphWriterTest.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph; // TODO This is a functional test and should not be run with standard unit tests @@ -54,7 +54,7 @@ public void smokeTest() { "n1 -> n5 [xlabel=\"-\" labeldistance=0.1]" + LS + "n2 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); ComponentGraph compgraph = dbgResult.getComponentGraph(); ComponentGraphWriter writer = new ComponentGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java index 942da90a5..8d5929e80 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/DependencyGraphWriterTest.java @@ -8,7 +8,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph; // TODO This is a functional test and should not be run with standard unit tests @@ -51,7 +51,7 @@ public void smokeTest() { "n6 -> n4 [xlabel=\"+\" labeldistance=0.1]" + LS + "n6 -> n5 [xlabel=\"+\" labeldistance=0.1]" + LS + "}" + LS; - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); DebugSolvingContext dbgResult = alpha.prepareDebugSolve(alpha.readProgramString(asp)); DependencyGraph depgraph = dbgResult.getDependencyGraph(); DependencyGraphWriter writer = new DependencyGraphWriter(); diff --git a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java index b528cd500..75a2d7cb6 100644 --- a/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java +++ b/alpha-cli-app/src/test/java/at/ac/tuwien/kr/alpha/app/mappers/AnswerSetToWorkbookMapperTest.java @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.impl.AlphaImpl; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -47,7 +47,7 @@ public void solveAndWriteWorkbookTest() { + "p(N) :- p(I), N = I + 1, N <= MX, maxP(MX)." + "q(A, B) :- p(A), p(B)."; //@formatter:on - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); List answerSets = alpha.solve(alpha.readProgramString(progstr)).collect(Collectors.toList()); assertEquals(1, answerSets.size()); AnswerSet as = answerSets.get(0); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java index 1228c74b5..ad6f80701 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/GrounderFactory.java @@ -35,22 +35,22 @@ import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; public final class GrounderFactory { - public static Grounder getInstance(String name, CompiledProgram program, AtomStore atomStore, java.util.function.Predicate filter, - GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks, Bridge... bridges) { - switch (name.toLowerCase()) { - case "naive": - return new NaiveGrounder(program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, bridges); - } - throw new IllegalArgumentException("Unknown grounder requested."); + + private final GrounderHeuristicsConfiguration heuristicsConfig; + private final boolean enableDebugChecks; + + public GrounderFactory(GrounderHeuristicsConfiguration heuristicsConfig, boolean enabledDebugChecks) { + this.heuristicsConfig = heuristicsConfig; + this.enableDebugChecks = enabledDebugChecks; } - - public static Grounder getInstance(String name, CompiledProgram program, AtomStore atomStore, java.util.function.Predicate filter, - GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, filter, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); + + public Grounder createGrounder(CompiledProgram program, AtomStore atomStore) { + return createGrounder(program, atomStore, InputConfig.DEFAULT_FILTER); } - public static Grounder getInstance(String name, CompiledProgram program, AtomStore atomStore, boolean debugInternalChecks) { - return getInstance(name, program, atomStore, InputConfig.DEFAULT_FILTER, - new GrounderHeuristicsConfiguration(), debugInternalChecks); + // TODO eliminate this method, filter should never go this deep into core, can be applied on answer sets from top-level + public Grounder createGrounder(CompiledProgram program, AtomStore atomStore, java.util.function.Predicate filter) { + return new NaiveGrounder(program, atomStore, filter, heuristicsConfig, enableDebugChecks, new Bridge[] {}); } + } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java index 1e498d50d..4d695d6af 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/grounder/NaiveGrounder.java @@ -108,6 +108,10 @@ public class NaiveGrounder extends BridgedGrounder implements ProgramAnalyzingGr private final LiteralInstantiator ruleInstantiator; private final DefaultLazyGroundingInstantiationStrategy instantiationStrategy; + public NaiveGrounder(CompiledProgram program, AtomStore atomStore, GrounderHeuristicsConfiguration heuristicsConfiguration, boolean debugInternalChecks) { + this(program, atomStore, p -> true, heuristicsConfiguration, debugInternalChecks, new Bridge[] {}); + } + public NaiveGrounder(CompiledProgram program, AtomStore atomStore, boolean debugInternalChecks, Bridge... bridges) { this(program, atomStore, new GrounderHeuristicsConfiguration(), debugInternalChecks, bridges); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java index 1498a4f0c..3042a1183 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java @@ -46,6 +46,7 @@ import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -74,7 +75,7 @@ import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2BaseVisitor; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -84,7 +85,7 @@ public class ParseTreeVisitor extends ASPCore2BaseVisitor { private final Map externals; private final boolean acceptVariables; - private InputProgram.Builder programBuilder; + private InputProgramImpl.Builder programBuilder; private InlineDirectives inlineDirectives; public ParseTreeVisitor(Map externals) { @@ -160,10 +161,10 @@ public InputProgram visitProgram(ASPCore2Parser.ProgramContext ctx) { } if (ctx.statements() == null) { - return InputProgram.EMPTY; + return InputProgramImpl.EMPTY; } inlineDirectives = new InlineDirectivesImpl(); - programBuilder = InputProgram.builder(); + programBuilder = InputProgramImpl.builder(); visitStatements(ctx.statements()); programBuilder.addInlineDirectives(inlineDirectives); return programBuilder.build(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java index a0a71d8a5..e67cfaa4a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ProgramParserImpl.java @@ -17,12 +17,12 @@ import org.antlr.v4.runtime.misc.ParseCancellationException; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.externals.Externals; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; public class ProgramParserImpl implements ProgramParser { @@ -38,12 +38,12 @@ public ProgramParserImpl(Map externals) { } @Override - public ASPCore2Program parse(String s) { + public InputProgram parse(String s) { return parse(s, Collections.emptyMap()); } @Override - public ASPCore2Program parse(String s, Map externals) { + public InputProgram parse(String s, Map externals) { try { return parse(CharStreams.fromString(s), externals); } catch (RecognitionException | ParseCancellationException e) { @@ -54,11 +54,11 @@ public ASPCore2Program parse(String s, Map exte } } - public ASPCore2Program parse(CharStream stream) { + public InputProgram parse(CharStream stream) { return parse(stream, Collections.emptyMap()); } - public ASPCore2Program parse(CharStream stream, Map externals) { + public InputProgram parse(CharStream stream, Map externals) { //@formatter:off /* * // In order to require less memory: use unbuffered streams and avoid constructing a full parse tree. @@ -131,18 +131,18 @@ public ASPCore2Program parse(CharStream stream, Map externalPredicateDefinitions) throws IOException { + public InputProgram parse(InputStream programSource, Map externalPredicateDefinitions) throws IOException { return parse(CharStreams.fromStream(programSource), externalPredicateDefinitions); } @Override - public ASPCore2Program parse(Path programPath, Map externalPredicateDefinitions) throws IOException { + public InputProgram parse(Path programPath, Map externalPredicateDefinitions) throws IOException { return parse(CharStreams.fromPath(programPath), externalPredicateDefinitions); } @Override - public ASPCore2Program parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { - InputProgram.Builder bld = InputProgram.builder(); + public InputProgram parse(Map externalPredicateDefinitions, Path... programSources) throws IOException { + InputProgramImpl.Builder bld = InputProgramImpl.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); } @@ -150,8 +150,8 @@ public ASPCore2Program parse(Map externalPredic } @Override - public ASPCore2Program parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { - InputProgram.Builder bld = InputProgram.builder(); + public InputProgram parse(Iterable programSources, Map externalPredicateDefinitions) throws IOException { + InputProgramImpl.Builder bld = InputProgramImpl.builder(); for (Path src : programSources) { bld.accumulate(parse(src, externalPredicateDefinitions)); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java similarity index 82% rename from alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java rename to alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java index e9ba20032..3ab39a124 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgram.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/InputProgramImpl.java @@ -31,7 +31,7 @@ import java.util.Collections; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.rules.Rule; @@ -43,15 +43,15 @@ *

* Copyright (c) 2017-2019, the Alpha Team. */ -public class InputProgram extends AbstractProgram> implements ASPCore2Program{ +public class InputProgramImpl extends AbstractProgram> implements InputProgram { - public static final InputProgram EMPTY = new InputProgram(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl()); + public static final InputProgramImpl EMPTY = new InputProgramImpl(Collections.emptyList(), Collections.emptyList(), new InlineDirectivesImpl()); - public InputProgram(List> rules, List facts, InlineDirectives inlineDirectives) { + public InputProgramImpl(List> rules, List facts, InlineDirectives inlineDirectives) { super(rules, facts, inlineDirectives); } - public InputProgram() { + public InputProgramImpl() { super(new ArrayList<>(), new ArrayList<>(), new InlineDirectivesImpl()); } @@ -59,12 +59,12 @@ public static Builder builder() { return new Builder(); } - public static Builder builder(ASPCore2Program prog) { + public static Builder builder(InputProgram prog) { return new Builder(prog); } /** - * Builder for more complex program construction scenarios, ensuring that an {@link InputProgram} is immutable + * Builder for more complex program construction scenarios, ensuring that an {@link InputProgramImpl} is immutable */ public static class Builder { @@ -72,7 +72,7 @@ public static class Builder { private List facts = new ArrayList<>(); private InlineDirectives inlineDirectives = new InlineDirectivesImpl(); - public Builder(ASPCore2Program prog) { + public Builder(InputProgram prog) { this.addRules(prog.getRules()); this.addFacts(prog.getFacts()); this.addInlineDirectives(prog.getInlineDirectives()); @@ -107,12 +107,12 @@ public Builder addInlineDirectives(InlineDirectives inlineDirectives) { return this; } - public Builder accumulate(ASPCore2Program prog) { + public Builder accumulate(InputProgram prog) { return this.addRules(prog.getRules()).addFacts(prog.getFacts()).addInlineDirectives(prog.getInlineDirectives()); } public InputProgram build() { - return new InputProgram(this.rules, this.facts, this.inlineDirectives); + return new InputProgramImpl(this.rules, this.facts, this.inlineDirectives); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java index dc886e47a..ad65431e0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/NormalProgramImpl.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -23,7 +23,7 @@ public NormalProgramImpl(List rules, List facts, InlineDirecti super(rules, facts, inlineDirectives); } - public static NormalProgramImpl fromInputProgram(ASPCore2Program inputProgram) { + public static NormalProgramImpl fromInputProgram(InputProgram inputProgram) { List normalRules = new ArrayList<>(); for (Rule r : inputProgram.getRules()) { normalRules.add(NormalRuleImpl.fromBasicRule(r)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java index e467c657f..e3f184886 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/Programs.java @@ -7,7 +7,7 @@ import org.antlr.v4.runtime.CharStreams; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; public class Programs { @@ -16,7 +16,7 @@ private Programs() { throw new AssertionError("This is a pure utility class and should therefore not be instantiated!"); } - public static ASPCore2Program fromInputStream(InputStream is, Map externals) throws IOException { + public static InputProgram fromInputStream(InputStream is, Map externals) throws IOException { ProgramParserImpl parser = new ProgramParserImpl(); return parser.parse(CharStreams.fromStream(is), externals); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java index f54778b8c..6c20981d0 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ChoiceHeadToNormal.java @@ -31,7 +31,7 @@ import java.util.Iterator; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -46,19 +46,19 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** * Copyright (c) 2017-2021, the Alpha Team. */ // TODO this could already give NormalProgram as result type -public class ChoiceHeadToNormal extends ProgramTransformation { +public class ChoiceHeadToNormal extends ProgramTransformation { private final static String PREDICATE_NEGATION_PREFIX = "_n"; @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { - InputProgram.Builder programBuilder = InputProgram.builder(); + public InputProgram apply(InputProgram inputProgram) { + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); List> additionalRules = new ArrayList<>(); List> srcRules = new ArrayList<>(inputProgram.getRules()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java index ca1c6a54a..f9498270e 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/EnumerationRewriting.java @@ -7,7 +7,7 @@ import java.util.LinkedList; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral; @@ -20,7 +20,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -30,10 +30,10 @@ * Copyright (c) 2017-2020, the Alpha Team. */ // TODO this should happen during/after internalization -public class EnumerationRewriting extends ProgramTransformation { +public class EnumerationRewriting extends ProgramTransformation { @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { + public InputProgram apply(InputProgram inputProgram) { // Read enumeration predicate from directive. String enumDirective = inputProgram.getInlineDirectives().getDirectiveValue(InlineDirectivesImpl.DIRECTIVE.enum_predicate_is); if (enumDirective == null) { @@ -42,7 +42,7 @@ public ASPCore2Program apply(ASPCore2Program inputProgram) { } Predicate enumPredicate = Predicates.getPredicate(enumDirective, 3); - InputProgram.Builder programBuilder = InputProgram.builder().addInlineDirectives(inputProgram.getInlineDirectives()); + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder().addInlineDirectives(inputProgram.getInlineDirectives()); checkFactsAreEnumerationFree(inputProgram.getFacts(), enumPredicate); programBuilder.addFacts(inputProgram.getFacts()); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java index a2f503ec2..341c46eb1 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/NormalizeProgramTransformation.java @@ -1,7 +1,8 @@ package at.ac.tuwien.kr.alpha.core.programs.transformation; -import at.ac.tuwien.kr.alpha.api.config.AggregateRewritingConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import java.util.function.Supplier; + +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.core.atoms.EnumerationAtom; import at.ac.tuwien.kr.alpha.core.programs.NormalProgramImpl; @@ -12,23 +13,23 @@ * * Copyright (c) 2019-2021, the Alpha Team. */ -public class NormalizeProgramTransformation extends ProgramTransformation { +public class NormalizeProgramTransformation extends ProgramTransformation { - private final AggregateRewritingConfig aggregateRewritingCfg; + private final Supplier aggregateRewritingFactory; - public NormalizeProgramTransformation(AggregateRewritingConfig aggregateCfg) { - this.aggregateRewritingCfg = aggregateCfg; + public NormalizeProgramTransformation(Supplier aggregateRewritingFactory) { + this.aggregateRewritingFactory = aggregateRewritingFactory; } @Override - public NormalProgram apply(ASPCore2Program inputProgram) { - ASPCore2Program tmpPrg; + public NormalProgram apply(InputProgram inputProgram) { + InputProgram tmpPrg; // Remove variable equalities. tmpPrg = new VariableEqualityRemoval().apply(inputProgram); // Transform choice rules. tmpPrg = new ChoiceHeadToNormal().apply(tmpPrg); // Transform aggregates. - tmpPrg = new AggregateRewriting(aggregateRewritingCfg.isUseSortingGridEncoding(), aggregateRewritingCfg.isSupportNegativeValuesInSums()).apply(tmpPrg); + tmpPrg = aggregateRewritingFactory.get().apply(tmpPrg); // Transform enumeration atoms. tmpPrg = new EnumerationRewriting().apply(tmpPrg); EnumerationAtom.resetEnumerations(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java index 6a71a1092..9deb24b06 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/PredicateInternalizer.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -15,7 +15,7 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -26,8 +26,8 @@ */ public class PredicateInternalizer { - public static ASPCore2Program makePrefixedPredicatesInternal(ASPCore2Program program, String prefix) { - InputProgram.Builder prgBuilder = InputProgram.builder(); + public static InputProgram makePrefixedPredicatesInternal(InputProgram program, String prefix) { + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); for (Atom atom : program.getFacts()) { if (atom.getPredicate().getName().startsWith(prefix)) { prgBuilder.addFact(PredicateInternalizer.makePredicateInternal((BasicAtom) atom)); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java index 9dfc543e2..2c3105134 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluation.java @@ -52,7 +52,7 @@ public class StratifiedEvaluation extends ProgramTransformation> modifiedInLastEvaluationRun = new HashMap<>(); - private List additionalFacts = new ArrayList<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. + private Set outputFacts = new HashSet<>(); // The additional facts derived by stratified evaluation. Note that it may contain duplicates. private Set solvedRuleIds = new HashSet<>(); // Set of rules that have been completely evaluated. private LiteralInstantiator literalInstantiator; @@ -82,6 +82,9 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { workingMemory.reset(); + // Set up set of facts to which we'll add everything derived during stratified evaluation. + outputFacts = new HashSet<>(inputProgram.getFacts()); + // Set up literal instantiator. literalInstantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory)); @@ -91,13 +94,12 @@ public InternalProgram apply(AnalyzedProgram inputProgram) { } // Build the program resulting from evaluating the stratified part. - additionalFacts.addAll(inputProgram.getFacts()); // Add original input facts to newly derived ones. List outputRules = new ArrayList<>(); inputProgram.getRulesById().entrySet().stream().filter((entry) -> !solvedRuleIds.contains(entry.getKey())) .forEach((entry) -> outputRules.add(entry.getValue())); // NOTE: if InternalProgram requires solved rules, they should be added here. - return new InternalProgram(outputRules, additionalFacts); + return new InternalProgram(outputRules, new ArrayList<>(outputFacts)); } private void evaluateComponent(ComponentGraph.SCComponent comp) { @@ -114,9 +116,7 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { evaluateRules(evaluationInfo.nonRecursiveRules, true); for (IndexedInstanceStorage instanceStorage : workingMemory.modified()) { // Directly record all newly derived instances as additional facts. - for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { - additionalFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } + recordRecentlyAddedInstances(instanceStorage); instanceStorage.markRecentlyAddedInstancesDone(); } } @@ -134,9 +134,7 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { // Since we are stratified we never have to backtrack, therefore just collect the added instances. for (IndexedInstanceStorage instanceStorage : workingMemory.modified()) { // Directly record all newly derived instances as additional facts. - for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { - additionalFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); - } + recordRecentlyAddedInstances(instanceStorage); modifiedInLastEvaluationRun.putIfAbsent(instanceStorage.getPredicate(), new LinkedHashSet<>()); modifiedInLastEvaluationRun.get(instanceStorage.getPredicate()).addAll(instanceStorage.getRecentlyAddedInstances()); instanceStorage.markRecentlyAddedInstancesDone(); @@ -149,6 +147,12 @@ private void evaluateComponent(ComponentGraph.SCComponent comp) { .forEach((rule) -> solvedRuleIds.add(rule.getRuleId())); } + private void recordRecentlyAddedInstances(IndexedInstanceStorage instanceStorage) { + for (Instance recentlyAddedInstance : instanceStorage.getRecentlyAddedInstances()) { + outputFacts.add(Atoms.newBasicAtom(instanceStorage.getPredicate(), recentlyAddedInstance.terms)); + } + } + private void evaluateRules(Set rules, boolean isInitialRun) { workingMemory.reset(); LOGGER.debug("Starting component evaluation run..."); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java index 1e1ae53a3..11f361cd4 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/VariableEqualityRemoval.java @@ -37,7 +37,7 @@ import java.util.List; import java.util.Map; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -49,7 +49,7 @@ import at.ac.tuwien.kr.alpha.api.terms.VariableTerm; import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.substitutions.Unifier; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** @@ -57,15 +57,15 @@ * * Copyright (c) 2017-2021, the Alpha Team. */ -public class VariableEqualityRemoval extends ProgramTransformation { +public class VariableEqualityRemoval extends ProgramTransformation { @Override - public ASPCore2Program apply(ASPCore2Program inputProgram) { + public InputProgram apply(InputProgram inputProgram) { List> rewrittenRules = new ArrayList<>(); for (Rule rule : inputProgram.getRules()) { rewrittenRules.add(findAndReplaceVariableEquality(rule)); } - return new InputProgram(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); + return new InputProgramImpl(rewrittenRules, inputProgram.getFacts(), inputProgram.getInlineDirectives()); } private Rule findAndReplaceVariableEquality(Rule rule) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java index 10625da60..66d93a737 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateOperatorNormalization.java @@ -5,6 +5,7 @@ import java.util.List; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom; @@ -19,7 +20,6 @@ import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; /** diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java index a810ee3db..da9352b3a 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewriting.java @@ -8,7 +8,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -16,7 +16,7 @@ import at.ac.tuwien.kr.alpha.api.rules.heads.Head; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.literals.Literals; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AbstractAggregateEncoder; @@ -30,7 +30,7 @@ * * Copyright (c) 2020, the Alpha Team. */ -public class AggregateRewriting extends ProgramTransformation { +public class AggregateRewriting extends ProgramTransformation { private final AbstractAggregateEncoder countEqualsEncoder; private final AbstractAggregateEncoder countLessOrEqualEncoder; @@ -49,13 +49,14 @@ public class AggregateRewriting extends ProgramTransformation> outputRules = new ArrayList<>(); for (Rule inputRule : inputProgram.getRules()) { @@ -88,7 +89,7 @@ public ASPCore2Program apply(ASPCore2Program inputProgram) { } // Substitute AggregateLiterals with generated result literals. outputRules.addAll(rewriteRulesWithAggregates(ctx)); - InputProgram.Builder resultBuilder = InputProgram.builder().addRules(outputRules).addFacts(inputProgram.getFacts()) + InputProgramImpl.Builder resultBuilder = InputProgramImpl.builder().addRules(outputRules).addFacts(inputProgram.getFacts()) .addInlineDirectives(inputProgram.getInlineDirectives()); // Add sub-programs deriving respective aggregate literals. for (Map.Entry, Set> aggToRewrite : ctx.getAggregateFunctionsToRewrite() diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java index 1e257d30a..e609c3984 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AbstractAggregateEncoder.java @@ -7,7 +7,7 @@ import org.apache.commons.collections4.ListUtils; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; @@ -22,7 +22,7 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.PredicateInternalizer; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -51,8 +51,8 @@ protected AbstractAggregateEncoder(AggregateFunctionSymbol aggregateFunctionToEn * @param aggregatesToEncode the aggregates to encode. * @return all rules encoding the given aggregates as an {@link InputProgram}. */ - public ASPCore2Program encodeAggregateLiterals(Set aggregatesToEncode) { - InputProgram.Builder programBuilder = InputProgram.builder(); + public InputProgram encodeAggregateLiterals(Set aggregatesToEncode) { + InputProgramImpl.Builder programBuilder = InputProgramImpl.builder(); for (AggregateInfo aggregateInfo : aggregatesToEncode) { programBuilder.accumulate(encodeAggregateLiteral(aggregateInfo)); } @@ -65,7 +65,7 @@ public ASPCore2Program encodeAggregateLiterals(Set aggregatesToEn * @param aggregateToEncode * @return */ - public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { + public InputProgram encodeAggregateLiteral(AggregateInfo aggregateToEncode) { AggregateLiteral literalToEncode = aggregateToEncode.getLiteral(); if (literalToEncode.getAtom().getAggregateFunction() != this.aggregateFunctionToEncode) { throw new IllegalArgumentException( @@ -76,13 +76,13 @@ public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { + literalToEncode.getAtom().getAggregateFunction() + " with operator " + literalToEncode.getAtom().getLowerBoundOperator()); } String aggregateId = aggregateToEncode.getId(); - ASPCore2Program literalEncoding = PredicateInternalizer.makePrefixedPredicatesInternal(encodeAggregateResult(aggregateToEncode), aggregateId); + InputProgram literalEncoding = PredicateInternalizer.makePrefixedPredicatesInternal(encodeAggregateResult(aggregateToEncode), aggregateId); List> elementEncodingRules = new ArrayList<>(); for (AggregateElement elementToEncode : literalToEncode.getAtom().getAggregateElements()) { Rule elementRule = encodeAggregateElement(aggregateToEncode, elementToEncode); elementEncodingRules.add(PredicateInternalizer.makePrefixedPredicatesInternal(elementRule, aggregateId)); } - return new InputProgram(ListUtils.union(literalEncoding.getRules(), elementEncodingRules), literalEncoding.getFacts(), new InlineDirectivesImpl()); + return new InputProgramImpl(ListUtils.union(literalEncoding.getRules(), elementEncodingRules), literalEncoding.getFacts(), new InlineDirectivesImpl()); } /** @@ -93,7 +93,7 @@ public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) { * @param aggregateToEncode * @return */ - protected abstract ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode); + protected abstract InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode); /** * Encodes individual aggregate elements. For each aggregate element, a rule is created that fires for each tuple matching the element. diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java new file mode 100644 index 000000000..cb3d1152a --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/AggregateEncoderFactory.java @@ -0,0 +1,44 @@ +package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders; + +import java.util.function.Supplier; + +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; + +public class AggregateEncoderFactory { + + private final Supplier parserFactory; + private final boolean useSortingGridEncoding; + private final boolean supportNegativeSumElements; + + public AggregateEncoderFactory(Supplier parserFactory, boolean useSortingGridEncoding, boolean supportNegativeSumElements) { + this.parserFactory = parserFactory; + this.useSortingGridEncoding = useSortingGridEncoding; + this.supportNegativeSumElements = supportNegativeSumElements; + } + + public CountEncoder newCountEqualsEncoder() { + return CountEncoder.buildCountEqualsEncoder(parserFactory.get()); + } + + public CountEncoder newCountLessOrEqualEncoder() { + return CountEncoder.buildCountLessOrEqualEncoder(parserFactory.get(), useSortingGridEncoding); + } + + public SumEncoder newSumEqualsEncoder() { + return SumEncoder.buildSumEqualsEncoder(parserFactory.get(), supportNegativeSumElements); + } + + public SumEncoder newSumLessOrEqualEncoder() { + return SumEncoder.buildSumLessOrEqualEncoder(parserFactory.get(), supportNegativeSumElements); + } + + public MinMaxEncoder newMinEncoder() { + return new MinMaxEncoder(AggregateFunctionSymbol.MIN); + } + + public MinMaxEncoder newMaxEncoder() { + return new MinMaxEncoder(AggregateFunctionSymbol.MAX); + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java index 0789c0330..be64efabd 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/CountEncoder.java @@ -4,6 +4,7 @@ import org.stringtemplate.v4.STGroup; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators; import at.ac.tuwien.kr.alpha.commons.util.Util; @@ -16,17 +17,17 @@ public final class CountEncoder extends StringtemplateBasedAggregateEncoder { private static final ST CNT_LE_SORTING_GRID_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_le_sorting_grid"); private static final ST CNT_EQ_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_eq"); private static final ST CNT_LE_COUNTING_GRID_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("cnt_le_counting_grid"); - - private CountEncoder(ComparisonOperator acceptedOperator, ST encodingTemplate) { - super(AggregateFunctionSymbol.COUNT, acceptedOperator, encodingTemplate); + + private CountEncoder(ProgramParser parser, ComparisonOperator acceptedOperator, ST encodingTemplate) { + super(parser, AggregateFunctionSymbol.COUNT, acceptedOperator, encodingTemplate); } - public static CountEncoder buildCountLessOrEqualEncoder(boolean useSortingGrid) { - return new CountEncoder(ComparisonOperators.LE, useSortingGrid ? CNT_LE_SORTING_GRID_TEMPLATE : CNT_LE_COUNTING_GRID_TEMPLATE); + static CountEncoder buildCountLessOrEqualEncoder(ProgramParser parser, boolean useSortingGrid) { + return new CountEncoder(parser, ComparisonOperators.LE, useSortingGrid ? CNT_LE_SORTING_GRID_TEMPLATE : CNT_LE_COUNTING_GRID_TEMPLATE); } - public static CountEncoder buildCountEqualsEncoder() { - return new CountEncoder(ComparisonOperators.EQ, CNT_EQ_TEMPLATE); + static CountEncoder buildCountEqualsEncoder(ProgramParser parser) { + return new CountEncoder(parser, ComparisonOperators.EQ, CNT_EQ_TEMPLATE); } } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java index 8e007f78b..316d1ad5c 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/MinMaxEncoder.java @@ -7,7 +7,7 @@ import org.stringtemplate.v4.ST; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; @@ -27,7 +27,7 @@ import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.commons.util.Util; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -69,7 +69,7 @@ public MinMaxEncoder(AggregateFunctionSymbol func) { } @Override - protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) { + protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { ST encodingTemplate = null; if (this.getAggregateFunctionToEncode() == AggregateFunctionSymbol.MAX) { encodingTemplate = new ST(MAX_LITERAL_ENCODING); @@ -118,7 +118,7 @@ protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) resultRuleBody.add(aggregateResult); resultRuleBody.add(aggregateValueComparison); resultRuleBody.addAll(aggregateToEncode.getDependencies()); - InputProgram.Builder bld = InputProgram.builder(parser.parse(encodingTemplate.render())); + InputProgramImpl.Builder bld = InputProgramImpl.builder(parser.parse(encodingTemplate.render())); BasicRule resultRule = new BasicRule(resultRuleHead, resultRuleBody); bld.addRule(resultRule); return bld.build(); diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java index ad8a9c932..c025a6d55 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/StringtemplateBasedAggregateEncoder.java @@ -7,7 +7,7 @@ import org.stringtemplate.v4.ST; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -19,8 +19,7 @@ import at.ac.tuwien.kr.alpha.commons.rules.heads.Heads; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.transformation.EnumerationRewriting; import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; @@ -37,13 +36,14 @@ */ public abstract class StringtemplateBasedAggregateEncoder extends AbstractAggregateEncoder { - private final ProgramParser parser = new ProgramParserImpl(); + private final ProgramParser parser; private final ST encodingTemplate; private final boolean needsBoundRule; - protected StringtemplateBasedAggregateEncoder(AggregateFunctionSymbol aggregateFunctionToEncode, ComparisonOperator acceptedOperator, ST encodingTemplate) { + protected StringtemplateBasedAggregateEncoder(ProgramParser parser, AggregateFunctionSymbol aggregateFunctionToEncode, ComparisonOperator acceptedOperator, ST encodingTemplate) { super(aggregateFunctionToEncode, Collections.singleton(acceptedOperator)); this.encodingTemplate = encodingTemplate; + this.parser = parser; if (acceptedOperator.equals(ComparisonOperators.EQ)) { this.needsBoundRule = false; } else if (acceptedOperator.equals(ComparisonOperators.LE)) { @@ -54,7 +54,7 @@ protected StringtemplateBasedAggregateEncoder(AggregateFunctionSymbol aggregateF } @Override - protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) { + protected InputProgram encodeAggregateResult(AggregateInfo aggregateToEncode) { String aggregateId = aggregateToEncode.getId(); /* @@ -82,10 +82,10 @@ protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) String coreEncodingAsp = coreEncodingTemplate.render(); // Create the basic program - ASPCore2Program coreEncoding = new EnumerationRewriting().apply(parser.parse(coreEncodingAsp)); + InputProgram coreEncoding = new EnumerationRewriting().apply(parser.parse(coreEncodingAsp)); // Add the programatically created bound rule and return - return new InputProgram(ListUtils.union(coreEncoding.getRules(), Collections.singletonList(boundRule)), coreEncoding.getFacts(), + return new InputProgramImpl(ListUtils.union(coreEncoding.getRules(), Collections.singletonList(boundRule)), coreEncoding.getFacts(), new InlineDirectivesImpl()); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java index 0a12b8752..95d9737a3 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/encoders/SumEncoder.java @@ -5,6 +5,7 @@ import at.ac.tuwien.kr.alpha.api.ComparisonOperator; import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -32,16 +33,16 @@ public final class SumEncoder extends StringtemplateBasedAggregateEncoder { private static final ST NON_NEG_ELEMENTS_SUM_LE_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("sum_le_no_negative_elements"); private static final ST NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE = AGGREGATE_ENCODINGS.getInstanceOf("sum_eq_no_negative_elements"); - private SumEncoder(ComparisonOperator acceptedOperator, ST encodingTemplate) { - super(AggregateFunctionSymbol.SUM, acceptedOperator, encodingTemplate); + private SumEncoder(ProgramParser parser, ComparisonOperator acceptedOperator, ST encodingTemplate) { + super(parser, AggregateFunctionSymbol.SUM, acceptedOperator, encodingTemplate); } - public static SumEncoder buildSumLessOrEqualEncoder(boolean supportNegativeIntegers) { - return new SumEncoder(ComparisonOperators.LE, supportNegativeIntegers ? SUM_LE_TEMPLATE : NON_NEG_ELEMENTS_SUM_LE_TEMPLATE); + public static SumEncoder buildSumLessOrEqualEncoder(ProgramParser parser, boolean supportNegativeIntegers) { + return new SumEncoder(parser, ComparisonOperators.LE, supportNegativeIntegers ? SUM_LE_TEMPLATE : NON_NEG_ELEMENTS_SUM_LE_TEMPLATE); } - public static SumEncoder buildSumEqualsEncoder(boolean supportNegativeIntegers) { - return new SumEncoder(ComparisonOperators.EQ, supportNegativeIntegers ? SUM_EQ_TEMPLATE : NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE); + public static SumEncoder buildSumEqualsEncoder(ProgramParser parser, boolean supportNegativeIntegers) { + return new SumEncoder(parser, ComparisonOperators.EQ, supportNegativeIntegers ? SUM_EQ_TEMPLATE : NON_NEG_ELEMENTS_SUM_EQ_TEMPLATE); } /** @@ -56,4 +57,4 @@ protected BasicAtom buildElementRuleHead(String aggregateId, AggregateElement el return Atoms.newBasicAtom(headPredicate, aggregateArguments, elementTuple, element.getElementTerms().get(0)); } -} \ No newline at end of file +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java index 50d78db70..dad66bc2d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/AbstractRule.java @@ -1,5 +1,6 @@ package at.ac.tuwien.kr.alpha.core.rules; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; @@ -47,6 +48,10 @@ public AbstractRule(H head, List body) { + "Notice: A rule is considered safe if all variables occurring in negative literals, builtin atoms, and the head of the rule also occur in some positive literal."); } } + + public AbstractRule(H head, Set body) { + this(head, new ArrayList<>(body)); + } /** * Checks whether a rule is safe. The actual safety condition may vary over the next improvements. Currently, a rule is diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java index c75bdcbc9..5283a6a6d 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/rules/NormalRuleImpl.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; @@ -24,6 +25,10 @@ public NormalRuleImpl(NormalHead head, List body) { super(head, body); } + public NormalRuleImpl(NormalHead head, Set body) { + super(head, body); + } + public static NormalRuleImpl fromBasicRule(Rule rule) { BasicAtom headAtom = null; if (!rule.isConstraint()) { diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java index b6d952e23..b66ff1e01 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/DefaultSolver.java @@ -51,7 +51,6 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.StatisticsReportingSolver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.api.grounder.Substitution; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; @@ -103,17 +102,17 @@ private static class SearchState { private final PerformanceLog performanceLog; - public DefaultSolver(AtomStore atomStore, Grounder grounder, NoGoodStore store, WritableAssignment assignment, Random random, SystemConfig config, HeuristicsConfiguration heuristicsConfiguration) { + public DefaultSolver(SolverConfig cfg, AtomStore atomStore, Grounder grounder, NoGoodStore store, WritableAssignment assignment) { super(atomStore, grounder); this.assignment = assignment; this.store = store; this.choiceManager = new ChoiceManager(assignment, store); - this.choiceManager.setChecksEnabled(config.isDebugInternalChecks()); + this.choiceManager.setChecksEnabled(cfg.isEnableDebugChecks()); this.learner = new GroundConflictNoGoodLearner(assignment, atomStore); - this.branchingHeuristic = chainFallbackHeuristic(grounder, assignment, random, heuristicsConfiguration); - this.disableJustifications = config.isDisableJustificationSearch(); - this.disableNoGoodDeletion = config.isDisableNoGoodDeletion(); + this.branchingHeuristic = chainFallbackHeuristic(grounder, assignment, new Random(cfg.getRandomSeed()), cfg.getHeuristicsConfiguration()); + this.disableJustifications = cfg.isDisableJustifications(); + this.disableNoGoodDeletion = cfg.isDisableNogoodDeletion(); this.performanceLog = new PerformanceLog(choiceManager, (TrailAssignment) assignment, 1000); } diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverConfig.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverConfig.java new file mode 100644 index 000000000..7af9920ea --- /dev/null +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverConfig.java @@ -0,0 +1,53 @@ +package at.ac.tuwien.kr.alpha.core.solver; + +import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; + +public class SolverConfig { + + private boolean enableDebugChecks; + private boolean disableJustifications; + private boolean disableNogoodDeletion; + private HeuristicsConfiguration heuristicsConfiguration; + private long randomSeed; + + public boolean isEnableDebugChecks() { + return this.enableDebugChecks; + } + + public void setEnableDebugChecks(boolean enableDebugChecks) { + this.enableDebugChecks = enableDebugChecks; + } + + public boolean isDisableJustifications() { + return this.disableJustifications; + } + + public void setDisableJustifications(boolean disableJustifications) { + this.disableJustifications = disableJustifications; + } + + public boolean isDisableNogoodDeletion() { + return this.disableNogoodDeletion; + } + + public void setDisableNogoodDeletion(boolean disableNogoodDeletion) { + this.disableNogoodDeletion = disableNogoodDeletion; + } + + public HeuristicsConfiguration getHeuristicsConfiguration() { + return this.heuristicsConfiguration; + } + + public void setHeuristicsConfiguration(HeuristicsConfiguration heuristicsConfiguration) { + this.heuristicsConfiguration = heuristicsConfiguration; + } + + public long getRandomSeed() { + return this.randomSeed; + } + + public void setRandomSeed(long randomSeed) { + this.randomSeed = randomSeed; + } + +} diff --git a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java index e6af12d0a..4d3df1154 100644 --- a/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java +++ b/alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/solver/SolverFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016-2017, the Alpha Team. + * Copyright (c) 2016-2021, the Alpha Team. * All rights reserved. * * Additional changes made by Siemens. @@ -28,23 +28,27 @@ package at.ac.tuwien.kr.alpha.core.solver; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; -import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfigurationBuilder; - -import java.util.Random; public final class SolverFactory { - - public static Solver getInstance(SystemConfig config, AtomStore atomStore, Grounder grounder) { - final String solverName = config.getSolverName(); - final String nogoodStoreName = config.getNogoodStoreName(); - final Random random = new Random(config.getSeed()); - final boolean debugInternalChecks = config.isDebugInternalChecks(); - final HeuristicsConfiguration heuristicsConfiguration = buildHeuristicsConfiguration(config); - final WritableAssignment assignment = new TrailAssignment(atomStore, debugInternalChecks); + + private final String solverName; + private final String nogoodStoreName; + private final SolverConfig solverConfig; + + public SolverFactory(String solverName, String noGoodStoreName, SolverConfig solverConfig) { + this.solverName = solverName; + this.nogoodStoreName = noGoodStoreName; + this.solverConfig = solverConfig; + } + + public Solver createSolver(Grounder grounder, AtomStore atomStore) { + return SolverFactory.createSolver(solverName, nogoodStoreName, solverConfig, atomStore, grounder); + } + + private static Solver createSolver(String solverName, String nogoodStoreName, SolverConfig solverConfig, AtomStore atomStore, Grounder grounder) { + final WritableAssignment assignment = new TrailAssignment(atomStore, solverConfig.isEnableDebugChecks()); NoGoodStore store; @@ -53,26 +57,19 @@ public static Solver getInstance(SystemConfig config, AtomStore atomStore, Groun store = new NaiveNoGoodStore(assignment); break; case "alpharoaming": - store = new NoGoodStoreAlphaRoaming(assignment, debugInternalChecks); + store = new NoGoodStoreAlphaRoaming(assignment, solverConfig.isEnableDebugChecks()); break; default: throw new IllegalArgumentException("Unknown store requested."); } switch (solverName.toLowerCase()) { - case "naive" : + case "naive": return new NaiveSolver(atomStore, grounder); case "default": - return new DefaultSolver(atomStore, grounder, store, assignment, random, config, heuristicsConfiguration); + return new DefaultSolver(solverConfig, atomStore, grounder, store, assignment); } throw new IllegalArgumentException("Unknown solver requested."); } - private static HeuristicsConfiguration buildHeuristicsConfiguration(SystemConfig config) { - HeuristicsConfigurationBuilder heuristicsConfigurationBuilder = HeuristicsConfiguration.builder(); - heuristicsConfigurationBuilder.setHeuristic(config.getBranchingHeuristic()); - heuristicsConfigurationBuilder.setMomsStrategy(config.getMomsStrategy()); - heuristicsConfigurationBuilder.setReplayChoices(config.getReplayChoices()); - return heuristicsConfigurationBuilder.build(); - } } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java index 0bd692dda..0557fe2c4 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/common/ProgramTest.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.literals.Literal; import at.ac.tuwien.kr.alpha.api.rules.Rule; @@ -41,14 +41,14 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.literals.Literals; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.Rules; public class ProgramTest { @Test public void testToString() { - ASPCore2Program program; + InputProgram program; // rule := q(X) :- p(X). List body = new ArrayList<>(); body.add(Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newVariable("X")), true)); @@ -59,7 +59,7 @@ public void testToString() { facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a"))); facts.add(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("b"))); // program := p(a). p(b). q(X) :- p(X). - program = InputProgram.builder().addFacts(facts).addRule(rule).build(); + program = InputProgramImpl.builder().addFacts(facts).addRule(rule).build(); assertEquals( "p(a)." + System.lineSeparator() + "p(b)." + System.lineSeparator() + diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java index 33cdef134..f8346e33a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java @@ -44,7 +44,7 @@ import org.antlr.v4.runtime.CharStreams; import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -69,7 +69,7 @@ public class ParserTest { @Test public void parseFact() { - ASPCore2Program parsedProgram = parser.parse("p(a,b)."); + InputProgram parsedProgram = parser.parse("p(a,b)."); assertEquals(1, parsedProgram.getFacts().size(), "Program contains one fact."); assertEquals("p", parsedProgram.getFacts().get(0).getPredicate().getName(), "Predicate name of fact is p."); @@ -80,7 +80,7 @@ public void parseFact() { @Test public void parseFactWithFunctionTerms() { - ASPCore2Program parsedProgram = parser.parse("p(f(a),g(h(Y)))."); + InputProgram parsedProgram = parser.parse("p(f(a),g(h(Y)))."); assertEquals(1, parsedProgram.getFacts().size(), "Program contains one fact."); assertEquals("p", parsedProgram.getFacts().get(0).getPredicate().getName(), "Predicate name of fact is p."); @@ -91,7 +91,7 @@ public void parseFactWithFunctionTerms() { @Test public void parseSmallProgram() { - ASPCore2Program parsedProgram = parser.parse( + InputProgram parsedProgram = parser.parse( "a :- b, not d." + System.lineSeparator() + "c(X) :- p(X,a,_), q(Xaa,xaa)." + System.lineSeparator() + ":- f(Y)."); @@ -108,7 +108,7 @@ public void parseBadSyntax() { @Test public void parseBuiltinAtom() { - ASPCore2Program parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); + InputProgram parsedProgram = parser.parse("a :- p(X), X != Y, q(Y)."); assertEquals(1, parsedProgram.getRules().size()); assertEquals(3, parsedProgram.getRules().get(0).getBody().size()); } @@ -123,7 +123,7 @@ public void parseProgramWithDisjunctionInHead() { @Test public void parseInterval() { - ASPCore2Program parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); + InputProgram parsedProgram = parser.parse("fact(2..5). p(X) :- q(a, 3 .. X)."); IntervalTerm factInterval = (IntervalTerm) parsedProgram.getFacts().get(0).getTerms().get(0); assertTrue(factInterval.equals(IntervalTerm.getInstance(Terms.newConstant(2), Terms.newConstant(5)))); IntervalTerm bodyInterval = (IntervalTerm) parsedProgram.getRules().get(0).getBody().stream().findFirst().get().getTerms().get(1); @@ -132,7 +132,7 @@ public void parseInterval() { @Test public void parseChoiceRule() { - ASPCore2Program parsedProgram = parser.parse("dom(1). dom(2). { a ; b } :- dom(X)."); + InputProgram parsedProgram = parser.parse("dom(1). dom(2). { a ; b } :- dom(X)."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); @@ -143,7 +143,7 @@ public void parseChoiceRule() { @Test public void parseChoiceRuleBounded() { - ASPCore2Program parsedProgram = parser.parse("dom(1). dom(2). 1 < { a: p(v,w), not r; b } <= 13 :- dom(X). foo."); + InputProgram parsedProgram = parser.parse("dom(1). dom(2). 1 < { a: p(v,w), not r; b } <= 13 :- dom(X). foo."); ChoiceHead choiceHead = (ChoiceHead) parsedProgram.getRules().get(0).getHead(); assertEquals(2, choiceHead.getChoiceElements().size()); assertTrue(choiceHead.getChoiceElements().get(0).getChoiceAtom().toString().equals("a")); @@ -193,7 +193,7 @@ public void testMissingDotNotIgnored() { @Test public void parseEnumerationDirective() { - ASPCore2Program parsedProgram = parser.parse("p(a,1)." + + InputProgram parsedProgram = parser.parse("p(a,1)." + "# enumeration_predicate_is mune." + "r(X) :- p(X), mune(X)." + "p(b,2)."); @@ -203,7 +203,7 @@ public void parseEnumerationDirective() { @Test public void cardinalityAggregate() { - ASPCore2Program parsedProgram = parser.parse("num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K)."); + InputProgram parsedProgram = parser.parse("num(K) :- K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K)."); Optional optionalBodyElement = parsedProgram.getRules().get(0).getBody().stream().filter((lit) -> lit instanceof AggregateLiteral).findFirst(); assertTrue(optionalBodyElement.isPresent()); Literal bodyElement = optionalBodyElement.get(); @@ -222,7 +222,7 @@ public void cardinalityAggregate() { @Test public void stringWithEscapedQuotes() throws IOException { CharStream stream = CharStreams.fromStream(ParserTest.class.getResourceAsStream("/escaped_quotes.asp")); - ASPCore2Program prog = parser.parse(stream); + InputProgram prog = parser.parse(stream); assertEquals(1, prog.getFacts().size()); Atom stringAtom = prog.getFacts().get(0); String stringWithQuotes = stringAtom.getTerms().get(0).toString(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java index cbc92ed2c..d008dd21b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java +++ b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/ProgramTransformationTest.java @@ -12,7 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Program; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.externals.Externals; @@ -45,11 +45,11 @@ private static String readTestResource(String resource) throws IOException { } private , O extends Program> void genericTransformationTest(ProgramTransformation transform, - Function prepareFunc, String resourceSet) { + Function prepareFunc, String resourceSet) { try { String inputCode = ProgramTransformationTest.readTestResource(resourceSet + ".in"); String expectedResult = ProgramTransformationTest.readTestResource(resourceSet + ".out"); - ASPCore2Program inputProg = PARSER.parse(inputCode, Externals.scan(ProgramTransformationTest.class)); + InputProgram inputProg = PARSER.parse(inputCode, Externals.scan(ProgramTransformationTest.class)); I transformInput = prepareFunc.apply(inputProg); String beforeTransformProg = transformInput.toString(); O transformedProg = transform.apply(transformInput); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java deleted file mode 100644 index 3c492d095..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationRegressionTest.java +++ /dev/null @@ -1,263 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; -import at.ac.tuwien.kr.alpha.commons.Predicates; -import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; -import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; - -// TODO This is a functional test and should not be run with standard unit tests -public class StratifiedEvaluationRegressionTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluationRegressionTest.class); - - private static final String STRATIFIED_NEG_ASP = "base(X) :- req(X), not incomp(X).\n" - + "depend_base(X, Y) :- base(X), base(Y).\n" - + "dep_b_hlp(X) :- depend_base(X, _).\n" - + "fallback_base(X) :- base(X), not dep_b_hlp(X).\n" - + "depend_further(X) :- depend_base(_, X).\n" - + "depend_further(X) :- fallback_base(X)."; - - private static final String BASIC_TEST_ASP = "a. b:- a."; - private static final String BASIC_MULTI_INSTANCE_ASP = "p(a). p(b). q(X) :- p(X)."; - private static final String BASIC_NEGATION_ASP = "p(a). q(b). p(c). q(d). r(c). s(X, Y) :- p(X), q(Y), not r(X)."; - private static final String PART_STRATIFIED_ASP = "p(a). q(a). p(b). m(c). n(d).\n" + "r(X) :- p(X), q(X).\n" + "s(X, Y, Z) :- r(X), m(Y), n(Z).\n" - + "t(X, Y) :- p(X), q(X), p(Y), not q(Y).\n" + "either(X) :- t(X, _), not or(X).\n" + "or(X) :- t(X, _), not either(X)."; - private static final String POSITIVE_RECURSION_ASP = "num(0).\n" + "max_num(10).\n" + "num(S) :- num(N), S = N + 1, S <= M, max_num(M)."; - private static final String EMPTY_PROG_ASP = ""; - private static final String FACTS_ONLY_ASP = "a. b. c. p(a). q(b, c). r(c, c, a). s(b)."; - private static final String STRATIFIED_NO_FACTS_ASP = STRATIFIED_NEG_ASP; - private static final String STRATIFIED_W_FACTS_ASP = "req(a). req(b). incomp(b).\n" + STRATIFIED_NEG_ASP; - private static final String EQUALITY_ASP = "equal :- 1 = 1."; - private static final String EQUALITY_WITH_VAR_ASP = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; - - private static final ImmutablePair, Consumer>> BASIC_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasic, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasic); - private static final ImmutablePair, Consumer>> BASIC_MULTI_INSTANCE_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasicMultiInstance, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicMultiInstance); - private static final ImmutablePair, Consumer>> BASIC_NEGATION_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramBasicNegation, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicNegation); - private static final ImmutablePair, Consumer>> PART_STRATIFIED_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramPartStratified, StratifiedEvaluationRegressionTest::verifyAnswerSetsPartStratified); - private static final ImmutablePair, Consumer>> POSITIVE_RECURSIVE_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramPositiveRecursive, StratifiedEvaluationRegressionTest::verifyAnswerSetsPositiveRecursive); - private static final ImmutablePair, Consumer>> EMPTY_PROG_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEmptyProg, StratifiedEvaluationRegressionTest::verifyAnswerSetsEmptyProg); - private static final ImmutablePair, Consumer>> FACTS_ONLY_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramFactsOnly, StratifiedEvaluationRegressionTest::verifyAnswerSetsFactsOnly); - private static final ImmutablePair, Consumer>> STRATIFIED_NO_FACTS_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramStratNoFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratNoFacts); - private static final ImmutablePair, Consumer>> STRATIFIED_W_FACTS_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramStratWithFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratWithFacts); - private static final ImmutablePair, Consumer>> EQUALITY_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEquality, StratifiedEvaluationRegressionTest::verifyAnswerSetsEquality); - private static final ImmutablePair, Consumer>> EQUALITY_WITH_VAR_VERIFIERS = new ImmutablePair<>( - StratifiedEvaluationRegressionTest::verifyProgramEqualityWithVar, StratifiedEvaluationRegressionTest::verifyAnswerSetsEqualityWithVar); - - public static List params() { - List, Consumer>>>> testCases = new ArrayList<>(); - List paramList = new ArrayList<>(); - testCases.add(new ImmutablePair<>(BASIC_TEST_ASP, BASIC_VERIFIERS)); - testCases.add(new ImmutablePair<>(BASIC_MULTI_INSTANCE_ASP, BASIC_MULTI_INSTANCE_VERIFIERS)); - testCases.add(new ImmutablePair<>(BASIC_NEGATION_ASP, BASIC_NEGATION_VERIFIERS)); - testCases.add(new ImmutablePair<>(PART_STRATIFIED_ASP, PART_STRATIFIED_VERIFIERS)); - testCases.add(new ImmutablePair<>(POSITIVE_RECURSION_ASP, POSITIVE_RECURSIVE_VERIFIERS)); - testCases.add(new ImmutablePair<>(EMPTY_PROG_ASP, EMPTY_PROG_VERIFIERS)); - testCases.add(new ImmutablePair<>(FACTS_ONLY_ASP, FACTS_ONLY_VERIFIERS)); - testCases.add(new ImmutablePair<>(STRATIFIED_NO_FACTS_ASP, STRATIFIED_NO_FACTS_VERIFIERS)); - testCases.add(new ImmutablePair<>(STRATIFIED_W_FACTS_ASP, STRATIFIED_W_FACTS_VERIFIERS)); - testCases.add(new ImmutablePair<>(EQUALITY_ASP, EQUALITY_VERIFIERS)); - testCases.add(new ImmutablePair<>(EQUALITY_WITH_VAR_ASP, EQUALITY_WITH_VAR_VERIFIERS)); - - testCases.forEach((pair) -> paramList.add(Arguments.of(pair.left, pair.right.left, pair.right.right))); - return paramList; - } - - @ParameterizedTest - @MethodSource("at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluationRegressionTest#params") - public void runTest(String aspString, Consumer programVerifier, Consumer> resultVerifier) { - // Parse and pre-evaulate program - ProgramParser parser = new ProgramParserImpl(); - ASPCore2Program prog = parser.parse(aspString); - AnalyzedProgram analyzed = AnalyzedProgram - .analyzeNormalProgram(new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG).apply(prog)); - CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); - // Verify stratified evaluation result - programVerifier.accept(evaluated); - // Solve remaining program - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", evaluated, atomStore, false); - Solver solver = SolverFactory.getInstance(new SystemConfig(), atomStore, grounder); - Set answerSets = solver.collectSet(); - resultVerifier.accept(answerSets); - } - - private static void verifyProgramBasic(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("a"), TestUtils.basicAtomWithSymbolicTerms("b")); - assertEquals(2, evaluated.getFacts().size()); - assertTrue(evaluated.getRules().size() == 0); - } - - private static void verifyAnswerSetsBasic(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a, b", answerSets); - } - - private static void verifyProgramBasicMultiInstance(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("q", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "b")); - assertTrue(evaluated.getRules().size() == 0); - } - - private static void verifyAnswerSetsBasicMultiInstance(Set answerSets) { - TestUtils.assertAnswerSetsEqual("p(a), p(b), q(a), q(b)", answerSets); - } - - private static void verifyProgramBasicNegation(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("s", "a", "b"), - TestUtils.basicAtomWithSymbolicTerms("s", "a", "d")); - assertEquals(7, evaluated.getFacts().size()); - assertEquals(0, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsBasicNegation(Set answerSets) { - TestUtils.assertAnswerSetsEqual("p(a), q(b), p(c), q(d), r(c), s(a,b), s(a,d)", answerSets); - } - - private static void verifyProgramPartStratified(CompiledProgram evaluated) { - TestUtils.assertFactsContainedInProgram(evaluated, TestUtils.basicAtomWithSymbolicTerms("p", "a"), TestUtils.basicAtomWithSymbolicTerms("q", "a"), - TestUtils.basicAtomWithSymbolicTerms("p", "b"), - TestUtils.basicAtomWithSymbolicTerms("m", "c"), TestUtils.basicAtomWithSymbolicTerms("n", "d"), TestUtils.basicAtomWithSymbolicTerms("r", "a"), - TestUtils.basicAtomWithSymbolicTerms("s", "a", "c", "d"), - TestUtils.basicAtomWithSymbolicTerms("t", "a", "b")); - LOGGER.debug("part stratified evaluated prog is:\n{}", evaluated.toString()); - assertEquals(2, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsPartStratified(Set answerSets) { - TestUtils.assertAnswerSetsEqual(new String[] {"p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), either(a)", - "p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), or(a)" }, answerSets); - } - - private static void verifyProgramPositiveRecursive(CompiledProgram evaluated) { - Predicate num = Predicates.getPredicate("num", 1); - TestUtils.assertFactsContainedInProgram(evaluated, Atoms.newBasicAtom(Predicates.getPredicate("max_num", 1), Terms.newConstant(10)), - Atoms.newBasicAtom(num, Terms.newConstant(0)), - Atoms.newBasicAtom(num, Terms.newConstant(1)), Atoms.newBasicAtom(num, Terms.newConstant(2)), - Atoms.newBasicAtom(num, Terms.newConstant(3)), Atoms.newBasicAtom(num, Terms.newConstant(4)), - Atoms.newBasicAtom(num, Terms.newConstant(5)), Atoms.newBasicAtom(num, Terms.newConstant(6)), - Atoms.newBasicAtom(num, Terms.newConstant(7)), Atoms.newBasicAtom(num, Terms.newConstant(8)), - Atoms.newBasicAtom(num, Terms.newConstant(9)), Atoms.newBasicAtom(num, Terms.newConstant(10))); - LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); - assertEquals(0, evaluated.getRules().size()); - } - - private static void verifyAnswerSetsPositiveRecursive(Set answerSets) { - TestUtils.assertAnswerSetsEqual("max_num(10), num(0), num(1), num(2), num(3), num(4), num(5), num(6), num(7), num(8), num(9), num(10)", answerSets); - } - - private static void verifyProgramEmptyProg(CompiledProgram evaluated) { - assertTrue(evaluated.getRules().isEmpty()); - assertTrue(evaluated.getRulesById().isEmpty()); - assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - assertTrue(evaluated.getFacts().isEmpty()); - assertTrue(evaluated.getFactsByPredicate().isEmpty()); - } - - private static void verifyAnswerSetsEmptyProg(Set answerSets) { - assertEquals(1, answerSets.size()); - assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramFactsOnly(CompiledProgram evaluated) { - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("b"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("c"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("p", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("q", "b", "c"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("r", "c", "c", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("s", "b"))); - } - - private static void verifyAnswerSetsFactsOnly(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a, b, c, p(a), q(b,c), r(c,c,a), s(b)", answerSets); - } - - private static void verifyProgramStratNoFacts(CompiledProgram evaluated) { - assertTrue(evaluated.getFacts().isEmpty()); - } - - private static void verifyAnswerSetsStratNoFacts(Set answerSets) { - assertEquals(1, answerSets.size()); - assertTrue(answerSets.iterator().next().isEmpty()); - } - - private static void verifyProgramStratWithFacts(CompiledProgram evaluated) { - // rules should all be taken care of at this point - assertTrue(evaluated.getRules().isEmpty()); - assertTrue(evaluated.getRulesById().isEmpty()); - assertTrue(evaluated.getPredicateDefiningRules().isEmpty()); - - // facts should be the full answer set - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("req", "b"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("incomp", "b"))); - - // below facts from stratified evaluation - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("base", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_base", "a", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("dep_b_hlp", "a"))); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("depend_further", "a"))); - } - - private static void verifyAnswerSetsStratWithFacts(Set answerSets) { - TestUtils.assertAnswerSetsEqual("req(a), req(b), incomp(b), base(a), depend_base(a,a), dep_b_hlp(a), depend_further(a)", answerSets); - } - - private static void verifyProgramEquality(CompiledProgram evaluated) { - assertEquals(0, evaluated.getRules().size()); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("equal"))); - } - - private static void verifyAnswerSetsEquality(Set answerSets) { - TestUtils.assertAnswerSetsEqual("equal", answerSets); - } - - private static void verifyProgramEqualityWithVar(CompiledProgram evaluated) { - assertEquals(0, evaluated.getRules().size()); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newConstant(1)))); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newConstant(2)))); - assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newConstant(3)))); - } - - private static void verifyAnswerSetsEqualityWithVar(Set answerSets) { - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); - } - -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java b/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java deleted file mode 100644 index 4d2aab5af..000000000 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ArithmeticTermsTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package at.ac.tuwien.kr.alpha.core.solver; - -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSet; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSetsWithBase; - -/** - * Tests ASP programs containing arithmetic terms at arbitrary positions. - * - * Copyright (c) 2020, the Alpha Team. - */ -// TODO This is a functional test and should not be run with standard unit tests -public class ArithmeticTermsTest { - - @RegressionTest - public void testArithmeticTermInHead(RegressionTestConfig cfg) { - String program = "dom(1). dom(2)." - + "p(X+3) :- dom(X)."; - assertRegressionTestAnswerSet(cfg, program, "dom(1),dom(2),p(4),p(5)"); - } - - @RegressionTest - public void testArithmeticTermInRule(RegressionTestConfig cfg) { - String program = "dom(1). dom(2)." - + "p(Y+4) :- dom(X+1), dom(X), Y=X, X=Y."; - assertRegressionTestAnswerSet(cfg, program, "dom(1),dom(2),p(5)"); - } - - @RegressionTest - public void testArithmeticTermInChoiceRule(RegressionTestConfig cfg) { - String program = "cycle_max(4). cycle(1)." + - "{ cycle(N+1) } :- cycle(N), cycle_max(K), N collectRegressionTestAnswerSets(ASPCore2Program prog, RegressionTestConfig cfg) { - return buildSolverForRegressionTest(prog, cfg).collectSet(); - } - - public static Set collectRegressionTestAnswerSets(String aspstr, RegressionTestConfig cfg) { - ASPCore2Program prog = new ProgramParserImpl().parse(aspstr); - return collectRegressionTestAnswerSets(prog, cfg); - } - - public static void assertRegressionTestAnswerSet(RegressionTestConfig cfg, String program, String answerSet) { - Set actualAnswerSets = collectRegressionTestAnswerSets(program, cfg); - TestUtils.assertAnswerSetsEqual(answerSet, actualAnswerSets); - } - - public static void assertRegressionTestAnswerSets(RegressionTestConfig cfg, String program, String... answerSets) { - Set actualAnswerSets = collectRegressionTestAnswerSets(program, cfg); - TestUtils.assertAnswerSetsEqual(answerSets, actualAnswerSets); - } - - public static void assertRegressionTestAnswerSetsWithBase(RegressionTestConfig cfg, String program, String base, String... answerSets) { - Set actualAnswerSets = collectRegressionTestAnswerSets(program, cfg); - TestUtils.assertAnswerSetsEqualWithBase(base, answerSets, actualAnswerSets); - } - - public static void runWithTimeout(RegressionTestConfig cfg, long baseTimeout, long timeoutFactor, Executable action) { - long timeout = cfg.isDebugChecks() ? timeoutFactor * baseTimeout : baseTimeout; - assertTimeoutPreemptively(Duration.ofMillis(timeout), action); - } - - public static void ignoreTestForNaiveSolver(RegressionTestConfig cfg) { - Assumptions.assumeFalse(cfg.getSolverName().equals("naive")); - } - - public static void ignoreTestForNonDefaultDomainIndependentHeuristics(RegressionTestConfig cfg) { - Assumptions.assumeTrue(cfg.getBranchingHeuristic() == Heuristic.VSIDS); - } - - public static void ignoreTestForSimplifiedSumAggregates(RegressionTestConfig cfg) { - Assumptions.assumeTrue(cfg.isSupportNegativeSumElements()); - } - } diff --git a/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java new file mode 100644 index 000000000..7de3ef84d --- /dev/null +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AlphaAssertions.java @@ -0,0 +1,75 @@ +package at.ac.tuwien.kr.alpha.test; + + +import static java.util.Collections.emptySet; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.StringJoiner; + +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.programs.Program; +import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; + +public class AlphaAssertions { + + public static void assertAnswerSetsEqual(Set expected, Set actual) { + if (expected == null) { + if (actual != null) { + throw new AssertionError("Expected answer sets are null, but actual are not!"); + } + } + try { + assertEquals(expected, actual); + } catch (AssertionError e) { + Set expectedMinusActual = new LinkedHashSet<>(expected); + expectedMinusActual.removeAll(actual); + Set actualMinusExpected = new LinkedHashSet<>(actual); + actualMinusExpected.removeAll(expected); + String setDiffs = "Expected and actual answer sets do not agree, differences are:\nExpected \\ Actual:\n" + expectedMinusActual + + "\nActual \\ Expected:\n" + actualMinusExpected; + throw new AssertionError(setDiffs + e.getMessage(), e); + } + } + + public static void assertAnswerSetsEqual(String[] expected, Set actual) { + if (expected.length == 0) { + assertAnswerSetsEqual(emptySet(), actual); + return; + } + StringJoiner joiner = new StringJoiner("} {", "{", "}"); + Arrays.stream(expected).forEach(joiner::add); + assertAnswerSetsEqual(AnswerSetsParser.parse(joiner.toString()), actual); + } + + public static void assertAnswerSetsEqual(String expectedAnswerSet, Set actual) { + assertAnswerSetsEqual(AnswerSetsParser.parse("{ " + expectedAnswerSet + " }"), actual); + } + + public static void assertAnswerSetsEqualWithBase(String base, String[] expectedAnswerSets, Set actual) { + base = base.trim(); + if (!base.endsWith(",")) { + base += ", "; + } + + for (int i = 0; i < expectedAnswerSets.length; i++) { + expectedAnswerSets[i] = base + expectedAnswerSets[i]; + // Remove trailing ",". + expectedAnswerSets[i] = expectedAnswerSets[i].trim(); + if (expectedAnswerSets[i].endsWith(",")) { + expectedAnswerSets[i] = expectedAnswerSets[i].substring(0, expectedAnswerSets[i].length() - 1); + } + } + assertAnswerSetsEqual(expectedAnswerSets, actual); + } + + public static void assertFactsContainedInProgram(Program prog, Atom... facts) { + for (Atom fact : facts) { + assertTrue(prog.getFacts().contains(fact)); + } + } + +} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/AnswerSetsParser.java b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java similarity index 97% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/AnswerSetsParser.java rename to alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java index b78ebc20c..c98e29f3a 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/test/util/AnswerSetsParser.java +++ b/alpha-core/src/testFixtures/java/at/ac/tuwien/kr/alpha/test/AnswerSetsParser.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.test.util; +package at.ac.tuwien.kr.alpha.test; import java.util.Collections; import java.util.Set; diff --git a/alpha-core/benchmarks/omiga/omiga-testcases.tar.gz b/alpha-solver/benchmarks/omiga/omiga-testcases.tar.gz similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases.tar.gz rename to alpha-solver/benchmarks/omiga/omiga-testcases.tar.gz diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-10-18.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/3col/3col-20-38.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-30.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/cutedge/cutedge-100-50.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-200.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/locstrat/locstrat-400.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-1.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-1.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-1.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-1.txt diff --git a/alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-4.txt b/alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-4.txt similarity index 100% rename from alpha-core/benchmarks/omiga/omiga-testcases/reach/reach-4.txt rename to alpha-solver/benchmarks/omiga/omiga-testcases/reach/reach-4.txt diff --git a/alpha-core/benchmarks/siemens/racks/racks.lp b/alpha-solver/benchmarks/siemens/racks/racks.lp similarity index 100% rename from alpha-core/benchmarks/siemens/racks/racks.lp rename to alpha-solver/benchmarks/siemens/racks/racks.lp diff --git a/alpha-solver/build.gradle.kts b/alpha-solver/build.gradle.kts index b0c59c197..aff85c7cc 100644 --- a/alpha-solver/build.gradle.kts +++ b/alpha-solver/build.gradle.kts @@ -6,6 +6,8 @@ dependencies { api(project(":alpha-api")) api(project(":alpha-commons")) implementation(project(":alpha-core")) + + testImplementation(testFixtures(project(":alpha-core"))) } tasks.test { diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java new file mode 100644 index 000000000..9a3093255 --- /dev/null +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaFactory.java @@ -0,0 +1,77 @@ +package at.ac.tuwien.kr.alpha.api.impl; + +import java.util.function.Supplier; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; +import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; +import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewriting; +import at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AggregateEncoderFactory; +import at.ac.tuwien.kr.alpha.core.solver.SolverConfig; +import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; +import at.ac.tuwien.kr.alpha.core.solver.heuristics.HeuristicsConfiguration; + +public final class AlphaFactory { + + private AlphaFactory() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static Alpha newAlpha(SystemConfig cfg) { + Supplier parserFactory = () -> new ProgramParserImpl(); + + // AggregateEncoderFactory depends on parser factory since stringtemplate-based aggregate encoders need to use the same parser that's used + // for input programs. + AggregateEncoderFactory aggregateEncoderFactory = new AggregateEncoderFactory(parserFactory, + cfg.getAggregateRewritingConfig().isUseSortingGridEncoding(), cfg.getAggregateRewritingConfig().isSupportNegativeValuesInSums()); + + // Factory for aggregate rewriting (depends on encoders provided by above factory). + Supplier aggregateRewritingFactory = () -> new AggregateRewriting(aggregateEncoderFactory.newCountEqualsEncoder(), + aggregateEncoderFactory.newCountLessOrEqualEncoder(), aggregateEncoderFactory.newSumEqualsEncoder(), + aggregateEncoderFactory.newSumLessOrEqualEncoder(), aggregateEncoderFactory.newMinEncoder(), aggregateEncoderFactory.newMaxEncoder()); + + // Factory for NormalizeProgramTransformation - needs a supplier for AggregateRewriting due to AggregateRewritings' dependency to encoder + // factory. + Supplier> programNormalizationFactory = () -> new NormalizeProgramTransformation( + aggregateRewritingFactory); + + // GrounderFactory - Since every grounder instance is only good for one program instance, we need a factory. + GrounderHeuristicsConfiguration grounderHeuristicsCfg = GrounderHeuristicsConfiguration.getInstance(cfg.getGrounderToleranceConstraints(), + cfg.getGrounderToleranceRules()); + grounderHeuristicsCfg.setAccumulatorEnabled(cfg.isGrounderAccumulatorEnabled()); + GrounderFactory grounderFactory = new GrounderFactory( + grounderHeuristicsCfg, + cfg.isDebugInternalChecks()); + + // SolverFactory - Same as for GrounderFactory, we need a new Solver for each program. + SolverConfig solverCfg = new SolverConfig(); + solverCfg.setDisableJustifications(cfg.isDisableJustificationSearch()); + solverCfg.setDisableNogoodDeletion(cfg.isDisableNoGoodDeletion()); + solverCfg.setEnableDebugChecks(cfg.isDebugInternalChecks()); + solverCfg.setRandomSeed(cfg.getSeed()); + solverCfg.setHeuristicsConfiguration( + HeuristicsConfiguration.builder() + .setHeuristic(cfg.getBranchingHeuristic()) + .setMomsStrategy(cfg.getMomsStrategy()) + .setReplayChoices(cfg.getReplayChoices()) + .build()); + SolverFactory solverFactory = new SolverFactory(cfg.getSolverName(), cfg.getNogoodStoreName(), solverCfg); + + // Now that all dependencies are taken care of, build new Alpha instance. + return new AlphaImpl(parserFactory, programNormalizationFactory, grounderFactory, solverFactory, cfg.isEvaluateStratifiedPart(), + cfg.isSortAnswerSets()); + } + + // Create Alpha instance with default config. + public static Alpha newAlpha() { + return newAlpha(new SystemConfig()); + } + +} diff --git a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java index c49a5ca39..934ce13bd 100644 --- a/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java +++ b/alpha-solver/src/main/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImpl.java @@ -36,24 +36,23 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.common.annotations.VisibleForTesting; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; - import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; -import at.ac.tuwien.kr.alpha.api.config.GrounderHeuristicsConfiguration; import at.ac.tuwien.kr.alpha.api.config.InputConfig; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; @@ -64,12 +63,11 @@ import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; import at.ac.tuwien.kr.alpha.core.grounder.Grounder; import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; +import at.ac.tuwien.kr.alpha.core.programs.transformation.ProgramTransformation; import at.ac.tuwien.kr.alpha.core.programs.transformation.StratifiedEvaluation; import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; @@ -77,20 +75,31 @@ public class AlphaImpl implements Alpha { private static final Logger LOGGER = LoggerFactory.getLogger(AlphaImpl.class); - private SystemConfig config = new SystemConfig(); // Config is initialized with default values. - private ProgramParser parser = new ProgramParserImpl(); - - public AlphaImpl(SystemConfig cfg) { - this.config = cfg; - } - - public AlphaImpl() { + private final Supplier parserFactory; + private final Supplier> programNormalizationFactory; + + private final GrounderFactory grounderFactory; + private final SolverFactory solverFactory; + + private final boolean enableStratifiedEvaluation; + private final boolean sortAnswerSets; + + AlphaImpl(Supplier parserFactory, Supplier> programNormalizationFactory, + GrounderFactory grounderFactory, + SolverFactory solverFactory, + boolean enableStratifiedEvaluation, boolean sortAnswerSets) { + this.parserFactory = parserFactory; + this.programNormalizationFactory = programNormalizationFactory; + this.grounderFactory = grounderFactory; + this.solverFactory = solverFactory; + this.enableStratifiedEvaluation = enableStratifiedEvaluation; + this.sortAnswerSets = sortAnswerSets; } @Override - public ASPCore2Program readProgram(InputConfig cfg) throws IOException { - InputProgram.Builder prgBuilder = InputProgram.builder(); - ASPCore2Program tmpProg; + public InputProgram readProgram(InputConfig cfg) throws IOException { + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); + InputProgram tmpProg; if (!cfg.getFiles().isEmpty()) { tmpProg = readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()); prgBuilder.accumulate(tmpProg); @@ -103,14 +112,16 @@ public ASPCore2Program readProgram(InputConfig cfg) throws IOException { } @Override - public ASPCore2Program readProgramFiles(boolean literate, Map externals, List paths) throws IOException { + public InputProgram readProgramFiles(boolean literate, Map externals, List paths) throws IOException { return readProgramFiles(literate, externals, paths.stream().map(Paths::get).collect(Collectors.toList()).toArray(new Path[] {})); } @Override - public ASPCore2Program readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { - InputProgram.Builder prgBuilder = InputProgram.builder(); - ASPCore2Program tmpProg; + @SuppressWarnings("resource") + public InputProgram readProgramFiles(boolean literate, Map externals, Path... paths) throws IOException { + ProgramParser parser = parserFactory.get(); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(); + InputProgram tmpProg; for (Path path : paths) { InputStream stream; if (!literate) { @@ -125,25 +136,25 @@ public ASPCore2Program readProgramFiles(boolean literate, Map externals) { - return parser.parse(aspString, externals); + public InputProgram readProgramString(String aspString, Map externals) { + return parserFactory.get().parse(aspString, externals); } @Override - public ASPCore2Program readProgramString(String aspString) { + public InputProgram readProgramString(String aspString) { return readProgramString(aspString, Collections.emptyMap()); } @Override - public NormalProgram normalizeProgram(ASPCore2Program program) { - return new NormalizeProgramTransformation(config.getAggregateRewritingConfig()).apply(program); + public NormalProgram normalizeProgram(InputProgram program) { + return programNormalizationFactory.get().apply(program); } @VisibleForTesting InternalProgram performProgramPreprocessing(NormalProgram program) { LOGGER.debug("Preprocessing InternalProgram!"); InternalProgram retVal = InternalProgram.fromNormalProgram(program); - if (config.isEvaluateStratifiedPart()) { + if (enableStratifiedEvaluation) { AnalyzedProgram analyzed = new AnalyzedProgram(retVal.getRules(), retVal.getFacts()); retVal = new StratifiedEvaluation().apply(analyzed); } @@ -155,7 +166,7 @@ InternalProgram performProgramPreprocessing(NormalProgram program) { * program analysis and normalization aren't of interest. */ @Override - public Stream solve(ASPCore2Program program) { + public Stream solve(InputProgram program) { return solve(program, InputConfig.DEFAULT_FILTER); } @@ -164,7 +175,7 @@ public Stream solve(ASPCore2Program program) { * details of the program analysis and normalization aren't of interest. */ @Override - public Stream solve(ASPCore2Program program, java.util.function.Predicate filter) { + public Stream solve(InputProgram program, java.util.function.Predicate filter) { NormalProgram normalized = normalizeProgram(program); return solve(normalized, filter); } @@ -193,7 +204,7 @@ public Stream solve(NormalProgram program, java.util.function.Predica */ private Stream solve(CompiledProgram program, java.util.function.Predicate filter) { Stream retVal = prepareSolverFor(program, filter).stream(); - return config.isSortAnswerSets() ? retVal.sorted() : retVal; + return sortAnswerSets ? retVal.sorted() : retVal; } /** @@ -206,35 +217,23 @@ private Stream solve(CompiledProgram program, java.util.function.Pred * @return a solver (and accompanying grounder) instance pre-loaded with the given program. */ private Solver prepareSolverFor(CompiledProgram program, java.util.function.Predicate filter) { - String grounderName = config.getGrounderName(); - boolean doDebugChecks = config.isDebugInternalChecks(); - - GrounderHeuristicsConfiguration grounderHeuristicConfiguration = GrounderHeuristicsConfiguration - .getInstance(config.getGrounderToleranceConstraints(), config.getGrounderToleranceRules()); - grounderHeuristicConfiguration.setAccumulatorEnabled(config.isGrounderAccumulatorEnabled()); - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance(grounderName, program, atomStore, filter, grounderHeuristicConfiguration, doDebugChecks); - - return SolverFactory.getInstance(config, atomStore, grounder); - } - - public void setConfig(SystemConfig config) { - this.config = config; + Grounder grounder = grounderFactory.createGrounder(program, atomStore, filter); + return solverFactory.createSolver(grounder, atomStore); } @Override - public DebugSolvingContext prepareDebugSolve(ASPCore2Program program) { + public DebugSolvingContext prepareDebugSolve(InputProgram program) { return prepareDebugSolve(program, InputConfig.DEFAULT_FILTER); } @Override public DebugSolvingContext prepareDebugSolve(NormalProgram program) { return prepareDebugSolve(program, InputConfig.DEFAULT_FILTER); - } - + } + @Override - public DebugSolvingContext prepareDebugSolve(final ASPCore2Program program, java.util.function.Predicate filter) { + public DebugSolvingContext prepareDebugSolve(final InputProgram program, java.util.function.Predicate filter) { return prepareDebugSolve(normalizeProgram(program), filter); } @@ -244,7 +243,7 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u final ComponentGraph compGraph; final AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(program); final NormalProgram preprocessed; - if (this.config.isEvaluateStratifiedPart()) { + if (enableStratifiedEvaluation) { preprocessed = new StratifiedEvaluation().apply(analyzed).toNormalProgram(); } else { preprocessed = program; @@ -253,27 +252,27 @@ public DebugSolvingContext prepareDebugSolve(final NormalProgram program, java.u compGraph = analyzed.getComponentGraph(); final Solver solver = prepareSolverFor(analyzed, filter); return new DebugSolvingContext() { - + @Override public Solver getSolver() { return solver; } - + @Override public NormalProgram getPreprocessedProgram() { return preprocessed; } - + @Override public NormalProgram getNormalizedProgram() { return program; } - + @Override public DependencyGraph getDependencyGraph() { return depGraph; } - + @Override public ComponentGraph getComponentGraph() { return compGraph; @@ -282,7 +281,7 @@ public ComponentGraph getComponentGraph() { } @Override - public Solver prepareSolverFor(ASPCore2Program program, java.util.function.Predicate filter) { + public Solver prepareSolverFor(InputProgram program, java.util.function.Predicate filter) { return prepareSolverFor(normalizeProgram(program), filter); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java similarity index 99% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java index f674121de..137074843 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateLiteralSplittingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateLiteralSplittingTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java similarity index 99% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java index 5813bd930..707fcd6a6 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateOperatorNormalizationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateOperatorNormalizationTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java similarity index 97% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java index 92b41c9d8..bd7011667 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AggregateRewritingContextTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingContextTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test; import at.ac.tuwien.kr.alpha.api.ComparisonOperator; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; @@ -60,7 +60,7 @@ public class AggregateRewritingContextTest { //@formatter:on private static final AggregateRewritingContext rewritingContextForAspString(String asp) { - ASPCore2Program program = new ProgramParserImpl().parse(asp); + InputProgram program = new ProgramParserImpl().parse(asp); AggregateRewritingContext ctx = new AggregateRewritingContext(); for (Rule rule : program.getRules()) { ctx.registerRule(rule); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java similarity index 81% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java index e7dc1543f..df015f477 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/aggregates/AggregateRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/AggregateRewritingTest.java @@ -1,49 +1,27 @@ -package at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import java.util.function.Function; +import java.util.stream.Collectors; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; -import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; -import at.ac.tuwien.kr.alpha.core.programs.transformation.NormalizeProgramTransformation; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; // TODO This is a functional test and should not be run with standard unit tests public class AggregateRewritingTest { - private static final ProgramParser PARSER = new ProgramParserImpl(); - private static final Function> NORMALIZE_AND_SOLVE = (str) -> { - SystemConfig cfg = new SystemConfig(); - ASPCore2Program prog = PARSER.parse(str); - NormalProgram normalized = new NormalizeProgramTransformation(cfg.getAggregateRewritingConfig()).apply(prog); - CompiledProgram compiled = InternalProgram.fromNormalProgram(normalized); - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", compiled, atomStore, cfg.isDebugInternalChecks()); - Solver solver = SolverFactory.getInstance(cfg, atomStore, grounder); - return solver.collectList(); - }; - //@formatter:off // Smoke-test case for "X <= #count{...}" aggregate private static final String CNT_LE1_ASP = @@ -100,9 +78,16 @@ public class AggregateRewritingTest { + " Y = #count { X : p( X ) }, 1 <= #count { X : p( X ) }, Z = #max { W : p( W ) }."; //@formatter:on + // Use an alpha instance with default config for all test cases + private final Alpha alpha = AlphaFactory.newAlpha(); + private final Function> solve = (asp) -> { + InputProgram prog = alpha.readProgramString(asp); + return alpha.solve(prog).collect(Collectors.toList()); + }; + @Test public void countLeSortingGridSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_LE1_ASP); + List answerSets = solve.apply(CNT_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -124,7 +109,7 @@ public void countLeSortingGridSimple() { @Test public void countEqSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_EQ1_ASP); + List answerSets = solve.apply(CNT_EQ1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -142,7 +127,7 @@ public void countEqSimple() { @Test public void countLeCountingGridSimple() { - List answerSets = NORMALIZE_AND_SOLVE.apply(CNT_LE1_ASP); + List answerSets = solve.apply(CNT_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate thing = Predicates.getPredicate("thing", 1); @@ -164,7 +149,7 @@ public void countLeCountingGridSimple() { @Test public void countEqGlobalVars() { - List answerSets = NORMALIZE_AND_SOLVE.apply(VERTEX_DEGREE_ASP); + List answerSets = solve.apply(VERTEX_DEGREE_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate vertexDegree = Predicates.getPredicate("graph_vertex_degree", 3); @@ -183,7 +168,7 @@ public void countEqGlobalVars() { @Test // Test "count eq" and "max eq" together with global vars public void graphVerticesOfMaxDegree() { - List answerSets = NORMALIZE_AND_SOLVE.apply(NUM_MAX_DEGREE_VERTICES_ASP); + List answerSets = solve.apply(NUM_MAX_DEGREE_VERTICES_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate maxDegreeVertices = Predicates.getPredicate("graph_max_degree_vertices", 3); @@ -197,7 +182,7 @@ public void graphVerticesOfMaxDegree() { @Test public void greaterMin() { - List answerSets = NORMALIZE_AND_SOLVE.apply(MIN_GT1_ASP); + List answerSets = solve.apply(MIN_GT1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate greaterMin = Predicates.getPredicate("greater_min_acceptable", 1); @@ -211,7 +196,7 @@ public void greaterMin() { @Test public void sumEquals1() { - List answerSets = NORMALIZE_AND_SOLVE.apply(SUM_EQ1_ASP); + List answerSets = solve.apply(SUM_EQ1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate sumThings = Predicates.getPredicate("sum_things", 1); @@ -225,7 +210,7 @@ public void sumEquals1() { @Test public void sumLessOrEqual1() { - List answerSets = NORMALIZE_AND_SOLVE.apply(SUM_LE1_ASP); + List answerSets = solve.apply(SUM_LE1_ASP); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate boundLe = Predicates.getPredicate("bound_le_sum", 1); @@ -239,7 +224,7 @@ public void sumLessOrEqual1() { @Test @Disabled("Open issue, as dependency analysis includes cyclic output-dependency, which it should not.") public void setComplexEqualityWithGlobals() { - List answerSets = NORMALIZE_AND_SOLVE.apply(COMPLEX_EQUALITY_WITH_GLOBALS); + List answerSets = solve.apply(COMPLEX_EQUALITY_WITH_GLOBALS); assertEquals(1, answerSets.size()); AnswerSet answerSet = answerSets.get(0); Predicate q = Predicates.getPredicate("q", 0); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java similarity index 98% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java index 8bc8d06b3..c812bfe95 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/ArithmeticTermsRewritingTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/ArithmeticTermsRewritingTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java similarity index 98% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java index ef0a1a625..0aafb40c7 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/FixedInterpretationLiteralsTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/FixedInterpretationLiteralsTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -17,6 +17,7 @@ import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; @@ -80,7 +81,7 @@ public static Set>> connection(String dummy) { private Map externals; public FixedInterpretationLiteralsTest() { - this.alpha = new AlphaImpl(); + this.alpha = AlphaFactory.newAlpha(); this.externals = new HashMap<>(); this.externals.putAll(Externals.scan(AspStandardLibrary.class)); this.externals.putAll(Externals.scan(FixedInterpretationLiteralsTest.class)); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java similarity index 80% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java index 0033015e6..4893a20d8 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleParser.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleParser.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; @@ -10,7 +10,7 @@ public class RuleParser { public static Rule parse(String str) { ProgramParser parser = new ProgramParserImpl(); - ASPCore2Program prog = parser.parse(str); + InputProgram prog = parser.parse(str); if (!prog.getFacts().isEmpty()) { throw new IllegalArgumentException("Expected exactly one rule and no facts!"); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java similarity index 96% rename from alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java index 9cf689a0b..46f359403 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/RuleToStringTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/RuleToStringTest.java @@ -23,7 +23,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.api.impl; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.rules.Rule; import at.ac.tuwien.kr.alpha.api.rules.heads.Head; @@ -98,7 +98,7 @@ private void constructNonGroundRuleAndCheckToString(String textualRule) { } private Rule parseSingleRule(String rule) { - ASPCore2Program program = parser.parse(rule); + InputProgram program = parser.parse(rule); List> rules = program.getRules(); assertEquals(1, rules.size(), "Number of rules"); return rules.get(0); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java similarity index 59% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java index ac7c30ec4..1a53a980f 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/programs/transformation/StratifiedEvaluationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/StratifiedEvaluationTest.java @@ -25,72 +25,57 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.programs.transformation; +package at.ac.tuwien.kr.alpha; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; + import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; +import java.util.stream.Collectors; import org.junit.jupiter.api.Test; +import at.ac.tuwien.kr.alpha.api.Alpha; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; import at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; -import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.externals.Externals; -import at.ac.tuwien.kr.alpha.commons.substitutions.Instance; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.Grounder; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderFactory; -import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram; -import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InternalProgram; import at.ac.tuwien.kr.alpha.core.programs.Programs; -import at.ac.tuwien.kr.alpha.core.solver.SolverFactory; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; -// TODO This is a functional test and should not be run with standard unit tests +// TODO This is an integration test and should be run in an extra suite public class StratifiedEvaluationTest { - private final ProgramParser parser = new ProgramParserImpl(); - private final NormalizeProgramTransformation normalizer = new NormalizeProgramTransformation(SystemConfig.DEFAULT_AGGREGATE_REWRITING_CONFIG); - private final StratifiedEvaluation evaluator = new StratifiedEvaluation(); - private final Function parseAndEvaluate = (str) -> { - return evaluator.apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parser.parse(str)))); - }; - - private final Function> solveCompiledProg = (prog) -> { - AtomStore atomStore = new AtomStoreImpl(); - Grounder grounder = GrounderFactory.getInstance("naive", prog, atomStore, false); - Solver solver = SolverFactory.getInstance(new SystemConfig(), atomStore, grounder); - return solver.collectSet(); - }; + // Alpha instance with default configuration (evolog support and stratified evaluation enabled) + private final Alpha alpha = AlphaFactory.newAlpha(); + /** + * Verifies that facts are not duplicated by stratified evaluation. + */ @Test public void testDuplicateFacts() { String aspStr = "p(a). p(b). q(b). q(X) :- p(X)."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Instance qOfB = new Instance(TestUtils.basicAtomWithSymbolicTerms("q", "b").getTerms()); - Set facts = evaluated.getFactsByPredicate().get(Predicates.getPredicate("q", 1)); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(aspStr)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + BasicAtom qOfB = Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("b")); int numQOfB = 0; - for (Instance at : facts) { - if (at.equals(qOfB)) { + for (Atom fact : evaluated.getFacts()) { + if (fact.equals(qOfB)) { numQOfB++; } } @@ -100,41 +85,38 @@ public void testDuplicateFacts() { @Test public void testEqualityWithConstantTerms() { String aspStr = "equal :- 1 = 1."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Atom equal = TestUtils.basicAtomWithSymbolicTerms("equal"); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(aspStr)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + Atom equal = Atoms.newBasicAtom(Predicates.getPredicate("equal", 0)); assertTrue(evaluated.getFacts().contains(equal)); } @Test public void testEqualityWithVarTerms() { String aspStr = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; - CompiledProgram evaluated = parseAndEvaluate.apply(aspStr); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(aspStr)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); } @Test public void testNonGroundableRule() { String asp = "p(a). q(a, b). s(X, Y) :- p(X), q(X, Y), r(Y)."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("p(a), q(a,b)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("p(a), q(a,b)", answerSets); } @Test public void testCountAggregate() { String asp = "a. b :- 1 <= #count { 1 : a }."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a, b", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a, b", answerSets); } @Test public void testIntervalFact() { String asp = "a(1..3)."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("a(1), a(2), a(3)", answerSets); } @Test @@ -143,18 +125,18 @@ public void testAggregateSpecial() { + "{ chosenThing(X) : thing(X) }.\n" + "chosenSomething :- chosenThing(X).\n" + ":- not chosenSomething.\n" + ":- chosenThing(X), chosenThing(Y), X != Y.\n" + "allThings :- 3 <= #count{ X : thing(X)}. \n" + "chosenMaxThing :- allThings, chosenThing(3).\n" + ":- not chosenMaxThing."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - assertTrue(evaluated.getFacts().contains(TestUtils.basicAtomWithSymbolicTerms("allThings"))); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("allThings, thing(1), thing(2), thing(3), chosenMaxThing, chosenSomething, chosenThing(3)", answerSets); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(asp)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("allThings", 0)))); + Set answerSets = dbgInfo.getSolver().collectSet(); + assertAnswerSetsEqual("allThings, thing(1), thing(2), thing(3), chosenMaxThing, chosenSomething, chosenThing(3)", answerSets); } @Test public void testNegatedFixedInterpretationLiteral() { String asp = "stuff(1). stuff(2). smallStuff(X) :- stuff(X), not X > 1."; - CompiledProgram evaluated = parseAndEvaluate.apply(asp); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp)).collect(Collectors.toSet()); + assertAnswerSetsEqual("stuff(1), stuff(2), smallStuff(1)", answerSets); } @SuppressWarnings("unused") @@ -168,11 +150,8 @@ public void testNegatedExternalLiteral() throws Exception { String asp = "claimedTruth(bla). truth(X) :- claimedTruth(X), &sayTrue[X]. lie(X) :- claimedTruth(X), not &sayTrue[X]."; Map externals = new HashMap<>(); externals.put("sayTrue", Externals.processPredicateMethod(this.getClass().getMethod("sayTrue", Object.class))); - ProgramParser parserWithExternals = new ProgramParserImpl(); - AnalyzedProgram analyzed = AnalyzedProgram.analyzeNormalProgram(normalizer.apply(parserWithExternals.parse(asp, externals))); - CompiledProgram evaluated = new StratifiedEvaluation().apply(analyzed); - Set answerSets = solveCompiledProg.apply(evaluated); - TestUtils.assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); + Set answerSets = alpha.solve(alpha.readProgramString(asp, externals)).collect(Collectors.toSet()); + assertAnswerSetsEqual("claimedTruth(bla), truth(bla)", answerSets); } /** @@ -181,8 +160,11 @@ public void testNegatedExternalLiteral() throws Exception { */ @Test public void testPartnerUnitsProblemTopologicalOrder() throws IOException { - ASPCore2Program prg = parser.parse(StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp")); - CompiledProgram evaluated = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prg))); + InputProgram prg = Programs.fromInputStream( + StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/pup_topological_order.asp"), + new HashMap<>()); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(prg); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); assertTrue(evaluated.getRules().isEmpty(), "Not all rules eliminated by stratified evaluation"); assertEquals(57, evaluated.getFacts().size()); } @@ -202,19 +184,25 @@ public void testNegatedLiteralInRecursiveRule() throws IOException { + "inc_value(4), inc_value(5), inc_value(6), inc_value(7), " + "inc_value(8)"; //@formatter:on - ASPCore2Program prog = Programs.fromInputStream( + InputProgram prog = Programs.fromInputStream( StratifiedEvaluationTest.class.getResourceAsStream("/partial-eval/recursive_w_negated_condition.asp"), new HashMap<>()); // Run stratified evaluation and solve - CompiledProgram inputStratEval = new StratifiedEvaluation().apply(AnalyzedProgram.analyzeNormalProgram(normalizer.apply(prog))); - Set asStrat = solveCompiledProg.apply(inputStratEval); - TestUtils.assertAnswerSetsEqual(expectedAnswerSet, asStrat); + SystemConfig cfgWithStratEval = new SystemConfig(); + cfgWithStratEval.setEvaluateStratifiedPart(true); + Alpha alphaStratEval = AlphaFactory.newAlpha(cfgWithStratEval); + DebugSolvingContext dbgWithStratEval = alphaStratEval.prepareDebugSolve(prog); + Set asStrat = dbgWithStratEval.getSolver().collectSet(); + assertAnswerSetsEqual(expectedAnswerSet, asStrat); // Solve without stratified evaluation - CompiledProgram inputNoStratEval = InternalProgram.fromNormalProgram(normalizer.apply(prog)); - Set as = solveCompiledProg.apply(inputNoStratEval); - TestUtils.assertAnswerSetsEqual(expectedAnswerSet, as); + SystemConfig cfgNoStratEval = new SystemConfig(); + cfgNoStratEval.setEvaluateStratifiedPart(false); + Alpha alphaNoStratEval = AlphaFactory.newAlpha(cfgNoStratEval); + DebugSolvingContext dbgNoStratEval = alphaNoStratEval.prepareDebugSolve(prog); + Set as = dbgNoStratEval.getSolver().collectSet(); + assertAnswerSetsEqual(expectedAnswerSet, as); } @Test @@ -246,7 +234,8 @@ public void testRecursiveRanking() { " thing_rank(Y, K),\n" + " R = K + 1."; //@formatter:on - CompiledProgram evaluated = parseAndEvaluate.apply(asp); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(alpha.readProgramString(asp)); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); Predicate rank = Predicates.getPredicate("thing_rank", 2); BasicAtom rank1 = Atoms.newBasicAtom(rank, Terms.newSymbolicConstant("a"), Terms.newConstant(1)); BasicAtom rank2 = Atoms.newBasicAtom(rank, Terms.newSymbolicConstant("b"), Terms.newConstant(2)); diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java index 9eba7a24f..96907fad6 100644 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AlphaImplTest.java @@ -60,7 +60,7 @@ import at.ac.tuwien.kr.alpha.api.config.Heuristic; import at.ac.tuwien.kr.alpha.api.config.InputConfig; import at.ac.tuwien.kr.alpha.api.config.SystemConfig; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; import at.ac.tuwien.kr.alpha.api.programs.ProgramParser; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; @@ -77,8 +77,9 @@ import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; import at.ac.tuwien.kr.alpha.core.programs.CompiledProgram; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; import at.ac.tuwien.kr.alpha.core.rules.BasicRule; +import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; // TODO This is a functional test and should not be run with standard unit tests public class AlphaImplTest { @@ -134,10 +135,10 @@ public static boolean thinger(Thingy thingy) { @Test public void withExternal() throws Exception { - Alpha alpha = new AlphaImpl(); + Alpha alpha = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isOne[1]."); inputCfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program program = alpha.readProgram(inputCfg); + InputProgram program = alpha.readProgram(inputCfg); Set actual = alpha.solve(program).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); assertEquals(expected, actual); @@ -145,11 +146,11 @@ public void withExternal() throws Exception { @Test public void addsFacts() { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Thingy a = new Thingy(); Thingy b = new Thingy(); List things = asList(a, b); - InputProgram program = InputProgram.builder().addFacts(Externals.asFacts(Thingy.class, things)).build(); + InputProgram program = InputProgramImpl.builder().addFacts(Externals.asFacts(Thingy.class, things)).build(); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("thingy").instance(a).instance(b).build())); assertEquals(expected, actual); @@ -158,7 +159,7 @@ public void addsFacts() { @Test public void withExternalTypeConflict() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("a :- &isFoo[\"adsfnfdsf\"]."); inputCfg.addPredicateMethod("isFoo", Externals.processPredicateMethod(this.getClass().getMethod("isFoo", Integer.class))); Set actual = system.solve(system.readProgram(inputCfg)).collect(Collectors.toSet()); @@ -169,10 +170,10 @@ public void withExternalTypeConflict() { @Test public void smallGraph() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). node(3). a :- &connected[1,2]."); inputCfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); - ASPCore2Program program = system.readProgram(inputCfg); + InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ a, node(1), node(2), node(3) }"); @@ -181,12 +182,12 @@ public void smallGraph() throws Exception { @Test public void filterOutput() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig inputCfg = InputConfig.forString("node(1). node(2). outgoing13(X) :- node(X), &getLargeGraphEdges(13,X)."); inputCfg.addPredicateMethod("getLargeGraphEdges", Externals.processPredicate(() -> new HashSet<>(asList(asList(Terms.newConstant(1), Terms.newConstant(2)), asList(Terms.newConstant(2), Terms.newConstant(1)), asList(Terms.newConstant(13), Terms.newConstant(1)))))); - ASPCore2Program program = system.readProgram(inputCfg); + InputProgram program = system.readProgram(inputCfg); Set actual = system.solve(program).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ node(1), node(2), outgoing13(1) }"); assertEquals(expected, actual); @@ -194,10 +195,10 @@ public void filterOutput() throws Exception { @Test public void supplier() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicate(() -> singleton(singletonList(Terms.newConstant(1))))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ node(1), a }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -211,10 +212,10 @@ public static Set>> bestNode() { @Test public void noInput() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1). a :- &bestNode(X), node(X)."); cfg.addPredicateMethod("bestNode", Externals.processPredicateMethod(this.getClass().getMethod("bestNode"))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ node(1), a }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -224,10 +225,10 @@ public void noInput() throws Exception { @Test public void smallGraphWithWrongType() { assertThrows(IllegalArgumentException.class, () -> { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &connected[\"hello\",2]."); cfg.addPredicateMethod("connected", Externals.processPredicate((Integer a, Integer b) -> (a == 1 && b == 2) || (b == 2 || b == 3))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); system.solve(prog).collect(Collectors.toSet()); }); @@ -250,10 +251,10 @@ public static Set>> coolNode(int node) { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphNoNeighbors() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("noNeighbors(2) :- not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ noNeighbors(2) }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -262,10 +263,10 @@ public void smallGraphNoNeighbors() throws Exception { @Test public void smallGraphCoolNode() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1..2). in(X) :- node(X), &coolNode[X]."); cfg.addPredicateMethod("coolNode", Externals.processPredicateMethod(this.getClass().getMethod("coolNode", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = AnswerSetsParser.parse("{ in(1), node(1), node(2) }"); @@ -274,10 +275,10 @@ public void smallGraphCoolNode() throws Exception { @Test public void smallGraphSingleNeighbor() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("node(1..3). in(1,X) :- &neighbors[1](X), node(X)."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ in(1,2), in(1,3), node(1), node(2), node(3) }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -287,10 +288,10 @@ public void smallGraphSingleNeighbor() throws Exception { @Test @Disabled("Test program is not safe (external lacking output variables). This should throw some exception.") public void smallGraphSingleNeighborNoTerm() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("success :- &neighbors[1], not &neighbors[2]."); cfg.addPredicateMethod("neighbors", Externals.processPredicateMethod(this.getClass().getMethod("neighbors", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set expected = AnswerSetsParser.parse("{ success }"); Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -307,6 +308,22 @@ public String toString() { public int compareTo(Thingy o) { return 0; } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!(o instanceof Thingy)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return 1; + } } private static class SubThingy extends Thingy { @@ -322,9 +339,9 @@ public void withExternalSubtype() throws Exception { new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true))); - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); - InputProgram prog = new InputProgram(singletonList(rule), emptyList(), new InlineDirectivesImpl()); + InputProgram prog = new InputProgramImpl(singletonList(rule), emptyList(), new InlineDirectivesImpl()); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("x").build())); @@ -333,10 +350,10 @@ public void withExternalSubtype() throws Exception { @Test public void withExternalViaAnnotation() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1]."); cfg.addPredicateMethods(Externals.scan(this.getClass())); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); @@ -359,10 +376,10 @@ public void errorDuplicateExternal() { @Test public void withNativeExternal() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isTwo[2]."); cfg.addPredicateMethod("isTwo", Externals.processPredicate((Integer t) -> t == 2)); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); Set actual = system.solve(prog).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").build())); @@ -372,10 +389,10 @@ public void withNativeExternal() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted1() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], &isOne[1]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -390,10 +407,10 @@ public void withExternalInvocationCounted1() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted2() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a. b :- &isOne[1], &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -408,10 +425,10 @@ public void withExternalInvocationCounted2() throws Exception { @Test @Disabled("External atom has state, which is not allowed. Caching of calls makes the number of invocations wrong.") public void withExternalInvocationCounted3() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); InputConfig cfg = InputConfig.forString("a :- &isOne[1], not &isOne[2]."); cfg.addPredicateMethod("isOne", Externals.processPredicateMethod(this.getClass().getMethod("isOne", int.class))); - ASPCore2Program prog = system.readProgram(cfg); + InputProgram prog = system.readProgram(cfg); int before = invocations; Set actual = system.solve(prog).collect(Collectors.toSet()); @@ -426,8 +443,8 @@ public void withExternalInvocationCounted3() throws Exception { @Test @SuppressWarnings("unchecked") public void programWithExternalStringStuff() throws IOException { - Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); + Alpha alpha = AlphaFactory.newAlpha(); + InputProgram prog = alpha.readProgram(InputConfig.forString(STRINGSTUFF_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); // Verify every result string has length 6 and contains "foo" for (AnswerSet as : answerSets) { @@ -442,8 +459,8 @@ public void programWithExternalStringStuff() throws IOException { @Test @SuppressWarnings("unchecked") public void withNegatedExternal() throws IOException { - Alpha alpha = new AlphaImpl(); - ASPCore2Program prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); + Alpha alpha = AlphaFactory.newAlpha(); + InputProgram prog = alpha.readProgram(InputConfig.forString(NEGATED_EXTERNAL_ASP)); Set answerSets = alpha.solve(prog).collect(Collectors.toSet()); assertEquals(31, answerSets.size()); // Verify every result string has length 6 and contains "foo" @@ -459,7 +476,7 @@ public void withNegatedExternal() throws IOException { @Test public void basicUsage() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(a)."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").symbolicInstance("a").build())); assertEquals(expected, actual); @@ -467,7 +484,7 @@ public void basicUsage() throws Exception { @Test public void basicUsageWithString() throws Exception { - Alpha system = new AlphaImpl(); + Alpha system = AlphaFactory.newAlpha(); Set actual = system.solve(system.readProgram(InputConfig.forString("p(\"a\")."))).collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("a").build())); assertEquals(expected, actual); @@ -479,8 +496,8 @@ public void basicUsageWithString() throws Exception { @Test public void filterTest() { String progstr = "a. b. c. d :- c. e(a, b) :- d."; - Alpha system = new AlphaImpl(); - ASPCore2Program prog = system.readProgramString(progstr); + Alpha system = AlphaFactory.newAlpha(); + InputProgram prog = system.readProgramString(progstr); Set actual = system.solve(prog, (p) -> p.equals(Predicates.getPredicate("a", 0)) || p.equals(Predicates.getPredicate("e", 2))) .collect(Collectors.toSet()); Set expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("a").predicate("e").symbolicInstance("a", "b").build())); @@ -496,8 +513,8 @@ public void disableStratifiedEvalTest() { String progstr = "p(a). q(X) :- p(X)."; SystemConfig cfg = new SystemConfig(); cfg.setEvaluateStratifiedPart(false); - AlphaImpl system = new AlphaImpl(cfg); - ASPCore2Program input = system.readProgramString(progstr); + AlphaImpl system = (AlphaImpl) AlphaFactory.newAlpha(cfg); + InputProgram input = system.readProgramString(progstr); NormalProgram normal = system.normalizeProgram(input); CompiledProgram preprocessed = system.performProgramPreprocessing(normal); assertFalse(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), @@ -512,8 +529,8 @@ public void enableStratifiedEvalTest() { // Note: This might be cleaner if the test used the debugSolve method from the interface String progstr = "p(a). q(X) :- p(X)."; SystemConfig cfg = new SystemConfig(); - AlphaImpl system = new AlphaImpl(cfg); - ASPCore2Program input = system.readProgramString(progstr); + AlphaImpl system = (AlphaImpl) AlphaFactory.newAlpha(cfg); + InputProgram input = system.readProgramString(progstr); NormalProgram normal = system.normalizeProgram(input); CompiledProgram preprocessed = system.performProgramPreprocessing(normal); assertTrue(preprocessed.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a"))), @@ -568,19 +585,18 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException * -DebugEnableInternalChecks -q -g naive -s default -sort -n 400 -i 3col-20-38.txt */ SystemConfig cfg = new SystemConfig(); - cfg.setGrounderName("naive"); cfg.setSolverName("default"); cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(1119718541727902L); - final Alpha system = new AlphaImpl(cfg); + final Alpha system = AlphaFactory.newAlpha(cfg); final Path path = Paths.get("src", "test", "resources", "PreviouslyProblematic").resolve("3col-20-38.txt"); InputConfig inputCfg = new InputConfig(); List files = new ArrayList<>(); files.add(path.toString()); inputCfg.setFiles(files); - ASPCore2Program prog = system.readProgram(inputCfg); + InputProgram prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).sorted().limit(400).collect(Collectors.toList()).isEmpty()); } @@ -588,17 +604,16 @@ public void problematicRun_3col_1119718541727902_sorted_400() throws IOException private void problematicRun(String program, long seed, int limit) throws IOException { final Path base = Paths.get("src", "test", "resources", "PreviouslyProblematic"); SystemConfig cfg = new SystemConfig(); - cfg.setGrounderName("naive"); cfg.setSolverName("default"); cfg.setNogoodStoreName("alpharoaming"); cfg.setDebugInternalChecks(true); cfg.setSeed(seed); - final Alpha system = new AlphaImpl(cfg); + final Alpha system = AlphaFactory.newAlpha(cfg); InputConfig inputCfg = new InputConfig(); List files = new ArrayList<>(); files.add(base.resolve(program).toString()); inputCfg.setFiles(files); - ASPCore2Program prog = system.readProgram(inputCfg); + InputProgram prog = system.readProgram(inputCfg); assertFalse(system.solve(prog).limit(limit).collect(Collectors.toList()).isEmpty()); } @@ -606,7 +621,7 @@ private void problematicRun(String program, long seed, int limit) throws IOExcep @Test public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOException { final ProgramParser parser = new ProgramParserImpl(); - InputProgram.Builder bld = InputProgram.builder(); + InputProgramImpl.Builder bld = InputProgramImpl.builder(); bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), StandardOpenOption.READ))); bld.accumulate(parser.parse(Files.newInputStream(Paths.get("src", "test", "resources", "HanoiTower_instances", "simple.asp"), StandardOpenOption.READ))); InputProgram parsedProgram = bld.build(); @@ -623,7 +638,7 @@ public void testLearnedUnaryNoGoodCausingOutOfOrderLiteralsConflict() throws IOE 433, 427, 442, 421, 415, 436, 409, 430, 397, 391, 424, 385, 379, 418, 373, 412, 406, 394, 388, 382, 245, 232, 208 )); - Alpha alpha = new AlphaImpl(config); + Alpha alpha = AlphaFactory.newAlpha(config); Optional answerSet = alpha.solve(parsedProgram).findFirst(); assertTrue(answerSet.isPresent()); } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AnswerSetsParser.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AnswerSetsParser.java deleted file mode 100644 index a197d62e8..000000000 --- a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/api/impl/AnswerSetsParser.java +++ /dev/null @@ -1,45 +0,0 @@ -package at.ac.tuwien.kr.alpha.api.impl; - -import java.util.Collections; -import java.util.Set; - -import org.antlr.v4.runtime.BailErrorStrategy; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; - -import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Lexer; -import at.ac.tuwien.kr.alpha.core.antlr.ASPCore2Parser; -import at.ac.tuwien.kr.alpha.core.parser.ParseTreeVisitor; - -// TODO this is duplicated from core module, need to pull out test utils into separate testsupport module -public class AnswerSetsParser { - - private static final ParseTreeVisitor VISITOR = new ParseTreeVisitor(Collections.emptyMap(), false); - - public static Set parse(String s) { - try { - return parse(CharStreams.fromString(s)); - } catch (RecognitionException | ParseCancellationException e) { - // If there were issues parsing the given string, we - // throw something that suggests that the input string - // is malformed. - throw new IllegalArgumentException("Could not parse answer sets.", e); - } - } - - public static Set parse(CharStream stream) { - final ASPCore2Parser parser = new ASPCore2Parser(new CommonTokenStream(new ASPCore2Lexer(stream))); - - // Try SLL parsing mode (faster but may terminate incorrectly). - parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - parser.removeErrorListeners(); - parser.setErrorHandler(new BailErrorStrategy()); - - return VISITOR.translate(parser.answer_sets()); - } -} diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java similarity index 76% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java index d81c3e435..f0f3508e2 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregatesTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/AggregatesTest.java @@ -23,13 +23,15 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSet; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSetsWithBase; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.ignoreTestForNaiveSolver; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.ignoreTestForSimplifiedSumAggregates; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNaiveSolver; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForSimplifiedSumAggregates; + +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.AggregateRegressionTest; /** * Tests if correct answer sets for programs containing aggregates are computed. @@ -40,68 +42,68 @@ public class AggregatesTest { private static final String LS = System.lineSeparator(); @AggregateRegressionTest - public void aggregateCountLeGroundPositive(RegressionTestConfig cfg) { + public void aggregateCountLeGroundPositive(SystemConfig cfg) { String program = "a." + LS + "b :- 1 <= #count { 1 : a }."; - assertRegressionTestAnswerSet(cfg, program, "a,b"); + assertRegressionTestAnswerSets(cfg, program, "a,b"); } @AggregateRegressionTest - public void aggregateCountEqSingleElementPositive(RegressionTestConfig cfg) { + public void aggregateCountEqSingleElementPositive(SystemConfig cfg) { String program = "thing(1..3)." + "cnt_things(N) :- N = #count{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(1), thing(2), thing(3), cnt_things(3)"); + assertRegressionTestAnswerSets(cfg, program, "thing(1), thing(2), thing(3), cnt_things(3)"); } @AggregateRegressionTest - public void aggregateCountEqEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateCountEqEmptySetPositive(SystemConfig cfg) { String program = "cnt_things(N) :- N = #count{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "cnt_things(0)"); + assertRegressionTestAnswerSets(cfg, program, "cnt_things(0)"); } @AggregateRegressionTest - public void aggregateCountLeEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateCountLeEmptySetPositive(SystemConfig cfg) { String program = "zero_leq_cnt :- 0 <= #count{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "zero_leq_cnt"); + assertRegressionTestAnswerSets(cfg, program, "zero_leq_cnt"); } @AggregateRegressionTest - public void aggregateSumEqEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateSumEqEmptySetPositive(SystemConfig cfg) { String program = "sum_things(S) :- S = #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "sum_things(0)"); + assertRegressionTestAnswerSets(cfg, program, "sum_things(0)"); } @AggregateRegressionTest - public void aggregateSumEqNegativeSum(RegressionTestConfig cfg) { + public void aggregateSumEqNegativeSum(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(-1). thing(-2). thing(-3). sum_things(S) :- S = #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(-1), thing(-2), thing(-3), sum_things(-6)"); + assertRegressionTestAnswerSets(cfg, program, "thing(-1), thing(-2), thing(-3), sum_things(-6)"); } @AggregateRegressionTest - public void aggregateSumEqMixedElementsSum(RegressionTestConfig cfg) { + public void aggregateSumEqMixedElementsSum(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(-1). thing(6). thing(-3). sum_things(S) :- S = #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(-1), thing(6), thing(-3), sum_things(2)"); + assertRegressionTestAnswerSets(cfg, program, "thing(-1), thing(6), thing(-3), sum_things(2)"); } @AggregateRegressionTest - public void aggregateSumLeEmptySetPositive(RegressionTestConfig cfg) { + public void aggregateSumLeEmptySetPositive(SystemConfig cfg) { String program = "zero_leq_sum :- 0 <= #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "zero_leq_sum"); + assertRegressionTestAnswerSets(cfg, program, "zero_leq_sum"); } @AggregateRegressionTest - public void aggregateSumLeNegativeSum(RegressionTestConfig cfg) { + public void aggregateSumLeNegativeSum(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(-3). thing(4). " + "minus_three_leq_sum :- -3 <= #sum{X : thing(X)}." + "two_gt_sum :- 2 > #sum{X : thing(X)}."; - assertRegressionTestAnswerSet(cfg, program, "thing(-3), thing(4), minus_three_leq_sum, two_gt_sum"); + assertRegressionTestAnswerSets(cfg, program, "thing(-3), thing(4), minus_three_leq_sum, two_gt_sum"); } @AggregateRegressionTest - public void aggregateSumLeNegativeElementsWithChoice(RegressionTestConfig cfg) { + public void aggregateSumLeNegativeElementsWithChoice(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "thing(3). thing(-5). thing(5). " + "{summed_up_thing(X) : thing(X)}. " @@ -119,7 +121,7 @@ public void aggregateSumLeNegativeElementsWithChoice(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountLeWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateCountLeWithChoicePositive(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -138,7 +140,7 @@ public void aggregateCountLeWithChoicePositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountEqWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateCountEqWithChoicePositive(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -157,7 +159,7 @@ public void aggregateCountEqWithChoicePositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumEqWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateSumEqWithChoicePositive(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -176,7 +178,7 @@ public void aggregateSumEqWithChoicePositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumEqOverMixedValuesWithChoicePositive(RegressionTestConfig cfg) { + public void aggregateSumEqOverMixedValuesWithChoicePositive(SystemConfig cfg) { ignoreTestForSimplifiedSumAggregates(cfg); String program = "potential_thing(-2). potential_thing(-1). potential_thing(0). potential_thing(1). " + "{ thing(N) : potential_thing(N)}." @@ -196,7 +198,7 @@ public void aggregateSumEqOverMixedValuesWithChoicePositive(RegressionTestConfig } @AggregateRegressionTest - public void aggregateSumBetweenNegative(RegressionTestConfig cfg) { + public void aggregateSumBetweenNegative(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N)}." + "two_things_chosen :- thing(N1), thing(N2), N1 != N2." @@ -215,7 +217,7 @@ public void aggregateSumBetweenNegative(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateMaxNegative(RegressionTestConfig cfg) { + public void aggregateMaxNegative(SystemConfig cfg) { String program = "potential_thing(1..4). " + "{ thing(N) : potential_thing(N) }." + "one_chosen :- thing(_)." @@ -223,12 +225,12 @@ public void aggregateMaxNegative(RegressionTestConfig cfg) { + ":- thing(N1), thing(N2), N1 != N2." + "max_chosen :- thing(X), not X < #max{M : potential_thing(M)}." + ":- not max_chosen."; - assertRegressionTestAnswerSet(cfg, program, + assertRegressionTestAnswerSets(cfg, program, "potential_thing(1), potential_thing(2), potential_thing(3), potential_thing(4), one_chosen, max_chosen, thing(4)"); } @AggregateRegressionTest - public void aggregateCountGroundNegative(RegressionTestConfig cfg) { + public void aggregateCountGroundNegative(SystemConfig cfg) { String program = "{a}." + LS + "b :- not c." + LS + "c :- 1 <= #count { 1 : a }."; @@ -236,7 +238,7 @@ public void aggregateCountGroundNegative(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountNonGroundPositive(RegressionTestConfig cfg) { + public void aggregateCountNonGroundPositive(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(3)." + LS @@ -247,7 +249,7 @@ public void aggregateCountNonGroundPositive(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountNonGroundLowerAndUpper(RegressionTestConfig cfg) { + public void aggregateCountNonGroundLowerAndUpper(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(2)." + LS @@ -261,14 +263,14 @@ public void aggregateCountNonGroundLowerAndUpper(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumGroundLower(RegressionTestConfig cfg) { + public void aggregateSumGroundLower(SystemConfig cfg) { String program = "a." + LS + "b :- 5 <= #sum { 2 : a; 3 }."; - assertRegressionTestAnswerSet(cfg, program, "a,b"); + assertRegressionTestAnswerSets(cfg, program, "a,b"); } @AggregateRegressionTest - public void aggregateSumNonGroundLowerAndUpper(RegressionTestConfig cfg) { + public void aggregateSumNonGroundLowerAndUpper(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(3)." + LS @@ -282,7 +284,7 @@ public void aggregateSumNonGroundLowerAndUpper(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumNonGroundLower(RegressionTestConfig cfg) { + public void aggregateSumNonGroundLower(SystemConfig cfg) { String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS + "min(3)." + LS @@ -294,7 +296,7 @@ public void aggregateSumNonGroundLower(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumComputed(RegressionTestConfig cfg) { + public void aggregateSumComputed(SystemConfig cfg) { ignoreTestForNaiveSolver(cfg); // Do not run this test case with the naive solver. String program = "n(1..3)." + LS + "{x(N)} :- n(N)." + LS @@ -314,7 +316,7 @@ public void aggregateSumComputed(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateCountGlobalVariable(RegressionTestConfig cfg) { + public void aggregateCountGlobalVariable(SystemConfig cfg) { String program = "box(1..2)." + LS + "in(1,1)." + LS + "in(1,2)." + LS @@ -325,7 +327,7 @@ public void aggregateCountGlobalVariable(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateSumGlobalVariable(RegressionTestConfig cfg) { + public void aggregateSumGlobalVariable(SystemConfig cfg) { String program = "box(1..2)." + LS + "item_size(I,I) :- I=1..2." + LS + "in(1,1)." + LS @@ -337,35 +339,35 @@ public void aggregateSumGlobalVariable(RegressionTestConfig cfg) { } @AggregateRegressionTest - public void aggregateRightHandTermCountGreater(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountGreater(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } > 1."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } @AggregateRegressionTest - public void aggregateRightHandTermCountEqAssigning(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountEqAssigning(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } = 2."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } @AggregateRegressionTest - public void aggregateRightHandTermCountNeqAssigning(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountNeqAssigning(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } != 1."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } @AggregateRegressionTest - public void aggregateRightHandTermCountLt(RegressionTestConfig cfg) { + public void aggregateRightHandTermCountLt(SystemConfig cfg) { String program = "p(1)." + "p(2)." + "q :- #count { N : p(N) } < 3."; - assertRegressionTestAnswerSet(cfg, program, "p(1), p(2), q"); + assertRegressionTestAnswerSets(cfg, program, "p(1), p(2), q"); } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java new file mode 100644 index 000000000..a7c5b5577 --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ArithmeticTermsTest.java @@ -0,0 +1,59 @@ +package at.ac.tuwien.kr.alpha.regressiontests; + +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; + +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; + +/** + * Tests ASP programs containing arithmetic terms at arbitrary positions. + * + * Copyright (c) 2020, the Alpha Team. + */ +// TODO This is a functional test and should not be run with standard unit tests +public class ArithmeticTermsTest { + + @RegressionTest + public void testArithmeticTermInHead(SystemConfig cfg) { + String program = "dom(1). dom(2)." + + "p(X+3) :- dom(X)."; + assertRegressionTestAnswerSets(cfg, program, "dom(1),dom(2),p(4),p(5)"); + } + + @RegressionTest + public void testArithmeticTermInRule(SystemConfig cfg) { + String program = "dom(1). dom(2)." + + "p(Y+4) :- dom(X+1), dom(X), Y=X, X=Y."; + assertRegressionTestAnswerSets(cfg, program, "dom(1),dom(2),p(5)"); + } + + @RegressionTest + public void testArithmeticTermInChoiceRule(SystemConfig cfg) { + String program = "cycle_max(4). cycle(1)." + + "{ cycle(N+1) } :- cycle(N), cycle_max(K), N testHanoiTower(1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance2(RegressionTestConfig cfg) { + public void testInstance2(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance3(RegressionTestConfig cfg) { + public void testInstance3(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testInstance4(RegressionTestConfig cfg) { + public void testInstance4(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower(4, cfg)); } @RegressionTest - public void testSimple(RegressionTestConfig cfg) { - TestUtils.ignoreTestForNaiveSolver(cfg); - TestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); + public void testSimple(SystemConfig cfg) { + ignoreTestForNaiveSolver(cfg); + ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testHanoiTower("simple", cfg)); } - private void testHanoiTower(int instance, RegressionTestConfig cfg) throws IOException { + private void testHanoiTower(int instance, SystemConfig cfg) throws IOException { testHanoiTower(String.valueOf(instance), cfg); } - private void testHanoiTower(String instance, RegressionTestConfig cfg) throws IOException { - ASPCore2Program prog = new ProgramParserImpl().parse( + private void testHanoiTower(String instance, SystemConfig cfg) throws IOException { + // TODO should be read by the Alpha instance constructed in buildSolverForRegressionTest, + // do not instantiate parsers "free-style"! + InputProgram prog = new ProgramParserImpl().parse( Paths.get("src", "test", "resources", "HanoiTower_Alpha.asp"), Paths.get("src", "test", "resources", "HanoiTower_instances", instance + ".asp")); - Solver solver = TestUtils.buildSolverForRegressionTest(prog, cfg); + Solver solver = buildSolverForRegressionTest(prog, cfg); Optional answerSet = solver.stream().findFirst(); assertTrue(answerSet.isPresent()); checkGoal(prog, answerSet.get()); @@ -116,7 +122,7 @@ private void testHanoiTower(String instance, RegressionTestConfig cfg) throws IO * for every goal/3 * fact in the input there is a corresponding on/3 atom in the output. */ - private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { + private void checkGoal(InputProgram parsedProgram, AnswerSet answerSet) { Predicate ongoal = Predicates.getPredicate("ongoal", 2); Predicate on = Predicates.getPredicate("on", 3); int steps = getSteps(parsedProgram); @@ -132,7 +138,7 @@ private void checkGoal(ASPCore2Program parsedProgram, AnswerSet answerSet) { } } - private int getSteps(ASPCore2Program parsedProgram) { + private int getSteps(InputProgram parsedProgram) { Predicate steps = Predicates.getPredicate("steps", 1); for (Atom atom : parsedProgram.getFacts()) { if (atom.getPredicate().getName().equals(steps.getName()) && atom.getPredicate().getArity() == steps.getArity()) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java similarity index 65% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java index 07839eda8..63b6ff59b 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/HeadBodyTransformationTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/HeadBodyTransformationTests.java @@ -23,8 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -38,10 +40,10 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; - +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests rule transformations described in the following research paper, and their effects on performance: * @@ -55,131 +57,131 @@ public class HeadBodyTransformationTests { @RegressionTest - public void testProgramB_N1(RegressionTestConfig cfg) { + public void testProgramB_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(1), cfg)); } @RegressionTest - public void testProgramB_Transformed_N1(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(1), cfg)); } @RegressionTest - public void testProgramA_N1(RegressionTestConfig cfg) { + public void testProgramA_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(1), cfg)); } @RegressionTest - public void testProgramA_Transformed_N1(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N1(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(1), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(1), cfg)); } @RegressionTest - public void testProgramB_N2(RegressionTestConfig cfg) { + public void testProgramB_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(2), cfg)); } @RegressionTest - public void testProgramB_Transformed_N2(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(2), cfg)); } @RegressionTest - public void testProgramA_N2(RegressionTestConfig cfg) { + public void testProgramA_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(2), cfg)); } @RegressionTest - public void testProgramA_Transformed_N2(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N2(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(2), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(2), cfg)); } @RegressionTest - public void testProgramB_N4(RegressionTestConfig cfg) { + public void testProgramB_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(4), cfg)); } @RegressionTest - public void testProgramB_Transformed_N4(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(4), cfg)); } @RegressionTest - public void testProgramA_N4(RegressionTestConfig cfg) { + public void testProgramA_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(4), cfg)); } @RegressionTest - public void testProgramA_Transformed_N4(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(4), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(4), cfg)); } @RegressionTest - public void testProgramB_N8(RegressionTestConfig cfg) { + public void testProgramB_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(8), cfg)); } @RegressionTest - public void testProgramB_Transformed_N8(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(8), cfg)); } @RegressionTest - public void testProgramA_N8(RegressionTestConfig cfg) { + public void testProgramA_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(8), cfg)); } @RegressionTest - public void testProgramA_Transformed_N8(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N8(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(8), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(8), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramB_N16(RegressionTestConfig cfg) { + public void testProgramB_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB(16), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramB_Transformed_N16(RegressionTestConfig cfg) { + public void testProgramB_Transformed_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramB_TransformationB(16), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramA_N16(RegressionTestConfig cfg) { + public void testProgramA_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA(16), cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testProgramA_Transformed_N16(RegressionTestConfig cfg) { + public void testProgramA_Transformed_N16(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(16), cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(constructProgramA_TransformationA(16), cfg)); } - private void test(ASPCore2Program program, RegressionTestConfig cfg) { - Solver solver = TestUtils.buildSolverForRegressionTest(program, cfg); + private void test(InputProgram program, SystemConfig cfg) { + Solver solver = buildSolverForRegressionTest(program, cfg); Optional answerSet = solver.stream().findFirst(); assertFalse(answerSet.isPresent()); } @@ -189,7 +191,7 @@ private void test(ASPCore2Program program, RegressionTestConfig cfg) { * * @param n */ - private ASPCore2Program constructProgramB(int n) { + private InputProgram constructProgramB(int n) { int numberOfRules = 3 * n + 1; List strRules = new ArrayList<>(numberOfRules); strRules.add("x :- not x."); @@ -203,7 +205,7 @@ private ASPCore2Program constructProgramB(int n) { * * @param n */ - private ASPCore2Program constructProgramB_TransformationB(int n) { + private InputProgram constructProgramB_TransformationB(int n) { int numberOfRules = 6 * n + 2; List strRules = new ArrayList<>(numberOfRules); strRules.add("b_notX :- not x."); @@ -218,7 +220,7 @@ private ASPCore2Program constructProgramB_TransformationB(int n) { * * @param n */ - private ASPCore2Program constructProgramA(int n) { + private InputProgram constructProgramA(int n) { int numberOfRules = 4 * n + 1; List strRules = new ArrayList<>(numberOfRules); strRules.add(createXCRule(n)); @@ -232,7 +234,7 @@ private ASPCore2Program constructProgramA(int n) { * * @param n */ - private ASPCore2Program constructProgramA_TransformationA(int n) { + private InputProgram constructProgramA_TransformationA(int n) { int numberOfRules = 7 * n + 2; List strRules = new ArrayList<>(numberOfRules); strRules.addAll(createXCRules_TransformationA(n)); @@ -241,10 +243,10 @@ private ASPCore2Program constructProgramA_TransformationA(int n) { return checkNumberOfRulesAndParse(strRules, numberOfRules); } - private ASPCore2Program checkNumberOfRulesAndParse(List strRules, int numberOfRules) { + private InputProgram checkNumberOfRulesAndParse(List strRules, int numberOfRules) { assertEquals(numberOfRules, strRules.size()); String strProgram = strRules.stream().collect(Collectors.joining(System.lineSeparator())); - ASPCore2Program parsedProgram = new ProgramParserImpl().parse(strProgram); + InputProgram parsedProgram = new ProgramParserImpl().parse(strProgram); assertEquals(numberOfRules, parsedProgram.getRules().size()); return parsedProgram; } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java similarity index 51% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java index 2d5713e14..31c67bae2 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/OmigaBenchmarksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/OmigaBenchmarksTest.java @@ -23,7 +23,12 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; + +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNaiveSolver; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.io.IOException; import java.nio.file.Files; @@ -35,80 +40,80 @@ import org.slf4j.LoggerFactory; import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.test.util.TestUtils; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using Omiga benchmark problems. * */ -// TODO This is a functional test and should not be run with standard unit tests +// TODO This is actually a performance benchmark and should not be run with standard unit tests public class OmigaBenchmarksTest { @SuppressWarnings("unused") private static final Logger LOGGER = LoggerFactory.getLogger(OmigaBenchmarksTest.class); - private static final int DEBUG_TIMEOUT_FACTOR = 15; + private static final int DEBUG_TIMEOUT_FACTOR = 20; @RegressionTest - public void test3Col_10_18(RegressionTestConfig cfg) { + public void test3Col_10_18(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-10-18.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-10-18.txt", cfg)); } @RegressionTest - public void test3Col_20_38(RegressionTestConfig cfg) { + public void test3Col_20_38(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-20-38.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("3col", "3col-20-38.txt", cfg)); } @RegressionTest - public void testCutedge_100_30(RegressionTestConfig cfg) { + public void testCutedge_100_30(SystemConfig cfg) { long timeout = 15000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-30.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-30.txt", cfg)); } @RegressionTest - public void testCutedge_100_50(RegressionTestConfig cfg) { + public void testCutedge_100_50(SystemConfig cfg) { long timeout = 15000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-50.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("cutedge", "cutedge-100-50.txt", cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testLocstrat_200(RegressionTestConfig cfg) { + public void testLocstrat_200(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-200.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-200.txt", cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testLocstrat_400(RegressionTestConfig cfg) { + public void testLocstrat_400(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-400.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("locstrat", "locstrat-400.txt", cfg)); } @RegressionTest - public void testReach_1(RegressionTestConfig cfg) { - long timeout = 15000L; - TestUtils.ignoreTestForNaiveSolver(cfg); - TestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-1.txt", cfg)); + public void testReach_1(SystemConfig cfg) { + long timeout = 20000L; + ignoreTestForNaiveSolver(cfg); + ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-1.txt", cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testReach_4(RegressionTestConfig cfg) { + public void testReach_4(SystemConfig cfg) { long timeout = 10000L; - TestUtils.runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-4.txt", cfg)); + runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test("reach", "reach-4.txt", cfg)); } - private void test(String folder, String aspFileName, RegressionTestConfig cfg) throws IOException { + private void test(String folder, String aspFileName, SystemConfig cfg) throws IOException { @SuppressWarnings("unused") - Optional answerSet = TestUtils - .buildSolverForRegressionTest( - new ProgramParserImpl().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) - .stream().findFirst(); + Optional answerSet = buildSolverForRegressionTest( + new ProgramParserImpl().parse(Files.newInputStream(Paths.get("benchmarks", "omiga", "omiga-testcases", folder, aspFileName))), cfg) + .stream().findFirst(); // System.out.println(answerSet); // TODO: check correctness of answer set } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java similarity index 84% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java index 670195ea1..d559b2971 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PartSubpartConfigurationTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PartSubpartConfigurationTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.collectRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertFalse; import java.util.ArrayList; @@ -36,6 +36,9 @@ import org.junit.jupiter.api.Disabled; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; + /** * Tests {@link AbstractSolver} using some configuration test cases in which subparts are assigned to parts. * @@ -46,61 +49,61 @@ public class PartSubpartConfigurationTest { private static final int DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN2(RegressionTestConfig cfg) { + public void testN2(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(4, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN8(RegressionTestConfig cfg) { + public void testN8(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(8, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN16(RegressionTestConfig cfg) { + public void testN16(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(16, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN32(RegressionTestConfig cfg) { + public void testN32(SystemConfig cfg) { long timeout = 61000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(32, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN60(RegressionTestConfig cfg) { + public void testN60(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(60, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN75(RegressionTestConfig cfg) { + public void testN75(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(75, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN100(RegressionTestConfig cfg) { + public void testN100(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPartSubpart(100, cfg)); } - private void testPartSubpart(int n, RegressionTestConfig cfg) { + private void testPartSubpart(int n, SystemConfig cfg) { List rules = new ArrayList<>(); for (int i = 1; i <= n; i++) { rules.add(String.format("n(%d).", i)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java similarity index 83% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java index 318452c64..73070b487 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/PigeonHoleTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/PigeonHoleTest.java @@ -23,11 +23,11 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.collectRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.ignoreTestForNonDefaultDomainIndependentHeuristics; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; @@ -38,6 +38,8 @@ import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some pigeon-hole test cases (see https://en.wikipedia.org/wiki/Pigeonhole_principle). @@ -48,49 +50,49 @@ public class PigeonHoleTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void test2Pigeons2Holes(RegressionTestConfig cfg) { + public void test2Pigeons2Holes(SystemConfig cfg) { long timeout = 5000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(2, 2, cfg)); } @RegressionTest - public void test3Pigeons2Holes(RegressionTestConfig cfg) { + public void test3Pigeons2Holes(SystemConfig cfg) { long timeout = 5000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(3, 2, cfg)); } @RegressionTest - public void test2Pigeons3Holes(RegressionTestConfig cfg) { + public void test2Pigeons3Holes(SystemConfig cfg) { long timeout = 5000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(2, 3, cfg)); } @RegressionTest - public void test3Pigeons3Holes(RegressionTestConfig cfg) { + public void test3Pigeons3Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(3, 3, cfg)); } @RegressionTest - public void test4Pigeons3Holes(RegressionTestConfig cfg) { + public void test4Pigeons3Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(4, 3, cfg)); } @RegressionTest - public void test3Pigeons4Holes(RegressionTestConfig cfg) { + public void test3Pigeons4Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(3, 4, cfg)); } @RegressionTest - public void test4Pigeons4Holes(RegressionTestConfig cfg) { + public void test4Pigeons4Holes(SystemConfig cfg) { long timeout = 10000L; ignoreTestForNonDefaultDomainIndependentHeuristics(cfg); runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(4, 4, cfg)); @@ -98,42 +100,42 @@ public void test4Pigeons4Holes(RegressionTestConfig cfg) { @RegressionTest @Disabled("disabled to save resources during CI") - public void test10Pigeons10Holes(RegressionTestConfig cfg) { + public void test10Pigeons10Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(10, 10, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test19Pigeons20Holes(RegressionTestConfig cfg) { + public void test19Pigeons20Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(19, 20, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test28Pigeons30Holes(RegressionTestConfig cfg) { + public void test28Pigeons30Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(28, 30, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test37Pigeons40Holes(RegressionTestConfig cfg) { + public void test37Pigeons40Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(37, 40, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test46Pigeons50Holes(RegressionTestConfig cfg) { + public void test46Pigeons50Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(46, 50, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void test55Pigeons60Holes(RegressionTestConfig cfg) { + public void test55Pigeons60Holes(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testPigeonsHoles(55, 60, cfg)); } @@ -141,7 +143,7 @@ public void test55Pigeons60Holes(RegressionTestConfig cfg) { /** * Tries to solve the problem of assigning P pigeons to H holes. */ - private void testPigeonsHoles(int pigeons, int holes, RegressionTestConfig cfg) { + private void testPigeonsHoles(int pigeons, int holes, SystemConfig cfg) { List rules = new ArrayList<>(); rules.add("pos(P,H) :- pigeon(P), hole(H), not negpos(P,H)."); rules.add("negpos(P,H) :- pigeon(P), hole(H), not pos(P,H)."); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java similarity index 84% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java index 4c9150ca0..6bca18e5e 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RacksTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/RacksTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.io.IOException; import java.nio.file.Paths; @@ -38,7 +38,9 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using a racks configuration problem. @@ -51,12 +53,12 @@ public class RacksTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testRacks(RegressionTestConfig cfg) { + public void testRacks(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> test(cfg)); } - private void test(RegressionTestConfig cfg) throws IOException { + private void test(SystemConfig cfg) throws IOException { CharStream programInputStream = CharStreams.fromPath( Paths.get("benchmarks", "siemens", "racks", "racks.lp")); Solver solver = buildSolverForRegressionTest(new ProgramParserImpl().parse(programInputStream), cfg); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java similarity index 78% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java index c091c53e9..b2bea6687 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverStatisticsTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverStatisticsTests.java @@ -23,9 +23,9 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -36,9 +36,12 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; import at.ac.tuwien.kr.alpha.api.StatisticsReportingSolver; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; import at.ac.tuwien.kr.alpha.core.common.AtomStore; import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithBasicProgram; +import at.ac.tuwien.kr.alpha.core.solver.DefaultSolver; +import at.ac.tuwien.kr.alpha.core.solver.NoGoodCounter; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; // TODO This is a functional test and should not be run with standard unit tests public class SolverStatisticsTests { @@ -51,32 +54,33 @@ public void setUp() { } @RegressionTest - public void checkStatsStringZeroChoices(RegressionTestConfig cfg) { + public void checkStatsStringZeroChoices(SystemConfig cfg) { Solver solver = buildSolverForRegressionTest("a.", cfg); assumeTrue(solver instanceof StatisticsReportingSolver); collectAnswerSetsAndCheckStats(solver, 1, 0, 0, 0, 0, 0, 0, 0); } @RegressionTest - public void checkStatsStringOneChoice(RegressionTestConfig cfg) { + public void checkStatsStringOneChoice(SystemConfig cfg) { Solver solver = buildSolverForRegressionTest("a :- not b. b :- not a.", cfg); assumeTrue(solver instanceof StatisticsReportingSolver); collectAnswerSetsAndCheckStats(solver, 2, 1, 1, 1, 1, 0, 0, 0); } - @RegressionTest - public void checkNoGoodCounterStatsByTypeUsingDummyGrounder(RegressionTestConfig cfg) { - Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); - assumeTrue(solver instanceof StatisticsReportingSolver); - collectAnswerSetsAndCheckNoGoodCounterStatsByType(solver, 4, 0, 0, 0); - } + // TODO Why are these tests config-dependent if they use a grounder mock and seem rather like unit tests on solver statistics? + // @RegressionTest + // public void checkNoGoodCounterStatsByTypeUsingDummyGrounder(SystemConfig cfg) { + // Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); + // assumeTrue(solver instanceof StatisticsReportingSolver); + // collectAnswerSetsAndCheckNoGoodCounterStatsByType(solver, 4, 0, 0, 0); + // } - @RegressionTest - public void checkNoGoodCounterStatsByCardinalityUsingDummyGrounder(RegressionTestConfig cfg) { - Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); - assumeTrue(solver instanceof StatisticsReportingSolver); - collectAnswerSetsAndCheckNoGoodCounterStatsByCardinality(solver, 2, 1, 1); - } + // @RegressionTest + // public void checkNoGoodCounterStatsByCardinalityUsingDummyGrounder(SystemConfig cfg) { + // Solver solver = buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg); + // assumeTrue(solver instanceof StatisticsReportingSolver); + // collectAnswerSetsAndCheckNoGoodCounterStatsByCardinality(solver, 2, 1, 1); + // } private void collectAnswerSetsAndCheckStats(Solver solver, int expectedNumberOfAnswerSets, int expectedNumberOfGuesses, int expectedTotalNumberOfBacktracks, int expectedNumberOfBacktracksWithinBackjumps, int expectedNumberOfBackjumps, int expectedNumberOfMBTs, int expectedNumberOfConflictsAfterClosing, int expectedNumberOfDeletedNoGoods) { diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java similarity index 78% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java index d7cf1ad99..b6a27ad22 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/SolverTests.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/SolverTests.java @@ -25,13 +25,12 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSet; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSets; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.assertRegressionTestAnswerSetsWithBase; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.collectRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSets; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.assertRegressionTestAnswerSetsWithBase; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.collectRegressionTestAnswerSets; import static java.util.Collections.singleton; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -44,6 +43,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.ConstantTerm; @@ -51,15 +52,12 @@ import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; -import at.ac.tuwien.kr.alpha.core.common.AtomStore; -import at.ac.tuwien.kr.alpha.core.common.AtomStoreImpl; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithChoice; -import at.ac.tuwien.kr.alpha.core.grounder.GrounderMockWithBasicProgram; import at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; -import at.ac.tuwien.kr.alpha.core.test.util.AnswerSetsParser; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; +import at.ac.tuwien.kr.alpha.test.AnswerSetsParser; -// // TODO This is a functional test and should not be run with standard unit tests +// TODO This is a functional test and should not be run with standard unit tests public class SolverTests { private static class Thingy implements Comparable { @@ -75,12 +73,12 @@ public int compareTo(Thingy o) { } @RegressionTest - public void testObjectProgram(RegressionTestConfig cfg) { + public void testObjectProgram(SystemConfig cfg) { final Thingy thingy = new Thingy(); final Atom fact = Atoms.newBasicAtom(Predicates.getPredicate("foo", 1), Terms.newConstant(thingy)); - final InputProgram program = new InputProgram( + final InputProgram program = new InputProgramImpl( Collections.emptyList(), Collections.singletonList(fact), new InlineDirectivesImpl() @@ -92,8 +90,8 @@ public void testObjectProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testFactsOnlyProgram(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testFactsOnlyProgram(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(a). p(b). foo(13). foo(16). q(a). q(c).", @@ -102,8 +100,8 @@ public void testFactsOnlyProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testSimpleRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testSimpleRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(a). p(b). r(X) :- p(X).", @@ -112,8 +110,8 @@ public void testSimpleRule(RegressionTestConfig cfg) { } @RegressionTest - public void testSimpleRuleWithGroundPart(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testSimpleRuleWithGroundPart(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p(1)." + "p(2)." + @@ -124,8 +122,8 @@ public void testSimpleRuleWithGroundPart(RegressionTestConfig cfg) { } @RegressionTest - public void testProgramZeroArityPredicates(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testProgramZeroArityPredicates(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "a. p(X) :- b, r(X).", @@ -134,7 +132,7 @@ public void testProgramZeroArityPredicates(RegressionTestConfig cfg) { } @RegressionTest - public void testChoiceGroundProgram(RegressionTestConfig cfg) { + public void testChoiceGroundProgram(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not b. b :- not a.", @@ -145,7 +143,7 @@ public void testChoiceGroundProgram(RegressionTestConfig cfg) { } @RegressionTest - public void testChoiceProgramNonGround(RegressionTestConfig cfg) { + public void testChoiceProgramNonGround(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1). dom(2). dom(3)." + @@ -166,7 +164,7 @@ public void testChoiceProgramNonGround(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgram3Way(RegressionTestConfig cfg) { + public void choiceProgram3Way(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not b, not c." + @@ -180,12 +178,12 @@ public void choiceProgram3Way(RegressionTestConfig cfg) { } @RegressionTest - public void emptyProgramYieldsEmptyAnswerSet(RegressionTestConfig cfg) { + public void emptyProgramYieldsEmptyAnswerSet(SystemConfig cfg) { assertRegressionTestAnswerSets(cfg, "", ""); } @RegressionTest - public void chooseMultipleAnswerSets(RegressionTestConfig cfg) { + public void chooseMultipleAnswerSets(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- not nota." + @@ -207,8 +205,8 @@ public void chooseMultipleAnswerSets(RegressionTestConfig cfg) { } @RegressionTest - public void builtinAtoms(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void builtinAtoms(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "dom(1). dom(2). dom(3). dom(4). dom(5)." + "p(X) :- dom(X), X = 4." + @@ -219,8 +217,8 @@ public void builtinAtoms(RegressionTestConfig cfg) { } @RegressionTest - public void builtinAtomsGroundRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void builtinAtomsGroundRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "a :- 13 != 4." + "b :- 2 != 3, 2 = 3." + @@ -232,8 +230,8 @@ public void builtinAtomsGroundRule(RegressionTestConfig cfg) { @RegressionTest - public void choiceProgramConstraintSimple(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void choiceProgramConstraintSimple(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "fact(a).\n" + "choice(either, X) :- fact(X), not choice(or, X).\n" + @@ -245,8 +243,8 @@ public void choiceProgramConstraintSimple(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraintSimple2(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void choiceProgramConstraintSimple2(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "fact(a).\n" + "desired(either).\n" + @@ -259,7 +257,7 @@ public void choiceProgramConstraintSimple2(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraint(RegressionTestConfig cfg) { + public void choiceProgramConstraint(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "eq(1,1)." + @@ -285,7 +283,7 @@ public void choiceProgramConstraint(RegressionTestConfig cfg) { } @RegressionTest - public void choiceProgramConstraintPermutation(RegressionTestConfig cfg) { + public void choiceProgramConstraintPermutation(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "eq(1,1)." + @@ -311,8 +309,8 @@ public void choiceProgramConstraintPermutation(RegressionTestConfig cfg) { } @RegressionTest - public void simpleNoPropagation(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void simpleNoPropagation(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "val(1,1)." + "val(2,2)." + @@ -323,7 +321,7 @@ public void simpleNoPropagation(RegressionTestConfig cfg) { } @RegressionTest - public void choiceAndPropagationAfterwards(RegressionTestConfig cfg) { + public void choiceAndPropagationAfterwards(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "node(a)." + @@ -342,7 +340,7 @@ public void choiceAndPropagationAfterwards(RegressionTestConfig cfg) { } @RegressionTest - public void choiceAndConstraints(RegressionTestConfig cfg) { + public void choiceAndConstraints(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "node(a)." + @@ -361,13 +359,13 @@ public void choiceAndConstraints(RegressionTestConfig cfg) { } @RegressionTest - public void testUnsatisfiableProgram(RegressionTestConfig cfg) { + public void testUnsatisfiableProgram(SystemConfig cfg) { assertRegressionTestAnswerSets(cfg, "p(a). p(b). :- p(a), p(b)."); } @RegressionTest - public void testFunctionTermEquality(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void testFunctionTermEquality(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "r1(f(a,b)). r2(f(a,b)). a :- r1(X), r2(Y), X = Y.", @@ -376,7 +374,7 @@ public void testFunctionTermEquality(RegressionTestConfig cfg) { } @RegressionTest - public void builtinInequality(RegressionTestConfig cfg) { + public void builtinInequality(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "location(a1)." + @@ -399,7 +397,7 @@ public void builtinInequality(RegressionTestConfig cfg) { } @RegressionTest - public void choiceConstraintsInequality(RegressionTestConfig cfg) { + public void choiceConstraintsInequality(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "assign(L, R) :- not nassign(L, R), possible(L, R)." + @@ -457,7 +455,7 @@ public void choiceConstraintsInequality(RegressionTestConfig cfg) { } @RegressionTest - public void sameVariableTwiceInAtom(RegressionTestConfig cfg) { + public void sameVariableTwiceInAtom(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(a, a)." + @@ -468,7 +466,7 @@ public void sameVariableTwiceInAtom(RegressionTestConfig cfg) { } @RegressionTest - public void sameVariableTwiceInAtomConstraint(RegressionTestConfig cfg) { + public void sameVariableTwiceInAtomConstraint(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(a, a)." + @@ -477,7 +475,7 @@ public void sameVariableTwiceInAtomConstraint(RegressionTestConfig cfg) { } @RegressionTest - public void noPositiveSelfFounding(RegressionTestConfig cfg) { + public void noPositiveSelfFounding(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- b." + @@ -487,7 +485,7 @@ public void noPositiveSelfFounding(RegressionTestConfig cfg) { } @RegressionTest - public void noPositiveCycleSelfFoundingChoice(RegressionTestConfig cfg) { + public void noPositiveCycleSelfFoundingChoice(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "c :- not d." + @@ -499,8 +497,8 @@ public void noPositiveCycleSelfFoundingChoice(RegressionTestConfig cfg) { } @RegressionTest - public void conflictFromUnaryNoGood(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void conflictFromUnaryNoGood(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "d(b)." + "sel(X) :- not nsel(X), d(X)." + @@ -513,7 +511,7 @@ public void conflictFromUnaryNoGood(RegressionTestConfig cfg) { } @RegressionTest - public void intervalsInFacts(RegressionTestConfig cfg) { + public void intervalsInFacts(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a." + @@ -550,7 +548,7 @@ public void intervalsInFacts(RegressionTestConfig cfg) { } @RegressionTest - public void intervalInRules(RegressionTestConfig cfg) { + public void intervalInRules(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- 3 = 1..4 ." + @@ -571,7 +569,7 @@ public void intervalInRules(RegressionTestConfig cfg) { } @RegressionTest - public void emptyIntervals(RegressionTestConfig cfg) { + public void emptyIntervals(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "p(3..1)." + @@ -582,7 +580,7 @@ public void emptyIntervals(RegressionTestConfig cfg) { } @RegressionTest - public void intervalInFunctionTermsInRules(RegressionTestConfig cfg) { + public void intervalInFunctionTermsInRules(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "a :- q(f(1..3,g(4..5)))." + @@ -607,8 +605,8 @@ public void intervalInFunctionTermsInRules(RegressionTestConfig cfg) { } @RegressionTest - public void groundAtomInRule(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void groundAtomInRule(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "p :- dom(X), q, q2." + "dom(1)." + @@ -623,7 +621,7 @@ public void groundAtomInRule(RegressionTestConfig cfg) { } @RegressionTest - public void simpleChoiceRule(RegressionTestConfig cfg) { + public void simpleChoiceRule(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "{ a; b; c} :- d." + @@ -642,7 +640,7 @@ public void simpleChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void conditionalChoiceRule(RegressionTestConfig cfg) { + public void conditionalChoiceRule(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1..3)." + @@ -666,7 +664,7 @@ public void conditionalChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void doubleChoiceRule(RegressionTestConfig cfg) { + public void doubleChoiceRule(SystemConfig cfg) { Solver solver = buildSolverForRegressionTest("{ a }. { a }.", cfg); // Make sure that no superfluous answer sets that only differ on hidden atoms occur. List actual = solver.collectList(); @@ -675,8 +673,8 @@ public void doubleChoiceRule(RegressionTestConfig cfg) { } @RegressionTest - public void simpleArithmetics(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void simpleArithmetics(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "eight(X) :- X = 4 + 5 - 1." + "three(X) :- X = Z, Y = 1..10, Z = Y / 3, Z > 2, Z < 4.", @@ -685,8 +683,8 @@ public void simpleArithmetics(RegressionTestConfig cfg) { } @RegressionTest - public void arithmeticsMultiplicationBeforeAddition(RegressionTestConfig cfg) { - assertRegressionTestAnswerSet( + public void arithmeticsMultiplicationBeforeAddition(SystemConfig cfg) { + assertRegressionTestAnswerSets( cfg, "seven(X) :- 1+2 * 3 = X.", @@ -697,7 +695,7 @@ public void arithmeticsMultiplicationBeforeAddition(RegressionTestConfig cfg) { * Tests the fix for issue #101 */ @RegressionTest - public void involvedUnsatisfiableProgram(RegressionTestConfig cfg) { + public void involvedUnsatisfiableProgram(SystemConfig cfg) { assertRegressionTestAnswerSets( cfg, "x :- c1, c2, not x." + @@ -712,7 +710,7 @@ public void involvedUnsatisfiableProgram(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationAtom(RegressionTestConfig cfg) { + public void instanceEnumerationAtom(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(1). dom(2). dom(3)." + "p(X) :- dom(X)." + @@ -729,7 +727,7 @@ public void instanceEnumerationAtom(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationArbitraryTerms(RegressionTestConfig cfg) { + public void instanceEnumerationArbitraryTerms(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(a). dom(f(a,b)). dom(d)." + "p(X) :- dom(X)." + @@ -746,7 +744,7 @@ public void instanceEnumerationArbitraryTerms(RegressionTestConfig cfg) { } @RegressionTest - public void instanceEnumerationMultipleIdentifiers(RegressionTestConfig cfg) { + public void instanceEnumerationMultipleIdentifiers(SystemConfig cfg) { Set answerSets = buildSolverForRegressionTest("# enumeration_predicate_is enum." + "dom(a). dom(b). dom(c). dom(d)." + "p(X) :- dom(X)." + @@ -784,7 +782,7 @@ private void assertEnumerationPositions(SortedSet positions, int numPositi } @RegressionTest - public void smallCardinalityAggregate(RegressionTestConfig cfg) { + public void smallCardinalityAggregate(SystemConfig cfg) { assertRegressionTestAnswerSetsWithBase( cfg, "dom(1..3)." + @@ -805,16 +803,17 @@ public void smallCardinalityAggregate(RegressionTestConfig cfg) { ); } - @RegressionTest - public void dummyGrounder(RegressionTestConfig cfg) { - AtomStore atomStore = new AtomStoreImpl(); - assertEquals(GrounderMockWithBasicProgram.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg).collectSet()); - } + // TODO @AntoniusW what are these? Can we get rid of them? If not, where do I move them? + // @RegressionTest + // public void dummyGrounder(SystemConfig cfg) { + // AtomStore atomStore = new AtomStoreImpl(); + // assertEquals(GrounderMockWithBasicProgram.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithBasicProgram(atomStore), cfg).collectSet()); + // } - @RegressionTest - public void choiceGrounder(RegressionTestConfig cfg) { - AtomStore atomStore = new AtomStoreImpl(); - assertEquals(GrounderMockWithChoice.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithChoice(atomStore), cfg).collectSet()); - } + // @RegressionTest + // public void choiceGrounder(SystemConfig cfg) { + // AtomStore atomStore = new AtomStoreImpl(); + // assertEquals(GrounderMockWithChoice.EXPECTED, buildSolverForRegressionTest(atomStore, new GrounderMockWithChoice(atomStore), cfg).collectSet()); + // } } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java new file mode 100644 index 000000000..62ba483dd --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/StratifiedEvaluationRegressionTest.java @@ -0,0 +1,293 @@ +package at.ac.tuwien.kr.alpha.regressiontests; + +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertFactsContainedInProgram; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.DebugSolvingContext; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; +import at.ac.tuwien.kr.alpha.api.programs.NormalProgram; +import at.ac.tuwien.kr.alpha.api.programs.Predicate; +import at.ac.tuwien.kr.alpha.commons.Predicates; +import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; +import at.ac.tuwien.kr.alpha.commons.terms.Terms; + +// TODO This is a functional test and should not be run with standard unit tests +public class StratifiedEvaluationRegressionTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(StratifiedEvaluationRegressionTest.class); + + //@formatter:off + private static final String STRATIFIED_NEG_ASP = "base(X) :- req(X), not incomp(X).\n" + + "depend_base(X, Y) :- base(X), base(Y).\n" + + "dep_b_hlp(X) :- depend_base(X, _).\n" + + "fallback_base(X) :- base(X), not dep_b_hlp(X).\n" + + "depend_further(X) :- depend_base(_, X).\n" + + "depend_further(X) :- fallback_base(X)."; + + private static final String BASIC_TEST_ASP = "a. b:- a."; + private static final String BASIC_MULTI_INSTANCE_ASP = "p(a). p(b). q(X) :- p(X)."; + private static final String BASIC_NEGATION_ASP = "p(a). q(b). p(c). q(d). r(c). s(X, Y) :- p(X), q(Y), not r(X)."; + private static final String PART_STRATIFIED_ASP = + "p(a). q(a). p(b). m(c). n(d).\n" + + "r(X) :- p(X), q(X).\n" + + "s(X, Y, Z) :- r(X), m(Y), n(Z).\n" + + "t(X, Y) :- p(X), q(X), p(Y), not q(Y).\n" + + "either(X) :- t(X, _), not or(X).\n" + + "or(X) :- t(X, _), not either(X)."; + private static final String POSITIVE_RECURSION_ASP = + "num(0).\n" + + "max_num(10).\n" + + "num(S) :- num(N), S = N + 1, S <= M, max_num(M)."; + private static final String EMPTY_PROG_ASP = ""; + private static final String FACTS_ONLY_ASP = "a. b. c. p(a). q(b, c). r(c, c, a). s(b)."; + private static final String STRATIFIED_NO_FACTS_ASP = STRATIFIED_NEG_ASP; + private static final String STRATIFIED_W_FACTS_ASP = "req(a). req(b). incomp(b).\n" + STRATIFIED_NEG_ASP; + private static final String EQUALITY_ASP = "equal :- 1 = 1."; + private static final String EQUALITY_WITH_VAR_ASP = "a(1). a(2). a(3). b(X) :- a(X), X = 1. c(X) :- a(X), X = 2. d(X) :- X = 3, a(X)."; + + private static final ImmutablePair, Consumer>> BASIC_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramBasic, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasic); + private static final ImmutablePair, Consumer>> BASIC_MULTI_INSTANCE_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramBasicMultiInstance, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicMultiInstance); + private static final ImmutablePair, Consumer>> BASIC_NEGATION_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramBasicNegation, StratifiedEvaluationRegressionTest::verifyAnswerSetsBasicNegation); + private static final ImmutablePair, Consumer>> PART_STRATIFIED_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramPartStratified, StratifiedEvaluationRegressionTest::verifyAnswerSetsPartStratified); + private static final ImmutablePair, Consumer>> POSITIVE_RECURSIVE_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramPositiveRecursive, StratifiedEvaluationRegressionTest::verifyAnswerSetsPositiveRecursive); + private static final ImmutablePair, Consumer>> EMPTY_PROG_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramEmptyProg, StratifiedEvaluationRegressionTest::verifyAnswerSetsEmptyProg); + private static final ImmutablePair, Consumer>> FACTS_ONLY_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramFactsOnly, StratifiedEvaluationRegressionTest::verifyAnswerSetsFactsOnly); + private static final ImmutablePair, Consumer>> STRATIFIED_NO_FACTS_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramStratNoFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratNoFacts); + private static final ImmutablePair, Consumer>> STRATIFIED_W_FACTS_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramStratWithFacts, StratifiedEvaluationRegressionTest::verifyAnswerSetsStratWithFacts); + private static final ImmutablePair, Consumer>> EQUALITY_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramEquality, StratifiedEvaluationRegressionTest::verifyAnswerSetsEquality); + private static final ImmutablePair, Consumer>> EQUALITY_WITH_VAR_VERIFIERS = new ImmutablePair<>( + StratifiedEvaluationRegressionTest::verifyProgramEqualityWithVar, StratifiedEvaluationRegressionTest::verifyAnswerSetsEqualityWithVar); + + public static List params() { + List, Consumer>>>> testCases = new ArrayList<>(); + List paramList = new ArrayList<>(); + testCases.add(new ImmutablePair<>(BASIC_TEST_ASP, BASIC_VERIFIERS)); + testCases.add(new ImmutablePair<>(BASIC_MULTI_INSTANCE_ASP, BASIC_MULTI_INSTANCE_VERIFIERS)); + testCases.add(new ImmutablePair<>(BASIC_NEGATION_ASP, BASIC_NEGATION_VERIFIERS)); + testCases.add(new ImmutablePair<>(PART_STRATIFIED_ASP, PART_STRATIFIED_VERIFIERS)); + testCases.add(new ImmutablePair<>(POSITIVE_RECURSION_ASP, POSITIVE_RECURSIVE_VERIFIERS)); + testCases.add(new ImmutablePair<>(EMPTY_PROG_ASP, EMPTY_PROG_VERIFIERS)); + testCases.add(new ImmutablePair<>(FACTS_ONLY_ASP, FACTS_ONLY_VERIFIERS)); + testCases.add(new ImmutablePair<>(STRATIFIED_NO_FACTS_ASP, STRATIFIED_NO_FACTS_VERIFIERS)); + testCases.add(new ImmutablePair<>(STRATIFIED_W_FACTS_ASP, STRATIFIED_W_FACTS_VERIFIERS)); + testCases.add(new ImmutablePair<>(EQUALITY_ASP, EQUALITY_VERIFIERS)); + testCases.add(new ImmutablePair<>(EQUALITY_WITH_VAR_ASP, EQUALITY_WITH_VAR_VERIFIERS)); + + testCases.forEach((pair) -> paramList.add(Arguments.of(pair.left, pair.right.left, pair.right.right))); + return paramList; + } + //@formatter:on + + @ParameterizedTest + @MethodSource("at.ac.tuwien.kr.alpha.regressiontests.StratifiedEvaluationRegressionTest#params") + public void runTest(String aspString, Consumer programVerifier, + Consumer> resultVerifier) { + LOGGER.debug("Testing ASP String {}", aspString); + // Parse and pre-evaluate program + // Alpha instance with default config, stratified evaluation enabled + Alpha alpha = AlphaFactory.newAlpha(); + InputProgram input = alpha.readProgramString(aspString); + DebugSolvingContext dbgInfo = alpha.prepareDebugSolve(input); + NormalProgram evaluated = dbgInfo.getPreprocessedProgram(); + // Verify stratified evaluation result + programVerifier.accept(evaluated); + // Solve remaining program + Solver solver = dbgInfo.getSolver(); + Set answerSets = solver.collectSet(); + resultVerifier.accept(answerSets); + } + + private static void verifyProgramBasic(NormalProgram evaluated) { + assertFactsContainedInProgram(evaluated, Atoms.newBasicAtom(Predicates.getPredicate("a", 0)), + Atoms.newBasicAtom(Predicates.getPredicate("b", 0))); + assertEquals(2, evaluated.getFacts().size()); + assertTrue(evaluated.getRules().size() == 0); + } + + private static void verifyAnswerSetsBasic(Set answerSets) { + assertAnswerSetsEqual("a, b", answerSets); + } + + private static void verifyProgramBasicMultiInstance(NormalProgram evaluated) { + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("b"))); + assertTrue(evaluated.getRules().size() == 0); + } + + private static void verifyAnswerSetsBasicMultiInstance(Set answerSets) { + assertAnswerSetsEqual("p(a), p(b), q(a), q(b)", answerSets); + } + + private static void verifyProgramBasicNegation(NormalProgram evaluated) { + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("s", 2), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("b")), + Atoms.newBasicAtom(Predicates.getPredicate("s", 2), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("d"))); + assertEquals(7, evaluated.getFacts().size()); + assertEquals(0, evaluated.getRules().size()); + } + + private static void verifyAnswerSetsBasicNegation(Set answerSets) { + assertAnswerSetsEqual("p(a), q(b), p(c), q(d), r(c), s(a,b), s(a,d)", answerSets); + } + + private static void verifyProgramPartStratified(NormalProgram evaluated) { + LOGGER.debug("part stratified evaluated prog is:\n{}", evaluated.toString()); + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("q", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("b")), + Atoms.newBasicAtom(Predicates.getPredicate("m", 1), Terms.newSymbolicConstant("c")), + Atoms.newBasicAtom(Predicates.getPredicate("n", 1), Terms.newSymbolicConstant("d")), + Atoms.newBasicAtom(Predicates.getPredicate("r", 1), Terms.newSymbolicConstant("a")), + Atoms.newBasicAtom(Predicates.getPredicate("s", 3), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("c"), Terms.newSymbolicConstant("d")), + Atoms.newBasicAtom(Predicates.getPredicate("t", 2), Terms.newSymbolicConstant("a"), + Terms.newSymbolicConstant("b"))); + assertEquals(2, evaluated.getRules().size()); + } + + private static void verifyAnswerSetsPartStratified(Set answerSets) { + assertAnswerSetsEqual(new String[] {"p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), either(a)", + "p(a), q(a), p(b), m(c), n(d), r(a), s(a,c,d), t(a,b), or(a)" }, answerSets); + } + + private static void verifyProgramPositiveRecursive(NormalProgram evaluated) { + Predicate num = Predicates.getPredicate("num", 1); + assertFactsContainedInProgram(evaluated, + Atoms.newBasicAtom(Predicates.getPredicate("max_num", 1), Terms.newConstant(10)), + Atoms.newBasicAtom(num, Terms.newConstant(0)), Atoms.newBasicAtom(num, Terms.newConstant(1)), + Atoms.newBasicAtom(num, Terms.newConstant(2)), Atoms.newBasicAtom(num, Terms.newConstant(3)), + Atoms.newBasicAtom(num, Terms.newConstant(4)), Atoms.newBasicAtom(num, Terms.newConstant(5)), + Atoms.newBasicAtom(num, Terms.newConstant(6)), Atoms.newBasicAtom(num, Terms.newConstant(7)), + Atoms.newBasicAtom(num, Terms.newConstant(8)), Atoms.newBasicAtom(num, Terms.newConstant(9)), + Atoms.newBasicAtom(num, Terms.newConstant(10))); + LOGGER.debug("Recursive program evaluated is:\n{}", evaluated.toString()); + assertEquals(0, evaluated.getRules().size()); + } + + private static void verifyAnswerSetsPositiveRecursive(Set answerSets) { + assertAnswerSetsEqual( + "max_num(10), num(0), num(1), num(2), num(3), num(4), num(5), num(6), num(7), num(8), num(9), num(10)", + answerSets); + } + + private static void verifyProgramEmptyProg(NormalProgram evaluated) { + assertTrue(evaluated.getRules().isEmpty()); + assertTrue(evaluated.getFacts().isEmpty()); + } + + private static void verifyAnswerSetsEmptyProg(Set answerSets) { + assertEquals(1, answerSets.size()); + assertTrue(answerSets.iterator().next().isEmpty()); + } + + private static void verifyProgramFactsOnly(NormalProgram evaluated) { + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("a", 0)))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("b", 0)))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("c", 0)))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("q", 2), + Terms.newSymbolicConstant("b"), Terms.newSymbolicConstant("c")))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("r", 3), + Terms.newSymbolicConstant("c"), Terms.newSymbolicConstant("c"), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("s", 1), Terms.newSymbolicConstant("b")))); + } + + private static void verifyAnswerSetsFactsOnly(Set answerSets) { + assertAnswerSetsEqual("a, b, c, p(a), q(b,c), r(c,c,a), s(b)", answerSets); + } + + private static void verifyProgramStratNoFacts(NormalProgram evaluated) { + assertTrue(evaluated.getFacts().isEmpty()); + } + + private static void verifyAnswerSetsStratNoFacts(Set answerSets) { + assertEquals(1, answerSets.size()); + assertTrue(answerSets.iterator().next().isEmpty()); + } + + private static void verifyProgramStratWithFacts(NormalProgram evaluated) { + // rules should all be taken care of at this point + assertTrue(evaluated.getRules().isEmpty()); + + // facts should be the full answer set + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("req", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("req", 1), Terms.newSymbolicConstant("b")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("incomp", 1), Terms.newSymbolicConstant("b")))); + + // below facts from stratified evaluation + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("base", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("depend_base", 2), + Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("dep_b_hlp", 1), Terms.newSymbolicConstant("a")))); + assertTrue(evaluated.getFacts().contains( + Atoms.newBasicAtom(Predicates.getPredicate("depend_further", 1), Terms.newSymbolicConstant("a")))); + } + + private static void verifyAnswerSetsStratWithFacts(Set answerSets) { + assertAnswerSetsEqual("req(a), req(b), incomp(b), base(a), depend_base(a,a), dep_b_hlp(a), depend_further(a)", + answerSets); + } + + private static void verifyProgramEquality(NormalProgram evaluated) { + assertEquals(0, evaluated.getRules().size()); + assertTrue(evaluated.getFacts().contains(Atoms.newBasicAtom(Predicates.getPredicate("equal", 0)))); + } + + private static void verifyAnswerSetsEquality(Set answerSets) { + assertAnswerSetsEqual("equal", answerSets); + } + + private static void verifyProgramEqualityWithVar(NormalProgram evaluated) { + assertEquals(0, evaluated.getRules().size()); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("a", 1), Terms.newConstant(1)))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("c", 1), Terms.newConstant(2)))); + assertTrue(evaluated.getFacts() + .contains(Atoms.newBasicAtom(Predicates.getPredicate("d", 1), Terms.newConstant(3)))); + } + + private static void verifyAnswerSetsEqualityWithVar(Set answerSets) { + assertAnswerSetsEqual("a(1), a(2), a(3), b(1), c(2), d(3)", answerSets); + } + +} \ No newline at end of file diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java similarity index 84% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java index 424ce245d..19bf3f7e5 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringRandomGraphTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringRandomGraphTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.List; @@ -36,14 +36,16 @@ import org.junit.jupiter.api.Disabled; import at.ac.tuwien.kr.alpha.api.AnswerSet; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; import at.ac.tuwien.kr.alpha.commons.Predicates; import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; // TODO This is a functional test and should not be run with standard unit tests public class ThreeColouringRandomGraphTest { @@ -51,62 +53,62 @@ public class ThreeColouringRandomGraphTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testV3E3(RegressionTestConfig cfg) { + public void testV3E3(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV10E18(RegressionTestConfig cfg) { + public void testV10E18(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, 18, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV20E38(RegressionTestConfig cfg) { + public void testV20E38(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(20, 38, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV30E48(RegressionTestConfig cfg) { + public void testV30E48(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(30, 48, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV200E300(RegressionTestConfig cfg) { + public void testV200E300(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(200, 300, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV300E200(RegressionTestConfig cfg) { + public void testV300E200(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(300, 200, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testV300E300(RegressionTestConfig cfg) { + public void testV300E300(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(300, 300, cfg)); } - private void testThreeColouring(int nVertices, int nEdges, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl().parse( + private void testThreeColouring(int nVertices, int nEdges, SystemConfig cfg) { + InputProgram tmpPrg = new ProgramParserImpl().parse( "blue(N) :- v(N), not red(N), not green(N)." + "red(N) :- v(N), not blue(N), not green(N)." + "green(N) :- v(N), not red(N), not blue(N)." + ":- e(N1,N2), blue(N1), blue(N2)." + ":- e(N1,N2), red(N1), red(N2)." + ":- e(N1,N2), green(N1), green(N2)."); - InputProgram.Builder prgBuilder = InputProgram.builder(tmpPrg); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(tmpPrg); prgBuilder.addFacts(createVertices(nVertices)); prgBuilder.addFacts(createEdges(nVertices, nEdges)); InputProgram program = prgBuilder.build(); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java similarity index 84% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java index 821499ce4..9f29deae8 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringTestWithRandom.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringTestWithRandom.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.Collections; @@ -38,7 +38,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -46,7 +47,8 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: @@ -61,133 +63,133 @@ public class ThreeColouringTestWithRandom { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN3(RegressionTestConfig cfg) { + public void testN3(SystemConfig cfg) { long timeout = 3000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, false, 0, cfg)); } @RegressionTest - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 4000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(4, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN5(RegressionTestConfig cfg) { + public void testN5(SystemConfig cfg) { long timeout = 5000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(5, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN6(RegressionTestConfig cfg) { + public void testN6(SystemConfig cfg) { long timeout = 6000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(6, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN7(RegressionTestConfig cfg) { + public void testN7(SystemConfig cfg) { long timeout = 7000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(7, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN8(RegressionTestConfig cfg) { + public void testN8(SystemConfig cfg) { long timeout = 8000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(8, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN9(RegressionTestConfig cfg) { + public void testN9(SystemConfig cfg) { long timeout = 9000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(9, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10(RegressionTestConfig cfg) { + public void testN10(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random0(RegressionTestConfig cfg) { + public void testN10Random0(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random1(RegressionTestConfig cfg) { + public void testN10Random1(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random2(RegressionTestConfig cfg) { + public void testN10Random2(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN10Random3(RegressionTestConfig cfg) { + public void testN10Random3(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(10, true, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19(RegressionTestConfig cfg) { + public void testN19(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, false, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random0(RegressionTestConfig cfg) { + public void testN19Random0(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 0, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random1(RegressionTestConfig cfg) { + public void testN19Random1(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 1, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random2(RegressionTestConfig cfg) { + public void testN19Random2(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 2, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN19Random3(RegressionTestConfig cfg) { + public void testN19Random3(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(19, true, 3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN101(RegressionTestConfig cfg) { + public void testN101(SystemConfig cfg) { long timeout = 10000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(101, false, 0, cfg)); } - private void testThreeColouring(int n, boolean shuffle, int seed, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl() + private void testThreeColouring(int n, boolean shuffle, int seed, SystemConfig cfg) { + InputProgram tmpPrg = new ProgramParserImpl() .parse("col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); - InputProgram.Builder prgBuilder = InputProgram.builder().accumulate(tmpPrg); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder().accumulate(tmpPrg); prgBuilder.addFacts(createColors("1", "2", "3")); prgBuilder.addFacts(createVertices(n)); prgBuilder.addFacts(createEdges(n, shuffle, seed)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java similarity index 85% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java index 989f241f3..554b6f8b5 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/ThreeColouringWheelTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/ThreeColouringWheelTest.java @@ -23,10 +23,10 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.buildSolverForRegressionTest; -import static at.ac.tuwien.kr.alpha.core.test.util.TestUtils.runWithTimeout; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.buildSolverForRegressionTest; +import static at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestUtils.runWithTimeout; import java.util.ArrayList; import java.util.List; @@ -36,7 +36,8 @@ import at.ac.tuwien.kr.alpha.api.AnswerSet; import at.ac.tuwien.kr.alpha.api.Solver; -import at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; import at.ac.tuwien.kr.alpha.api.programs.Predicate; import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom; import at.ac.tuwien.kr.alpha.api.terms.Term; @@ -44,7 +45,8 @@ import at.ac.tuwien.kr.alpha.commons.atoms.Atoms; import at.ac.tuwien.kr.alpha.commons.terms.Terms; import at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl; -import at.ac.tuwien.kr.alpha.core.programs.InputProgram; +import at.ac.tuwien.kr.alpha.core.programs.InputProgramImpl; +import at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTest; /** * Tests {@link AbstractSolver} using some three-coloring test cases, as described in: @@ -59,51 +61,51 @@ public class ThreeColouringWheelTest { private static final long DEBUG_TIMEOUT_FACTOR = 5; @RegressionTest - public void testN4(RegressionTestConfig cfg) { + public void testN4(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(4, cfg)); } @RegressionTest - public void testN5(RegressionTestConfig cfg) { + public void testN5(SystemConfig cfg) { long timeout = 1000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(5, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN6(RegressionTestConfig cfg) { + public void testN6(SystemConfig cfg) { long timeout = 6000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(6, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN3(RegressionTestConfig cfg) { + public void testN3(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(3, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN7(RegressionTestConfig cfg) { + public void testN7(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(7, cfg)); } @RegressionTest @Disabled("disabled to save resources during CI") - public void testN11(RegressionTestConfig cfg) { + public void testN11(SystemConfig cfg) { long timeout = 60000L; runWithTimeout(cfg, timeout, DEBUG_TIMEOUT_FACTOR, () -> testThreeColouring(11, cfg)); } - private void testThreeColouring(int n, RegressionTestConfig cfg) { - ASPCore2Program tmpPrg = new ProgramParserImpl().parse( + private void testThreeColouring(int n, SystemConfig cfg) { + InputProgram tmpPrg = new ProgramParserImpl().parse( "col(V,C) :- v(V), c(C), not ncol(V,C)." + "ncol(V,C) :- col(V,D), c(C), C != D." + ":- e(V,U), col(V,C), col(U,C)."); - InputProgram.Builder prgBuilder = InputProgram.builder(tmpPrg); + InputProgramImpl.Builder prgBuilder = InputProgramImpl.builder(tmpPrg); prgBuilder.addFacts(createColors("red", "blue", "green")); prgBuilder.addFacts(createVertices(n)); prgBuilder.addFacts(createEdges(n)); diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregateRegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/AggregateRegressionTest.java similarity index 71% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregateRegressionTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/AggregateRegressionTest.java index 8b12f3866..ee4b07305 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/AggregateRegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/AggregateRegressionTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests.util; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -11,7 +11,7 @@ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @ParameterizedTest -@MethodSource("at.ac.tuwien.kr.alpha.core.solver.RegressionTestConfigProvider#provideAggregateTestConfigs") +@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestConfigProvider#provideAggregateTestConfigs") public @interface AggregateRegressionTest { } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTest.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTest.java similarity index 72% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTest.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTest.java index f6f3e28a2..4b5b6f3cd 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTest.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests.util; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -11,7 +11,7 @@ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @ParameterizedTest -@MethodSource("at.ac.tuwien.kr.alpha.core.solver.RegressionTestConfigProvider#provideConfigs") +@MethodSource("at.ac.tuwien.kr.alpha.regressiontests.util.RegressionTestConfigProvider#provideConfigs") public @interface RegressionTest { - + } diff --git a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTestConfigProvider.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java similarity index 57% rename from alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTestConfigProvider.java rename to alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java index 20f139581..7a5e06633 100644 --- a/alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/solver/RegressionTestConfigProvider.java +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestConfigProvider.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.kr.alpha.core.solver; +package at.ac.tuwien.kr.alpha.regressiontests.util; import java.lang.reflect.Field; import java.util.ArrayList; @@ -7,13 +7,14 @@ import org.junit.jupiter.params.provider.Arguments; +import at.ac.tuwien.kr.alpha.api.config.AggregateRewritingConfig; import at.ac.tuwien.kr.alpha.api.config.Heuristic; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; public class RegressionTestConfigProvider { private static final String DEFAULT_SOLVER_NAME = "default"; - private static final String DEFAULT_GROUNDER_NAME = "naive"; - private static final String DEFAULT_ATOM_STORE = "alpharoaming"; + private static final String DEFAULT_NOGOOD_STORE = "alpharoaming"; private static final String DEFAULT_BRANCHING_HEURISTIC = "VSIDS"; private static final String DEFAULT_GROUNDER_TOLERANCE = "strict"; private static final boolean DEFAULT_DISABLE_INSTANCE_REMOVAL = false; @@ -27,18 +28,17 @@ public class RegressionTestConfigProvider { * * @return */ - private static List buildConfigs() { + private static List buildConfigs() { // Check whether we are running in a CI environment. boolean ci = Boolean.valueOf(System.getenv("CI")); //@formatter:off String[] solvers = ci ? new String[]{DEFAULT_SOLVER_NAME, "naive" } : new String[]{DEFAULT_SOLVER_NAME }; - String grounder = DEFAULT_GROUNDER_NAME; - String[] atomStores = ci ? new String[]{DEFAULT_ATOM_STORE, "naive" } : new String[]{DEFAULT_ATOM_STORE }; + String[] nogoodStores = ci ? new String[]{DEFAULT_NOGOOD_STORE, "naive" } : new String[]{DEFAULT_NOGOOD_STORE }; String[] heuristics = ci ? nonDeprecatedHeuristics() : new String[]{"NAIVE", DEFAULT_BRANCHING_HEURISTIC }; String[] gtcValues = new String[]{DEFAULT_GROUNDER_TOLERANCE, "permissive" }; - String gtrValue = DEFAULT_GROUNDER_TOLERANCE; - boolean[] disableInstanceRemovalValues = ci ? new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL, true } : new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL }; + String grounderToleranceRules = DEFAULT_GROUNDER_TOLERANCE; + boolean[] grounderAccumulatorValues = ci ? new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL, true } : new boolean[]{DEFAULT_DISABLE_INSTANCE_REMOVAL }; boolean[] evaluateStratifiedValues = new boolean[]{false, true }; boolean[] enableDebugChecksValues = new boolean[]{DEFAULT_ENABLE_DEBUG_CHECKS, true }; //@formatter:on @@ -52,18 +52,26 @@ private static List buildConfigs() { String seedProperty = System.getProperty("seed", ci ? "0" : ""); long seed = seedProperty.isEmpty() ? (new Random().nextLong()) : Long.valueOf(seedProperty); - List configsToTest = new ArrayList<>(); + List configsToTest = new ArrayList<>(); for (String solverName : solvers) { - for (String atomStoreName : atomStores) { + for (String nogoodStoreName : nogoodStores) { for (String branchingHeuristicName : heuristics) { - for (String grounderTolerance : gtcValues) { - for (boolean disableInstanceRemoval : disableInstanceRemovalValues) { + for (String grounderToleranceConstraints : gtcValues) { + for (boolean grounderAccumulatorEnabled : grounderAccumulatorValues) { for (boolean evaluateStratified : evaluateStratifiedValues) { for (boolean enableDebugChecks : enableDebugChecksValues) { - configsToTest.add(new RegressionTestConfig( - solverName, grounder, atomStoreName, Heuristic.valueOf(branchingHeuristicName), - seed, enableDebugChecks, grounderTolerance, gtrValue, disableInstanceRemoval, evaluateStratified, - true, true)); + SystemConfig cfg = new SystemConfig(); + cfg.setSolverName(solverName); + cfg.setNogoodStoreName(nogoodStoreName); + cfg.setBranchingHeuristicName(branchingHeuristicName); + cfg.setGrounderToleranceRules(grounderToleranceRules); + cfg.setGrounderToleranceConstraints(grounderToleranceConstraints); + cfg.setGrounderAccumulatorEnabled(grounderAccumulatorEnabled); + cfg.setEvaluateStratifiedPart(evaluateStratified); + cfg.setDebugInternalChecks(enableDebugChecks); + cfg.setSeed(seed); + + configsToTest.add(cfg); } } } @@ -82,8 +90,8 @@ private static List buildConfigs() { * * @return */ - private static List buildConfigsForAggregateTests() { - List configsToTest = new ArrayList<>(); + private static List buildConfigsForAggregateTests() { + List configsToTest = new ArrayList<>(); boolean[] evaluateStratifiedValues = new boolean[] {true, false }; boolean[] useSortingGridValues = new boolean[] {true, false }; @@ -92,12 +100,28 @@ private static List buildConfigsForAggregateTests() { for (boolean evalStratified : evaluateStratifiedValues) { for (boolean useSortingGrid : useSortingGridValues) { for (boolean supportNegativeElements : supportNegativeSumElementsValues) { - configsToTest.add( - new RegressionTestConfig( - DEFAULT_SOLVER_NAME, DEFAULT_GROUNDER_NAME, DEFAULT_ATOM_STORE, Heuristic.valueOf(DEFAULT_BRANCHING_HEURISTIC), - 0, DEFAULT_ENABLE_DEBUG_CHECKS, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_DISABLE_INSTANCE_REMOVAL, - evalStratified, - useSortingGrid, supportNegativeElements)); + // new RegressionTestConfig( + // DEFAULT_SOLVER_NAME, DEFAULT_GROUNDER_NAME, DEFAULT_NOGOOD_STORE, Heuristic.valueOf(DEFAULT_BRANCHING_HEURISTIC), + // 0, DEFAULT_ENABLE_DEBUG_CHECKS, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_GROUNDER_TOLERANCE, DEFAULT_DISABLE_INSTANCE_REMOVAL, + // evalStratified, + // useSortingGrid, supportNegativeElements)); + AggregateRewritingConfig aggCfg = new AggregateRewritingConfig(); + aggCfg.setUseSortingGridEncoding(useSortingGrid); + aggCfg.setSupportNegativeValuesInSums(supportNegativeElements); + + SystemConfig cfg = new SystemConfig(); + cfg.setSolverName(DEFAULT_SOLVER_NAME); + cfg.setNogoodStoreName(DEFAULT_NOGOOD_STORE); + cfg.setBranchingHeuristicName(DEFAULT_BRANCHING_HEURISTIC); + cfg.setSeed(0); + cfg.setDebugInternalChecks(DEFAULT_ENABLE_DEBUG_CHECKS); + cfg.setGrounderToleranceRules(DEFAULT_GROUNDER_TOLERANCE); + cfg.setGrounderToleranceConstraints(DEFAULT_GROUNDER_TOLERANCE); + cfg.setGrounderAccumulatorEnabled(DEFAULT_DISABLE_INSTANCE_REMOVAL); + cfg.setEvaluateStratifiedPart(evalStratified); + cfg.setAggregateRewritingConfig(aggCfg); + + configsToTest.add(cfg); } } } @@ -107,7 +131,7 @@ private static List buildConfigsForAggregateTests() { public static List provideConfigs() { List retVal = new ArrayList<>(); - for (RegressionTestConfig cfg : buildConfigs()) { + for (SystemConfig cfg : buildConfigs()) { retVal.add(Arguments.of(cfg)); } return retVal; @@ -115,7 +139,7 @@ public static List provideConfigs() { public static List provideAggregateTestConfigs() { List retVal = new ArrayList<>(); - for (RegressionTestConfig cfg : buildConfigsForAggregateTests()) { + for (SystemConfig cfg : buildConfigsForAggregateTests()) { retVal.add(Arguments.of(cfg)); } return retVal; @@ -130,4 +154,5 @@ private static final String[] nonDeprecatedHeuristics() { } return nonDeprecatedHeuristicsNames.toArray(new String[] {}); } + } diff --git a/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java new file mode 100644 index 000000000..82f2b88df --- /dev/null +++ b/alpha-solver/src/test/java/at/ac/tuwien/kr/alpha/regressiontests/util/RegressionTestUtils.java @@ -0,0 +1,83 @@ +package at.ac.tuwien.kr.alpha.regressiontests.util; + +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqual; +import static at.ac.tuwien.kr.alpha.test.AlphaAssertions.assertAnswerSetsEqualWithBase; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +import java.time.Duration; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.function.Executable; + +import at.ac.tuwien.kr.alpha.api.Alpha; +import at.ac.tuwien.kr.alpha.api.AnswerSet; +import at.ac.tuwien.kr.alpha.api.Solver; +import at.ac.tuwien.kr.alpha.api.config.Heuristic; +import at.ac.tuwien.kr.alpha.api.config.InputConfig; +import at.ac.tuwien.kr.alpha.api.config.SystemConfig; +import at.ac.tuwien.kr.alpha.api.impl.AlphaFactory; +import at.ac.tuwien.kr.alpha.api.programs.InputProgram; + +public final class RegressionTestUtils { + + private RegressionTestUtils() { + throw new AssertionError("Cannot instantiate utility class!"); + } + + public static void runWithTimeout(SystemConfig cfg, long baseTimeout, long timeoutFactor, Executable action) { + long timeout = cfg.isDebugInternalChecks() ? timeoutFactor * baseTimeout : baseTimeout; + assertTimeoutPreemptively(Duration.ofMillis(timeout), action); + } + + public static Solver buildSolverForRegressionTest(String programString, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + InputProgram program = alpha.readProgramString(programString); + return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); + } + + public static Solver buildSolverForRegressionTest(InputProgram program, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + return alpha.prepareSolverFor(program, InputConfig.DEFAULT_FILTER); + } + + public static Set collectRegressionTestAnswerSets(String program, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + InputProgram in = alpha.readProgramString(program); + return alpha.solve(in).collect(Collectors.toSet()); + } + + public static Set collectRegressionTestAnswerSets(InputProgram program, SystemConfig cfg) { + return AlphaFactory.newAlpha(cfg) + .solve(program) + .collect(Collectors.toSet()); + } + + private static Set solveForConfig(String programString, SystemConfig cfg) { + Alpha alpha = AlphaFactory.newAlpha(cfg); + InputProgram program = alpha.readProgramString(programString); + return alpha.solve(program).collect(Collectors.toSet()); + } + + public static void assertRegressionTestAnswerSets(SystemConfig cfg, String programString, String... expectedAnswerSets) { + assertAnswerSetsEqual(expectedAnswerSets, solveForConfig(programString, cfg)); + } + + public static void assertRegressionTestAnswerSetsWithBase(SystemConfig cfg, String programString, String base, String... expectedAnswerSets) { + assertAnswerSetsEqualWithBase(base, expectedAnswerSets, solveForConfig(programString, cfg)); + } + + public static void ignoreTestForNaiveSolver(SystemConfig cfg) { + Assumptions.assumeFalse(cfg.getSolverName().equals("naive")); + } + + public static void ignoreTestForSimplifiedSumAggregates(SystemConfig cfg) { + Assumptions.assumeTrue(cfg.getAggregateRewritingConfig().isSupportNegativeValuesInSums()); + } + + public static void ignoreTestForNonDefaultDomainIndependentHeuristics(SystemConfig cfg) { + Assumptions.assumeTrue(cfg.getBranchingHeuristic() == Heuristic.VSIDS); + } + +} diff --git a/alpha-core/src/test/resources/partial-eval/pup_topological_order.asp b/alpha-solver/src/test/resources/partial-eval/pup_topological_order.asp similarity index 100% rename from alpha-core/src/test/resources/partial-eval/pup_topological_order.asp rename to alpha-solver/src/test/resources/partial-eval/pup_topological_order.asp diff --git a/alpha-core/src/test/resources/partial-eval/recursive_w_negated_condition.asp b/alpha-solver/src/test/resources/partial-eval/recursive_w_negated_condition.asp similarity index 100% rename from alpha-core/src/test/resources/partial-eval/recursive_w_negated_condition.asp rename to alpha-solver/src/test/resources/partial-eval/recursive_w_negated_condition.asp diff --git a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts index 4f89b9542..deace0036 100644 --- a/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/alpha.java-common-conventions.gradle.kts @@ -6,6 +6,7 @@ plugins { id("jacoco") id("checkstyle") id("maven-publish") + id("java-test-fixtures") } repositories { @@ -34,6 +35,8 @@ dependencies { // Logging for tests testImplementation("org.slf4j:slf4j-simple:1.7.32") + + testFixturesApi(jupiter("api")) } // JUnit 5