Two Xmrs objects are isomorphic if they have the same structure as
    determined by variable linkages between preds.
979501
def _var_isomorphic(a, b, check_varprops=True):
    
    # first some quick checks
    if len(a.eps()) != len(b.eps()): return False
    if len(a.variables()) != len(b.variables()): return False
    #if len(a.hcons()) != len(b.hcons()): return False

    # pre-populate varmap; first top variables
    varmap = {}
    for pair in [(a.top, b.top), (a.index, b.index), (a.xarg, b.xarg)]:
        if pair != (None, None):
            v1, v2 = pair
            if None in pair:
                return False
            if check_varprops and a.properties(v1) != b.properties(v2):
                return False
            varmap[v1] = v2

    # find permutations of variables, grouped by those that share the
    # same signature.

    a_sigs = defaultdict(list)
    for var, vd in a._vars.items():
        if var not in varmap:
            var_sig = _isomorphic_var_signature(vd, a, check_varprops)
            a_sigs[var_sig].append(var)
    b_sigs = defaultdict(list)
    tgtmapped = set(varmap.values())
    for var, vd in b._vars.items():
        if var not in tgtmapped:
            var_sig = _isomorphic_var_signature(vd, b, check_varprops)
            b_sigs[var_sig].append(var)

    candidates = []
    for sig, a_vars in sorted(a_sigs.items(), key=lambda x: len(x[1])):
        b_vars = b_sigs.get(sig, [])
        if len(a_vars) != len(b_vars):
            return False
        print(sig, a_vars, b_vars)
        candidates.append((a_vars, b_vars))

    varmaps = _var_isomorphic(a, b, candidates, varmap)

    # double check HCONS (it's hard to do with var signatures)
    for vm in varmaps:
        if all(vm[lo] == b._hcons.get(vm[hi], (None, None, None))[2]
               for hi, _, lo in a.hcons()):
            return True
    return False
1271006
def same_type(t1, t2):
    
    if isinstance(t1, string_type) and isinstance(t2, string_type):
        return True

    return type(t1) == type(t2)
506879
private boolean sameKeys(KTypeSet<?> other) {
    if (other.size() != size()) {
      return false;
    }

    for (KTypeCursor<?> c : other) {
      if (!contains(Intrinsics.<KType> cast(c.value))) {
        return false;
      }
    }

    return true;
  }
