Exemplo n.º 1
0
def create_mapping(root1, root2):
    """Creates mapping between trees rooted at root1 and root2

    Returns:
    -- new root
    -- map from node index 1 to resulting node
    -- map from node index 2 to resulting node
    """
    apted = APTED(root1, root2, CONFIG)
    mapping = apted.compute_edit_mapping()

    combined_duration = copy(root1.duration)
    combined_duration.update(root2.duration)
    trial_ids = root1.trial_ids + root2.trial_ids
    id_to_node1 = {}
    id_to_node2 = {}

    for node1, node2 in mapping:
        if node1 is None:
            node = id_to_node2[node2.index] = copy(node2)
            node.children1 = []
            node.children2 = node2.children
            node.original1 = None
            node.original2 = node2.index

        elif node2 is None:
            node = id_to_node1[node1.index] = copy(node1)
            node.children1 = node1.children
            node.children2 = []
            node.original1 = node1.index
            node.original2 = None
        else:
            if node1.name != node2.name:
                print("Warning. Mismatch?", node1.name, node2.name)
            merge(node1, node2, id_to_node1, id_to_node2)
            # Note that it overrides node1 attributes

    if id_to_node1[root1.index] is not id_to_node2[root2.index]:
        root = Node(
            index=0,
            parent_index=0,
            name="<diff>",
            caller_id=0,
            original1=None,
            original2=None,
            children1=[root1],
            children2=[root2],
            activations=[],
            duration=combined_duration,
            full_tooltip=True,
            tooltip={x: "Diff" for x in trial_ids},
            children_index=-1,
            trial_ids=trial_ids
        )
    else:
        root = id_to_node1[root1.index]

    return root, id_to_node1, id_to_node2
Exemplo n.º 2
0
def diff(tree_before: Node, tree_after: Node) -> (int, dict):
    """
    Returns the difference between two QEP trees

    :param tree_before: The 'before tree'.
    :param tree_after: The 'after tree'.
    :return:
        distance: The structural edit distance between the two trees.
            Only difference in algorithm is captured.
        delta: The difference between the two trees. Has 3 keys:
            - deleted: Those nodes that are deleted from tree_before
            - inserted: Those nodes that are inserted into tree_after
            - stayed: Those nodes that are present in both trees. Has two
                keys:

                - before: the nodes in tree_before
                - after : the nodes in tree_after

                Note that the before and after may be different in attributes
                other than algorithm and operation.
    """
    apted = APTED(tree_before, tree_after, APTEDConfig())
    distance = apted.compute_edit_distance()
    mapping = apted.compute_edit_mapping()

    delta = {
        "deleted": [m[0] for m in mapping if m[1] is None],
        "inserted": [m[1] for m in mapping if m[0] is None],
        "stayed": {
            "before":
            [m[0] for m in mapping if m[0] is not None and m[1] is not None],
            "after":
            [m[1] for m in mapping if m[0] is not None and m[1] is not None]
        }
    }
    return distance, delta