Peter Szeredi <szeredi(a)cs.bme.hu> writes:
pkt-zer0 <pktzerus(a)gmail.com> writes:
Hello,
A kisháziban megadott count/2 eljárás b. és c. extra funkciónak
megvalósításához (elegendõ számú behelyettesített egyes/nulla után a lista
többi elemét megfelelõen leköti) jól jönne némi segítség. Úgy gondoltam,
hogy valamiféle akkumulátor változóban kéne növelni az egyesek/nullák
számát, amikor egy-egy daemon felébred, de hogy ezt a változót hogyan
lehetne megfelelõen megosztani, nem világos. Esetleg egyáltalán nem így kéne
nekikezdeni a problémának? Bármiféle tippet megköszönnék.
count(L, N) eseten nyilvan erdemes az L-et megszurni, ugy hogy mar csak
valtozok maradjanak benne (persze ekkor N erteke is modosulhat). Ezutan meg
lehet vizsgalni a szelso eseteket (lasd a fenti: "elegendõ számú
behelyettesített egyes/nulla ...." esetet, illetve celszeru azt is
eszrevenni, ha biztos, hogy a count meghiusul). Ha ezek nem jonnek be,
nyilvan az a teendo, hogy csinalunk egy demont, amely arra var, hogy
valamelyik valtozo behelyettesitodjek. Ezt egy vagylagos when feltetellel
lehet megcsinalni, amihez egy [X1,X2,...Xn] listabol elo kell allitani a
(when(X1);when(X2);...when(Xn)) adatstrukturat.
Erre gondoltam:
(nonvar(X1);nonvar(X2);...nonvar(Xn)) adatstrukturat.
Eloadason valamelyikotok mondta, hogy ugyanezt freeze-zel oldotta meg, ha
jol ertettem valahogy igy:
Goal = p([X1,...,Xn],Param), freeze(X1, Goal), ..., freeze(Xn, Goal)
Itt nyilvan igaz, hogy Goal meghivodik ha barmelyik Xi behelyettesitodik. A
gond az, hogy ott marad felfuggesztve n-1 darab tovabbi Goal hivas, amely
kesobb, egy masik Xj behelyettesitesekor fel fog ebredni. Ezek
semlegesitesere mutatok egy trukkot. A Goal-t kiegeszitjuk egy argumentummal:
Goal = p1([X1,...,Xn],Stop,Param), freeze(X1, Goal), ..., freeze(Xn, Goal)
Es p1/3-at igy definialjuk:
p1(L, Stop, Param) :-
( nonvar(Stop) -> true
; Stop = stop, % (*)
p(L, Param)
).
Amelyik p1 eloszor ebred fel, az meg egy behelyettesitetlen Stop
argumentumot lat, tehat rafut a (*) sorra, ott behelyettesiti a kozos Stop
valtozot, ezzel hatastalanitva a tobbi p1 hivast.
Alabb mutatok egy nyomkovetest is egy ilyen futasrol.
-Peter
| ?- [user].
% consulting user...
| p(L, Param) :- write(L-Param), nl.
| eq(U, U).
|
% consulted user in module user, 0 msec 128 bytes
yes
% trace
| ?- Goal = p1([X1,Xn],Stop,param), freeze(X1, Goal), freeze(Xn, Goal), eq(X1-Xn, a-b).
- - Block: freeze(_1262,user:p1([_1262,_520],_551,param))
- - Block: freeze(_1315,user:p1([_1262,_1315],_551,param))
1 1 Call: eq(_1262-_1315,a-b) ?
- - Unblock: prolog:freeze__int(a,user:p1([a,b],_551,param))
2 2 Call: p1([a,b],_551,param) ?
3 3 Call: nonvar(_551) ?
3 3 Fail: nonvar(_551) ?
4 3 Call: _551=stop ?
4 3 Exit: stop=stop ?
5 3 Call: p([a,b],param) ?
6 4 Call: write([a,b]-param) ?
6 4 Exit: write([a,b]-param) ? [a,b]-param
7 4 Call: nl ?
7 4 Exit: nl ?
5 3 Exit: p([a,b],param) ?
2 2 Exit: p1([a,b],stop,param) ?
- - Unblock: prolog:freeze__int(b,user:p1([a,b],stop,param))
8 2 Call: p1([a,b],stop,param) ?
9 3 Call: nonvar(stop) ?
9 3 Exit: nonvar(stop) ?
8 2 Exit: p1([a,b],stop,param) ?
1 1 Exit: eq(a-b,a-b) ?
X1 = a,
Xn = b,
Goal = p1([a,b],stop,param),
Stop = stop ? ;