IEnumerable <BitVector> enumerateCmp(JoinGraph graph, BitVector S1) { int ntables = graph.vertices_.Count; Debug.Assert(S1 != SetOp.EmptySet); // min(S1) := min({i|v_i \in S1}) int minS1 = SetOp.MinTableIndex(S1); // B_i(W) := {vj |v_j \in W, j <= i} // X = union (B_min(S1), S) BitVector BminS1 = SetOp.OrderBeforeSet(minS1); BitVector X = SetOp.Union(BminS1, S1); // N = neighbour(S1) \ X BitVector N = SetOp.Substract(graph.NeighboursExcluding(S1), X); // for all(vi 2 N by descending i) foreach (int vi in SetOp.TablesDescending(N)) { // emit {v_i} BitVector VI = SetOp.SingletonSet(vi); yield return(VI); // recursively invoke enumerateCmp(graph, {v_i}, X union (B_i intersect N)) BitVector Bi = SetOp.OrderBeforeSet(vi); BitVector BiN = SetOp.Intersect(Bi, N); foreach (var csg in enumerateCsgRecursive(graph, VI, SetOp.Union(X, BiN))) { yield return(csg); } } }
static public void Test() { BitVector S1 = 0b0011_0010; BitVector S2 = 0b0100_0011; Debug.Assert(SetOp.Union(S1, S2) == 0b0111_0011); Debug.Assert(SetOp.Union(S1, S2) == SetOp.Union(S2, S1)); Debug.Assert(SetOp.Intersect(S1, S2) == 0b0000_0010); Debug.Assert(SetOp.Intersect(S1, S2) == SetOp.Intersect(S2, S1)); Debug.Assert(SetOp.Substract(S1, S2) == 0b0011_0000); Debug.Assert(SetOp.Substract(S2, S1) == 0b0100_0001); Debug.Assert(SetOp.CountSetBits(S1) == 3); Debug.Assert(SetOp.MinTableIndex(S1) == 1); Debug.Assert(SetOp.MinTableIndex(S2) == 0); Debug.Assert(SetOp.OrderBeforeSet(3) == 15); var l = SetOp.TablesAscending(S2).ToList(); Debug.Assert(l.SequenceEqual(new List <int>() { 0, 1, 6 })); l = SetOp.TablesDescending(S2).ToList(); Debug.Assert(l.SequenceEqual(new List <int>() { 6, 1, 0 })); }
IEnumerable <BitVector> enumerateCsg(JoinGraph graph) { int ntables = graph.vertices_.Count; for (int i = ntables - 1; i >= 0; i--) { // emit S // S: {vi} BitVector VI = SetOp.SingletonSet(i); // Console.WriteLine("S: {0}", i); yield return(VI); // EnumerateCsgRec (G, S, X) // X: {vj|j<=i} BitVector X = SetOp.OrderBeforeSet(i); foreach (var csg in enumerateCsgRecursive(graph, VI, X)) { yield return(csg); } } }