Skip to content

Commit

Permalink
#281 fix tag cyk general broken trees
Browse files Browse the repository at this point in the history
  • Loading branch information
SamyaDaleh committed May 21, 2023
1 parent 80807b8 commit 88ba565
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.github.samyadaleh.cltoolbox.chartparsing.dynamicdeductionrule.AbstractDynamicDeductionRule;
import com.github.samyadaleh.cltoolbox.chartparsing.item.ChartItemInterface;
import com.github.samyadaleh.cltoolbox.chartparsing.item.DeductionChartItem;
import com.github.samyadaleh.cltoolbox.common.TreeUtils;
import com.github.samyadaleh.cltoolbox.common.tag.Tag;
import com.github.samyadaleh.cltoolbox.common.tag.Tree;

Expand Down Expand Up @@ -57,13 +58,47 @@ public TagCykMoveGeneral(Tag tag, int antNeeded) {
ChartItemInterface consequence = new DeductionChartItem(treeName,
parentGorn + "⊥", boundaries[firstEntry * 2], foot[0], foot[1],
boundaries[lastEntry * 2 + 1]);
consequence.setTrees(antecedences.get(0).getTrees());
if (antecedences.size() == 1) {
consequence.setTrees(antecedences.get(0).getTrees());
} else {
List<Tree[]> treeCombinations = getAllTreeCombinations();
List<Tree> derivedTrees = new ArrayList<>();
for (Tree[] combination : treeCombinations) {
derivedTrees.add(TreeUtils.mergeTrees(combination));
}
consequence.setTrees(derivedTrees);
}
logItemGeneration(consequence);
consequences.add(consequence);
}
return consequences;
}

public List<Tree[]> getAllTreeCombinations() {
List<Tree[]> combinations = new ArrayList<>();
getAllTreeCombinationsHelper(combinations, new ArrayList<>(),
antecedences, 0);
return combinations;
}

private void getAllTreeCombinationsHelper(
List<Tree[]> combinations, List<Tree> currentCombination,
List<ChartItemInterface> antecedences, int index) {
if (index == antecedences.size()) {
// We've selected a tree from each antecedent, so add the combination to the result list
combinations.add(currentCombination.toArray(new Tree[0]));
} else {
List<Tree> trees = antecedences.get(index).getTrees();
for (Tree tree : trees) {
List<Tree> newCombination = new ArrayList<>(currentCombination);
newCombination.add(tree);
getAllTreeCombinationsHelper(combinations, newCombination,
antecedences, index + 1);
}
}
}


private boolean checkAllAntecedences(String treeName, String parentGorn,
List<Integer> children, String[] boundaries, String[] foot) {
int i = 0;
Expand Down Expand Up @@ -101,7 +136,7 @@ private boolean checkAllAntecedences(String treeName, String parentGorn,
StringBuilder bars = new StringBuilder();
for (i = 1; i <= antNeeded; i++) {
repr.append("[ɣ,(p.").append(i).append(")⊤,i_").append(i).append(",f1")
.append(bars.toString()).append(",f2+bars.toString()+,i_")
.append(bars).append(",f2+bars.toString()+,i_")
.append(i + 1).append("] ");
bars.append("'");
}
Expand Down
66 changes: 49 additions & 17 deletions src/main/java/com/github/samyadaleh/cltoolbox/common/TreeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,34 +234,66 @@ private static String collectSubtreeAsString(Tree tree2, Vertex node2) {
return newTree.toString();
}

public static Tree mergeTrees(Tree tree1, Tree tree2) {
public static Tree mergeTrees(Tree... trees) {
String[] treeStrings = new String[trees.length];
for (int i = 0; i < trees.length; i++) {
treeStrings[i] = trees[i].toString();
}
try {
return new Tree(mergeTrees(tree1.toString(), tree2.toString()));
return new Tree(mergeTrees(treeStrings));
} catch (ParseException e) {
// should never happen
throw new RuntimeException(e);
}
}

public static String mergeTrees(String tree1, String tree2) {
public static String mergeTrees(String... trees) {
StringBuilder merged = new StringBuilder();
int i = 0, j = 0;
int[] positions = new int[trees.length]; // All initially 0

while (true) {
// Check if we've reached the end of all trees, if so break
boolean allEndReached = true;
for (int i = 0; i < positions.length; i++) {
if (positions[i] < trees[i].length()) {
allEndReached = false;
break;
}
}

while (i < tree1.length() && j < tree2.length()) {
if (tree1.charAt(i) == tree2.charAt(j)) {
// Same character, add it to the result and advance both pointers
merged.append(tree1.charAt(i));
i++;
j++;
} else if (tree1.charAt(i) == '(' && tree2.charAt(j) == ')') {
// Tree1 has a subtree where tree2 has none
i = copySubtree(tree1, merged, i);
} else if (tree1.charAt(i) == ')' && tree2.charAt(j) == '(') {
// Tree2 has a subtree where tree1 has none
j = copySubtree(tree2, merged, j);
if (allEndReached) {
return merged.toString();
}

// Check for the start of a subtree in a tree where others don't have
int subtreeStartIndex = -1;
for (int i = 0; i < trees.length; i++) {
char ch = trees[i].charAt(positions[i]);
if (ch == '(') {
boolean othersHaveClosingBracket = false;
for (int j = 0; j < trees.length; j++) {
if (j != i && positions[j] < trees[j].length() && trees[j].charAt(positions[j]) == ')') {
othersHaveClosingBracket = true;
break;
}
}
if (othersHaveClosingBracket) {
subtreeStartIndex = i;
break;
}
}
}

if (subtreeStartIndex == -1) { // All chars are the same
merged.append(trees[0].charAt(positions[0]));
for (int i = 0; i < positions.length; i++) {
positions[i]++;
}
} else { // We have a unique char, so copy the subtree
positions[subtreeStartIndex] = copySubtree(trees[subtreeStartIndex],
merged, positions[subtreeStartIndex]);
}
}
return merged.toString();
}

private static int copySubtree(String tree1, StringBuilder merged, int i) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,23 @@ public class DeductionTest {
deduction.getDerivedTrees().get(0).toString());
}

@Test public void testTagCykGeneralBrokenTrees()
throws ParseException, FileNotFoundException {
String w2 = "t0 t0";
Tag tag = GrammarLoader.readTag("brokentrees.tag");
ParsingSchema schema = TagToCykRulesConverter
.tagToCykGeneralRules(tag, w2);
Deduction deduction = new Deduction();
assertTrue(deduction.doParse(schema, false));
String[][] data = deduction.getTraceTable();
deduction.printTrace(data);
for (Tree tree : deduction.getDerivedTrees()) {
if (tree.toString().contains("(N1 )")) {
fail();
}
}
}

@Test public void testTagCykGeneralTooManyTrees()
throws ParseException, FileNotFoundException {
String w2 = "t0 t1";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@ public class TreeUtilsTest {
Tree treeMerged = TreeUtils.mergeTrees(tree1, tree2);
assertEquals("(S (N1 (S (ε )))(N1 (S (ε ))))", treeMerged.toString());
}

@Test public void testMergeTrees2() throws ParseException {
Tree tree1 = new Tree("(S (N1 (t0 )(S (ε )))(N1 ))");
Tree tree2 = new Tree("(S (N1 )(N1 (S (ε ))))");
Tree treeMerged = TreeUtils.mergeTrees(tree2, tree1);
assertEquals("(S (N1 (t0 )(S (ε )))(N1 (S (ε ))))", treeMerged.toString());
}
}

0 comments on commit 88ba565

Please sign in to comment.