Excellent, good to hear.
On second thought, the Set<Set<Integer>> can be represented much more efficiently than I suggested. If there are no more than 32 elements, you can just use a Set<Integer>. If there are no more than 64 elements, use a Set<Long>. For more, use a Set<BigInteger> or Set<BitSet>. In each of these, every possible element that could be in a set is represented by one bit. And that bit is either 0, indicating the element is not a member of the set, or 1, indicating it is a member. You can do other bit twiddling tricks to perform other operations - for example if A and B are ints representing setA and setB, then if (A & B) == A that tells you that A is a subset of B. This sort of thing should take a lot less space than a HashSet of HashSets of Integers.
You can either keep a set of all forbidden sets, or a set of all allowed sets. I would choose whichever is smaller. If there are a lot of forbidden rules, it may be easier to reverse things and only keep track of allowed things. But I will generally assume that it's easier to use a forbidden set - if that's incorrect, then you may have to reverse some of what I say, accordingly.
Note that you don't actually have to keep a set of
all forbidden items. If {1,2} is forbidden, then there's no need to also put {1,2,4} in the forbidden set - you can already exclude any supersets of {1,2,4} based on the fact that they will also contain {1,2}, and that's enough to be forbidden.
It does seem like this technique could still be quite computationally intensive. It may be worthwhile trying to find other ways to do this more efficiently. I'm not sure what other improvements may be possible. But it may also be instructive to implement this algorithm anyway. Maybe it will turn out to be good enough, or maybe there
is no shorter way to do this. Or maybe, in the course of implementing the algorithm, you will learn new things about the problem, and thus get new ideas.
I also have the feeling this may be suitable for a rules engine and the Rete algorithm. But I'm not sure; I don't understand that very well. Perhaps others here may offer suggestions in this area.
It could also be useful to know more about the "certain unrelated conditions" that you are using to test if a row is forbidden. If we knew what these conditions were, there may be other mathematical properties to be exploited.