Skip to content

Commit

Permalink
Merge branch 'domind_heuristics' into domind_plus_grounder_heu
Browse files Browse the repository at this point in the history
  • Loading branch information
rtaupe committed Mar 13, 2019
2 parents fede066 + 2a5e559 commit 6c7a49b
Show file tree
Hide file tree
Showing 31 changed files with 1,285 additions and 654 deletions.
237 changes: 74 additions & 163 deletions src/main/java/at/ac/tuwien/kr/alpha/Alpha.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2017-2018, the Alpha Team.
* Copyright (c) 2017-2019, the Alpha Team.
* All rights reserved.
*
* Additional changes made by Siemens.
Expand Down Expand Up @@ -31,199 +31,110 @@
import at.ac.tuwien.kr.alpha.common.AtomStore;
import at.ac.tuwien.kr.alpha.common.AtomStoreImpl;
import at.ac.tuwien.kr.alpha.common.Program;
import at.ac.tuwien.kr.alpha.common.atoms.Atom;
import at.ac.tuwien.kr.alpha.common.atoms.BasicAtom;
import at.ac.tuwien.kr.alpha.common.fixedinterpretations.*;
import at.ac.tuwien.kr.alpha.common.terms.ConstantTerm;
import at.ac.tuwien.kr.alpha.common.fixedinterpretations.PredicateInterpretation;
import at.ac.tuwien.kr.alpha.config.InputConfig;
import at.ac.tuwien.kr.alpha.config.SystemConfig;
import at.ac.tuwien.kr.alpha.grounder.Grounder;
import at.ac.tuwien.kr.alpha.grounder.GrounderFactory;
import at.ac.tuwien.kr.alpha.grounder.parser.InlineDirectives;
import at.ac.tuwien.kr.alpha.grounder.parser.ProgramParser;
import at.ac.tuwien.kr.alpha.solver.Solver;
import at.ac.tuwien.kr.alpha.solver.SolverFactory;
import at.ac.tuwien.kr.alpha.solver.heuristics.BranchingHeuristicFactory;
import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfiguration;
import at.ac.tuwien.kr.alpha.solver.heuristics.HeuristicsConfigurationBuilder;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.*;
import java.nio.charset.CodingErrorAction;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Stream;

public class Alpha {
private final Map<String, PredicateInterpretation> predicateMethods = new HashMap<>();

private final String grounderName;
private final String solverName;
private final String storeName;
private final boolean debug;
private SystemConfig config = new SystemConfig(); // config is initialized with default values

private Solver solver;

private Program program;

private long seed;

public Alpha(String grounderName, String solverName, String storeName, boolean debug) {
this.grounderName = grounderName;
this.solverName = solverName;
this.storeName = storeName;
this.debug = debug;
}

public Alpha(String grounderName, String solverName, String storeName) {
this(grounderName, solverName, storeName, false);
}

public Alpha(String grounderName, String solverName) {
this(grounderName, solverName, "alpharoaming");
}

public Alpha(String grounderName) {
this(grounderName, "default");
public Alpha(SystemConfig cfg) {
this.config = cfg;
}

public Alpha() {
this("naive");
}

public long getSeed() {
return seed;
}

public void setSeed(long seed) {
this.seed = seed;
}

public void setDeterministic() {
setSeed(0);
}

public void scan(String base) {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage(base))
.setScanners(new MethodAnnotationsScanner())
);

Set<Method> predicateMethods = reflections.getMethodsAnnotatedWith(Predicate.class);

for (Method method : predicateMethods) {
String name = method.getAnnotation(Predicate.class).name();

if (name.isEmpty()) {
name = method.getName();
}

this.register(method, name);
}
}

public void register(Method method, String name) {
if (method.getReturnType().equals(boolean.class)) {
this.predicateMethods.put(name, new MethodPredicateInterpretation(method));
return;
}

if (method.getGenericReturnType().getTypeName().startsWith(PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX)) {
this.predicateMethods.put(name, new BindingMethodPredicateInterpretation(method));
return;
}

throw new IllegalArgumentException("Passed method has unexpected return type. Should be either boolean or start with " + PredicateInterpretation.EVALUATE_RETURN_TYPE_NAME_PREFIX + ".");
}

public void register(Method method) {
register(method, method.getName());
}

public <T> void register(String name, java.util.function.Predicate<T> predicate) {
this.predicateMethods.put(name, new UnaryPredicateInterpretation<>(predicate));
}

public void register(String name, java.util.function.IntPredicate predicate) {
this.predicateMethods.put(name, new IntPredicateInterpretation(predicate));
}

public void register(String name, java.util.function.LongPredicate predicate) {
this.predicateMethods.put(name, new LongPredicateInterpretation(predicate));
}

public <T, U> void register(String name, java.util.function.BiPredicate<T, U> predicate) {
this.predicateMethods.put(name, new BinaryPredicateInterpretation<>(predicate));
}

public void register(String name, java.util.function.Supplier<Set<List<ConstantTerm<?>>>> supplier) {
this.predicateMethods.put(name, new SuppliedPredicateInterpretation(supplier));
}

