Пример #1
0
 def ancestor_explanation(self, G: InferenceGraph, alist: Alist, summary,
                          max_length, length):
     if length <= max_length:
         # for parent in alist.parent:
         for parent in G.parent_alists(alist.id):
             summary = f"{parent.get('why') if 'why' in parent.attributes else ''} {summary}".strip(
             )
             summary = self.ancestor_explanation(G, parent, summary,
                                                 max_length, length + 1)
     return summary
Пример #2
0
def reduce(alist: Alist, children: List[Alist], G: InferenceGraph):
    if not children:
        return None

    nodes_enqueue = []
    nodes_enqueue_process = []

    # get intersection of child values
    common_items = set()
    head, *tail = children
    has_head_children = False
    has_tail_children = False
    for c in G.child_alists(head.id):
        has_head_children = True
        if c.get(tt.OP) != 'comp':
            if c.get(tt.OPVAR).startswith(vx.NESTING):
                common_items.add(str(c.instantiation_value(c.get(tt.OPVAR))))
            else:
                projVars = c.projection_variables()
                if projVars != None:
                    for pvkey, pvval in projVars.items():
                        common_items.add(c.instantiation_value(pvkey))

    for t in tail:
        c_items = set()
        for tc in G.child_alists(t.id):
            has_tail_children = True
            if tc.get(tt.OPVAR).startswith(vx.NESTING):
                c_items.add(str(c.instantiation_value(tc.get(tt.OPVAR))))
            projVars = tc.projection_variables()
            if projVars != None:
                for pvkey, pvval in projVars.items():
                    c_items.add(tc.instantiation_value(pvkey))
        common_items = common_items.intersection(c_items)

    if not common_items and not has_head_children and not has_tail_children:
        for c in children:
            if c.get(tt.OP) != 'comp':
                if c.get(tt.OPVAR).startswith(vx.NESTING):
                    common_items.add(
                        str(c.instantiation_value(c.get(tt.OPVAR))))
                else:
                    projVars = c.projection_variables()
                    if projVars != None:
                        for pvkey, pvval in projVars.items():
                            common_items.add(c.instantiation_value(pvkey))

    if not common_items:
        return None
    else:
        # if common items not empty, ignore existing siblings before creating new siblings
        sibs = G.child_alists(G.parent_alists(alist.id)[0].id)
        for x in sibs:
            if x.id != alist.id:
                # x.prune()
                G.prune(x.id)
                print(
                    f'{pcol.RED}sibling pruned {x.id}{pcol.RESET} {x}{pcol.RESETALL}'
                )

    # setup new sibling branch(s)
    parent = G.parent_alists(alist.id)[0]
    op_alist = parent.copy()
    op_alist.set(alist.get(tt.OPVAR), '')

    op_alist.set(tt.OP, parent.get(tt.OP))
    op_alist.set(tt.OPVAR, parent.get(tt.OPVAR))
    op_alist.set(op_alist.get(tt.OPVAR), '')
    op_alist.state = states.EXPLORED
    # set as an aggregation node to help with display rendering
    op_alist.node_type = nt.HNODE
    G.link(parent, op_alist, 'comp')
    G.link(alist, op_alist, 'set-comp', create_new_id=False)
    nodes_enqueue.append((op_alist, parent, False, 'comp'))
    print(
        f'{pcol.BLUE}set-comp >> {op_alist.id}{pcol.RESET} {op_alist}{pcol.RESETALL}'
    )
    if alist.children:
        nodes_enqueue.append((op_alist, alist, False, 'setcomp'))

    # create children of the new branch
    # copy to avoid using different version from another thread in loop
    op_alist_copy = op_alist.copy()
    for ff in common_items:
        new_sibling: Alist = op_alist_copy.copy()
        new_sibling.set(tt.OP, 'value')
        new_sibling.set(tt.OPVAR, op_alist_copy.get(tt.OPVAR))
        new_sibling.set(alist.get(tt.OPVAR), ff)
        new_sibling.instantiate_variable(alist.get(tt.OPVAR), ff)
        for ref in new_sibling.variable_references(alist.get(tt.OPVAR)):
            if ref not in [tt.OPVAR]:
                new_sibling.set(ref, ff)
        new_sibling.node_type = nt.ZNODE
        G.link(op_alist, new_sibling, 'comp_lookup')
        nodes_enqueue_process.append(
            (new_sibling, op_alist, True, 'comp_lookup'))
        print(
            f'{pcol.BLUE}  set-comp-child >>> {new_sibling.id}{pcol.RESET} {new_sibling}{pcol.RESETALL}'
        )

    alist.state = states.IGNORE
    alist.nodes_to_enqueue_only = nodes_enqueue
    alist.nodes_to_enqueue_and_process = nodes_enqueue_process
    return alist