« Return to Thread: 'not' as atomic symbol

Re: message queue put-back and backtracking

by Samer Abdallah :: Rate this Message:

Reply to Author | View in Thread


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@...

 « Return to Thread: 'not' as atomic symbol