Skip to content

Commit 1b54094

Browse files
committed
basic patching idea
1 parent 8a229af commit 1b54094

2 files changed

Lines changed: 182 additions & 0 deletions

File tree

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package org.variantsync.diffdetective.experiments.thesis_pm;
2+
3+
import java.io.IOException;
4+
import java.nio.file.Path;
5+
import java.util.ArrayList;
6+
import java.util.HashSet;
7+
import java.util.Iterator;
8+
import java.util.List;
9+
import java.util.Set;
10+
11+
import org.variantsync.diffdetective.diff.result.DiffParseException;
12+
import org.variantsync.diffdetective.show.Show;
13+
import org.variantsync.diffdetective.show.engine.GameEngine;
14+
import org.variantsync.diffdetective.util.fide.FixTrueFalse.Formula;
15+
import org.variantsync.diffdetective.variation.DiffLinesLabel;
16+
import org.variantsync.diffdetective.variation.diff.DiffNode;
17+
import org.variantsync.diffdetective.variation.diff.DiffType;
18+
import org.variantsync.diffdetective.variation.diff.Time;
19+
import org.variantsync.diffdetective.variation.diff.VariationDiff;
20+
import org.variantsync.diffdetective.variation.diff.parse.VariationDiffParseOptions;
21+
import org.variantsync.diffdetective.variation.diff.view.DiffView;
22+
import org.variantsync.diffdetective.variation.tree.VariationTree;
23+
import org.variantsync.diffdetective.variation.tree.view.relevance.Configure;
24+
import org.variantsync.diffdetective.variation.tree.view.relevance.Relevance;
25+
26+
public class PatchingExperiment {
27+
28+
private static Relevance calculateFeatureSetToDeselect(VariationTree<DiffLinesLabel> variant1, VariationTree<DiffLinesLabel> variant2, boolean debug) {
29+
Set<String> featuresTreeV1 = new HashSet<String>();
30+
variant1.forAllPreorder(node -> {featuresTreeV1.addAll(node.getFeatureMapping().getUniqueContainedFeatures());});
31+
Set<String> featuresTreeV2 = new HashSet<String>();
32+
variant2.forAllPreorder(node -> {featuresTreeV2.addAll(node.getFeatureMapping().getUniqueContainedFeatures());});
33+
34+
Set<String> intersectSet1 = new HashSet<>(featuresTreeV1);
35+
intersectSet1.removeAll(featuresTreeV2);
36+
Set<String> intersectSet2 = new HashSet<>(featuresTreeV2);
37+
intersectSet2.removeAll(featuresTreeV1);
38+
intersectSet1.addAll(intersectSet2);
39+
40+
if (debug) {
41+
System.out.println(featuresTreeV1);
42+
System.out.println(featuresTreeV2);
43+
System.out.println(intersectSet1);
44+
}
45+
46+
47+
Formula[] f = new Formula[intersectSet1.size()];
48+
Iterator<String> iterator = intersectSet1.iterator();
49+
for (int i = 0; i < f.length; i++) {
50+
f[i] = Formula.not(Formula.var(iterator.next()));
51+
}
52+
Formula formula = Formula.and(f);
53+
54+
if (debug) System.out.println(formula.get().toString());
55+
56+
Relevance rho = new Configure(formula);
57+
return rho;
58+
}
59+
60+
private static Set<DiffNode<DiffLinesLabel>> findRootsOfSubtrees(Set<DiffNode<DiffLinesLabel>> nodes, boolean debug) {
61+
Set<DiffNode<DiffLinesLabel>> subtreeRoots = new HashSet<DiffNode<DiffLinesLabel>>();
62+
for (DiffNode<DiffLinesLabel> node : nodes) {
63+
if (!nodes.contains(node.getParent(Time.AFTER))) {
64+
subtreeRoots.add(node);
65+
}
66+
}
67+
if (debug) System.out.println(subtreeRoots);
68+
69+
return subtreeRoots;
70+
}
71+
72+
private static void patchVariationTrees(VariationTree<DiffLinesLabel> sourceVariantVersion1, VariationTree<DiffLinesLabel> sourceVariantVersion2, VariationTree<DiffLinesLabel> targetVariant) {
73+
if (sourceVariantVersion1 == null || sourceVariantVersion2 == null || targetVariant == null) {
74+
System.out.println("Parsing error");
75+
return;
76+
}
77+
78+
VariationDiff<DiffLinesLabel> diff = VariationDiff.fromTrees(sourceVariantVersion1, sourceVariantVersion2);
79+
Relevance rho = calculateFeatureSetToDeselect(sourceVariantVersion1, targetVariant, false);
80+
VariationDiff<DiffLinesLabel> optimizedDiff = DiffView.optimized(diff, rho);
81+
82+
// add new nodes
83+
Set<DiffNode<DiffLinesLabel>> addedNodes = new HashSet<DiffNode<DiffLinesLabel>>();
84+
optimizedDiff.forAll(node -> {if (node.isAdd()) {addedNodes.add(node);}});
85+
86+
// find roots of subtrees of added nodes
87+
Set<DiffNode<DiffLinesLabel>> addedSubtreeRoots = findRootsOfSubtrees(addedNodes, false);
88+
89+
VariationDiff<DiffLinesLabel> targetVariantDiff = VariationDiff.fromTrees(targetVariant, targetVariant);
90+
for (DiffNode<DiffLinesLabel> root : addedSubtreeRoots) {
91+
VariationDiff<DiffLinesLabel> subTree = new VariationDiff<DiffLinesLabel>(root.deepCopy(), optimizedDiff.getSource());
92+
GameEngine.showAndAwaitAll(Show.diff(subTree));
93+
List<DiffNode<DiffLinesLabel>> targetNodes = new ArrayList<DiffNode<DiffLinesLabel>>();
94+
if (root.isArtifact()) {
95+
targetNodes = targetVariantDiff.computeAllNodesThat(node -> node.getPresenceCondition(Time.AFTER)
96+
.equals(root.getPresenceCondition(Time.AFTER)) && node.isAnnotation());
97+
} else if (root.isAnnotation()) {
98+
targetNodes = targetVariantDiff.computeAllNodesThat(node -> node.getPresenceCondition(Time.AFTER)
99+
.equals(root.getParent(Time.AFTER).getPresenceCondition(Time.AFTER)) && node.isAnnotation());
100+
}
101+
102+
if (targetNodes.size() != 1) {
103+
System.out.println("too much or too less target nodes found");
104+
} else {
105+
System.out.println("subtree added");
106+
targetNodes.get(0).addChild(root.deepCopy(), Time.AFTER);
107+
}
108+
}
109+
110+
// remove old nodes
111+
Set<DiffNode<DiffLinesLabel>> removedNodes = new HashSet<DiffNode<DiffLinesLabel>>();
112+
optimizedDiff.forAll(node -> {if (node.isRem()) {removedNodes.add(node);}});
113+
114+
Set<DiffNode<DiffLinesLabel>> removedSubtreeRoots = findRootsOfSubtrees(removedNodes, false);
115+
116+
// VariationDiff<DiffLinesLabel> targetVariantDiff2 = VariationDiff.fromTrees(targetVariant, targetVariant);
117+
for (DiffNode<DiffLinesLabel> root : removedSubtreeRoots) {
118+
VariationDiff<DiffLinesLabel> subTree = new VariationDiff<DiffLinesLabel>(root.deepCopy(), optimizedDiff.getSource());
119+
GameEngine.showAndAwaitAll(Show.diff(subTree));
120+
List<DiffNode<DiffLinesLabel>> targetNodes = new ArrayList<DiffNode<DiffLinesLabel>>();
121+
if (root.isArtifact()) {
122+
targetNodes = targetVariantDiff.computeAllNodesThat(node -> node.getPresenceCondition(Time.AFTER)
123+
.equals(root.getPresenceCondition(Time.BEFORE)) && node.isAnnotation());
124+
} else if (root.isAnnotation()) {
125+
targetNodes = targetVariantDiff.computeAllNodesThat(node -> node.getPresenceCondition(Time.AFTER)
126+
.equals(root.getParent(Time.BEFORE).getPresenceCondition(Time.BEFORE)) && node.isAnnotation());
127+
}
128+
if (targetNodes.size() != 1) {
129+
System.out.println("too much or too less target nodes found");
130+
} else {
131+
132+
// System.out.println(targetNodes.get(0));
133+
DiffNode<DiffLinesLabel> parent = targetNodes.get(0);
134+
List<DiffNode<DiffLinesLabel>> nodesToRem = new ArrayList<DiffNode<DiffLinesLabel>>();
135+
parent.getAllChildrenStream().forEach(node -> { if (node.isSameAs(root, Time.BEFORE)) nodesToRem.add(node);});
136+
if (nodesToRem.size() != 1) {
137+
System.out.println("too much or too less target nodes found");
138+
} else {
139+
System.out.println("subtree removed");
140+
nodesToRem.get(0).diffType = DiffType.REM;
141+
nodesToRem.get(0).drop(Time.AFTER);
142+
}
143+
}
144+
}
145+
146+
GameEngine.showAndAwaitAll(
147+
Show.tree(sourceVariantVersion1),
148+
Show.tree(sourceVariantVersion2),
149+
Show.tree(targetVariant),
150+
Show.diff(optimizedDiff),
151+
Show.diff(targetVariantDiff)
152+
);
153+
154+
}
155+
156+
private static VariationTree<DiffLinesLabel> parseVariationTreeFromFile(String file) {
157+
Path examplesDir = Path.of("data", "examples");
158+
Path path = examplesDir.resolve(file);
159+
try {
160+
VariationTree<DiffLinesLabel> tree = VariationTree.fromFile(
161+
path,
162+
VariationDiffParseOptions.Default
163+
);
164+
return tree;
165+
} catch (IOException e) {
166+
e.printStackTrace();
167+
} catch (DiffParseException e) {
168+
e.printStackTrace();
169+
}
170+
return null;
171+
}
172+
173+
public static void main(String[] args) {
174+
patchVariationTrees(parseVariationTreeFromFile("exampleA1.cpp"), parseVariationTreeFromFile("exampleA2.cpp"), parseVariationTreeFromFile("exampleB.cpp"));
175+
}
176+
177+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.variantsync.diffdetective.variation.diff.patching;
2+
3+
public class Patching {
4+
5+
}

0 commit comments

Comments
 (0)