Hi there all,
Since I started using BDDs in automata, I have faced the following
computational problem a few times. If you have any insight on how to solve
it more efficiently, I'd be very interested. In particular, is there a
spot in spot where this is implemented? Let me spell the problem out in
general terms, then tie it to BDDs.
*Definitions.*
- A collection C of sets over a finite universe U is *unambiguous* if all
sets in C are pairwise disjoint. In other words, C is a partition of the
union of its sets.
- A collection C' refines a collection C if each set in C can be obtained
as the union of sets in C'.
*Problem.*
Given a collection C, compute a (minimal) unambiguous refinement of C.
[[For complexity purposes, the computational task can also be written as:
Given C and k, does there exist an unambiguous refinement of C of size < k?
This is certainly NP-complete ([SP7] in Garey and Johnson is that problem
without "unambiguous").]]
*Motivation.*
In BDDs, my use case is to have C be a collection of BDDs and a BDD
represent the set of its satisfying assignments.
Building an unambiguous refinement of BDDs seems an essential step in
determinization: If I have a state with two outgoing transitions labeled
with BDDs {F, G} such that F&G is not False, then this state is
nondeterministic. To determinize it, we will have to consider the
transition labels {F&G, F&!G, !F&G}. Note that this set refines {F, G},
since F = (F&G)|(F&!G) and similarly for G.
*Question.*
What is known about that problem? Is there a good heuristic for it that
would give an unambiguous refinement not far from the optimal?
*Implementations.*
I implemented it in a few different ways and would be interested in
alternative implementations. Two options I have are:
*- The straightforward way:*
1. C' = {U} (recall that U is our universe, with BDDs this would be True)
2. for each S in C:
3. for each S' in C':
4. if (S cap S' is not empty)
5. Remove S' from C'
6. Add (S cap S') and (S^c cap S') to C' (^c denotes complement).
*- A slightly more complex implementation.*
I encode C' as a BDD itself, introducing lots of fresh variables; namely,
if C' = {F, G} for two BDDs F and G, I introduce two fresh variables X_F
and X_G, and encode C' as (F & X_F) | (G & X_G). This allows lines 3 and 4
to become:
3. Compute C' & S and project it on the X_? variables.
4. Iterate through each of the variables that appear: if X_S' appears, this
means that S cap S' is nonempty.
Thanks for reading!
Cheers,
Michaël