See Theorem 6.2 in paper.
    Prunes (x,...,a) when (x,a) is explored and a has the same neighbour set in both graphs.
484401
def _theorem6p2():
    
    pruning_set2 = set()

    def _prune2(x, a, nbrs_a):
        frozen_nbrs_a = frozenset(nbrs_a)
        for i in range(len(x)):
            key = (tuple(x[0:i]), a, frozen_nbrs_a)
            if key in pruning_set2:
                return True
        return False

    def _explored2(x, a, nbrs_a):
        prunable = (tuple(x), a, frozenset(nbrs_a))  # (s,a,N(a))
        pruning_set2.add(prunable)
        return prunable

    def _finished2(prunable):
        pruning_set2.remove(prunable)

    return _prune2, _explored2, _finished2
313386
def __matches(s1, s2, ngrams_fn, n=3):
    
    ngrams1, ngrams2 = set(ngrams_fn(s1, n=n)), set(ngrams_fn(s2, n=n))
    return ngrams1.intersection(ngrams2)
1092673
static boolean mergeVertices(Point pt_1, Point pt_2, double w_1,
			int rank_1, double w_2, int rank_2, Point pt_res, double[] w_res,
			int[] rank_res) {
		assert (!pt_1.isEmpty() && !pt_2.isEmpty());
		boolean res = pt_1.equals(pt_2);

		if (rank_1 > rank_2) {
			pt_res = pt_1;
			if (w_res != null) {
				rank_res[0] = rank_1;
				w_res[0] = w_1;
			}
			return res;
		} else if (rank_2 > rank_1) {
			pt_res = pt_2;
			if (w_res != null) {
				rank_res[0] = rank_1;
				w_res[0] = w_1;
			}
			return res;
		}

		pt_res = pt_1;
		Point2D pt2d = new Point2D();
		mergeVertices2D(pt_1.getXY(), pt_2.getXY(), w_1, rank_1, w_2, rank_2,
				pt2d, w_res, rank_res);
		pt_res.setXY(pt2d);
		return res;
	}
461885
private static boolean between(int[] verts, int a, int b, int c) {
        if (!collinear(verts, a, b, c))
            return false;
        // If ab not vertical, check betweenness on x; else on y.
        if (verts[a + 0] != verts[b + 0])
            return ((verts[a + 0] <= verts[c + 0]) && (verts[c + 0] <= verts[b + 0]))
                    || ((verts[a + 0] >= verts[c + 0]) && (verts[c + 0] >= verts[b + 0]));
        else
            return ((verts[a + 2] <= verts[c + 2]) && (verts[c + 2] <= verts[b + 2]))
                    || ((verts[a + 2] >= verts[c + 2]) && (verts[c + 2] >= verts[b + 2]));
    }
1087627
private boolean areaLinePredicates_(int half_edge, int id_a, int id_b) {
        boolean bRelationKnown = true;

        if (m_perform_predicates[MatrixPredicate.InteriorInterior])
        {
            interiorAreaInteriorLine_(half_edge, id_a, id_b);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorInterior);
        }

        if (m_perform_predicates[MatrixPredicate.InteriorBoundary])
        {
            interiorAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorBoundary);
        }

        if (m_perform_predicates[MatrixPredicate.InteriorExterior])
        {
            interiorAreaExteriorLine_(half_edge, id_a, id_b);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorExterior);
        }

        if (m_perform_predicates[MatrixPredicate.BoundaryInterior])
        {
            boundaryAreaInteriorLine_(half_edge, id_a, id_b, m_cluster_index_b);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryInterior);
        }

        if (m_perform_predicates[MatrixPredicate.BoundaryBoundary])
        {
            boundaryAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryBoundary);
        }

        if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
        {
            boundaryAreaExteriorLine_(half_edge, id_a, id_b);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryExterior);
        }

        if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
        {
            exteriorAreaInteriorLine_(half_edge, id_a);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorInterior);
        }

        if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
        {
            exteriorAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
            bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorBoundary);
        }

        return bRelationKnown;
	}
1284333
function linComb_(x, y, a, b) {
  var i, c, k, kk;
  k=x.length<y.length ? x.length : y.length;
  kk=x.length;
  for (c=0, i=0; i<k; i++) {
    c+=a*x[i]+b*y[i];
    x[i]=c & mask;
    c>>=bpe;
  }
  for (i=k; i<kk; i++) {
    c+=a*x[i];
    x[i]=c & mask;
    c>>=bpe;
  }
}
407122
private static int findOther(int[] vs, int u, int x) {
        for (int v : vs) {
            if (v != u && v != x) return v;
        }
        throw new IllegalArgumentException("vs[] did not contain another vertex");
    }
1067266
static boolean overlapQuantBounds(int amin[], int amax[], int bmin[], int bmax[]) {
        boolean overlap = true;
        overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
        overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap;
        overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap;
        return overlap;
    }
648383
private static boolean intersectProp(int[] verts, int a, int b, int c, int d) {
        // Eliminate improper cases.
        if (collinear(verts, a, b, c) || collinear(verts, a, b, d) || collinear(verts, c, d, a)
                || collinear(verts, c, d, b))
            return false;

        return (left(verts, a, b, c) ^ left(verts, a, b, d)) && (left(verts, c, d, a) ^ left(verts, c, d, b));
    }
