Example #1
0
def render_rg(rg):
    """
    Render an ivy_arg.AnalysisGraph object

    """
    g = CyElements()

    # add nodes for states
    for s in rg.states:
        if s.is_bottom():
            classes = ['bottom_state']
        else:
            classes = ['state']
        g.add_node(
            obj=s,
            label=str(s.id),
            classes=classes,
            short_info=str(s.id),
            long_info=[str(x) for x in s.clauses.to_open_formula()],
            locked=True,
        )

    # add edges for transitions
    for source, op, label, target in rg.transitions:
        if label == 'join':
            classes = ['transition_join']
            label = 'join'
            info = 'join'
        else:
            classes = ['transition_action']

            # Curly braces don't survive dot (even if they balance). We work around this by replacing them with digraphs
            # and then fixing it later by modding the text of the canvas items. Also, we want our code labels to be left 
            # justified, so we end the lines with \l, which dot recognizes. Note the backslashes are escaped, since this
            # is *not* a special character, it is a two-character sequence.

            label = label.replace('}',']-').replace('{','-[')
            label = label.replace('\n','\\l')+'\\l'
            info = str(op)
        g.add_edge(
            op,
            source,
            target,
            label=label,
            classes=classes,
            short_info=info,
            long_info=info,
        )

    # add edges for covering
    for covered, by in rg.covering:
        g.add_edge(
            'cover',
            covered,
            by,
            label='',
            classes=['cover'],
            short_info='',
            long_info='',
            events=[],
            actions=[],
        )

    return g
Example #2
0
def render_concept_graph(widget):
    """
    Render the result of concept_alpha to an annotated graph.

    The graph is represented using Python objects compatible with
    Cytoscape's JSON format.

    TODO: maybe this should be a method of ConceptSessionWidget
    """

    concept_session = widget.concept_session

    a = dict(concept_session.abstract_value)
    domain = concept_session.domain

    # treat custom_edge_info and custom_node_label
    custom = set()
    for tag in a.keys():
        if tag[0].startswith('custom_'):
            not_custom_tag = (tag[0][len('custom_'):], ) + tag[1:]
            a[not_custom_tag] = a[tag]
            custom.add(tag[2:])

    # get information from the abstract value
    nodes = set()
    node_labels = set()
    edges = set()
    for tag in a:
        if tag[0] == 'node_info':
            nodes.add(tag[2])
        elif tag[0] == 'edge_info':
            nodes.add(tag[3])
            nodes.add(tag[4])
            edges.add(tag[2:])
        elif tag[0] == 'node_label':
            nodes.add(tag[2])
            node_labels.add(tag[3])
    nodes = sorted(nodes)
    node_labels = sorted(node_labels)
    edges = sorted(edges)

    g = CyElements()

    # add nodes
    non_existing_nodes = set()

    for node in nodes:
        if a[('node_info', 'none', node)]:
            non_existing_nodes.add(node)
            classes = ['non_existing']
            class_disp = 'non existing'
        elif a[('node_info', 'at_least_one',
                node)] and a[('node_info', 'at_most_one', node)]:
            classes = ['exactly_one']
            class_disp = 'exactly one'
        elif a[('node_info', 'at_least_one', node)]:
            classes = ['at_least_one']
            class_disp = 'at least one'
        elif a[('node_info', 'at_most_one', node)]:
            classes = ['at_most_one']
            class_disp = 'at most one'
        else:
            classes = ['node_unknown']
            class_disp = 'maybe non existing, maybe more than one'

        possible_splits = []
        label_lines = []
        for label_name in node_labels:
            if ('node_label', 'node_necessarily', node, label_name) not in a:
                # label not present, probably not well sorted, skip
                continue
            possible_splits.append(label_name)
            if a[('node_label', 'node_necessarily', node, label_name)]:
                k = 'node_necessarily'
            elif a[('node_label', 'node_necessarily_not', node, label_name)]:
                k = 'node_necessarily_not'
            else:
                k = 'node_maybe'
            if (widget.node_label_display_checkboxes[label_name][k].value is
                    False and (node, label_name) not in custom):
                # don't add invisible labels
                continue
            lab = widget.concept_label(domain.concepts[label_name])
            if k == 'node_maybe':
                lab += '?'
            elif k == 'node_necessarily_not':
                lab = '~' + lab
            label_lines.append(lab)

        disp = widget.node_label(domain.concepts[node])
        label = '\n'.join([disp] + label_lines)
        info = '\n'.join([
            node,
            str(domain.concepts[node]),
            class_disp,
        ] + label_lines)

        cluster = domain.concepts[node].sort.name

        if hasattr(widget, 'apply_structure_renaming'):
            label = widget.apply_structure_renaming(label)
            info = widget.apply_structure_renaming(info)
            actions = [(widget.apply_structure_renaming(action[0]), ) +
                       tuple(action[1:]) for action in actions]

        shape = get_shape(node)

        g.add_node(
            obj=node,
            label=label,
            classes=classes,
            short_info=info,
            long_info=info,
            events=[],
            locked=True,
            cluster=cluster,
            shape=shape,
        )

    # add edges
    hidden_by_transitive = get_transitive_reduction(widget, a, edges)
    for edge, source, target in edges:
        x = (edge, source, target)

        if (x in hidden_by_transitive and x not in custom):
            # don't draw edges hidden by transitive reduction
            continue

        if (source in non_existing_nodes or target in non_existing_nodes):
            # don't draw edges to non-existing nodes
            continue

        classes = []
        if a[('edge_info', 'none_to_none') + x]:
            classes.append('none_to_none')
        elif a[('edge_info', 'all_to_all') + x]:
            classes.append('all_to_all')
        else:
            classes.append('edge_unknown')

        if (widget.edge_display_checkboxes[edge][classes[0]].value is False
                and x not in custom):
            # don't add invisible edges
            continue

        if not a[('edge_info', 'none_to_none') + x]:
            classes += [
                c for c in [
                    'total',
                    'functional',
                    'surjective',
                    'injective',
                ] if a.get(('edge_info', c) + x)
            ]

        # TODO: custom edge labels
        labels = ['{}({}, {}):'.format(edge, source, target)]
        labels += [
            c.replace('_', ' ') for c in [
                'none_to_none',
                'all_to_all',
                'total',
                'functional',
                'surjective',
                'injective',
            ] if a.get(('edge_info', c) + x)
        ]

        if hasattr(widget, 'apply_structure_renaming'):
            labels[0] = widget.apply_structure_renaming(labels[0])

        transitive = widget.edge_display_checkboxes[edge]['transitive'].value

        g.add_edge(
            edge,
            source,
            target,
            label=edge,
            classes=classes,
            short_info='\n'.join(labels),
            long_info=[str(domain.concepts[edge])] + labels[1:],
            events=[],
            transitive=transitive,
        )

    return g
