def cross_compare(node, conode, proposal): ar = proposal.get(conode) # y -> x' if ar == None: return (None, None) how = cl.how_related(node, ar.cod) if how == rel.disjoint: return (None, conode) # conode ! node elif how == rel.eq or how == rel.gt: return (conode, None) # conode <= node assert how == rel.lt # node < back is inconclusive d_seen = None # < both node and conode e_seen = None # < conode only for child in cl.get_children(conode): saw = cross_compare(node, child, proposal) if saw: (d, e) = saw if d and e: return saw elif d: if e_seen: return (d, e_seen) else: d_seen = d elif e: if d_seen: return (d_seen, e) else: e_seen = e return (d_seen, e_seen)
def cross_compare(node, conode, xmrcas): back = xmrcas.get(conode) if back == None: return (None, None) how = cl.how_related(node, back) if how == rel.eq: return (conode, None) # conode <= node elif how == rel.gt: return (conode, None) # conode <= node elif how == rel.disjoint: return (None, conode) # conode ! node assert how == rel.lt # node < back is inconclusive x_seen = None y_seen = None for child in cl.get_children(conode): saw = cross_compare(node, child, xmrcas) if saw: (x, y) = saw if x and y: return saw elif x: if y_seen: return (x, y_seen) else: x_seen = x elif y: if x_seen: return (x_seen, y) else: y_seen = y return (x_seen, y_seen)
def process(x): ar = proposal.get(x) if ar and ar.relation == rel.lt: proof = test_compatibility(ar.dom, ar.cod, proposal) if proof: retractions[x] = proof for child in cl.get_children(x): process(child)
def process(node): children = cl.get_children(node) if children: if not cl.is_container(node): out.write("(%s" % cl.get_spaceless(node)) for child in children: out.write(" %s" % cl.get_spaceless(child)) out.write(")\n") for child in children: process(child)
def process(node): merged = inject(node, al) if not merged in parents: p = merged_parent(merged, al) if p: if dribble.watch(node): (x, y) = p dribble.log("# Merged parent(%s) = (%s, %s)" % (cl.get_unique(node), cl.get_unique(x), cl.get_unique(y))) parents[merged] = p # Otherwise it's a root else: if dribble.watch(node): dribble.log("# No merge(%s)" % cl.get_unique(node)) if not merged in roots: roots.append(merged) for child in cl.get_children(node): process(child)
def process(node, less): if not draft.get(node): e = extensional_match(node, xmrcas) if e: if e.relation == rel.lt: if less and e.cod == less.cod: print("# Suppressing %s because redundant with\n %s" % (art.express(e), art.express(less))) pass else: less = e ext[node] = e else: less = None ext[node] = e else: less = None for child in cl.get_children(node): process(child, less)
def filter(node): debug = dribble.watch(node) found_match = None for child in cl.get_children(node): ar = filter(child) if ar: found_match = ar if found_match: # Some descendant is a particle if debug: dribble.log("# %s: descendant matches, not keeping: %s" % (cl.get_unique(node), art.express(found_match))) return found_match elif node in amap: ar = amap[node] tw[ar.dom] = ar if debug: dribble.log("# %s is a tipward match, keeping: %s" % (cl.get_unique(node), art.express(ar))) return ar else: if debug: dribble.log("# %s is unmatched" % cl.get_unique(node)) return None
def subinfer_partners(x, other): y = None for child in cl.get_children(x): child_ar = subinfer_partners(child, other) # an articulation if child_ar != None: child_y = child_ar.cod if y == None: y = child_y else: y = cl.mrca(y, child_y) if y != None: ar = art.extensional(x, y, rel.matches, "cross-mrca") else: ar = get_mutual(best, x) if ar: assert cl.get_checklist(ar.cod) != cl.get_checklist(x) if dribble.watch(x): dribble.log("# Cross-mrca: %s" % (art.express(ar))) xmrcas[x] = ar return ar # in B
def test_compatibility(x, y, proposal): # Look for an intersection between any y-child and x # x is in A checklist, y is in B checklist # Let y1, y2, ... yn be y's children. # We seek a child yk with descendants (d,e) with d<yk and and e!yk, # and a second child yj with c<yj in x (i.e. c and x intersect). yk = c = d = e = None for yi in cl.get_children(y): if not yk: (di, ei) = cross_compare(x, yi, proposal) if di and ei: yk = yi d = di e = ei elif not di and not ei: c = yi else: c = yi if yk: return (yk, c, d, e) else: return None
def subanalyze_cross_mrcas(node, other): result = None probe = tipwards.get(node) if probe: # Could be: = < or > result = probe.cod else: children = cl.get_children(node) if children: m = None # None is the identity for mrca for child in children: m2 = subanalyze_cross_mrcas(child, other) if m2 != None: m = cl.mrca(m, m2) if m != None else m2 if m != None: result = m if result: assert cl.get_checklist(result) != cl.get_checklist(node) if dribble.watch(node): dribble.log("# Cross-mrca(%s) = %s" % (cl.get_unique(node), cl.get_unique(result))) cross_mrcas[node] = result return result # in B
def extensional_match(node, xmrcas): partner = xmrcas.get(node) # node in other checklist; 'conode' if not partner: # Descendant of a particle if dribble.watch(node): dribble.log("# EM: %s is not tipward." % cl.get_unique(node)) return None back = xmrcas.get(partner) # 'bounce' if not back: # Not sure how this can happen but it does (NCBI vs. GBIF) dribble.log("%s <= %s <= nowhere" % (cl.get_unique(node), cl.get_unique(partner))) if dribble.watch(node): dribble.log("# EM: %s killed because aborted round trip." % cl.get_unique(node)) return None # node <= partner <= back how = cl.how_related(node, back) # Alway rcc5 if how == rel.eq: # Should end up being eq iff name match or unique match # Can test for unique match by looking at xmrca of parent # Could be part of a 'monotypic' chain; fix later how = rel.matches reason = "mutual-cross-mrca" elif how == rel.gt: how = rel.matches reason = "monotypic-inversion" elif how == rel.disjoint: reason = "particle-set-exclusion" else: # must be rel.lt # Assume resolution (node < partner) until conflict is proven reason = "refinement" # Look for an intersection between any partner-child and node # x is in A checklist, y is in B checklist for pchild in cl.get_children(partner): pchild_back = xmrcas.get(pchild) if pchild_back == None: # pchild ! node pass else: (d, e) = cross_compare(node, pchild, xmrcas) # d < node while e ! node if d and e: how = rel.conflict reason = ("%s is in; its sibling %s is not" % (cl.get_unique(d), cl.get_unique(e))) dribble.log("** %s conflicts with %s because\n" " %s ! %s\n (but sibling %s < %s)" % (cl.get_unique(node), cl.get_unique(partner), cl.get_unique(e), cl.get_unique(node), cl.get_unique(d), cl.get_unique(node))) break elif e: reason = ("%s is not in it" % cl.get_unique(e)) ar = art.extensional(node, partner, how, reason) if dribble.watch(node): dribble.log("# Extensional articulation %s" % art.express(ar)) return ar
def differences(uid1, uid2, props = None): # mask (add, change, drop) = differences_in_record(uid1, uid2, props = None) if len(cl.get_children(uid1)) != len(cl.get_children(uid2)): change |= 1 << number_of_children.specificity return (add, change, drop)