public static Stream <Pair <Pair <Pair <int, int>, int>, int>, Epoch> Rectangles(this Stream <bool, Epoch> source, Indices.EmptyKeyIndex <int, Pair <int, int> > emptyIndex, DenseIntKeyIndex <Pair <int, int> > denseIndex) { // prefix extenders take prefixes of various types and propose / validate new values. var prefixExtenders0 = new[] { emptyIndex.CreateExtender <bool>() }; var prefixExtenders1 = new[] { denseIndex.CreateExtender((int xA) => xA) }; var prefixExtenders2 = new[] { denseIndex.CreateExtender((Pair <int, int> xAB) => xAB.First) }; var prefixExtenders3 = new[] { denseIndex.CreateExtender((Pair <Pair <int, int>, int> xABC) => xABC.First.Second), denseIndex.CreateExtender((Pair <Pair <int, int>, int> xABC) => xABC.Second) }; // add new variables one layer at a time. we start with a bool, but discard it asap. var rectangles = source.GenericJoinLayer(prefixExtenders0).Expand().Select(x => x.Second) .GenericJoinLayer(prefixExtenders1).Expand() .GenericJoinLayer(prefixExtenders2).Expand().Where(x => x.First.Second != x.Second) .GenericJoinLayer(prefixExtenders3).Expand().Where(x => x.First.First.First != x.Second); return(rectangles); }
/// <summary> /// Enumerates triangles as triples (a, b, array of c), where each element of the list makes a triangle with edge (a,b). /// </summary> /// <param name="source">An empty bool stream off of which to base the computation; introducing true starts the computation.</param> /// <param name="emptyIndex">The un-keyed index built off of the graph.</param> /// <param name="denseIndex">The int-keyed index built off of the graph.</param> /// <returns>Stream of triangles represented as triples (a, b, cs) of values c completing triangles (a,b).</returns> public static Stream <Pair <Pair <int, int>, int[]>, Epoch> Triangles(this Stream <bool, Epoch> source, Indices.EmptyKeyIndex <int, Pair <int, int> > emptyIndex, DenseIntKeyIndex <Pair <int, int> > denseIndex) { // prefix extenders take prefixes of various types and propose / validate new values. // each of these extender collections are of prefixes of length 0, 1, 2, respectively. // the length 1 extender is cheating a bit; it does not validate against G(b, *). var prefixExtenders0 = new[] { emptyIndex.CreateExtender <bool>() }; var prefixExtenders1 = new[] { denseIndex.CreateExtender((int xA) => xA) }; var prefixExtenders2 = new[] { denseIndex.CreateExtender((Pair <int, int> xAB) => xAB.First), denseIndex.CreateExtender((Pair <int, int> xAB) => xAB.Second) }; // add new variables one layer at a time. we start with a bool, but discard it asap. var triangles = source.GenericJoinLayer(prefixExtenders0).Expand().Select(x => x.Second) .GenericJoinLayer(prefixExtenders1).Expand() .GenericJoinLayer(prefixExtenders2); return(triangles); }