Example #1
0
def intensional_proposal(best, A, B):
    matches = tipward(best, A, B)

    result = {}

    incoming = index_by_target(matches)

    # Suppose `node` x comes from the A checklist, and there is a split
    # such that x matches multiple nodes y1, y2 in the B checklist.

    # Modify the relation for all approximate-match nodes.
    for y in incoming:  # Many x's, one y
        arts = incoming[y]

        # Canonical.  back.cod will be among the incoming, by construction.
        back = matches.get(y)  # back : y -> x
        if not back: continue
        x0 = back.cod  # Back match y -> x -> y

        revarts = incoming[x0]

        if len(arts) > 1:  # multiple x's
            if len(revarts) > 1:
                art.proclaim(result, art.set_relation(back, rel.eq))
                dribble.log("** Tangle:\n   %s\n   %s" %
                            ("\n   ".join(map(art.express, arts)),
                             ("\n   ".join(map(art.express, revarts)))))
                art.proclaim(result, art.set_relation(back, rel.eq))
            else:

                # OK.  We're going to just throw away all non-sibling matches.

                rent = cl.get_parent(x0)
                sibs = [ar for ar in arts if cl.get_parent(ar.dom) == rent]
                # e.g. ar: x2 -> y
                # Don't even try to do anything with N->M node tangles.
                if len(sibs) == 1:
                    art.proclaim(result, art.set_relation(back, rel.eq))
                else:
                    for sib in sibs:
                        ar = art.change_relation(sib, rel.lt, "merge", "split")
                        if sib.dom == x0:
                            art.proclaim(result, ar)  # gt
                        else:
                            art.half_proclaim(result, ar)
                    art.half_proclaim(
                        result, art.bridge(y, rent, rel.lt, "split", "merge"))
                    # Report!
                    dribble.log(
                        "# Split/lump %s < %s < %s" %
                        (" + ".join(map(lambda e: cl.get_unique(e.dom), sibs)),
                         cl.get_unique(y), cl.get_unique(rent)))

        elif len(revarts) > 1:  # multiple y's
            pass
        else:
            # n.b. arts[0] is reverse of back
            art.proclaim(result, art.set_relation(back, rel.eq))

    return result
Example #2
0
def merged_parent(merged, al):
    (x, y) = merged  # False if node is inconsistent

    if y:
        q = cl.get_parent(y)
        if x:
            p = cl.get_parent(x)
        else:
            p = partner(y, al)  # cannot be =, must be <

        # If p takes us back to q, then parent should be p, else q
        scan = p
        while scan:
            z = partner(scan, al)
            if z:
                if z == q:
                    return inject_A(p, al)
                else:
                    return inject_B(q, al)
            scan = cl.get_parent(scan)
        return inject_B(q, al)

    else:
        assert x
        q = partner(x, al)
        if q:
            return inject_B(q, al)
        else:
            return inject_A(cl.get_parent(x), al)
Example #3
0
  def taxon_report(mnode, indent):
    nodiff = None
    different = mnode in any_descendant_differs

    id = id_table[mnode]
    (x, y) = mnode
    re = None
    dif = None
    z = None
    note = None
    if x and y:
      op = "SHARED"
      ar = al.get(x)
      comparison = changes.differences(x, y, all_props)    # (drop, change, add)
      if not changes.same(comparison):
        props = changes.unpack(comparison)
        dif = ("; ".join(map(lambda x:x.pet_name, props)))
      px = cl.get_parent(x)
      qx = al.get(px)
      if qx and qx.cod != cl.get_parent(y):
        #note = ("moved from %s" % cl.get_taxon_id(px))
        note = "moved"

      if not different:
        childs = children.get(mnode, [])
        if len(childs) > 0:
          nodiff = "subtree="
        else:
          nodiff = "shared tip"

    elif x:
      op = "A ONLY"
      ar = al.get(x)
      if ar:
        z = ar.cod
        # Equivalence, usually, but sometimes not

        if ar.relation == rel.eq:
          note = "lump"         # ??? is this right?
        elif ar.relation == rel.matches:
          note = "near miss"
        elif ar.relation == rel.conflict:
          note = "conflict"
        elif ar.relation == rel.refines:
          note = "loss of resolution"
    else:                       # y
      op = "B ONLY"
      ar = al.get(y)
      if ar:
        z = ar.cod
        if ar.relation == rel.eq:
          note = "split"
        elif ar.relation == rel.conflict:
          note = "reorganization"
        elif ar.relation == rel.refines:
          note = "increased resolution"

    report_one_articulation(id, op, nodiff, dif, x, y, z, ar, note, writer, indent)
    return different
Example #4
0
 def luup(x, y):
   if x == cl.forest_tnu or y == cl.forest_tnu: return
   assert cl.get_checklist(x) != cl.get_checklist(y)
   if in_chain(x, y0) and in_chain(y, x0):
     bar = best.get(x)
     if bar and find_in_chain(bar.cod, y, x0):
       if bar.cod == y:
         art.proclaim(draft, art.change_relation(bar, rel.eq, "extensional"))
         luup(cl.get_parent(x), cl.get_parent(y))
       else:
         art.proclaim(draft, art.extensional(y, x, rel.lt, "presumed 0"))
         luup(x, cl.get_parent(y))
     else:
       bar = best.get(y)
       if bar and find_in_chain(bar.cod, x, y0):
         if bar.cod == y:
           art.proclaim(draft, bar)
           luup(cl.get_parent(x), cl.get_parent(y))
         else:
           art.proclaim(draft, art.extensional(x, y, rel.lt, "presumed 1"))
           luup(cl.get_parent(x), y)
       else:
         # neither x nor y matches by name
         art.proclaim(draft, art.extensional(x, y, rel.eq, "presumed mutual"))
         luup(cl.get_parent(x), cl.get_parent(y))
Example #5
0
 def luup(x, y):
   if x == cl.forest_tnu or y == cl.forest_tnu: return
   assert cl.get_checklist(x) != cl.get_checklist(y)
   if in_chain(x, y0) and in_chain(y, x0):
     bar = best.get(x)
     if bar and find_in_chain(bar.cod, y, x0):
       if bar.cod == y:
         art.proclaim(proposal, art.change_relation(bar, rel.eq, "extensional"))
         luup(cl.get_parent(x), cl.get_parent(y))
       else:
         art.proclaim(proposal, art.extensional(y, x, rel.lt, "refines", "refined by"))
         luup(x, cl.get_parent(y))
     else:
       bar = best.get(y)
       if bar and find_in_chain(bar.cod, x, y0):
         if bar.cod == y:
           art.proclaim(proposal, bar)
           luup(cl.get_parent(x), cl.get_parent(y))
         else:
           art.proclaim(proposal, art.extensional(x, y, rel.lt, "refines*", "refined by*"))
           luup(cl.get_parent(x), y)
       else:
         # neither x nor y matches by name
         art.proclaim(proposal, art.extensional(x, y, rel.eq, "similar="))
         luup(cl.get_parent(x), cl.get_parent(y))
Example #6
0
 def find_in_chain(b, y, x0):
   if y == cl.forest_tnu:
     return False
   elif in_chain(y, x0):
     if b == y:
       return True
     else:
       return find_in_chain(b, cl.get_parent(y), x0)
   else:
     return False
Example #7
0
 def compatible_ancestor(x):
     p = cl.get_parent(x)
     if p in retract:
         return compatible_ancestor(p)
     return x