186872
private List<List<Integer>> assignRingGroups(List<Integer[]> rBondsArray) {
        List<List<Integer>> ringGroups;
        ringGroups = new ArrayList<List<Integer>>();
        for (int i = 0; i < rBondsArray.size() - 1; i++) { //for each ring except the last in rBondsArray
            for (int j = 0; j < rBondsArray.get(i).length; j++) { //for each bond in each ring

                //check there's no shared bond with any other ring already in ringGroups
                for (int k = i + 1; k < rBondsArray.size(); k++) {
                    for (int l = 0; l < rBondsArray.get(k).length; l++) { //for each ring in each ring

                        //Is there a bond in common? Then add both rings
                        if (Objects.equals(rBondsArray.get(i)[j], rBondsArray.get(k)[l])) {
                            if (i != k) {
                                ringGroups.add(new ArrayList<Integer>());
                                ringGroups.get(ringGroups.size() - 1).add(i);
                                ringGroups.get(ringGroups.size() - 1).add(k);
                            }
                        }
                    }
                }
            }
        }
        while (combineGroups(ringGroups));

        //Anything not added yet is a singleton
        for (int i = 0; i < rBondsArray.size(); i++) {
            boolean found = false;
            for (int j = 0; j < ringGroups.size(); j++) {
                if (ringGroups.get(j).contains(i)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                ringGroups.add(new ArrayList<Integer>());
                ringGroups.get(ringGroups.size() - 1).add(i);
            }
        }
        return ringGroups;
    }
1985
@Override
	protected boolean areEqual(XSerializer a, XSerializer b) {
		return a.getClass().equals(b.getClass());
	}
186926
function dual(cells, vertex_count) {
  if(!vertex_count) {
    return incidence(unique(skeleton(cells, 0)), cells, 0)
  }
  var res = new Array(vertex_count)
  for(var i=0; i<vertex_count; ++i) {
    res[i] = []
  }
  for(var i=0, len=cells.length; i<len; ++i) {
    var c = cells[i]
    for(var j=0, cl=c.length; j<cl; ++j) {
      res[c[j]].push(i)
    }
  }
  return res
}
212522
def similar(obj1, obj2):
    """"""
    Comparable.log(obj1, obj2, '%')
    similarity = obj1.similarity(obj2)
    Comparable.log(obj1, obj2, '%', result=similarity)
    return similarity
65993
private void hashMix() {
       a = subtract(a, b); a = subtract(a, c); a = xor(a, c >> 13);
       b = subtract(b, c); b = subtract(b, a); b = xor(b, leftShift(a, 8));
       c = subtract(c, a); c = subtract(c, b); c = xor(c, (b >> 13));
       a = subtract(a, b); a = subtract(a, c); a = xor(a, (c >> 12));
       b = subtract(b, c); b = subtract(b, a); b = xor(b, leftShift(a, 16));
       c = subtract(c, a); c = subtract(c, b); c = xor(c, (b >> 5));
       a = subtract(a, b); a = subtract(a, c); a = xor(a, (c >> 3));
       b = subtract(b, c); b = subtract(b, a); b = xor(b, leftShift(a, 10));
       c = subtract(c, a); c = subtract(c, b); c = xor(c, (b >> 15));
     }
1050788
public static boolean iincInsnEqual(IincInsnNode node1, IincInsnNode node2)
	{
		return node1.var == node2.var && node1.incr == node2.incr;
	}
297783
public static boolean sameTypeVars(Type t1, Type t2) {
		return t1 instanceof TypeVariable &&
			t2 instanceof TypeVariable &&
			((TypeVariable<?>) t1).getName().equals(((TypeVariable<?>) t2).getName()) &&
			((TypeVariable<?>) t1).getGenericDeclaration().equals(((TypeVariable<?>) t2).getGenericDeclaration());
	}
338477
public final boolean sameNodeAs(Node other)
  {

    if (!(other instanceof DTMNodeProxy))
      return false;

    DTMNodeProxy that = (DTMNodeProxy) other;

    return this.dtm == that.dtm && this.node == that.node;
  }
253398
def rs_generator_poly(nsym, fcr=0, generator=2):
    ''''''
    g = bytearray([1])
    for i in xrange(nsym):
        g = gf_poly_mul(g, [1, gf_pow(generator, i+fcr)])
    return g
872746
private Node<K, V> joinLR(Node<K, V> a, Node<K, V> b) {
    if (a == null) {
      return b;
    }
    if (b == null) {
      return a;
    }

    if (java.lang.Math.random() * (size(a) + size(b)) < size(a)) {
      a.right = joinLR(a.right, b);
      fix(a);
      return a;
    } else {
      b.left = joinLR(a, b.left);
      fix(b);
      return b;
    }
  }
408776
def identical(self, a, b):
        
        return self._identical(self.convert(a), self.convert(b))
1063112
private static <K, V> HamtPMap<K, V> reconcile(
      @Nullable HamtPMap<K, V> t1,
      @Nullable HamtPMap<K, V> t2,
      BiFunction<V, V, V> joiner) {
    if (t1 == t2) {
      return t1;
    } else if (t1 == null) {
      V newValue = joiner.apply(null, t2.value);
      HamtPMap<K, V>[] newChildren = Arrays.copyOf(t2.children, t2.children.length);
      for (int i = 0; i < newChildren.length; i++) {
        newChildren[i] = reconcile(null, newChildren[i], joiner);
      }
      return newValue != null
          ? new HamtPMap<>(t2.key, t2.hash, newValue, t2.mask, newChildren)
          : deleteRoot(t2.mask, newChildren);
    } else if (t2 == null) {
      V newValue = joiner.apply(t1.value, null);
      HamtPMap<K, V>[] newChildren = Arrays.copyOf(t1.children, t1.children.length);
      for (int i = 0; i < newChildren.length; i++) {
        newChildren[i] = reconcile(newChildren[i], null, joiner);
      }
      return newValue != null
          ? new HamtPMap<>(t1.key, t1.hash, newValue, t1.mask, newChildren)
          : deleteRoot(t1.mask, newChildren);
    }

    // Try as hard as possible to return input trees exactly.
    boolean sameChildrenAs1 = true;
    boolean sameChildrenAs2 = true;

    // If the hashes are different, we need to keep the lower one at the top.
    int hashCmp = compareUnsigned(t1.hash, t2.hash);
    K key = t1.key;
    int hash = t1.hash;
    if (hashCmp < 0) {
      // t1.key is missing from t2
      t2 = t2.vacateRoot();
      sameChildrenAs2 = false;
    } else if (hashCmp > 0) {
      // t2.key is missing from t1
      t1 = t1.vacateRoot();
      sameChildrenAs1 = false;
      key = t2.key;
      hash = t2.hash;
    } else if (!t1.key.equals(t2.key)) {
      // Hash collision: try to rearrange t2 to have the same root as t1
      t2 = t2.pivot(t1.key, t1.hash);
      sameChildrenAs2 = false;
    }
    // Note: one or the other (but not both) tree may have a null key at root.

    V newValue = Objects.equals(t1.value, t2.value) ? t1.value : joiner.apply(t1.value, t2.value);
    int newMask = t1.mask | t2.mask;
    sameChildrenAs1 &= (newMask == t1.mask);
    sameChildrenAs2 &= (newMask == t2.mask);

    @SuppressWarnings("unchecked") // only used internally.
    HamtPMap<K, V>[] newChildren =
        newMask != 0
            ? (HamtPMap<K, V>[]) new HamtPMap<?, ?>[Integer.bitCount(newMask)]
            : emptyChildren();
    int mask = newMask;
    int index = 0;
    while (mask != 0) {
      int childBit = Integer.lowestOneBit(mask);
      mask &= ~childBit;
      HamtPMap<K, V> child1 = t1.getChild(childBit);
      HamtPMap<K, V> child2 = t2.getChild(childBit);
      newChildren[index] = reconcile(child1, child2, joiner);
      sameChildrenAs1 &= (newChildren[index] == child1);
      sameChildrenAs2 &= (newChildren[index] == child2);
      if (newChildren[index] != null) {
        index++;
      } else {
        newMask &= ~childBit;
      }
    }
    if (sameChildrenAs1 && t1.value.equals(newValue)) {
      return t1;
    } else if (sameChildrenAs2 && t2.value.equals(newValue)) {
      return t2;
    } else if (newValue == null) {
      return deleteRoot(newMask, newChildren);
    }
    return new HamtPMap<>(key, hash, newValue, newMask, newChildren);
  }
704402
function swappable(a, b) {
	return DOMUtils.numNonDeletedChildNodes(a) === 1 &&
		similar(a, DOMUtils.firstNonDeletedChild(a)) &&
		mergable(DOMUtils.firstNonDeletedChild(a), b);
}
282939
def links(xmrs):
    """"""

    # Links exist for every non-intrinsic argument that has a variable
    # that is the intrinsic variable of some other predicate, as well
    # as for label equalities when no argument link exists (even
    # considering transitivity).
    links = []
    prelinks = []

    _eps = xmrs._eps
    _hcons = xmrs._hcons
    _vars = xmrs._vars

    lsh = xmrs.labelset_heads
    lblheads = {v: lsh(v) for v, vd in _vars.items() if 'LBL' in vd['refs']}

    top = xmrs.top
    if top is not None:
        prelinks.append((0, top, None, top, _vars[top]))

    for nid, ep in _eps.items():
        for role, val in ep[3].items():
            if role == IVARG_ROLE or val not in _vars:
                continue
            prelinks.append((nid, ep[2], role, val, _vars[val]))

    for src, srclbl, role, val, vd in prelinks:
        if IVARG_ROLE in vd['refs']:
            tgtnids = [n for n in vd['refs'][IVARG_ROLE]
                       if not _eps[n].is_quantifier()]
            if len(tgtnids) == 0:
                continue  # maybe some bad MRS with a lonely quantifier
            tgt = tgtnids[0]  # what do we do if len > 1?
            tgtlbl = _eps[tgt][2]
            post = EQ_POST if srclbl == tgtlbl else NEQ_POST
        elif val in _hcons:
            lbl = _hcons[val][2]
            if lbl not in lblheads or len(lblheads[lbl]) == 0:
                continue  # broken MRS; log this?
            tgt = lblheads[lbl][0]  # sorted list; first item is most "heady"
            post = H_POST
        elif 'LBL' in vd['refs']:
            if val not in lblheads or len(lblheads[val]) == 0:
                continue  # broken MRS; log this?
            tgt = lblheads[val][0]  # again, should be sorted already
            post = HEQ_POST
        else:
            continue  # CARGs, maybe?
        links.append(Link(src, tgt, role, post))

    # now EQ links unattested by arg links
    for lbl, heads in lblheads.items():
        # I'm pretty sure this does what we want
        if len(heads) > 1:
            first = heads[0]
            for other in heads[1:]:
                links.append(Link(other, first, BARE_EQ_ROLE, EQ_POST))
        # If not, something like this is more explicit
        # lblset = self.labelset(lbl)
        # sg = g.subgraph(lblset)
        # ns = [nid for nid, deg in sg.degree(lblset).items() if deg == 0]
        # head = self.labelset_head(lbl)
        # for n in ns:
        #     links.append(Link(head, n, post=EQ_POST))
    def _int(x):
        try:
            return int(x)
        except ValueError:
            return 0
    return sorted(
        links,
        key=lambda link: (_int(link.start), _int(link.end), link.rargname)
    )