docs: def _var_isomorphic(a, b, check_varprops=True):
      """
      Two Xmrs objects are isomorphic if they have the same structure as
      determined by variable linkages between preds.
      """
      # 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