Skip to content

Commit

Permalink
Merge pull request #262 from alpha-asp/answer_set_formatting
Browse files Browse the repository at this point in the history
Command Line Interface - Make separator string for atoms within printed answer set configurable
  • Loading branch information
AntoniusW committed Aug 25, 2020
2 parents b642729 + 75494af commit f1d1cd9
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 19 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dependencies {
implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1'
implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.1'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.6'
implementation group: 'org.apache.commons', name: 'commons-text', version: '1.8'
implementation group: 'org.reflections', name: 'reflections', version: '0.9.11'
implementation group: 'org.apache.poi', name: 'poi', version: '4.1.1'
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.1'
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/at/ac/tuwien/kr/alpha/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@

import at.ac.tuwien.kr.alpha.api.Alpha;
import at.ac.tuwien.kr.alpha.common.AnswerSet;
import at.ac.tuwien.kr.alpha.common.AnswerSetFormatter;
import at.ac.tuwien.kr.alpha.common.SimpleAnswerSetFormatter;
import at.ac.tuwien.kr.alpha.common.Program;
import at.ac.tuwien.kr.alpha.config.AlphaConfig;
import at.ac.tuwien.kr.alpha.config.CommandLineParser;
Expand Down Expand Up @@ -102,8 +104,9 @@ private static void computeAndConsumeAnswerSets(Alpha alpha, InputConfig inputCf
if (!alpha.getConfig().isQuiet()) {
AtomicInteger counter = new AtomicInteger(0);
final BiConsumer<Integer, AnswerSet> answerSetHandler;
final AnswerSetFormatter<String> fmt = new SimpleAnswerSetFormatter(alpha.getConfig().getAtomSeparator());
BiConsumer<Integer, AnswerSet> stdoutPrinter = (n, as) -> {
System.out.println("Answer set " + Integer.toString(n) + ":" + System.lineSeparator() + as.toString());
System.out.println("Answer set " + Integer.toString(n) + ":" + System.lineSeparator() + fmt.format(as));
};
if (inputCfg.isWriteAnswerSetsAsXlsx()) {
BiConsumer<Integer, AnswerSet> xlsxWriter = new AnswerSetToXlsxWriter(inputCfg.getAnswerSetFileOutputPath());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package at.ac.tuwien.kr.alpha.common;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.stream.Collectors;

import at.ac.tuwien.kr.alpha.common.atoms.Atom;

public class SimpleAnswerSetFormatter implements AnswerSetFormatter<String> {

private final String atomSeparator;

public SimpleAnswerSetFormatter(String atomSeparator) {
this.atomSeparator = atomSeparator;
}

@Override
public String format(AnswerSet answerSet) {
List<String> predicateInstanceStrings = new ArrayList<>();
for (Predicate p : answerSet.getPredicates()) {
SortedSet<Atom> instances;
if ((instances = answerSet.getPredicateInstances(p)) == null || instances.isEmpty()) {
predicateInstanceStrings.add(p.getName());
} else {
List<String> atomStrings = instances.stream().map((atom) -> atom.toString()).collect(Collectors.toList());
predicateInstanceStrings.add(String.join(this.atomSeparator, atomStrings));
}
}
return "{ " + String.join(this.atomSeparator, predicateInstanceStrings) + " }";
}

}
32 changes: 22 additions & 10 deletions src/main/java/at/ac/tuwien/kr/alpha/config/CommandLineParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,26 @@
*/
package at.ac.tuwien.kr.alpha.config;

import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation;
import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import at.ac.tuwien.kr.alpha.solver.BinaryNoGoodPropagationEstimation;
import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory.Heuristic;

/**
* Parses given argument lists (as passed when Alpha is called from command line) into {@link AlphaConfig}s and {@link InputConfig}s.
Expand Down Expand Up @@ -113,7 +115,7 @@ public class CommandLineParser {
.build();
private static final Option OPT_NO_NOGOOD_DELETION = Option.builder("dnd").longOpt("disableNoGoodDeletion")
.desc("disable the deletion of (learned, little active) nogoods (default: "
+ SystemConfig.DEFAULT_DISABLE_NOGOOD_DELETION + ")")
+ SystemConfig.DEFAULT_DISABLE_NOGOOD_DELETION + ")")
.build();
private static final Option OPT_GROUNDER_TOLERANCE_CONSTRAINTS = Option.builder("gtc").longOpt("grounderToleranceConstraints")
.desc("grounder tolerance for constraints (default: " + SystemConfig.DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS + ")")
Expand All @@ -125,7 +127,11 @@ public class CommandLineParser {
.build();
private static final Option OPT_GROUNDER_ACCUMULATOR_ENABLED = Option.builder("acc").longOpt("enableAccumulator")
.desc("activates the accumulator grounding strategy by disabling removal of instances from grounder memory in certain cases (default: "
+ SystemConfig.DEFAULT_GROUNDER_ACCUMULATOR_ENABLED + ")")
+ SystemConfig.DEFAULT_GROUNDER_ACCUMULATOR_ENABLED + ")")
.build();
private static final Option OPT_OUTPUT_ATOM_SEPARATOR = Option.builder("sep").longOpt("atomSeparator").hasArg(true).argName("separator")
.desc("a character (sequence) to use as separator for atoms in printed answer sets (default: "
+ SystemConfig.DEFAULT_ATOM_SEPARATOR + ")")
.build();
//@formatter:on

Expand Down Expand Up @@ -162,6 +168,7 @@ public class CommandLineParser {
CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER_TOLERANCE_CONSTRAINTS);
CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER_TOLERANCE_RULES);
CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_GROUNDER_ACCUMULATOR_ENABLED);
CommandLineParser.CLI_OPTS.addOption(CommandLineParser.OPT_OUTPUT_ATOM_SEPARATOR);
}

/*
Expand Down Expand Up @@ -208,6 +215,7 @@ public CommandLineParser(String cmdLineSyntax, Consumer<String> abortAction) {
this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER_TOLERANCE_CONSTRAINTS.getOpt(), this::handleGrounderToleranceConstraints);
this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER_TOLERANCE_RULES.getOpt(), this::handleGrounderToleranceRules);
this.globalOptionHandlers.put(CommandLineParser.OPT_GROUNDER_ACCUMULATOR_ENABLED.getOpt(), this::handleGrounderNoInstanceRemoval);
this.globalOptionHandlers.put(CommandLineParser.OPT_OUTPUT_ATOM_SEPARATOR.getOpt(), this::handleAtomSeparator);

this.inputOptionHandlers.put(CommandLineParser.OPT_NUM_ANSWER_SETS.getOpt(), this::handleNumAnswerSets);
this.inputOptionHandlers.put(CommandLineParser.OPT_INPUT.getOpt(), this::handleInput);
Expand Down Expand Up @@ -410,4 +418,8 @@ private void handleGrounderNoInstanceRemoval(Option opt, SystemConfig cfg) {
cfg.setGrounderAccumulatorEnabled(true);
}

private void handleAtomSeparator(Option opt, SystemConfig cfg) {
cfg.setAtomSeparator(StringEscapeUtils.unescapeJava(opt.getValue(SystemConfig.DEFAULT_ATOM_SEPARATOR)));
}

}
10 changes: 10 additions & 0 deletions src/main/java/at/ac/tuwien/kr/alpha/config/SystemConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class SystemConfig {
public static final String DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS = GrounderHeuristicsConfiguration.STRICT_STRING;
public static final String DEFAULT_GROUNDER_TOLERANCE_RULES = GrounderHeuristicsConfiguration.STRICT_STRING;
public static final boolean DEFAULT_GROUNDER_ACCUMULATOR_ENABLED = false;
public static final String DEFAULT_ATOM_SEPARATOR = ", ";

private String grounderName = SystemConfig.DEFAULT_GROUNDER_NAME;
private String solverName = SystemConfig.DEFAULT_SOLVER_NAME;
Expand All @@ -79,6 +80,7 @@ public class SystemConfig {
private String grounderToleranceConstraints = DEFAULT_GROUNDER_TOLERANCE_CONSTRAINTS;
private String grounderToleranceRules = DEFAULT_GROUNDER_TOLERANCE_RULES;
private boolean grounderAccumulatorEnabled = DEFAULT_GROUNDER_ACCUMULATOR_ENABLED;
private String atomSeparator = DEFAULT_ATOM_SEPARATOR;

public String getGrounderName() {
return this.grounderName;
Expand Down Expand Up @@ -235,4 +237,12 @@ public boolean isGrounderAccumulatorEnabled() {
public void setGrounderAccumulatorEnabled(boolean grounderAccumulatorEnabled) {
this.grounderAccumulatorEnabled = grounderAccumulatorEnabled;
}

public String getAtomSeparator() {
return this.atomSeparator;
}

public void setAtomSeparator(String atomSeparator) {
this.atomSeparator = atomSeparator;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package at.ac.tuwien.kr.alpha.common;

import org.junit.Assert;
import org.junit.Test;

public class AnswerSetFormatterTest {

@Test
public void basicFormatterWithSeparator() {
AnswerSetFormatter<String> fmt = new SimpleAnswerSetFormatter(" bla ");
AnswerSet as = new AnswerSetBuilder().predicate("p").instance("a").predicate("q").instance("b").build();
String formatted = fmt.format(as);
Assert.assertEquals("{ p(\"a\") bla q(\"b\") }", formatted);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void numAnswerSets() throws ParseException {
AlphaConfig ctx = parser.parseCommandLine(new String[] {"-str", "aString.", "-n", "00435"});
assertEquals(435, ctx.getInputConfig().getNumAnswerSets());
}

@Test(expected = ParseException.class)
public void noInputGiven() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
Expand All @@ -103,49 +103,56 @@ public void noInputGiven() throws ParseException {
@Test
public void replay() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-rc", "\"1,2, 3\""});
AlphaConfig alphaConfig = parser.parseCommandLine(new String[] {"-str", "aString.", "-rc", "\"1,2, 3\""});
assertEquals(Arrays.asList(1, 2, 3), alphaConfig.getAlphaConfig().getReplayChoices());
}

@Test(expected = ParseException.class)
public void replayWithNonNumericLiteral() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-rc", "\"1, 2, x\""});
parser.parseCommandLine(new String[] {"-str", "aString.", "-rc", "\"1, 2, x\""});
}

@Test
public void grounderToleranceConstraints_numeric() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtc", "-1"});
AlphaConfig alphaConfig = parser.parseCommandLine(new String[] {"-str", "aString.", "-gtc", "-1"});
assertEquals("-1", alphaConfig.getAlphaConfig().getGrounderToleranceConstraints());
}

@Test
public void grounderToleranceConstraints_string() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtc", "strict"});
AlphaConfig alphaConfig = parser.parseCommandLine(new String[] {"-str", "aString.", "-gtc", "strict"});
assertEquals("strict", alphaConfig.getAlphaConfig().getGrounderToleranceConstraints());
}

@Test
public void grounderToleranceRules_numeric() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtr", "1"});
AlphaConfig alphaConfig = parser.parseCommandLine(new String[] {"-str", "aString.", "-gtr", "1"});
assertEquals("1", alphaConfig.getAlphaConfig().getGrounderToleranceRules());
}

@Test
public void grounderToleranceRules_string() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-gtr", "permissive"});
AlphaConfig alphaConfig = parser.parseCommandLine(new String[] {"-str", "aString.", "-gtr", "permissive"});
assertEquals("permissive", alphaConfig.getAlphaConfig().getGrounderToleranceRules());
}

@Test
public void noInstanceRemoval() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig alphaConfig = parser.parseCommandLine(new String[]{"-str", "aString.", "-acc"});
AlphaConfig alphaConfig = parser.parseCommandLine(new String[] {"-str", "aString.", "-acc"});
assertTrue(alphaConfig.getAlphaConfig().isGrounderAccumulatorEnabled());
}

@Test
public void atomSeparator() throws ParseException {
CommandLineParser parser = new CommandLineParser(DEFAULT_COMMAND_LINE, DEFAULT_ABORT_ACTION);
AlphaConfig cfg = parser.parseCommandLine(new String[] {"-str", "aString.", "-sep", "some-string"});
assertEquals("some-string", cfg.getAlphaConfig().getAtomSeparator());
}

}

0 comments on commit f1d1cd9

Please sign in to comment.