Example #3
0
def render_concept_graph(widget):
    """
    Render the result of concept_alpha to an annotated graph.

    The graph is represented using Python objects compatible with
    Cytoscape's JSON format.

    TODO: maybe this should be a method of ConceptSessionWidget
    """

    concept_session = widget.concept_session

    a = dict(concept_session.abstract_value)
    domain = concept_session.domain

    # treat custom_edge_info and custom_node_label
    custom = set()
    for tag in a.keys():
        if tag[0].startswith('custom_'):
            not_custom_tag = (tag[0][len('custom_'):],) + tag[1:]
            a[not_custom_tag] = a[tag]
            custom.add(tag[2:])

    # get information from the abstract value
    nodes = set()
    node_labels = set()
    edges = set()
    for tag in a:
        if tag[0] == 'node_info':
            nodes.add(tag[2])
        elif tag[0] == 'edge_info':
            nodes.add(tag[3])
            nodes.add(tag[4])
            edges.add(tag[2:])
        elif tag[0] == 'node_label':
            nodes.add(tag[2])
            node_labels.add(tag[3])
    nodes = sorted(nodes)
    node_labels = sorted(node_labels)
    edges = sorted(edges)

    g = CyElements()

    # add nodes
    non_existing_nodes = set()

    for node in nodes:
        if a[('node_info', 'none', node)]:
            non_existing_nodes.add(node)
            classes = ['non_existing']
            class_disp = 'non existing'
        elif a[('node_info', 'at_least_one', node)] and a[('node_info', 'at_most_one', node)]:
            classes = ['exactly_one']
            class_disp = 'exactly one'
        elif a[('node_info', 'at_least_one', node)]:
            classes = ['at_least_one']
            class_disp = 'at least one'
        elif a[('node_info', 'at_most_one', node)]:
            classes = ['at_most_one']
            class_disp = 'at most one'
        else:
            classes = ['node_unknown']
            class_disp = 'maybe non existing, maybe more than one'

        possible_splits = []
        label_lines = []
        for label_name in node_labels:
            if ('node_label', 'node_necessarily', node, label_name) not in a:
                # label not present, probably not well sorted, skip
                continue
            possible_splits.append(label_name)
            if a[('node_label', 'node_necessarily', node, label_name)]:
                k = 'node_necessarily'
            elif a[('node_label', 'node_necessarily_not', node, label_name)]:
                k = 'node_necessarily_not'
            else:
                k = 'node_maybe'
            if (widget.node_label_display_checkboxes[label_name][k].value is False and
                (node, label_name) not in custom):
                # don't add invisible labels
                continue
            lab = widget.concept_label(domain.concepts[label_name])
            if k == 'node_maybe':
                lab += '?'
            elif k == 'node_necessarily_not':
                lab = '~' + lab
            label_lines.append(lab)

        disp = widget.node_label(domain.concepts[node])
        label = '\n'.join([disp] + label_lines)
        info = '\n'.join(
            [
                node,
                str(domain.concepts[node]),
                class_disp,
            ] +
            label_lines
        )
        
        cluster = domain.concepts[node].sort.name


        if hasattr(widget, 'apply_structure_renaming'):
            label = widget.apply_structure_renaming(label)
            info = widget.apply_structure_renaming(info)
            actions = [
                (widget.apply_structure_renaming(action[0]), ) + tuple(action[1:])
                for action in actions
            ]

        shape = get_shape(node)

        g.add_node(
            obj=node,
            label=label,
            classes=classes,
            short_info=info,
            long_info=info,
            events=[],
            locked=True,
            cluster=cluster,
            shape=shape,
        )

    # add edges
    hidden_by_transitive = get_transitive_reduction(widget, a, edges)
    for edge, source, target in edges:
        x = (edge, source, target)

        if (x in hidden_by_transitive and x not in custom):
            # don't draw edges hidden by transitive reduction
            continue

        if (source in non_existing_nodes or
            target in non_existing_nodes):
            # don't draw edges to non-existing nodes
            continue

        classes = []
        if a[('edge_info', 'none_to_none') + x]:
            classes.append('none_to_none')
        elif a[('edge_info', 'all_to_all') + x]:
            classes.append('all_to_all')
        else:
            classes.append('edge_unknown')

        if (widget.edge_display_checkboxes[edge][classes[0]].value is False and
            x not in custom):
            # don't add invisible edges
            continue

        if not a[('edge_info', 'none_to_none') + x]:
            classes += [
                c for c in [
                    'total',
                    'functional',
                    'surjective',
                    'injective',
                ] if a.get(('edge_info', c) + x)
            ]

        # TODO: custom edge labels
        labels = ['{}({}, {}):'.format(edge, source, target)]
        labels += [
            c.replace('_', ' ') for c in [
                'none_to_none',
                'all_to_all',
                'total',
                'functional',
                'surjective',
                'injective',
            ] if a.get(('edge_info', c) + x)
        ]

        if hasattr(widget, 'apply_structure_renaming'):
            labels[0] = widget.apply_structure_renaming(labels[0])

        transitive = widget.edge_display_checkboxes[edge]['transitive'].value

        g.add_edge(
            edge,
            source,
            target,
            label=edge,
            classes=classes,
            short_info='\n'.join(labels),
            long_info=[str(domain.concepts[edge])] + labels[1:],
            events=[],
            transitive = transitive,
        )

    return g
