Hi Jan,
Thank you for reply. I see your point on shift and throw. I agree. This is a concrete example on your request, though it is not complete one, but I hope my use of balls shifted are always used only in the form of call(ball). My main purpose of using shift is to hide state from programming on ZDD like phrase to hide string from programming on given a grammar, though this may be my superficial impression on shift/reset. Anyway it turned out very useful for the current purpose of mine. Overhead of shift/reset seems good as far as profile tells, though I am occupied only for first climbing high two walls of ZDD (counting paths and associative algebras).
% ?- zdd((X<< pow([a,b]), card(X, C), psa(X)))
%@
%@ zdd 3:
%@ []
%@ [b]
%@ [a]
%@ [a,b]
%@ X = 3,
%@ C = 4.
where, pow is for powerset, card is for cardinality, psa is for printing a zdd in state at X for debugging. This is a complete source listing of card/2, in which shift is used as a la phrase/1,2,3 in the typical usage of shift in my ZDD package. There is no other way of use.
card(X, Y):- shift(card(X, Y)).
%
card(X, Y, S):- setup_call_cleanup( open_memo(M),
card(X, Y, S, M),
close_memo(M)).
card(I, I, _, _):- I < 2, !.
card(I, C, S, M):- memo(I-C, M),
( nonvar(C) -> true
; cofact(I, t(_, L, R), S),
card(R, Cr, S, M),
card(L, Cl, S, M),
C is Cl + Cr
).
zdd(E):- context_module(M),
setup_call_cleanup(
open_state(S),
zdd(E, S, M),
close_state(S)).
%
zdd((A,B), S, M):-!, zdd(A, S, M), zdd(B, S, M).
zdd(X<<E, S, _):-!, zdd_eval(E, X, S).
zdd(M:G, S, _):-!, zdd(G, S, M).
zdd(0, _, _):-!.
zdd(true, _, _):-!.
zdd({G}, _, _):-!, call(G).
zdd((A;B), S, M):-!, (zdd(A, S, M); zdd(B, S, M)).
zdd((A->B), S, M):-!, (zdd(A, S, M)->zdd(B, S, M)).
zdd(Cont, S, M):- reset(M:Cont, Ball, Cont0),
( var(Ball) -> true
; call(Ball, S)
),
zdd(Cont0, S, M).
%
zdd_eval(X, X, _) :-integer(X), !. % for any x >= 0.
zdd_eval(L, Y, S) :-is_list(L), !, sort(L, L0),
list_to_path(L0, Y, S).
zdd_eval({X}, Y, S) :-!, comma_to_list(X, U, []), zdd_family(U, Y, S).
zdd_eval(dnf(A), X, S):-!, expand_boole_macro(A, A0),
boole_to_dnf(A0, X, S).
zdd_eval(cnf(A), X, S):-!, expand_boole_macro(A, A0),
boole_to_cnf(A0, X, S).
zdd_eval(X + Y, A1, S):-!, zdd_eval(X, A2, S),
zdd_eval(Y, A3, S),
zdd_join(A2, A3, A1, S).
zdd_eval(X * Y, A1, S):-!, zdd_eval(X, A2, S),
zdd_eval(Y, A3, S),
zdd_meet(A2, A3, A1, S).
zdd_eval(X - Y, A1, S):-!, zdd_eval(X, A2, S),
zdd_eval(Y, A3, S),
zdd_subtr(A2, A3, A1, S).
zdd_eval(\(X,Y), A, S):-!, zdd_eval(X-Y, A, S).
zdd_eval(merge(X, Y), A1, S):-!, zdd_eval(X, A2, S),
zdd_eval(Y, A3, S),
zdd_merge(A2, A3, A1, S).
zdd_eval(&(X, Y), A, S):-!, zdd_eval(merge(X, Y), A, S).
zdd_eval(prod(X, Y), A1, S):-!, zdd_eval(X, A2, S),
zdd_eval(Y, A3, S),
zdd_product(A2, A3, A1, S).
zdd_eval(**(X, Y), A, S):-!, zdd_eval(prod(X, Y), A, S).
zdd_eval(pow(X), A, S) :-!, zdd_power(X, A, S).
zdd_eval(power(X), A, S):-!, zdd_eval(pow(X), A, S).
zdd_eval(sets(X), A, S) :-!, zdd_eval(X, Y, S),
sets(Y, A, S).
zdd_eval(zdd(E), A, S) :-!, call(E, A, S).
zdd_eval(Other, A, S) :- call(Other, B), zdd_eval(B, A, S).
Kuniaki Mukai