public void setProgram(Program program) {
this.program = program;
}

public <T extends Comparable<T>> void addFacts(Collection<T> c, String name) {
if (c.isEmpty()) {
return;
public Program readProgram(InputConfig cfg) throws IOException {
Program retVal = new Program();
if (!cfg.getFiles().isEmpty()) {
retVal.accumulate(this.readProgramFiles(cfg.isLiterate(), cfg.getPredicateMethods(), cfg.getFiles()));
}

final List<Atom> atoms = new ArrayList<>();

for (T it : c) {
atoms.add(new BasicAtom(at.ac.tuwien.kr.alpha.common.Predicate.getInstance(name, 1), ConstantTerm.getInstance(it)));
}

final Program acc = new Program(Collections.emptyList(), atoms, new InlineDirectives());

if (this.program == null) {
this.program = acc;
} else {
this.program.accumulate(acc);
if (!cfg.getAspStrings().isEmpty()) {
retVal.accumulate(this.readProgramString(StringUtils.join(cfg.getAspStrings(), System.lineSeparator()), cfg.getPredicateMethods()));
}
}

public <T extends Comparable<T>> void addFacts(Collection<T> c) {
if (c.isEmpty()) {
return;
return retVal;
}

public Program readProgramFiles(boolean literate, Map<String, PredicateInterpretation> externals, List<String> paths) throws IOException {
ProgramParser parser = new ProgramParser(externals);
Program retVal = new Program();
for (String fileName : paths) {
CharStream stream;
if (!literate) {
stream = CharStreams.fromFileName(fileName);
} else {
stream = CharStreams.fromChannel(Util.streamToChannel(Util.literate(Files.lines(Paths.get(fileName)))), 4096, CodingErrorAction.REPLACE,
fileName);
}
retVal.accumulate(parser.parse(stream));
}
return retVal;
}

public Program readProgramString(String aspString, Map<String, PredicateInterpretation> externals) {
ProgramParser parser = new ProgramParser(externals);
return parser.parse(aspString);
}

/**
* Prepares a solver (and accompanying grounder) instance pre-loaded with the given program. Use this if the solver is needed after reading answer sets
* (e.g. for obtaining statistics)
*
* @param program the program to solve
* @return a solver (and accompanying grounder) instance pre-loaded with the given program
*/
public Solver prepareSolverFor(Program program) {
String grounderName = this.config.getGrounderName();
String solverName = this.config.getSolverName();
String nogoodStoreName = this.config.getNogoodStoreName();
long seed = this.config.getSeed();
boolean doDebugChecks = this.config.isDebugInternalChecks();
boolean disableJustificationSearch = this.config.isDisableJustificationSearch();

HeuristicsConfigurationBuilder heuristicsConfigurationBuilder = HeuristicsConfiguration.builder();
heuristicsConfigurationBuilder.setHeuristic(this.config.getBranchingHeuristic());
heuristicsConfigurationBuilder.setMomsStrategy(this.config.getMomsStrategy());

T first = c.iterator().next();
AtomStore atomStore = new AtomStoreImpl();
Grounder grounder = GrounderFactory.getInstance(grounderName, program, atomStore, doDebugChecks);

String simpleName = first.getClass().getSimpleName();
addFacts(c, simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1));
Solver solver = SolverFactory.getInstance(solverName, nogoodStoreName, atomStore, grounder, new Random(seed),
heuristicsConfigurationBuilder.build(), doDebugChecks, disableJustificationSearch);
return solver;
}

public Stream<AnswerSet> solve(Path program) throws IOException {
return solve(CharStreams.fromPath(program));
public Stream<AnswerSet> solve(Program program) {
Stream<AnswerSet> retVal = this.prepareSolverFor(program).stream();
return this.config.isSortAnswerSets() ? retVal.sorted() : retVal;
}

public Stream<AnswerSet> solve(String program) throws IOException {
return solve(CharStreams.fromString(program));
public SystemConfig getConfig() {
return this.config;
}

private Stream<AnswerSet> solve(CharStream program) throws IOException {
if (solver != null) {
// TODO: Maybe cache the result and instantly return here without throwing.
throw new IllegalStateException("This system has already been used.");
}

ProgramParser parser = new ProgramParser(predicateMethods);

setProgram(parser.parse(program));

// Obtain grounder instance and feed it with parsedProgram.
return solve();
public void setConfig(SystemConfig config) {
this.config = config;
}

public Stream<AnswerSet> solve() {
AtomStore atomStore = new AtomStoreImpl();
Grounder grounder = GrounderFactory.getInstance(grounderName, program, atomStore, debug);
HeuristicsConfiguration heuristicsConfiguration = HeuristicsConfiguration.builder().setHeuristic(BranchingHeuristicFactory.Heuristic.NAIVE).build();
Solver solver = SolverFactory.getInstance(solverName, storeName, atomStore, grounder, new Random(seed), heuristicsConfiguration, debug, false);
return solver.stream();
}
}
Loading

0 comments on commit 6c7a49b

Please sign in to comment.