public HashSet <ArmadaPC> AssumeIntro(Dictionary <ArmadaPC, ArmadaPC> pcMap) { Diff(); HashSet <ArmadaPC> assumeIntroduced = new HashSet <ArmadaPC>(); // introduced assume statements should not be mapped from any low-level assume statement foreach (var pair in map) { if (pair.Value != null && pair.Key.startPC != null && pair.Key.endPC != null && pair.Value.startPC != null && pair.Value.endPC != null) { if (pcMap.ContainsKey(pair.Key.startPC) && pcMap[pair.Key.startPC] != pair.Value.startPC) { } else { pcMap[pair.Key.startPC] = pair.Value.startPC; } if (pcMap.ContainsKey(pair.Key.endPC) && pcMap[pair.Key.endPC] != pair.Value.endPC) { } else { pcMap[pair.Key.endPC] = pair.Value.endPC; } } } foreach (var node in ASTHelper.Traverse(tgt, false, true)) { if (!map.ContainsValue(node)) { // this statement is not in the map, therefore it should be an assume statement if ((node.Flags & ASTFlag.ASSUME) != ASTFlag.ASSUME) { Console.WriteLine($"{node.TraverseId} is not in the map, but not an assume statement"); } else { assumeIntroduced.Add(node.startPC); assumeIntroduced.Add(node.endPC); } } } return(assumeIntroduced); }
public void Diff() { ASTHelper.InitId(this.src); ASTHelper.InitId(this.tgt); TopDown(); bottomUp(); foreach (var srcNode in ASTHelper.Traverse(src)) { if (!map.ContainsKey(srcNode)) { unmatched.Add(srcNode); map.Add(srcNode, null); } } }
private IEnumerable <ASTNode> FindCandidates(ASTNode node, ASTNode root) { foreach (var candidate in ASTHelper.Traverse(root)) { if (candidate.Value == node.Value && !map.ContainsValue(candidate)) { foreach (var child in node.EnumerateChildren) { if (map.ContainsKey(child) && map[child].parent == candidate) { yield return(candidate); break; } } } } }
private void bottomUp() { foreach (var node in ASTHelper.Traverse(src, true)) { if (!map.ContainsKey(node)) { bool flag = false; foreach (var child in node.EnumerateChildren) { if (map.ContainsKey(child)) { flag = true; break; } } if (flag) { List <ASTNode> candidates = FindCandidates(node, tgt).ToList(); double dice = 0; ASTNode elected = null; foreach (var candidate in candidates) { double temp = Dice(node, candidate, map); if (temp > dice) { elected = candidate; dice = temp; } } if (elected != null && dice > 0.5) { map.Add(node, elected); // TODO(luke): For transformation-specific algorithms } else if (elected != null) { Console.WriteLine($"{elected.TraverseId} elected for {node.TraverseId}, but dice=${dice} failed"); } } } } }
// calculate the weight function private double Dice(ASTNode src, ASTNode tgt, IDictionary <ASTNode, ASTNode> map) { int denominator = 0, numerator = 0; foreach (var srcNode in ASTHelper.Traverse(src)) { foreach (var tgtNode in ASTHelper.Traverse(tgt)) { if (map.ContainsKey(srcNode) && Object.ReferenceEquals(map[srcNode], tgtNode)) { ++numerator; } } } denominator = ASTHelper.Traverse(src).Count() + ASTHelper.Traverse(tgt).Count() - 2; // deleting themselves return(2.0 * ((double)numerator) / ((double)denominator)); }
// Top-Down(preOrder) scan of the AST tree, finish course matches private void TopDown() { var prioritySrc = new SortedSet <ASTNode>(); var priorityTgt = new SortedSet <ASTNode>(); var candidates = new List <Tuple <ASTNode, ASTNode> >(); prioritySrc.Add(this.src); priorityTgt.Add(this.tgt); while (Math.Min(prioritySrc.Max()?.Height ?? -1, priorityTgt.Max()?.Height ?? -1) > minHeight) { if (prioritySrc.Max().Height != priorityTgt.Max().Height) { if (prioritySrc.Max().Height > priorityTgt.Max().Height) { var maxList = Pop(prioritySrc); Open(prioritySrc, maxList); } else { var maxList = Pop(priorityTgt); Open(priorityTgt, maxList); } } else { var srcList = Pop(prioritySrc); var tgtList = Pop(priorityTgt); foreach (var srcNode in srcList) { foreach (var tgtNode in tgtList) { if (Isomorphic(srcNode, tgtNode)) { bool flag = false; foreach (var node in ASTHelper.Traverse(tgt)) { if (Isomorphic(srcNode, node) && tgtNode.TraverseId != node.TraverseId) { flag = true; break; } } if (!flag) { foreach (var node in ASTHelper.Traverse(src)) { if (Isomorphic(node, tgtNode) && srcNode.TraverseId != node.TraverseId) { flag = true; break; } } } if (!flag) { map.Add(srcNode, tgtNode); } else { candidates.Add(Tuple.Create(srcNode, tgtNode)); } } } } Open(prioritySrc, srcList); Open(priorityTgt, tgtList); } } candidates = new List <Tuple <ASTNode, ASTNode> >(candidates.OrderBy(tuple => { if (tuple.Item1.parent == null || tuple.Item2.parent == null) // TODO(luke): what about root? { return(Dice(tuple.Item1, tuple.Item2, map)); } else { return(Dice(tuple.Item1.parent, tuple.Item2.parent, map)); } }).Where(tuple => Dice(tuple.Item1.parent, tuple.Item2.parent, map) > 0)); while (candidates.Count() > 0) { var pair = candidates.Last(); var src = pair.Item1; var tgt = pair.Item2; foreach (var srcNode in ASTHelper.Traverse(src)) { foreach (var tgtNode in ASTHelper.Traverse(tgt)) { if (Isomorphic(srcNode, tgtNode) && !map.ContainsKey(srcNode) && !map.ContainsValue(tgtNode)) { map.Add(srcNode, tgtNode); } } } candidates.RemoveAt(candidates.Count() - 1); } }