1:- module(count_cudg, []). 2:- use_module(util(math)). 3:- use_module(util(meta2)). 4:- use_module(pac(basic)). 5:- use_module(pac(meta)). 6:- use_module(util(misc)). 7:- use_module(pac('expand-pac')). 8:- use_module(zdd('zdd-array')). 9:- use_module(zdd(zdd)). 10:- use_module(zdd('zdd-misc')). 11:- use_module(zdd('zdd-plain')). 12:- use_module(pac(op)). 13
14:- current_op(X, Y, zdd), op(X, Y, zdd1). 15:- meta_predicate zdd1(:). 16zdd1(G) :- (zdd set_compare(ccu_compare), G).
17
18
21
22 25
37
44
50
57
58count_cudg(Ns, C):- count_connected_udg(Ns, C, _, _).
60count_connected_udg(Ns, C, X, S):-
61 open_state(S),
62 set_compare(ccu_compare, S),
63 zdd_sort(Ns, Ns0, S),
64 all_links(Ns0, Links),
65 findall([A], member(A, Ns0), Singletons),
66 zdd_ord_insert(Singletons, 1, Init, S),
67 memo(add_link(1)-Init, S),
68 zdd_power(Links, Pow, S),
69 add_links_to_udg(Pow, U, S),
70 collect_finals(U, X, S),
71 card(X, C, S).
73add_links_to_udg(0, 0, _):- !.
74add_links_to_udg(1, Y, S):- !, memo(add_link(1)-Y, S).
75add_links_to_udg(X, Y, S):- memo(add_link(X)-Y, S),
76 ( nonvar(Y) -> true 77 ; cofact(X, t(A, L, R), S),
78 add_links_to_udg(L, L0, S),
79 add_links_to_udg(R, R1, S),
80 add_link(A, R1, R0, S),
81 zdd_join(L0, R0, Y, S)
82 ).
83
84 88ccu_compare(=, X, X):-!.
89ccu_compare(<, X, _->_):- listp(X), !.
90ccu_compare(>, _->_, X):- listp(X), !.
91ccu_compare(C, X, Y):- compare(C, X, Y).
98mk_union_find_command(A-B, D, F):- successive_select(D, [A, B], R),
99 ( R = [] -> F = zdd_ord_insert([D, A->B])
100 ; R = [A] -> F = union_find_insert(A->B, A, D)
101 ; R = [B] -> F = union_find_insert(A->B, B, D)
102 ).
103
106successive_select([], Y, Y):-!.
107successive_select([A|X], Y, Z):-select(A, Y, Y0), !,
108 successive_select(X, Y0, Z).
109successive_select([_|X], Y, Z):-successive_select(X, Y, Z).
110
112all_links(Nodes, Links):-
113 findall(A-B, (append(_, [A|R], Nodes),
114 member(B, R),
115 A@<B
116 ),
117 Links).
118
120union_find_insert(_E, _A, _G, X, X, _):- X < 2, !.
121union_find_insert(E, A, G, X, Y, S):-
122 cofact(X, t(U, L, R), S),
123 ( U= (_->_) -> Y = 0
124 ; union_find_insert(E, A, G, L, L0, S),
125 ( memberchk(A, U) ->
126 ord_union(G, U, H),
127 zdd_ord_insert([H,E], R, R0, S)
128 ; union_find_insert(E, A, G, R, R1, S),
129 zdd_insert(U, R1, R0, S)
130 ),
131 zdd_join(L0, R0, Y, S)
132 ).
133
137
142
143add_link(_, X, 0, _):- X<2, !.
144add_link(U, X, Y, S):- 145 cofact(X, t(A, L, R), S),
146 ( A = (_->_) -> Y = 0
147 ; add_link(U, L, L0, S),
148 ( mk_union_find_command(U, A, F) ->
149 call(F, R, R0, S)
150 ; add_link(U, R, R1, S),
151 zdd_insert(A, R1, R0, S)
152 ),
153 zdd_join(L0, R0, Y, S)
154 ).
155
157collect_finals(X, 0, _):- X<2, !.
158collect_finals(X, Y, S):- cofact(X, t(_, L, R), S),
159 collect_finals(L, L0, S),
160 collect_pure_links(R, R0, S),
161 zdd_join(L0, R0, Y, S).
162
164collect_pure_links(X, X, _):-X<2, !.
165collect_pure_links(X, Y, S):- cofact(X, t(A, L, R), S),
166 collect_pure_links(L, L0, S),
167 ( A=[] -> collect_pure_links(R, R0, S)
168 ; A=[_|_] -> R0 = 0
169 ; zdd_insert(A, R, R0, S)
170 ),
171 zdd_join(L0, R0, Y, S).
172
173 176
191
192naive_count_cudg(Ns, C):- naive_count_connected_udg(Ns, C, _, _).
194naive_count_connected_udg(Ns, C, X, S):-
195 open_state(S),
196 set_compare(ccu_compare, S),
197 zdd_sort(Ns, Ns0, S),
198 all_links(Ns0, Links),
199 findall([A], member(A, Ns0), Singletons),
200 zdd_ord_insert(Singletons, 1, Init, S),
201 add_links(Links, Init, U, S),
202 collect_finals(U, X, S),
203 card(X, C, S).
204
206add_links([], X, X, _).
207add_links([L|Ls], X, X0, S):- 208 add_link(L, X, X1, S),
209 zdd_join(X, X1, X2, S),
210 add_links(Ls, X2, X0, S)