396496
def neighbors_of( p )
      Set.new.tap do |neighbors|
        i = index_mapping[p]
        (0..index_mapping.size-1).each do |j|
          neighbors.add(points[j]) if adjacency_matrix.lookup(i,j) <= eps
        end
      end
    end
337564
public static final <A,B> Set<OrderedPair<A,B>> cartesianProduct(Set<A> a, Set<B> b)
    {
        Set<OrderedPair<A,B>> set = new HashSet<>();
        for (A t : a)
        {
            for (B v : b)
            {
                set.add(new OrderedPair(t, v));
            }
        }
        return set;
    }
563988
def same_network(atree, btree) -> bool:
    
    return same_hierarchy(atree, btree) and same_topology(atree, btree)
274831
private static boolean diagonalie(int i, int j, int n, int[] verts, int[] indices) {
        int d0 = (indices[i] & 0x0fffffff) * 4;
        int d1 = (indices[j] & 0x0fffffff) * 4;

        // For each edge (k,k+1) of P
        for (int k = 0; k < n; k++) {
            int k1 = next(k, n);
            // Skip edges incident to i or j
            if (!((k == i) || (k1 == i) || (k == j) || (k1 == j))) {
                int p0 = (indices[k] & 0x0fffffff) * 4;
                int p1 = (indices[k1] & 0x0fffffff) * 4;

                if (vequal(verts, d0, p0) || vequal(verts, d1, p0) || vequal(verts, d0, p1) || vequal(verts, d1, p1))
                    continue;

                if (intersect(verts, d0, d1, p0, p1))
                    return false;
            }
        }
        return true;
    }
854401
def _graph_reduction(adj, x, g, f):
    
    as_list = set()
    as_nodes = {v for v in adj if len(adj[v]) <= f and is_almost_simplicial(adj, v)}
    while as_nodes:
        as_list.union(as_nodes)
        for n in as_nodes:

            # update g and f
            dv = len(adj[n])
            if dv > g:
                g = dv
            if g > f:
                f = g

            # eliminate v
            x.append(n)
            _elim_adj(adj, n)

        # see if we have any more simplicial nodes
        as_nodes = {v for v in adj if len(adj[v]) <= f and is_almost_simplicial(adj, v)}

    return g, f, as_list
16804
function cutEdges (floatPoints, edges, crossings, junctions, useColor) {
  var i, e

  // Convert crossings into tjunctions by constructing rational points
  var ratPoints = floatPoints.map(function(p) {
      return [
          rat(p[0]),
          rat(p[1])
      ]
  })
  for (i = 0; i < crossings.length; ++i) {
    var crossing = crossings[i]
    e = crossing[0]
    var f = crossing[1]
    var ee = edges[e]
    var ef = edges[f]
    var x = solveIntersection(
      ratVec(floatPoints[ee[0]]),
      ratVec(floatPoints[ee[1]]),
      ratVec(floatPoints[ef[0]]),
      ratVec(floatPoints[ef[1]]))
    if (!x) {
      // Segments are parallel, should already be handled by t-junctions
      continue
    }
    var idx = floatPoints.length
    floatPoints.push([ratToFloat(x[0]), ratToFloat(x[1])])
    ratPoints.push(x)
    junctions.push([e, idx], [f, idx])
  }

  // Sort tjunctions
  junctions.sort(function (a, b) {
    if (a[0] !== b[0]) {
      return a[0] - b[0]
    }
    var u = ratPoints[a[1]]
    var v = ratPoints[b[1]]
    return ratCmp(u[0], v[0]) || ratCmp(u[1], v[1])
  })

  // Split edges along junctions
  for (i = junctions.length - 1; i >= 0; --i) {
    var junction = junctions[i]
    e = junction[0]

    var edge = edges[e]
    var s = edge[0]
    var t = edge[1]

    // Check if edge is not lexicographically sorted
    var a = floatPoints[s]
    var b = floatPoints[t]
    if (((a[0] - b[0]) || (a[1] - b[1])) < 0) {
      var tmp = s
      s = t
      t = tmp
    }

    // Split leading edge
    edge[0] = s
    var last = edge[1] = junction[1]

    // If we are grouping edges by color, remember to track data
    var color
    if (useColor) {
      color = edge[2]
    }

    // Split other edges
    while (i > 0 && junctions[i - 1][0] === e) {
      var junction = junctions[--i]
      var next = junction[1]
      if (useColor) {
        edges.push([last, next, color])
      } else {
        edges.push([last, next])
      }
      last = next
    }

    // Add final edge
    if (useColor) {
      edges.push([last, t, color])
    } else {
      edges.push([last, t])
    }
  }

  // Return constructed rational points
  return ratPoints
}
1108314
function pnpoly (x,y,coords) {
    var vert = [ [0,0] ]

    for (var i = 0; i < coords.length; i++) {
      for (var j = 0; j < coords[i].length; j++) {
        vert.push(coords[i][j])
      }
      vert.push([0,0])
    }

    var inside = false
    for (var i = 0, j = vert.length - 1; i < vert.length; j = i++) {
      if (((vert[i][0] > y) != (vert[j][0] > y)) && (x < (vert[j][1] - vert[i][1]) * (y - vert[i][0]) / (vert[j][0] - vert[i][0]) + vert[i][1])) inside = !inside
    }

    return inside
  }
1246476
function mpn_one_p(n, l) {
	if (l <= 0 || n[0] != 1) {
		return false;
	}
	for (var i = 1; i < l; ++i) {
		if (n[i] != 0) {
			return false;
		}
	}
	return true;
}