Example #4
0
def render_rg(rg):
    """
    Render an ivy_arg.AnalysisGraph object

    """
    g = CyElements()

    # add nodes for states
    for s in rg.states:
        if s.is_bottom():
            classes = ['bottom_state']
        else:
            classes = ['state']
        g.add_node(
            obj=s,
            label=str(s.id),
            classes=classes,
            short_info=str(s.id),
            long_info=[str(x) for x in s.clauses.to_open_formula()],
            locked=True,
        )

    # add edges for transitions
    for source, op, label, target in rg.transitions:
        if label == 'join':
            classes = ['transition_join']
            label = 'join'
            info = 'join'
        else:
            classes = ['transition_action']

            # Curly braces don't survive dot (even if they balance). We work around this by replacing them with digraphs
            # and then fixing it later by modding the text of the canvas items. Also, we want our code labels to be left
            # justified, so we end the lines with \l, which dot recognizes. Note the backslashes are escaped, since this
            # is *not* a special character, it is a two-character sequence.

            label = label.replace('}', ']-').replace('{', '-[')
            label = label.replace('\n', '\\l') + '\\l'
            info = str(op)
        g.add_edge(
            op,
            source,
            target,
            label=label,
            classes=classes,
            short_info=info,
            long_info=info,
        )

    # add edges for covering
    for covered, by in rg.covering:
        g.add_edge(
            'cover',
            covered,
            by,
            label='',
            classes=['cover'],
            short_info='',
            long_info='',
            events=[],
            actions=[],
        )

    return g