Skip to content
This repository was archived by the owner on Mar 2, 2020. It is now read-only.

Commit 423a035

Browse files
authored
Specmate DSL integration (#441)
* Finished DSL Integration * Bugfixes; Tested Integration * Fixed dublicte Nodes issue * Added Rules; Better Language Detection; Bugfixes * Added Rules * Added English Adjective Unfolding * Removed Debugging Code * Fixed Tree Merging * Improved Roboustness, added new Rules, begun testing. * Added More rules, fixed order of operations, bugfixes * Refactoring * Fixed last request
1 parent f39434d commit 423a035

File tree

83 files changed

+3876
-154
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+3876
-154
lines changed

bundles/specmate-cause-effect-patterns/bnd.bnd

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ Private-Package: \
2525
Export-Package: \
2626
com.specmate.cause_effect_patterns.parse,\
2727
com.specmate.cause_effect_patterns.parse.matcher,\
28+
com.specmate.cause_effect_patterns.parse.wrapper,\
2829
com.specmate.cause_effect_patterns.resolve
2930
Import-Package: \
3031
org.eclipse.xtext.smap;resolution:=optional,\
3132
*
3233
-runfw: org.eclipse.osgi;version='[3.10.2.v20150203-1939,3.10.2.v20150203-1939]'
3334
-runee: JavaSE-1.8
34-
Bundle-Version: 0.0.0.${tstamp}

bundles/specmate-cause-effect-patterns/src/com/specmate/cause_effect_patterns/parse/DependencyNode.java

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.Iterator;
44
import java.util.List;
5+
import java.util.Map.Entry;
56
import java.util.Set;
67

78
import com.google.common.collect.ArrayListMultimap;
@@ -26,6 +27,16 @@ public void addDepenency(Dependency d) {
2627
this.dependencies.put(d.getDependencyType(), d);
2728
}
2829

30+
public void addDependencies(DependencyNode other) {
31+
for(Entry<String, Dependency> entry: other.dependencies.entries()) {
32+
String key = entry.getKey();
33+
Dependency value = entry.getValue();
34+
if(!this.dependencies.containsEntry(key, value)) {
35+
this.dependencies.put(key, value);
36+
}
37+
}
38+
}
39+
2940
public List<Dependency> getDependenciesFromTag(String dependencyTag) {
3041
return this.dependencies.get(dependencyTag);
3142
}

bundles/specmate-cause-effect-patterns/src/com/specmate/cause_effect_patterns/parse/DependencyParsetree.java

+44-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Map;
99
import java.util.Set;
1010
import java.util.Vector;
11+
import java.util.stream.Collectors;
1112

1213
import org.apache.uima.fit.util.JCasUtil;
1314
import org.apache.uima.internal.util.SortedIntSet;
@@ -26,8 +27,15 @@
2627
*
2728
*/
2829
public class DependencyParsetree {
30+
private static Set<String> ignoreDependency;
31+
static {
32+
DependencyParsetree.ignoreDependency = new HashSet<String>();
33+
DependencyParsetree.ignoreDependency.add("punct");
34+
}
35+
2936
private static String ROOT = "ROOT";
3037

38+
3139
private Map<Token, DependencyNode> dependencies;
3240
private Set<Token> heads;
3341
private List<TextInterval> treeFragments;
@@ -45,6 +53,10 @@ public static DependencyParsetree generateFromJCas(JCas jcas) {
4553
for(Dependency d: dependencyList) {
4654
Token governor = d.getGovernor();
4755

56+
if(DependencyParsetree.ignoreDependency.contains(d.getDependencyType())) {
57+
continue;
58+
}
59+
4860
if(!result.dependencies.containsKey(governor)) {
4961
result.dependencies.put(governor, new DependencyNode());
5062
result.addFragment(governor);
@@ -95,19 +107,22 @@ public DependencyParsetree() {
95107
}
96108

97109
public void addSubtree(DependencyParsetree subtree) {
98-
this.dependencies.putAll(subtree.dependencies);
110+
for(Token token: subtree.dependencies.keySet()) {
111+
if(this.dependencies.containsKey(token)) {
112+
DependencyNode nodeA = this.dependencies.get(token);
113+
DependencyNode nodeB = subtree.dependencies.get(token);
114+
nodeA.addDependencies(nodeB);
115+
} else {
116+
this.dependencies.put(token, subtree.dependencies.get(token));
117+
}
118+
}
99119
this.treeFragments.addAll(subtree.treeFragments);
100120
this.tokenOrder.union(subtree.tokenOrder);
101121
this.minimizeTreeFragments();
102122
}
103123

104124
public void addSubtree(DependencyParsetree subtree, Dependency dependency) {
105-
Token governor = dependency.getGovernor();
106-
if(!this.dependencies.containsKey(governor)) {
107-
this.dependencies.put(governor, new DependencyNode());
108-
addFragment(governor);
109-
}
110-
this.dependencies.get(governor).addDepenency(dependency);
125+
addDependency(dependency);
111126
this.addSubtree(subtree);
112127
}
113128

@@ -157,6 +172,18 @@ public TextInterval getTextInterval(int index) {
157172
return this.treeFragments.get(index);
158173
}
159174

175+
public String getRepresentationString(boolean capitalize) {
176+
String result = this.treeFragments.stream()
177+
.map(f -> f.text)
178+
.filter(str -> str.length() > 1)
179+
.collect(Collectors.joining(" "));
180+
if(capitalize) {
181+
result = result.substring(0, 1).toUpperCase() + result.substring(1);
182+
}
183+
184+
return result;
185+
}
186+
160187
public String getTreeFragmentText() {
161188
String result = "Fragments:\n";
162189
for(TextInterval i: this.treeFragments) {
@@ -187,6 +214,15 @@ public String toString() {
187214
result+= this.getTreeFragmentText();
188215
return result;
189216
}
217+
218+
public void addDependency(Dependency dependency) {
219+
Token governor = dependency.getGovernor();
220+
if(!this.dependencies.containsKey(governor)) {
221+
this.dependencies.put(governor, new DependencyNode());
222+
addFragment(governor);
223+
}
224+
this.dependencies.get(governor).addDepenency(dependency);
225+
}
190226

191227
public class TextInterval implements Comparable<TextInterval>{
192228
public int from, to;
@@ -257,4 +293,5 @@ public int compareTo(TextInterval o) {
257293
return 0;
258294
}
259295
}
296+
260297
}

bundles/specmate-cause-effect-patterns/src/com/specmate/cause_effect_patterns/parse/matcher/MatchResult.java

+55-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.specmate.cause_effect_patterns.parse.matcher;
22

3+
import java.util.Collections;
34
import java.util.HashMap;
45
import java.util.Map;
6+
import java.util.Optional;
57
import java.util.Set;
8+
import java.util.Vector;
69

710
import com.specmate.cause_effect_patterns.parse.DependencyParsetree;
8-
import com.specmate.cause_effect_patterns.parse.matcher.MatchResult;
9-
import com.specmate.cause_effect_patterns.parse.matcher.SubtreeMatcher;
1011

1112
/**
1213
* Class storing the result of a dependency matching operation.
@@ -23,12 +24,13 @@ public class MatchResult {
2324
private boolean isSuccessfulMatch;
2425
private Map<String, MatchResult> submatch;
2526
private DependencyParsetree matchTree;
26-
27+
private Optional<String> ruleName;
2728

2829
private MatchResult(boolean success, DependencyParsetree matchTree) {
2930
this.matchTree = matchTree;
3031
this.isSuccessfulMatch = success;
3132
this.submatch = new HashMap<String, MatchResult>();
33+
this.ruleName = Optional.empty();
3234
}
3335

3436
private MatchResult(boolean success) {
@@ -39,6 +41,24 @@ private MatchResult() {
3941
this(false);
4042
}
4143

44+
public void setRuleName(String ruleName) {
45+
this.ruleName = Optional.of(ruleName);
46+
for(String sub: this.submatch.keySet()) {
47+
MatchResult subRes = this.submatch.get(sub);
48+
if(!subRes.hasRuleName()) {
49+
subRes.setRuleName(ruleName);
50+
}
51+
}
52+
}
53+
54+
public boolean hasRuleName() {
55+
return this.ruleName.isPresent();
56+
}
57+
58+
public String getRuleName() {
59+
return this.ruleName.get();
60+
}
61+
4262
public boolean isSuccessfulMatch() {
4363
return isSuccessfulMatch;
4464
}
@@ -60,10 +80,35 @@ public void addSubtree(MatchResult subtree) {
6080
for(String subtreeID: subtree.submatch.keySet()) {
6181
this.submatch.put(subtreeID, subtree.submatch.get(subtreeID));
6282
}
83+
if(subtree.submatch.size() > 0) {
84+
this.mergePrefixSubmatches();
85+
}
86+
6387
this.isSuccessfulMatch = this.isSuccessfulMatch() && subtree.isSuccessfulMatch();
6488
this.getMatchTree().addSubtree(subtree.getMatchTree());
6589
}
6690

91+
92+
private void mergePrefixSubmatches() {
93+
Vector<String> keys = new Vector<String>(this.submatch.keySet());
94+
Collections.sort(keys, (s1,s2) -> s1.length() - s2.length());
95+
for (int i = 0; i < keys.size(); i++) {
96+
String keyA = keys.get(i);
97+
for (int j = i+1; j < keys.size(); j++) {
98+
String keyB = keys.get(j);
99+
if(keyB.startsWith(keyA+"_")) {
100+
//merge keys
101+
MatchResult resA = this.submatch.get(keyA);
102+
MatchResult resB = this.submatch.get(keyB);
103+
resA.addSubtree(resB);
104+
keys.remove(j);
105+
this.submatch.remove(keyB);
106+
j--;
107+
}
108+
}
109+
}
110+
}
111+
67112
public DependencyParsetree getMatchTree() {
68113
return matchTree;
69114
}
@@ -75,6 +120,9 @@ public void clearMatchTree() {
75120
public void addSubmatch(String subtreeName, MatchResult submatch) {
76121
this.isSuccessfulMatch = this.isSuccessfulMatch && submatch.isSuccessfulMatch;
77122
this.submatch.put(subtreeName, submatch);
123+
if(this.submatch.size() > 1) {
124+
this.mergePrefixSubmatches();
125+
}
78126
}
79127

80128
public boolean hasSubmatch(String subtreeName) {
@@ -88,4 +136,8 @@ public MatchResult getSubmatch(String subtreeName) {
88136
public Set<String> getSubmatchNames() {
89137
return this.submatch.keySet();
90138
}
139+
140+
public void clearSubmatches() {
141+
this.submatch.clear();
142+
}
91143
}

bundles/specmate-cause-effect-patterns/src/com/specmate/cause_effect_patterns/parse/matcher/MatchRule.java

+9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.specmate.cause_effect_patterns.parse.matcher;
22

3+
import com.specmate.cause_effect_patterns.parse.DependencyParsetree;
34
import com.specmate.cause_effect_patterns.parse.matcher.MatcherBase;
45

6+
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token;
7+
58
public class MatchRule {
69
public MatcherBase matcher;
710
public String ruleName;
@@ -11,6 +14,12 @@ public MatchRule(MatcherBase matcher, String name) {
1114
this.ruleName = name;
1215
}
1316

17+
public MatchResult match(DependencyParsetree data, Token head) {
18+
MatchResult result = this.matcher.match(data, head);
19+
result.setRuleName(this.ruleName);
20+
return result;
21+
}
22+
1423
@Override
1524
public String toString() {
1625
return "Match Rule: " + this.ruleName+"\n"+this.matcher;

bundles/specmate-cause-effect-patterns/src/com/specmate/cause_effect_patterns/parse/matcher/MatchUtil.java

+42-17
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
import java.util.Vector;
55

66
import com.specmate.cause_effect_patterns.parse.DependencyParsetree;
7-
import com.specmate.cause_effect_patterns.parse.matcher.MatchResult;
8-
import com.specmate.cause_effect_patterns.parse.matcher.MatchUtil;
9-
import com.specmate.cause_effect_patterns.parse.matcher.MatcherBase;
107

118
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token;
129

@@ -18,14 +15,17 @@ public class MatchUtil {
1815
* @param data
1916
* @return A List of Results for each head of the dependency data object.
2017
*/
21-
public static List<MatchResult> evaluateRuleset(List<MatcherBase> rules, DependencyParsetree data) {
18+
public static List<MatchResult> evaluateRuleset(List<MatchRule> rules, DependencyParsetree data) {
2219
Vector<MatchResult> result = new Vector<MatchResult>();
2320
for(Token head: data.getHeads()) {
2421
result.add(MatchUtil.evaluateRuleset(rules, data, head));
2522
}
2623
return result;
2724
}
2825

26+
27+
28+
2929
/**
3030
* Recursively applies the list of matchers on the given dependency data object starting at the head token.
3131
*
@@ -34,26 +34,51 @@ public static List<MatchResult> evaluateRuleset(List<MatcherBase> rules, Depende
3434
* @param head
3535
* @return
3636
*/
37-
public static MatchResult evaluateRuleset(List<MatcherBase> rules, DependencyParsetree data, Token head) {
37+
public static MatchResult evaluateRuleset(List<MatchRule> rules, DependencyParsetree data, Token head) {
38+
return evaluateRuleset(rules, data, head, 0);
39+
}
40+
41+
private static MatchResult evaluateRuleset(List<MatchRule> rules, DependencyParsetree data, Token head, int ruleOffset) {
3842
MatchResult result = MatchResult.unsuccessful();
39-
for(MatcherBase rule: rules) {
43+
44+
List<MatchRule> offsetedRules = rules.subList(ruleOffset, rules.size());
45+
for(MatchRule rule: offsetedRules) {
4046
result = rule.match(data, head);
4147
if(result.isSuccessfulMatch()) {
42-
for(String submatchName: result.getSubmatchNames()) {
43-
MatchResult sub = result.getSubmatch(submatchName);
44-
DependencyParsetree subData = sub.getMatchTree();
45-
Token subHead = subData.getHeads().stream().findFirst().get();
46-
MatchResult recursiveCall = evaluateRuleset(rules, subData, subHead);
47-
if(recursiveCall.isSuccessfulMatch()) {
48-
for( String subKey: recursiveCall.getSubmatchNames()) {
49-
sub.addSubmatch(subKey, recursiveCall.getSubmatch(subKey));
50-
}
51-
}
52-
}
48+
evaluateRulesetOnSubtrees(rules, rule, data, head, result);
5349
break;
5450
}
5551
}
5652

5753
return result;
5854
}
55+
56+
private static void evaluateRulesetOnSubtrees(List<MatchRule> rules, MatchRule currentRule,
57+
DependencyParsetree data, Token head, MatchResult result) {
58+
for(String submatchName: result.getSubmatchNames()) {
59+
MatchResult sub = result.getSubmatch(submatchName);
60+
DependencyParsetree subData = sub.getMatchTree();
61+
Token subHead = subData.getHeads().stream().findFirst().get();
62+
63+
MatchResult recursiveCall;
64+
if(subData.getTreeFragmentText().equals(data.getTreeFragmentText()) && subHead.equals(head)) {
65+
int newOffset = rules.indexOf(currentRule) + 1;
66+
recursiveCall = evaluateRuleset(rules, subData, subHead, newOffset);
67+
} else {
68+
recursiveCall = evaluateRuleset(rules, subData, subHead);
69+
}
70+
71+
if(recursiveCall.isSuccessfulMatch()) {
72+
sub.setRuleName(recursiveCall.getRuleName());
73+
for( String subKey: recursiveCall.getSubmatchNames()) {
74+
MatchResult subRes = recursiveCall.getSubmatch(subKey);
75+
if(!subRes.hasRuleName() ) {
76+
subRes.setRuleName(recursiveCall.getRuleName());
77+
}
78+
sub.addSubmatch(subKey, subRes);
79+
}
80+
}
81+
}
82+
}
83+
5984
}

0 commit comments

Comments
 (0)