1:- module(path_count6, [zdd0/1, co_compare/3]). 2
3:- use_module(library(apply)). 4:- use_module(library(apply_macros)). 5:- use_module(library(clpfd)). 6:- use_module(library(statistics)). 7:- use_module(zdd('zdd-array')). 8:- use_module(util(math)). 9:- use_module(util('pac-meta')). 10:- use_module(pac(basic)). 11:- use_module(pac(meta)). 12:- use_module(util(misc)). 13:- use_module(pac('expand-pac')). 14:- use_module(zdd('zdd-misc')). 15:- use_module(zdd(zdd)). 16:- use_module(zdd('mqp-update2')). 17:- use_module(pac(op)). 18
19
20:- set_prolog_flag(stack_limit, 10_200_147_483_648). 21
22 :- op(1060, xfy, ~). 23 :- op(1060, xfy, #). 24 :- op(1060, xfy, <->). 25 :- op(1050, yfx, <-). 26 :- op(1060, xfy, <=> ). 27 :- op(1040, xfy, \/). 28 :- op(1030, xfy, /\). 29 :- op(1020, fy, \). 30 :- op(700, xfx, :=). 31 :- op(1000, xfy, &). 32
34 :- pac:op(1000, xfy, &). 35 :- pac:op(700, xfx, :=). 36
37term_expansion --> pac:expand_pac.
38
41
42:- meta_predicate zdd0(:). 43zdd0(X):- zdd((set_compare(co_compare),
44 set_pred(admissibility, admissible_qp_link),
45 X)).
46
49
50admissible_qp(X, Y):- X = (_-_),
51 (inadmissible_qp(X, Y) -> false ; true).
52
53
56
57admissible_qp_link(p(I, _)-p(J, _), p(A, B)-p(C, B)):- !, U is min(A, C),
58 I >= U,
59 J >= U.
60admissible_qp_link(p(I, _)-p(J, _), p(A, _)-p(A, _)):- U is A - 1,
61 I >= U,
62 J >= U.
63
66inadmissible_qp(A-B, P-Q):-min(A, B, M),
67 (P @< M ; Q @< M), !.
68
70test_mqp_update:-
71 forall( mqp_query(Mqp, Links),
72 zdd0((X<<Mqp,
73 nl,
74 format("Links = ~w, mqp = ~w\n", [Links, Mqp]),
75 mqp_update_links(Links, X, Y),
76 sets(Y, Y0),
77 maplist(writeln, Y0)))).
79mqp_query({[]}, [a-b]).
80mqp_query({[a-a, b-b]}, [a-b]).
81mqp_query({[a-a, b-b]}, [b-a]).
82mqp_query({[a-a, b-b], [a-a, c-c]}, [a-b]).
83mqp_query({[a-a, b-b], [a-a, b-b, c-c]}, [a-b]).
84mqp_query({[a-a, b-b], [a-a, b-b, c-c]}, [c-d]).
85mqp_query({[a-a, b-c], [a-a, b-b, c-c]}, [c-b]).
86mqp_query({[a-a, b-c], [a-a, b-b, c-c]}, [a-b, c-b]).
87mqp_query({[a-a, b-c], [a-a, b-b, c-c]}, [a-b, c-a]).
88mqp_query({[a-a, b-b]}, [a-b]).
89mqp_query({[a-a, b-b]}, [b-a]).
90mqp_query({[a-a, b-b, c-c]},[a-b, b-c]).
91mqp_query({[a-a, b-b, c-c]}, [b-a, c-b]).
92
105
106co_compare(C, X, Y):- compare(C0, X, Y),
107 ( C0 = (=) -> C = (=)
108 ; functor(X, Fx, _),
109 functor(Y, Fy, _),
110 ( Fx == Fy
111 -> ( Fx = (-)
112 -> ( C0 = (<) -> C = (>) ; C = (<) )
113 ; C = C0
114 )
115 ; ( Fx = (-) -> C = (<) ; C = (>) )
116 )
117 ).
118
121
125link_symbol(_->_).
126change_symbol(A-B, A->B).
128touch(A-_, _-A):-!.
129touch(_-A, A-_).
132
133connect_pairs(X-Y, [U-X, Y-V], U-V):-!.
134connect_pairs(X-Y, [Y-V, U-X], U-V).
135
139
143
147
148prune_frontier(F, E, P, F0):- @(prune_frontier(F, E, P, F0)).
150prune_frontier(F, _, _, F, _):- F<2, !.
151prune_frontier(F, E, P, F0, S):- s_cofact(F, t(A, L, R), S),
152 prune_frontier(L, E, P, L0, S),
153 ( ( A = (X-X)
154 ; A = (P-_)
155 ; admissible_qp(E, A)
156 )
157 -> prune_frontier(R, E, P, R0, S)
158 ; R0 = 0
159 ),
160 s_cofact(F0, t(A, L0, R0), S).
161
163prune_frontier_by_level(F, K, P, F0):- @(prune_frontier_by_level(F, K, P, F0)).
165prune_frontier_by_level(F, _, _, F, _):- F<2, !.
166prune_frontier_by_level(F, K, P, F0, S):- s_cofact(F, t(A, L, R), S),
167 prune_frontier_by_level(L, K, P, L0, S),
168 ( ( A = (X-X)
169 ; A = P - p(K,_)
170 ; A = p(K, _)-p(K, _)
171 )
172 -> prune_frontier_by_level(R, K, P, R0, S)
173 ; R0 = 0
174 ),
175 s_cofact(F0, t(A, L0, R0), S).
176
177
178
179
180 183
200
202
203count_path(X, Y, Z, U):- @(count_path(X, Y, Z, U)).
205count_path(p(I, J), p(_K, L), Bridge, Col, S):-
206 initial_bridge(I, J, L, Bridge),
207 initial_column(I, J, L, Col, S).
208
209
212bridge_shift(F, X, Y):- maplist(shift_link(F), X, Y).
213
216map_h_shift(X, Y):- @(map_h_shift(X, Y)).
218map_h_shift([], [], _).
219map_h_shift([X|Y], [X0|Y0], S):- h_shift(X, X0, S),
220 map_h_shift(Y, Y0, S).
221
224map_v_shift(X, Y):- @(map_v_shift(X, Y)).
226map_v_shift([], [], _).
227map_v_shift([X|Y], [X0|Y0], S):- v_shift(X, X0, S),
228 map_v_shift(Y, Y0, S).
229
231h_shift(X, Y):- @(h_shift(X, Y)).
233h_shift(X, X, _):- X < 2, !.
234h_shift(X, Y, S):- cofact(X, t(p(I, J)-p(I, K), L, R), S),
235 I0 is I + 1,
236 h_shift(L, L0, S),
237 h_shift(R, R0, S),
238 cofact(Y, t(p(I0, J)-p(I0, K), L0, R0), S).
239
243
244v_shift(X, Y):- @(v_shift(X, Y)).
246v_shift(X, X, _):- X < 2, !.
247v_shift(X, Y, S):- cofact(X, t(p(I, J)-p(K, J), L, R), S),
248 v_shift(L, L0, S),
249 v_shift(R, R0, S),
250 J0 is J + 1,
251 cofact(Y, t(p(I, J0)-p(K, J0), L0, R0), S).
252
259
280
288
289solve_rect(X, Y, Z, C):- @(solve_rect(X, Y, Z, C)).
291solve_rect(p(I, J), p(I, L), Z, 1, S):-!, initial_column(I, J, L, Z, S).
292solve_rect(p(I, J), p(K, L), Z, C, S):-
293 initial_col_bridge(I, J, L, Col, B, S),
294 N is (K-I),
295 repeat_bridge(N, Col, I, p(I,J), Col, B, Z, S),
296 card(Z, C, S).
297
298s_psa(X):- @(s_psa(X)).
299
300s_psa(X, @(S,_,_)):-!, psa(X, S).
301s_psa(X, S):- psa(X, S).
303repeat_bridge(0, X, _, _, _, _, X, _):-!, writeln(0).
304repeat_bridge(N, X, K, P, C, B, Y, S):- writeln(N),
305 prune_frontier_by_level(X, K, P, X0, S),
306 mqp_shift(h, C, C0, S),
307 s_zdd_merge(X0, C0, X1, S), 308 s_mqp_update_links(B, X1, Y0, S), 309 maplist(shift_link(h), B, B0),
310 K0 is K + 1,
311 N0 is N - 1,
312 repeat_bridge(N0, Y0, K0, P, C0, B0, Y, S).
313
316initial_col_bridge(I, L, H, C, B):- @(initial_col_bridge(I, L, H, C, B)).
318initial_col_bridge(I, L, H, C, B, S):- initial_column(I, L, H, C, S),
319 initial_bridge(I, L, H, B).
320
321
331
332initial_column(I, Low, Hi, Col):- @(initial_column(I, Low, Hi, Col)).
334initial_column(I, Low, Hi, Col, S):-
335 mqp_linear_grid(Low, Hi, X, S),
336 mqp_lift(x(I), X, Col, S).
337
339initial_bridge(I, Low, Hi, Bridge):- J is I + 1,
340 findall(A,
341 ( member(A, [p(I, V)-p(J, V), p(J, V)-p(I, V)]),
342 between(Low, Hi, V)
343 ),
344 Bridge0),
345 sort(Bridge0, Bridge).
346
347 350
353
354prune_by_column(F, X, P, F0):- @(prune_by_column(F, X, P, F0)).
356prune_by_column([], _, _, [], _).
357prune_by_column([Q|F], X, P, [Q|F0], S):- admissible_qp(Q, X, P, S), !,
358 prune_by_column(F, X, P, F0, S).
359prune_by_column([_|F], X, P, F0, S):-
360 prune_by_column(F, X, P, F0, S).
362admissible_qp(Q, X, P):- @(admissible_qp(Q, X, P)).
364admissible_qp(Q, X, P, S):- qp_list(Q, List, S),
365 admissible_qp_list(List, X, P).
366
368admissible_qp_list([], _, _):-!.
369admissible_qp_list([P-p(X, _)|List], X, P):-!,
370 admissible_qp_list(List, X, P).
371admissible_qp_list([p(X, _)-p(X, _)|List], X, P):- !,
372 admissible_qp_list(List, X, P).
373admissible_qp_list([p(Z, _)-_|_], X, _):- Z>X, !.
374admissible_qp_list([P-P|List], X, P):- admissible_qp_list(List, X, P).
375
380
381
388
390
392mqp_linear_grid(X, Y, Z):- @(mqp_linear_grid(X, Y, Z)).
393
394mqp_linear_grid(E, X, Y, S):-
395 open_state(M, [hash_size(128)]),
396 get_key(admissibility, Pred, S),
397 s_mqp_linear_grid(E, X, Y, @(S, M, Pred)),
398 close_state(M).
400s_mqp_linear_grid(I, I, P, S):-!, s_zdd_singleton(I-I, P, S).
401s_mqp_linear_grid(I, J, Q, S):-
402 M is (I+J)//2,
403 M0 is M+1,
404 s_mqp_linear_grid(I, M, R, S),
405 s_mqp_linear_grid(M0, J, R0, S),
406 s_zdd_merge(R, R0, Q0, S),
407 s_mqp_update_links([M-M0, M0-M], Q0, Q, S).
408
409
412mqp_lift(F, X, Y):- @(mqp_lift(F, X, Y)).
414mqp_lift(F, X, Y, S):-open_state(M, [hash_size(128)]),
415 mqp_lift(F, X, Y, S, M),
416 close_state(M).
418mqp_lift(_, X, X, _, _):- X<2, !.
419mqp_lift(F, X, Y, S, M):- memo(mqp_lift(X)-Y, M), 420 ( nonvar(Y)-> true
421 ; s_cofact(X, t(A, L, R), S),
422 mqp_lift(F, L, L0, S, M),
423 mqp_lift(F, R, R0, S, M),
424 lift_link(F, A, B),
425 s_cofact(Y, t(B, L0, R0), S)
426 ).
427
433
435mqp_shift(F, X, Y):- @(mqp_shift(F, X, Y)).
437mqp_shift(F, X, Y, S):-
438 open_state(M, [hash_size(128)]),
439 mqp_shift(F, X, Y, S, M),
440 close_state(M).
441
443mqp_shift(_, X, X, _, _):- X<2, !.
444mqp_shift(F, X, Y, S, M):- memo(mqp_shift(X)-Y, M), 445 ( nonvar(Y)-> true
446 ; s_cofact(X, t(A, L, R), S),
447 mqp_shift(F, L, L0, S, M),
448 mqp_shift(F, R, R0, S, M),
449 shift_link(F, A, B),
450 s_cofact(Y, t(B, L0, R0), S)
451 ).
452
453
457lift_point(J, x(I), p(I, J)):-!.
458lift_point(J, y(I), p(J, I)).
459
461lift_link(Ctr, A-B, P-Q):-!, lift_point(A, Ctr, P),
462 lift_point(B, Ctr, Q).
464lift_link(Ctr, A->B, P->Q):- lift_point(A, Ctr, P),
465 lift_point(B, Ctr, Q).
467shift_link(h, A, B):-!, h_shift_link(A, B).
468shift_link(v, A, B):- v_shift_link(A, B).
469
472h_shift_point(p(I, J), p(I0, J)):- I0 is I + 1.
473h_shift_point(K, p(I, J), p(I0, J)):- I0 is I + K.
475v_shift_point(p(I, J), p(I, J0)):- J0 is J + 1.
476v_shift_point(K, p(I, J), p(I, J0)):- J0 is J + K.
477
479h_shift_link(P-Q, P0-Q0):-!, h_shift_point(P, P0),
480 h_shift_point(Q, Q0).
481h_shift_link(P->Q, P0->Q0):- h_shift_point(P, P0),
482 h_shift_point(Q, Q0).
484v_shift_link(P-Q, P0-Q0):-!, v_shift_point(P, P0),
485 v_shift_point(Q, Q0).
486v_shift_link(P->Q, P0->Q0):- v_shift_point(P, P0),
487 v_shift_point(Q, Q0).
488
492simple_bridge(A-B, L, M, N):- 493 ( select(B-V, M, M0),
494 select(U-A, L, L0)
495 ; select(B-V, L, L0),
496 select(U-A, M, M0)
497 ),
498 !,
499 ( U @> V
500 -> ord_union(L0, [U-V|M0], N)
501 ; ord_union([U-V], M0, M1),
502 ord_union(L0, M1, N)
503 ).
504simple_bridge(_, _, _, []).
505
507simple_bridge_links([], _, _, Z, Z).
508simple_bridge_links([E|Es], X, Y, Z, U):-
509 simple_bridge_link(X, E, Y, Z, Z0),
510 simple_bridge_links(Es, X, Y, Z0, U).
512simple_bridge_link([], _, _, Z, Z).
513simple_bridge_link([X|Xs], E, Y, Z, U):-
514 simple_bridge_basic(Y, X, E, Z, Z0),
515 simple_bridge_link(Xs, E, Y, Z0, U).
517simple_bridge_basic([], _, _, Z, Z).
518simple_bridge_basic([Y|Ys], X, E, Z, U):- simple_bridge(E, X, Y, V),
519 ( V = []
520 -> Z0 = Z
521 ; Z = [V|Z0]
522 ),
523 simple_bridge_basic(Ys, X, E, Z0, U).
524
527
529simple_prod_union(X, Y, Z):- simple_prod_union(X, Y, Z, []).
531simple_prod_union([], _, U, U).
532simple_prod_union([L|Y], Z, U, V):-
533 simple_union(Z, L, U, U0),
534 simple_prod_union(Y, Z, U0, V).
536simple_union([], _, U, U).
537simple_union([M|As], L, [N|U], V):-
538 ord_union(L, M, N),
539 simple_union(As, L, U, V).
540
541%% test basics.
542% ?- zdd((
543% qp_list(X, [a-a]), qp_list(Y, [b-b]),
544% qp_joint([a-b, b-a], [X], [Y], Z),
545% maplist(pred(([U]:-qp_list(U, List), writeln(List))), Z))).
546% ?- zdd((
547% qp_list(X, [a-a]), qp_list(Y, [b-b]),
548% qp_joint([a-b, b-a], [X], [Y], Z),
549% zdd_join(X, Y, A),
550% memo(qp_suc(A)-L), writeln(qp_suc(A)-L),
551% maplist(pred(([U]:-qp_list(U, List), writeln(List))), Z))).
552% ?- zdd((
553% qp_list(X, [a-a]), qp_list(Y, [b-b]),
554% qp_joint([a-b, b-a], [X], [Y], Z),
555% zdd_join(X, Y, A),
556% memo(qp_suc(A)-L), writeln(qp_suc(A)-L),
557% maplist(pred(([U]:-qp_list(U, List), writeln(List))), Z))).
558
559qp_joint(X, Y, Z, U):-@(qp_joint(X, Y, Z, U)).
561qp_joint(X, Y, Z, U, S):- map_prod_sum(Y, Z, V, [], S),
562 qp_bridge_links(X, Y, Z, U, V, S).
563
568
569qp_bridge(E, X, Y, Z):- @(qp_bridge(E, X, Y, Z)).
571qp_bridge(A-B, X, Y, Z, S):- 572 qp_list(X, L, S),
573 qp_list(Y, M, S),
574 ( select(U-A, L, L0),
575 select(B-V, M, M0)
576 ; select(B-V, L, L0),
577 select(U-A, M, M0)
578 ),
579 !,
580 ord_union(L0, M0, N0),
581 ord_union([U-V], N0, N),
582 qp_list(Z, N, S).
583qp_bridge(_, _, _, 0, _).
584
586qp_bridge_links(X, Y, Z, U, V):- @(qp_bridge_links(X, Y, Z, U, V)).
588qp_bridge_links([], _, _, Z, Z, _).
589qp_bridge_links([E|Es], X, Y, Z, U, S):-
590 qp_bridge_link(X, E, Y, Z, Z0, S),
591 qp_bridge_links(Es, X, Y, Z0, U, S).
593qp_bridge_link([], _, _, Z, Z, _).
594qp_bridge_link([X|Xs], E, Y, Z, U, S):-
595 qp_bridge_basic(Y, X, E, Z, Z0, S),
596 qp_bridge_link(Xs, E, Y, Z0, U, S).
598qp_bridge_basic([], _, _, Z, Z, _).
599qp_bridge_basic([Y|Ys], X, E, Z, U, S):- qp_bridge(E, X, Y, V, S),
600 ( V = 0
601 -> Z0 = Z
602 ; Z = [V|Z0],
603 select_goto(E, X, Y, V, S)
604 ),
605 qp_bridge_basic(Ys, X, E, Z0, U, S).
607select_goto(E, X, Y, Z):- @(select_goto(E, X, Y, Z)).
609select_goto(A-B, X, Y, Z, S):-
610 G = (A-B)-Z,
611 ( A@<B -> W = X ; W = Y ),
612 getmemo(qp_suc(W)-U, V, S),
613 ( var(V) -> V = [] ; true ),
614 add_new(G, V, U).
615
616 619
622belong(X, I, J):- I @=< J, !, I @=< X, X @=< J.
623belong(X, I, J):- J @=< X, X @=< I.
625sub_interval(I, J, X, Y):- belong(I, X, Y), belong(J, X, Y).
627disjoint_interval(I, J, X, Y):- \+ belong(I, X, Y), \+ belong(J, X, Y).
628
633
634compatible_interval(I, J, X, Y):- disjoint_interval(I, J, X, Y), !.
635compatible_interval(I, J, X, Y):- sub_interval(I, J, X, Y), !.
636compatible_interval(I, J, X, Y):- sub_interval(X, Y, I, J).
637
638
645
650
651
654
655rect_dg(rect(W, H), Nodes, Links):-
656 rect_nodes(W, H, Nodes),
657 rect_links(W, H, Nodes, Links).
659
660rect_nodes(W, H, Nodes):-
661 findall(p(I, J),
662 ( between(0, W, I),
663 between(0, H, J)
664 ),
665 Nodes0),
666 sort(Nodes0, Nodes).
667
669rect_links(W, H, Ns, Links):-
670 findall(P-Q,
671 ( member(P, Ns),
672 P = p(I, J),
673 ( Q = p(I, J1),
674 ( J1 is J-1,
675 J1 >= 0
676 ; J1 is J+1,
677 J1 =< H
678 )
679 ; Q = p(I1, J),
680 ( I1 is I-1,
681 I1 >= 0
682 ; I1 is I+1,
683 I1 =< W
684 )
685 )
686 ),
687 Links0),
688 sort(Links0, Links).
689
690 693
708
709path_count(Rect, C):- @(path_count(Rect, C)).
710
712path_count(rect(0,0), 1, _):-!.
713path_count(Rect, C, S):-
714 rect_dg(Rect, Ns, Links),
715 findall(A-A, member(A, Ns), Ids),
716 Rect = rect(W, H),
717 set_key(final, p(W, H), S),
718 qp_list(Q, Ids, S),
719 memo(qp_suc(Q)-[], S),
720 frontier(Links, [Q], FinalQs, S),
721 fold_qp_memo_final(FinalQs, S),
722 path_tree(Q, Tree, S),
723 card(Tree, C, S).
724
726frontier([], Qs, Qs, _).
727frontier([E|Es], Qs, Qs0, S):-
728 frontier_link(E, Qs, Qs1, Qs, S),
729 prune_frontier(Qs1, E, Qs2, S),
730 frontier(Es, Qs2, Qs0, S).
731
733frontier_link(_, [], Qs, Qs, _):-!.
734frontier_link(E, [X|Qs], Qs0, Qs1, S):- X<2, !,
735 frontier_link(E, Qs, Qs0, Qs1, S).
736frontier_link(E, [Q|Qs], Next, Qs1, S):-
737 qp_update(E, Q, Q0, S),
738 ( Q0 < 2
739 -> Next = Qs0
740 ; qp_memo_final(Q0, S),
741 Next = [Q0|Qs0]
742 ),
743 qp_update_succs(E-Q0, Q, S),
744 frontier_link(E, Qs, Qs0, Qs1, S).
745
750map_prod_sum(X, Y, Z):- map_prod_sum(X, Y, Z, []).
752map_prod_sum(X, Y, Z, U):- @(map_prod_sum(X, Y, Z, U)).
753
754map_prod_sum([], _, U, U, _).
755map_prod_sum([Q|Y], Z, U, V, S):- qp_list(Q, L, S),
756 map_qp_sum(Z, L, U, U0, S),
757 map_prod_sum(Y, Z, U0, V, S).
759map_qp_sum([], _, U, U, _).
760map_qp_sum([Q|As], L, [Q0|U], V, S):-qp_list(Q, M, S),
761 ord_union(L, M, N),
762 qp_list(Q0, N, S),
763 map_qp_sum(As, L, U, V, S).
764
765
782
783qp_update(E, X, Y):- @(qp_update(E, X, Y)).
785qp_update(_, X, 0, _):- X < 2.
786qp_update(E, X, Y, S):- qp_list(X, U, S),
787 memo(qp_update(E, X)-Y, S),
788 ( nonvar(Y) -> true
789 ; select_touch(E, [A, B], U, U0)
790 -> connect_pairs(E, [A, B], W),
791 ord_union([W], U0, V),
792 qp_list(Y, V, S)
793 ; Y = 0
794 ).
795qp_update(_, _, 0, _).
796
798qp_update_succs(G, Q):- @(qp_update_succs(G, Q)).
799
801qp_update_succs(G, Q, S):- getmemo(qp_suc(Q)-U, V, S),
802 G = E-Q0,
803 ( var(V) -> U = [E-Q0]
804 ; add_new(E-Q0, V, U)
805 ).
806
807qp_admissible(L):-
808 forall((select(A-B, L, L0), select(C-D, L0, _)),
809 compatible_interval(A, B, C, D)).
810
815
816
822
827
831
832select_touch(_, [], V, V).
833select_touch(E, [A|As], [A|U], V):- touch(E, A), !,
834 select_touch(E, As, U, V).
835select_touch(E, As, [A|U], [A|V]):-select_touch(E, As, U, V).
836
838add_new(X, Y, Y):- memberchk(X, Y), !.
839add_new(X, Y, [X|Y]).
840
844qp_list(Q, List):- @(qp_list(Q, List)).
846qp_list(0, 0, _):-!.
847qp_list(1, [], _):-!.
848qp_list(Q, List, S):- var(Q), !,
849 zdd_insert_atoms(List, 1, Q, S),
850 memo(qp_suc(Q)-U, S),
851 ( var(U) -> U = []
852 ; true 853 ).
854qp_list(Q, [A|As], S):- cofact(Q, t(A, 0, R), S),
855 qp_list(R, As, S).
856
858qp_memo_final(X):- @(qp_memo_final(X)).
860qp_memo_final(Q, S):- memoq(qp_final(Q)-true, S), !.
861qp_memo_final(Q, S):- qp_list(Q, List, S),
862 get_key(final, F, S),
863 ( qp_final(List, F)
864 -> memo(qp_final(Q)-true, S)
865 ; true
866 ).
868fold_qp_memo_final([], _).
869fold_qp_memo_final([Q|Qs], S):- qp_memo_final(Q, S),
870 fold_qp_memo_final(Qs, S).
871
873path_tree(Q, T):- @(path_tree(Q, T)).
875
876path_tree(X, 0, _):- X<1, !.
877path_tree(Q, 1, S):- memoq(qp_final(Q)-true, S), !.
878path_tree(Q, T, S):- memo(path_tree(Q)-T, S),
879 ( nonvar(T) -> true
880 ; memo(qp_suc(Q) - L, S), 881 path_tree_list(L, 0, T, S)
882 ).
884path_tree_list([], C, C, _).
885path_tree_list([E-Q|Qs], C0, C, S):-
886 path_tree(Q, A, S),
887 zdd_insert(E, A, A0, S),
888 zdd_join(C0, A0, C1, S),
889 path_tree_list(Qs, C1, C, S).
890
892
893qp_final([X-Y|R], X, Y):-!, qp_all_id(R).
894qp_final([A-A|R], X, Y):- qp_final(R, X, Y).
895
896qp_final([p(0,0)-F|R], F):-!, qp_all_id(R).
897qp_final([A-A|R], F):- qp_final(R, F).
898
900qp_all_id([]).
901qp_all_id([A-A|R]):- qp_all_id(R).
902
904dag_card(Q, C):- @(dag_card(Q, C)).
906dag_card(Q, C, S):- open_state(M),
907 dag_card(Q, C, S, M),
908 close_state(M).
910dag_card(Q, 0, _, _):- Q<2, !.
911dag_card(Q, 1, S, _):- memoq(qp_final(Q)-true, S), !.
912dag_card(Q, C, S, M):- memo(dag_card(Q)-C, M),
913 ( nonvar(C) -> true
914 ; memo(qp_suc(Q) - L, S),
915 dag_card_list(L, 0, C, S, M)
916 ).
918dag_card_list([], C, C, _, _).
919dag_card_list([_-Q|Qs], C0, C, S, M):-
920 dag_card(Q, A, S, M),
921 C1 is C0 + A,
922 dag_card_list(Qs, C1, C, S, M).
923
924
925 929snap_qp_update(E, X, Y, S):- qp_update(E, X, Y, S),
930 qp_list(X, X0, S),
931 qp_list(Y, Y0, S),
932 format("~w\n~w\n~w\n\n", [qp_update(E, X, Y), X0, Y0]).
934dump_frontier(Qs, S):- maplist(pred(S,
935 ([Q]:- qp_list(Q, U, S), writeln(U))), Qs).
937dump_qp(X, _):- X<2, !, writeln(X).
938dump_qp(X, S):- qp_list(X, L, S),
939 writeln(X=L).
940
942delta_star([], Q, Q, _).
943delta_star([E|Es], Q, Q0, S):- memo(qp_suc(Q)-L, S),
944 writeln(E),
945 memberchk(E-Q1, L),
946 dump_qp(Q1, S),
947 delta_star(Es, Q1, Q0, S).
948
950mirror(X, Y):- @(mirror(X, Y)).
952mirror(X, X, _):- X<2, !.
953mirror(X, Y, S):- cofact(X, t(p(I,J)-p(K,L), Lx, Rx), S),
954 mirror(Lx, MLx, S),
955 mirror(Rx, MRx, S),
956 zdd_insert(p(J, I)-p(L, K), MRx, MRx0, S),
957 zdd_join(MLx, MRx0, Y, S).
958
959%
960rect_path_tree(Rect, T):-@(rect_path_tree(Rect, T)).
961
962rect_path_tree(Rect, T, S):-
963 sort_links_by_rank(Rect, Rs, Ids),
964 Rect = rect(W, H),
965 set_key(final, p(W, H), S),
966 qp_list(Q, Ids, S),
967 repeat_frontier(Rs, [Q], FinalQs, S),
968 fold_qp_memo_final(FinalQs, S),
969 path_tree(Q, T, S).
970
974
975remove_end_links(R, R0, ST):- maplist(pred(ST,
976 ( [J-Es, J-Es0]:- foldl(
977 pred([ST, Es, Es0],
978 ( [P-Q, U, V]:- ST = S-T,
979 ( ( Q==S; P==T)
980 -> V = U
981 ; U = [P-Q|V]
982 ))), Es, Es0, []))), R, R0).
983
985rest(Q, X, Y, S):- memo(qp_suc(Q)-L, S),
986 ( select(Q, X, X0)-> true
987 ; X0 = X
988 ),
989 rest_list(L, X0, Y, S).
991rest_list([], X, X, _).
992rest_list([_-Q|Qs], X, Y, S):-
993 rest(Q, X, X0, S),
994 rest_list(Qs, X0, Y, S).
995
996
1000
1001dbg_qp_update(E, X, Y):- @(dbg_qp_update(E, X, Y)).
1003dbg_qp_update(E, X, Y, S):- qp_list(Q, X, S),
1004 qp_update(E, Q, Q0, S),
1005 qp_list(Q0, Y, S).
1006
1007
1015
1016