Commit a3e2a780 authored by Sarah Grebing's avatar Sarah Grebing

Bugfix and modified testcases

parent 1b7640ff
Pipeline #20382 failed with stages
in 3 minutes and 7 seconds
package edu.kit.iti.formal.psdbg.interpreter.matcher;
import java.util.*;
@Deprecated
public class EmptyMatch implements Matchings {
public static EmptyMatch INSTANCE = new EmptyMatch();
// public static Matching EMPTY_MATCH_INSTANCE = new Matching();
private EmptyMatch() {
}
@Override
public boolean isNoMatch() {
return false;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public void add(String binder, MatchPath term) {
//throw new IllegalStateException();
}
@Override
public void add(Match singleton) {
throw new IllegalStateException();
}
@Override
public void addAll(Collection<Match> matchings) {
throw new IllegalStateException();
}
@Override
public Collection<Match> getMatchings() {
ArrayList<Match> l = new ArrayList<Match>();
l.add(new Match());
return l;
}
@Override
public Matchings reduceConform(Matchings other) {
return other;
}
@Override
public String toString() {
return "{{}}";
}
}
......@@ -178,7 +178,7 @@ public class KeYMatcher implements MatcherApi<KeyData> {
LOGGER.debug("currentState has no match= " + currentState.getData().getNode().sequent());
return Collections.emptyList();
} else {
Map<String, MatchPath> firstMatch = m.first();
Match firstMatch = m.getMatchings().iterator().next() ;
VariableAssignment va = new VariableAssignment(null);
for (String s : firstMatch.keySet()) {
MatchPath matchPath = firstMatch.get(s);
......
package edu.kit.iti.formal.psdbg.interpreter.matcher;
import java.util.TreeMap;
public class Match extends TreeMap<String, MatchPath> {
public Match() {
}
public Match(Match h1) {
super(h1);
}
public static Match singleton(String binder, MatchPath path) {
Match m = new Match();
m.put(binder, path);
return m;
}
public static Match empty() {
Match m = new Match();
return m;
}
}
......@@ -4,90 +4,19 @@ import com.google.common.collect.Sets;
import java.util.*;
public class Matchings extends TreeSet<Map<String, MatchPath>> {
public Matchings() {
super(new VariableAssignmentComparator());
}
public Matchings(TreeMap<String, MatchPath> m) {
this();
add(m);
}
public interface Matchings {
public boolean isNoMatch();
public boolean isEmpty();
public static Matchings singleton(String name, MatchPath term) {
Matchings matchings = new Matchings();
Map<String, MatchPath> va = new TreeMap<>();
va.put(name, term);
matchings.add(va);
return matchings;
}
public void add(String binder, MatchPath term);
public void add(Match singleton);
public void addAll(Collection<Match> matchings);
}
public Collection<Match> getMatchings();
class VariableAssignmentComparator implements Comparator<Map<String, MatchPath>> {
/**
* <ol>
* <li>both maps contains the same keys</li>
* <li>foreach key in lexi-order, the depth has to be greater</li>
* </ol>
*
* @return
*/
@Override
public int compare(Map<String, MatchPath> o1, Map<String, MatchPath> o2) {
if (isTrueSubset(o1.keySet(), o2.keySet())) {
return 1;
}
if (isTrueSubset(o2.keySet(), o1.keySet())) {
return -1;
}
public Matchings reduceConform(Matchings other);
if (!o1.keySet().equals(o2.keySet())) {
// different domains,
// there exists at least one variable that is not assign in the other
int cmp = Integer.compare(o1.size(), o2.size());
if (cmp != 0) {
return cmp;
} else {
return compareVariableName(o1, o2);
}
}
ArrayList<String> keys = new ArrayList<>(Sets.intersection(o1.keySet(), o2.keySet()));
keys.sort(String::compareTo); // order of the traversal
keys.remove("EMPTY_MATCH");
for (String k : keys) {
int depthA = o1.get(k).depth();
int depthB = o2.get(k).depth();
int cmp = Integer.compare(depthA, depthB);
if (cmp != 0)
return cmp;
}
// all terms same depth: now let the lexi-order decide
for (String k : keys) {
int cmp = o1.get(k).toString().compareTo(o2.get(k).toString());
if (cmp != 0)
return cmp;
}
return 0;
default void addAll(Matchings matches) {
addAll(matches.getMatchings());
}
private int compareVariableName(Map<String, MatchPath> o1, Map<String, MatchPath> o2) {
return variableNames(o1).compareTo(variableNames(o2));
}
private String variableNames(Map<String, MatchPath> va) {
return va.keySet().stream().reduce((a, b) -> a + '#' + b).orElse("#");
}
/**
* @param a
* @param b
* @return
*/
private boolean isTrueSubset(Set<String> a, Set<String> b) {
return b.containsAll(a) && !a.containsAll(b);
}
}
\ No newline at end of file
package edu.kit.iti.formal.psdbg.interpreter.matcher;
import com.google.common.collect.Sets;
import de.uka.ilkd.key.logic.SequentFormula;
import de.uka.ilkd.key.logic.Term;
import de.uka.ilkd.key.logic.op.QuantifiableVariable;
import java.util.*;
public class MutableMatchings implements Matchings {
public Set<Match> inner = new TreeSet<>(new VariableAssignmentComparator());
public static Matchings singleton(String name, MatchPath term) {
Matchings matchings = new MutableMatchings();
matchings.add(name,term);
return matchings;
}
public static Matchings emptySingleton() {
Matchings matchings = new MutableMatchings();
matchings.add(Match.empty());
return matchings;
}
@Override
public boolean isNoMatch() {
return false;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public void add(String binder, MatchPath term) {
add(Match.singleton(binder, term));
}
@Override
public void add(Match matching) {
inner.add(matching);
}
@Override
public void addAll(Collection<Match> matchings) {
inner.addAll(matchings);
}
@Override
public Collection<Match> getMatchings() {
return inner;
}
@Override
public String toString() {
return inner.toString();
}
/**
* Reduce the matchings by eliminating non-compatible matchings.
* For example:
* m1: <X, f(y)>, <Y,g> and m2: <X, g> <Y, f(x)>
*
* @param other
* @return
*/
@Override
public Matchings reduceConform(Matchings other) {
//shortcuts
if(other.isNoMatch()) return other.reduceConform(this);
if(other.isEmpty()) return other.reduceConform(this);
if(this.inner.size() == 0) return other;
MutableMatchings mother = (MutableMatchings) other;
MutableMatchings m3 = new MutableMatchings();
boolean oneMatch = false;
for (Match h1 : inner) {
for (Match h2 : mother.inner) {
Match h3 = reduceConform(h1, h2);
if (h3 != null) {
if (!m3.inner.contains(h3))
m3.add(h3);
oneMatch = true;
}
}
}
return oneMatch ? m3 : NoMatch.INSTANCE;
}
/**
*
* @param h1
* @param h2
* @return
*/
public static Match reduceConform(Match h1, Match h2) {
Match newMatch = new Match(h1);
for (String s1 : newMatch.keySet()) {
if (h2.containsKey(s1)) {
if (h2.get(s1) instanceof MatchPath.MPQuantifiableVariable &&
!((QuantifiableVariable) h2.get(s1).getUnit()).name().toString().equals(h1.get(s1).toString())) {
return null;
}
if (h1.get(s1) instanceof MatchPath.MPQuantifiableVariable &&
!((QuantifiableVariable) h1.get(s1).getUnit()).name().toString().equals(h2.get(s1).toString())) {
return null;
}
if (!h2.get(s1).equals(h1.get(s1))) {
return null;
}
}
}
newMatch.putAll(h2);
return newMatch;
}
class VariableAssignmentComparator implements Comparator<Match> {
/**
* <ol>
* <li>both maps contains the same keys</li>
* <li>foreach key in lexi-order, the depth has to be greater</li>
* </ol>
*
* @return
*/
@Override
public int compare(Match o1, Match o2) {
if (isTrueSubset(o1.keySet(), o2.keySet())) {
return 1;
}
if (isTrueSubset(o2.keySet(), o1.keySet())) {
return -1;
}
if (!o1.keySet().equals(o2.keySet())) {
// different domains,
// there exists at least one variable that is not assign in the other
int cmp = Integer.compare(o1.size(), o2.size());
if (cmp != 0) {
return cmp;
} else {
return compareVariableName(o1, o2);
}
}
ArrayList<String> keys = new ArrayList<>(Sets.intersection(o1.keySet(), o2.keySet()));
keys.sort(String::compareTo); // order of the traversal
keys.remove("EMPTY_MATCH");
for (String k : keys) {
int depthA = o1.get(k).depth();
int depthB = o2.get(k).depth();
int cmp = Integer.compare(depthA, depthB);
if (cmp != 0)
return cmp;
}
// all terms same depth: now let the lexi-order decide
for (String k : keys) {
int cmp = o1.get(k).toString().compareTo(o2.get(k).toString());
if (cmp != 0)
return cmp;
}
return 0;
}
private int compareVariableName(Match o1, Match o2) {
return variableNames(o1).compareTo(variableNames(o2));
}
private String variableNames(Match va) {
return va.keySet().stream().reduce((a, b) -> a + '#' + b).orElse("#");
}
/**
* @param a
* @param b
* @return
*/
private boolean isTrueSubset(Set<String> a, Set<String> b) {
return b.containsAll(a) && !a.containsAll(b);
}
}
}
package edu.kit.iti.formal.psdbg.interpreter.matcher;
import java.util.Collection;
import java.util.Collections;
public class NoMatch implements Matchings {
public static NoMatch INSTANCE = new NoMatch();
private NoMatch() {
}
@Override
public boolean isNoMatch() {
return true;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public void add(String binder, MatchPath term) {
throw new IllegalStateException();
}
@Override
public void add(Match singleton) {
throw new IllegalStateException();
}
@Override
public void addAll(Collection<Match> matchings) {
throw new IllegalStateException();
}
@Override
public Collection<Match> getMatchings() {
return Collections.emptyList();
}
@Override
public Matchings reduceConform(Matchings other) {
return this;
}
@Override
public String toString() {
return "{NOMATCH}";
}
}
......@@ -47,12 +47,11 @@ public class KeyMatcherFacadeTest {
*/
@Test
public void matchTerms() throws Exception {
shouldMatchT("f(a)", "?");
shouldMatchT("f(a)", "f(a)");
System.out.println(shouldMatchT("f(a)", "?"));
System.out.println(shouldMatchT("f(a)", "f(a)"));
shouldMatchT("f(a)", "?X", "[{?X=f(a)}]");
shouldMatchT("h(a,a)", "h(?X,?X)", "[{?X=a}]");
shouldMatchT("h(a,b)", "h(?X,?X)", "[]");
}
......@@ -61,19 +60,22 @@ public class KeyMatcherFacadeTest {
public void matchSeq() throws Exception {
//atm missing is catching the toplevel formula
//shouldMatch("==> pred(a)", "==> pred(?)", "[]");
shouldMatch("2 >= 1, h2(1,2) = h2(2,3), h2(2,3) = 0 ==> p, !p", "?X=0 ==>", "[{?X=h2(Z(2(#)),Z(3(#)))}]");
shouldMatch("h2(2,2) = 0 ==>p, !p", "?X=0 ==>", "[{EMPTY_MATCH=null, ?X=h2(Z(2(#)),Z(2(#)))}]");
shouldMatch("2 >= 1, h2(1,2) = h2(2,3), h2(2,3) = 0 ==> p, !p", "?X=0 ==>", "[{EMPTY_MATCH=null, ?X=Z(2(#))}, {EMPTY_MATCH=null, ?X=h2(Z(2(#)),Z(3(#)))}]");
shouldMatch("h2(2,2) = 0 ==>p, !p", "?X=0 ==>", "[{?X=h2(Z(2(#)),Z(2(#)))}]");
shouldMatch("p ==>", "p ==>", "[{EMPTY_MATCH=null}]");
shouldMatch("p ==>", "p ==>", "[{}]");
shouldMatch("==> pred(a), q", "==> pred(?X:S), q", "[{?X=a}]");
shouldMatch("==> p, q", "==> ?X:Formula", "[{?X=p}, {?X=q}]");
shouldMatch("==> p, q", "==> p, q","[{EMPTY_MATCH=null}]");
shouldMatch("==> p, q", "==> q, p", "[{EMPTY_MATCH=null}]");
shouldMatch("==> p, q", "==> p, q","[{}]");
shouldMatch("==> p, q", "==> q, p", "[{}]");
shouldMatch("==> pred(a), q", "==> pred(?X)", "[{?X=a}]");
shouldMatch("h2(2,2) = 0 ==>", "?X=0 ==>", "[{?X=h2(Z(2(#)),Z(2(#)))}]");
shouldMatch("==>f(g(a))= 0", "==> f(...a...) = 0", "[{EMPTY_MATCH=null}]");
shouldMatch("==>f(g(a))= 0", "==> f(...a...) = 0", "[{}]");
}
@Test
......@@ -84,20 +86,20 @@ public class KeyMatcherFacadeTest {
@Test
public void testBindContext() throws Exception {
//shouldMatch("f(a)", "f(a) : ?Y", "[{?Y=f(a)}]");
//how to deal with trying to match top-level, w.o. adding the type of the variable
shouldMatch("f(a)=0 ==> ", "(f(a)=0) : ?Y:Formula ==>", "[{?Y=equals(f(a),Z(0(#)))}]");
//shouldMatch("f(g(a))", "_ \\as ?Y", "[{?Y=f(g(a))}]");
//shouldMatch("i+i+j", "(?X + ?Y) : ?Z", "[{?X=add(i,i), ?Y=j, ?Z=add(add(i,i),j)}]");
shouldMatch("==>f(g(a))= 0", "==> f((...a...):?G) = 0", "[{?G=g(a), EMPTY_MATCH=null}]");
shouldMatch("==>f(f(g(a)))= 0", "==> f((...a...):?G) = 0", "[{?G=f(g(a)), EMPTY_MATCH=null}]");
shouldMatch("==>f(f(g(a)))= 0", "==> f((...g(...a...)...):?G) = 0", "[{?G=f(g(a)), EMPTY_MATCH=null}]");
shouldMatch("==>f(f(g(a)))= 0", "==> f((...g((...a...):?Q)...):?G) = 0", "[{?G=f(g(a)), EMPTY_MATCH=null, ?Q=a}]");
shouldMatch("pred(f(a)) ==>", "pred((...a...):?Q) ==>","[{EMPTY_MATCH=null, ?Q=f(a)}]");
shouldMatch("p ==>", "(p):?X:Formula ==>", "[{EMPTY_MATCH=null, ?X=p}]");
shouldMatch("==>f(g(a))= 0", "==> f((...a...):?G) = 0", "[{?G=g(a)}]");
shouldMatch("==>f(f(g(a)))= 0", "==> f((...a...):?G) = 0", "[{?G=f(g(a))}]");
shouldMatch("==>f(f(g(a)))= 0", "==> f((...g(...a...)...):?G) = 0", "[{?G=f(g(a))}]");
shouldMatch("==>f(f(g(a)))= 0", "==> f((...g((...a...):?Q)...):?G) = 0", "[{?G=f(g(a)), ?Q=a}]");
shouldMatch("pred(f(a)) ==>", "pred((...a...):?Q) ==>","[{?Q=f(a)}]");
shouldMatch("p ==>", "(p):?X:Formula ==>", "[{?X=p}]");
shouldMatch("pred(a) ==>", "(pred(?)):?X:Formula ==>");
shouldMatch("==>f(f(g(a)))= 0", "==> (f((...g((...a...):?Q)...):?G)):?Y = 0", "[{?G=f(g(a)), EMPTY_MATCH=null, ?Q=a, ?Y=f(f(g(a)))}]");
shouldMatch("==>f(f(g(a)))= 0", "==> (f((...g((...a...):?Q)...):?G)):?Y = 0", "[{?G=f(g(a)), ?Q=a, ?Y=f(f(g(a)))}]");
// shouldMatch("f(f(g(a)))= 0 ==>", "f( (... g( (...a...):?Q ) ...) : ?R) : ?Y = 0 ==>",
......@@ -115,7 +117,7 @@ public class KeyMatcherFacadeTest {
//region: helper
private void shouldNotMatch(String s, String s1) throws Exception{
Assert.assertTrue(shouldMatch(s, s1).size()==0);
Assert.assertTrue(shouldMatch(s, s1).getMatchings().size()==0);
}
private void shouldMatch(String keysequent, String pattern, String exp) throws Exception {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment