Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflict generalisation #242

Draft
wants to merge 60 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5e41ba8
Add references to original nogoods to Antecedents
rtaupe Mar 20, 2020
a5c6a9b
Introduce NonGroundNoGood
rtaupe Mar 20, 2020
0cf2dbc
Generate first non-ground nogood (for head of rule)
rtaupe Mar 20, 2020
16ca3fe
Generate non-ground nogoods for static rule nogoods
rtaupe Mar 23, 2020
2d8689d
Reset rule IDs before running tests
rtaupe Mar 23, 2020
ff97640
Satisfy Checkstyle
rtaupe Mar 23, 2020
46b9883
Generate non-ground nogoods for static constraint nogoods
rtaupe Mar 23, 2020
b545c27
Remember original nogoods in binary watch list
rtaupe Mar 23, 2020
95e5914
Learn non-ground nogoods (preliminary implementation)
rtaupe Mar 23, 2020
350e7ab
Include variables in non-ground rule atom
rtaupe Mar 24, 2020
674aa8f
Fix: do not try to find atom in conflict reason
rtaupe Mar 24, 2020
e628068
Do not add the same original nogood twice to binary watch list
rtaupe Mar 25, 2020
e84056f
Remove faulty code from conflict generalisation
rtaupe Mar 25, 2020
2f20021
Skeleton for separate conflict analysis method
rtaupe Mar 25, 2020
d7c1b25
Remove conflict generalisation code from #analyzeTrailBased
rtaupe Mar 25, 2020
21de49b
Merge branch 'master' into conflict_generalisation
rtaupe Mar 25, 2020
ecd6bd4
Extract ConflictAnalysisResult to separate file
rtaupe Mar 25, 2020
d19f95a
Re-implement CDNL without 1UIP
rtaupe Mar 25, 2020
5c628ea
Learn nogoods on all UIPs
rtaupe Mar 25, 2020
bc1957e
Use underlying ground learner in non-ground learner
rtaupe Mar 25, 2020
a37eceb
Fix re-implementation of 1UIP learning by using trail walker
rtaupe Mar 27, 2020
af1160e
If current DL = 0, learn nothing and return UNSAT
rtaupe Mar 27, 2020
0cb9bcc
1UIP learning: consider sophisticated techniques to prove UNSAT
rtaupe Mar 31, 2020
0cfa69c
Make variable names unique in nogoods before resolution
rtaupe Apr 1, 2020
e838da0
Move substitution stuff from grounder to common
rtaupe Apr 1, 2020
4de090c
Fix visibility of Substitution constructor and method
rtaupe Apr 1, 2020
5c24ad9
Implement explanation-based learning of non-ground constraints
rtaupe Apr 3, 2020
498a008
Substitution: left constant / right variable is unsupported
rtaupe Apr 7, 2020
19d1fec
Fix get...Variables in BodyRepresentingLiteral
rtaupe Apr 7, 2020
59b1f18
Logging: output learned non-ground nogoods
rtaupe Apr 7, 2020
7890cb7
Output learned non-ground nogoods with counters
rtaupe Apr 7, 2020
1c1dd68
GroundAndNonGroundNoGood#toString
rtaupe Apr 7, 2020
dc663bc
Fix unification of conflicting atoms during non-ground resolution
rtaupe Apr 7, 2020
ae2cfc3
Satisfy Checkstyle
rtaupe Apr 8, 2020
2c33c21
Apply conflict unifier to whole non-ground nogood
rtaupe Apr 8, 2020
b4cdc6b
Implement NonGroundNoGood#equals() and hashCode() and compareTo
rtaupe Apr 8, 2020
b27e283
Enable more kinds of unifiers
rtaupe Apr 9, 2020
edc03ca
stop conflict generalisation after 1000 conflicts
rtaupe Apr 17, 2020
1a5660f
Move SubsitutionTest to common package
rtaupe Apr 22, 2020
b3484a0
Move SubsitutionTest to common package
rtaupe Apr 22, 2020
87adc46
Merge branch 'move_substitution_test' into conflict_generalisation
rtaupe Apr 22, 2020
fafecf1
move method parseTerm from Substitution to ProgramPartParser
rtaupe Apr 22, 2020
80b0cf1
use ProgramPartParser to construct literals for unit tests
rtaupe Apr 22, 2020
06d8199
Merge branch 'program_part_parser' into conflict_generalisation
rtaupe Apr 22, 2020
d61a4a6
Fix: ProgramPartParser must accept variables
rtaupe Apr 23, 2020
7ae49ea
Merge branch 'program_part_parser' into conflict_generalisation
rtaupe Apr 23, 2020
9c47b90
Throw exception if variable name is invalid
rtaupe Apr 23, 2020
18c50ba
Merge branch 'forbid_lowercase_variable_terms' into conflict_generali…
rtaupe Apr 23, 2020
6934d80
Do not learn multiple equivalent non-ground nogoods
rtaupe Apr 23, 2020
a877134
Output most effective learned non-ground nogoods as constraints
rtaupe Apr 23, 2020
2e89d91
Simplify variable names in learned nogoods
rtaupe Apr 23, 2020
276b8d5
Further simplify variable names in learned nogoods
rtaupe Apr 23, 2020
fa045d0
Do not attempt to print violated nogoods if there are none
rtaupe May 3, 2020
ef7a796
Satisfy CheckStyle
rtaupe Jul 12, 2020
d84305a
Log all learned non-ground nogoods if ...
rtaupe Jul 13, 2020
5a5f6a2
Learn non-ground nogood from non-UIP
rtaupe Jul 15, 2020
cf8a47f
Output all learned constraints ordered by number of violations
rtaupe Jul 15, 2020
d56eea4
Fix bug in NonGroundNoGood#simplifyVariableNames
rtaupe Jul 22, 2020
f5e8824
use also literals assigned at DL below current DL for resolution
rtaupe Jul 22, 2020
aa79539
Satisfy CheckStyle
rtaupe Sep 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions src/main/java/at/ac/tuwien/kr/alpha/Util.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016, the Alpha Team.
/*
* Copyright (c) 2016-2020, the Alpha Team.
* All rights reserved.
*
* Additional changes made by Siemens.
Expand Down Expand Up @@ -33,8 +33,13 @@
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringJoiner;
import java.util.stream.Collector;
Expand All @@ -52,6 +57,13 @@ public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
}

public static <K, V extends Integer> K getKeyWithMaximumValue(Map<K, V> map) {
if (map.isEmpty()) {
return null;
}
return Collections.max(map.entrySet(), Comparator.comparingInt(Map.Entry::getValue)).getKey();
}

public static <E> String join(String prefix, Iterable<E> iterable, String suffix) {
return join(prefix, iterable, ", ", suffix);
}
Expand Down Expand Up @@ -117,4 +129,22 @@ public static int arrayGrowthSize(int oldSize) {
// Growth factor is 1.5.
return oldSize + (oldSize >> 1);
}

public static Set<Integer> intArrayToLinkedHashSet(int[] array) {
final Set<Integer> set = new LinkedHashSet<>(array.length);
for (int element : array) {
set.add(element);
}
return set;
}

public static int[] collectionToIntArray(Collection<? extends Integer> collection) {
final int[] array = new int[collection.size()];
int i = 0;
for (Integer element : collection) {
array[i++] = element;
}
return array;
}

}
2 changes: 1 addition & 1 deletion src/main/java/at/ac/tuwien/kr/alpha/common/AtomStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ default String literalToString(int literal) {
* @param noGood the nogood to translate
* @return the string representation of the NoGood.
*/
default <T extends NoGoodInterface> String noGoodToString(T noGood) {
default <T extends NoGoodInterface<Integer>> String noGoodToString(T noGood) {
StringBuilder sb = new StringBuilder();

if (noGood.hasHead()) {
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/at/ac/tuwien/kr/alpha/common/Literals.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016-2019, the Alpha Team.
/*
* Copyright (c) 2016-2020, the Alpha Team.
* All rights reserved.
*
* Additional changes made by Siemens.
Expand Down Expand Up @@ -80,4 +80,19 @@ public static int positiveLiteral(int literal) {
public static String literalToString(int literal) {
return (isPositive(literal) ? "+" : "-") + atomOf(literal);
}

/**
* Returns the index of the first position at which a literal of the given atom occurs in the given array of literals.
* @param atom the atom to look for
* @param literals an array of literals
* @return the first index where the atom occurs, or -1 if it does not occur
*/
public static int findAtomInLiterals(int atom, int[] literals) {
for (int i = 0; i < literals.length; i++) {
if (atomOf(literals[i]) == atom) {
return i;
}
}
return -1;
}
}
63 changes: 45 additions & 18 deletions src/main/java/at/ac/tuwien/kr/alpha/common/NoGood.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,36 @@
import java.util.stream.IntStream;

import static at.ac.tuwien.kr.alpha.Util.oops;
import static at.ac.tuwien.kr.alpha.common.Literals.*;
import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.*;

public class NoGood implements NoGoodInterface, Comparable<NoGood> {
public static final int HEAD = 0;
import static at.ac.tuwien.kr.alpha.common.Literals.atomOf;
import static at.ac.tuwien.kr.alpha.common.Literals.isNegated;
import static at.ac.tuwien.kr.alpha.common.Literals.isPositive;
import static at.ac.tuwien.kr.alpha.common.Literals.negateLiteral;
import static at.ac.tuwien.kr.alpha.common.Literals.positiveLiteral;
import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.INTERNAL;
import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.LEARNT;
import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.STATIC;
import static at.ac.tuwien.kr.alpha.common.NoGoodInterface.Type.SUPPORT;

public class NoGood implements NoGoodInterface<Integer>, Comparable<NoGood> {
public static final NoGood UNSAT = new NoGood();

protected final int[] literals;
private final boolean head;
private final Type type;
private NonGroundNoGood nonGroundNoGood;

public NoGood(int... literals) {
this(STATIC, literals, false);
}

public NoGood(Type type, int... literals) {
this(type, literals, false);
}

private NoGood(Type type, int[] literals, boolean head) {
this.type = type;
this.head = head;
if (head && !isNegated(literals[0])) {
if (head && !isNegated(literals[HEAD])) {
throw oops("Head is not negative");
}

Expand All @@ -80,8 +87,9 @@ protected NoGood(NoGood noGood) {
this.literals = noGood.literals.clone();
this.head = noGood.head;
this.type = noGood.type;
this.nonGroundNoGood = noGood.nonGroundNoGood;
}

public static NoGood learnt(int... literals) {
return new NoGood(LEARNT, literals);
}
Expand All @@ -93,7 +101,7 @@ public static NoGood headFirst(int... literals) {
public static NoGood headFirstInternal(int... literals) {
return headFirst(INTERNAL, literals);
}

public static NoGood headFirst(Type type, int... literals) {
return new NoGood(type, literals, true);
}
Expand All @@ -109,11 +117,11 @@ public static NoGood support(int headLiteral, int bodyRepresentingLiteral) {
public static NoGood fromConstraint(List<Integer> posLiterals, List<Integer> negLiterals) {
return new NoGood(addPosNeg(new int[posLiterals.size() + negLiterals.size()], posLiterals, negLiterals, 0));
}

public static NoGood fromBody(List<Integer> posLiterals, List<Integer> negLiterals, int bodyRepresentingLiteral) {
return fromBody(STATIC, posLiterals, negLiterals, bodyRepresentingLiteral);
}

public static NoGood fromBodyInternal(List<Integer> posLiterals, List<Integer> negLiterals, int bodyRepresentingLiteral) {
return fromBody(INTERNAL, posLiterals, negLiterals, bodyRepresentingLiteral);
}
Expand Down Expand Up @@ -144,6 +152,8 @@ public int size() {
public Antecedent asAntecedent() {
return new Antecedent() {

private final NoGood originalNoGood = NoGood.this;

@Override
public int[] getReasonLiterals() {
return NoGood.this.literals; // Beware: returned array must not be modified!
Expand All @@ -156,6 +166,11 @@ public void bumpActivity() {
@Override
public void decreaseActivity() {
}

@Override
public NoGood getOriginalNoGood() {
return originalNoGood;
}
};
}

Expand All @@ -171,7 +186,7 @@ public int getPositiveLiteral(int index) {
}

@Override
public int getLiteral(int index) {
public Integer getLiteral(int index) {
return literals[index];
}

Expand All @@ -180,16 +195,19 @@ public boolean hasHead() {
return head;
}

@Override
public int getHead() {
return getLiteral(HEAD);
}

@Override
public Type getType() {
return type;
}

public NonGroundNoGood getNonGroundNoGood() {
return nonGroundNoGood;
}

public void setNonGroundNoGood(NonGroundNoGood nonGroundNoGood) {
this.nonGroundNoGood = nonGroundNoGood;
}

@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
Expand All @@ -211,6 +229,15 @@ public IntStream stream() {
return Arrays.stream(literals);
}

public int indexOf(int literal) {
for (int i = 0; i < literals.length; i++) {
if (literals[i] == literal) {
return i;
}
}
return -1;
}

@Override
public int compareTo(NoGood o) {
if (o == null) {
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/at/ac/tuwien/kr/alpha/common/NoGoodInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@

import at.ac.tuwien.kr.alpha.solver.Antecedent;

public interface NoGoodInterface extends Iterable<Integer> {
public interface NoGoodInterface<T> extends Iterable<T> {

int HEAD = 0;

/**
* Returns the literal at the given index.
* @param index the index position within the NoGood.
* @return the literal at the index.
*/
int getLiteral(int index);
T getLiteral(int index);

/**
* Returns whether the NoGood has a head.
Expand All @@ -46,9 +48,11 @@ public interface NoGoodInterface extends Iterable<Integer> {

/**
* Returns the head literal of the NoGood, if present.
* @return the head literal if the NoGood has a head, otherwise an arbitrary integer.
* @return the head literal if the NoGood has a head, otherwise an arbitrary literal.
*/
int getHead();
default T getHead() {
return getLiteral(HEAD);
}

/**
* Returns the size, i.e., number of literals, in the NoGood.
Expand Down
Loading