On 12 Jan 2007, at 20:04, Jan Wielemaker wrote:
> On Friday 12 January 2007 20:19, Samer Abdallah wrote:
>> On 12 Jan 2007, at 16:27, Jan Wielemaker wrote:
>>> Another disadvantage is that it makes thread_get_message
>>> non-deterministic. Somewhat more in line with the desing might be
>>> a thread_send_message that puts the new message at the head rather
>>> than at the tail. That allows for a design like:
>>>
>>> ndet_get_message(Queue, Message) :-
>>> thread_get_message(Queue, Message),
>>> ( true
>>> ; thread_send_message(Queue, Message, [at(head)]),
>>> fail
>>> ).
>>>
>>> Note however that this implementation is not correct with respect
>>> to the
>>> cut.
>
> Simply consider
>
> ( ndet_get_message(Queue, Message)
> -> fail
> ; true
> ).
>
> With a truly logical predicate this would not change Queue. After
> pruning the choicepoint however the message will not be put back.
>
> You can do the above with the current system easily (not tested):
>
> :- dynamic
> pushed_message/2.
>
> ndet_getmsg(Queue, Message) :-
> ndet_getmsg1(Queue, Message),
> ( true
> ; push_back(Queue, Message)
> ).
>
> ndet_getmsg1(Queue, Message) :-
> retract(pushed_message(Queue, Message)).
> ndet_getmsg1(Queue, Message) :-
> thread_get_message(Queue, Message).
>
> push_back(Queue, Message) :-
> asserta(pushed_message(Queue, Message)).
Thanks Jan, that did the trick, except that I used a backtracking
meta-predicate
that I was already using elsewhere (to manage backtrackable database
updates)
ndet_getmsg(Queue,Message) :-
bt_call(ndet_getmsg1(Queue,Message),push_back(Queue,Message)).
bt_call(Do,Undo) :- Do, on_backtracking(Undo).
on_backtracking(_).
on_backtracking(G) :- G, !, fail.
though now I'm getting paranoid about cuts and whether or not they're
doing the right thing! For example, I originally had
bt_call(Do,Undo) :- Do, !, on_backtracking(Undo).
but just now I removed the cut so that Do can be non-deterministic.
>
>>> So, I'd prefer to consider the problem at a somewhat higher level
>>> first
>>> to see whether there is an elegant solution you missed there.
>>
>> Well, I would like to be able to solve the problem without invoking
>> another thread - essentially what I want is a findall that returns
>> a *lazy* list that carries enough information about the state of
>> solution search to build itself on demand as it goes along. I can't
>> see how to do it without using a meta-interpreter which handles
>> the search tree explicitly at the meta level.
>> My current transaction logic interpreter still relies on backtracking
>> in the underlying interpreter - doing otherwise would make it much
>> more complex. Hence the quick and i hope not-too-dirty multithreading
>> approach.
>
> I'm not very good at that, but you can hack some of these things using
> coroutining or attributed variables. Its a really nice puzzle :-)
corouting --> next rainy sunday!
Thanks,
Samer
>
> Success --- Jan
>
>
> ------------
> For further info, please visit
http://www.swi-prolog.org/>
> To unsubscribe, send a plaintext mail with "unsubscribe prolog <e-
> mail>"
> in its body to
majordomo@...
------------
For further info, please visit
http://www.swi-prolog.org/To unsubscribe, send a plaintext mail with "unsubscribe prolog <e-mail>"
in its body to
majordomo@...