'not' as atomic symbol

View: New views
11 Messages — Rating Filter:   Alert me  

'not' as atomic symbol

by randy sharp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

How do I disable the predicate interpretation of 'not'? I have an NL
application which involves the word 'not', but it seems to be trying to
interpret the word as a predicate rather than as an atomic symbol.

In SICStus, this wasn't a problem. I used the following statement to disable
the prolog interpretation of the following words:

:- op(0,fx,[(wait),(public),(mod),(dynamic)].

I thought the same might apply here:

:- op(0,fx,[(not)].

but this didn't work either. Any advice?
Thanks.

Randy



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

Re: 'not' as atomic symbol

by Jan Wielemaker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tuesday 09 January 2007 23:32, randy sharp wrote:
> How do I disable the predicate interpretation of 'not'? I have an NL
> application which involves the word 'not', but it seems to be trying to
> interpret the word as a predicate rather than as an atomic symbol.

not (or 'not') is an atom.  not/1 is also a predicate.  That should't
bother you.

> In SICStus, this wasn't a problem. I used the following statement to
> disable
>
> the prolog interpretation of the following words:
> :- op(0,fx,[(wait),(public),(mod),(dynamic)].

This is about *operators*.  There isn't much special about these too,
except "dynamic foo/1" is read as "dynamic(foo/1)".  More specifically,
some Prologs to not accept term(dynamic) without the declaration above
as dynamic is an operator > 1000.  SWI-Prolog doesn't care.

> I thought the same might apply here:
> :- op(0,fx,[(not)].

not is not an operator in SWI-Prolog. It is only there as a predicate
for backward compatibility.

> but this didn't work either. Any advice?

Explain the real problem. In a properly designed NLP application it
should not be an issue whether any of these are operators, predicates or
whatever. For one thing, do not use read/1 to read NLP input. read/1 is
to read Prolog terms. Use one of the predicates from the library
readutil or roll your own. Next break the input into words and
punctuation (typically using a DCG). Typically turn the words into atoms
using atom_codes/2. There are some options left here. For example how to
deal with upper/lower case. Also, how to deal with -for example-
all-in-one, etc. Finally start high-level interpretation.

The NLP package contains some useful stuff for western languages (mostly
english I'm afraid).

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

message queue put-back and backtracking

by Samer Abdallah :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Would it be much trouble to add a
thread_putback_message(Queue,Term) procedure
which pushes Term onto the head of the queue?
Even better would be a backtrackable version of
thread_get_message/2 which pushes back the term it just
read on backtracking. (If this seems like an odd request,
I can explain what I'm trying to do - just thought I'd
keep my initial post short and to-the-point.)

cheers,
Samer




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

Re: message queue put-back and backtracking

by Jan Wielemaker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Samer,

On Friday 12 January 2007 15:26, Samer Abdallah wrote:
> Would it be much trouble to add a
> thread_putback_message(Queue,Term) procedure
> which pushes Term onto the head of the queue?
> Even better would be a backtrackable version of
> thread_get_message/2 which pushes back the term it just
> read on backtracking. (If this seems like an odd request,
> I can explain what I'm trying to do - just thought I'd
> keep my initial post short and to-the-point.)

The analogy for message queus is more like a reading/writing to a pipe,
containing terms rather than characters. I'm not saying this can't be
done, but given the possibility of access from multiple threads, strange
things can happen.

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.

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.

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

Parent Message unknown Re: message queue put-back and backtracking

by Samer Abdallah :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 12 Jan 2007, at 15:42, Paulo Moura wrote:

>
> On 2007/01/12, at 14:26, Samer Abdallah wrote:
>
>> Would it be much trouble to add a
>> thread_putback_message(Queue,Term) procedure
>> which pushes Term onto the head of the queue?
>> Even better would be a backtrackable version of
>> thread_get_message/2 which pushes back the term it just
>> read on backtracking.
>
> I assume that the predicate thread_peek_message/2 is not useful for  
> what you're trying to accomplish...
no, because we may have to extract several elements from the
queue before something fails and we have to backtrack to try
an alternative strategy.

>
>> (If this seems like an odd request,
>> I can explain what I'm trying to do - just thought I'd
>> keep my initial post short and to-the-point.)
>
> I'm curious... me, Jan, and a few other people are working on a  
> draft ISO proposal for multi-threading in Prolog.

ok. The particular problem I'm trying to solve is to achieve an effect
something like this:

        forallseq(X,Q,P) :-
                findall(X,Q,Solns),
                mapseq(X-P,Solns).
       
        mapseq(X-P,[Y|YY]) :-
                % create copy of P with variables bound as in Y,
                % like doing a lambda abstraction and beta reduction
                % to apply the result to Y
                copy_term(X-P,Y-R),
                call(R),
                callseq(X-P,YY).

*without* having to wait for findall to finish. I can't
use forall(Q,P) because the way it is defined using negation means
that it doesn't control backtracking through the calls to P in the way
that I want.

It wouldn't matter if the P were purely logical with
no side-effects, but I'm working on a sort of transaction logic which
formalises the logic of mutable systems, database updates etc
(see Anthony Bonner's work). In this case, each call is a transaction  
that
can take the system from one global state to another, advancing a
sort of 'time' counter as it does so. This requires that any changes be
undone on backtracking in the event that a transaction fails. So, if
P1, P2 etc represent the alternative bindings of P as solutions to Q are
found, I want to achieve the effect of the *sequenced* transaction
        P1 >>> P2 >>> P3 ..
(where >>> is my sequencing operator), that is P1 *followed by* P2 etc.

My current solution uses a background thread to generate solutions
to Q and post them to a message queue. The foreground thread reads
the queue and sequences instantiations of P one after the other. It
works perfectly if the P are all deterministic (as would forall/2), but
if, say, P1 is non-deterministic and P3 fails, I want it to backtrack
through P2 and P1 (undoing any state changes), retry P1 some other
way, and then try P2 and P3 again. If thread_get_message was
backtrackable, this would work without any further effort from me!

Samer

>
> Cheers,
>
> Paulo
>
>
> -----------------------------------------------------------------
> Paulo Jorge Lopes de Moura
> Dep. of Computer Science, University of Beira Interior
> 6201-001 Covilhã, Portugal
>
> Office 4.3  Ext. 3257
> Phone: +351 275319891 Fax: +351 275319899
> Email: <mailto:pmoura@...>
>
> Home page: <http://www.di.ubi.pt/~pmoura>
> Research: <http://logtalk.org/>
> -----------------------------------------------------------------
>
>
>


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

Re: message queue put-back and backtracking

by Samer Abdallah :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 12 Jan 2007, at 16:27, Jan Wielemaker wrote:

> Samer,
>
> On Friday 12 January 2007 15:26, Samer Abdallah wrote:
>> Would it be much trouble to add a
>> thread_putback_message(Queue,Term) procedure
>> which pushes Term onto the head of the queue?
>> Even better would be a backtrackable version of
>> thread_get_message/2 which pushes back the term it just
>> read on backtracking. (If this seems like an odd request,
>> I can explain what I'm trying to do - just thought I'd
>> keep my initial post short and to-the-point.)
>
> The analogy for message queus is more like a reading/writing to a  
> pipe,
> containing terms rather than characters. I'm not saying this can't be
> done, but given the possibility of access from multiple threads,  
> strange
> things can happen.
I see what you mean. In that case the solution you propose below
would be ok - provide a method to send a message to the head
of the queue and leave us the option to construct a backtrackable
get_message to use in restricted cases (such as my own) where it is
known to be safe.

>
> 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.
I'm not sure I understand what you mean.

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

Thanks,
Samer



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

Re: message queue put-back and backtracking

by Jan Wielemaker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

> > 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 :-)

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

Re: message queue put-back and backtracking

by Samer Abdallah :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


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

Parent Message unknown Re: message queue put-back and backtracking

by Richard A. O'Keefe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Why not simply represent the queue as a process,
and let that process store the data any way it feels like?

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

Re: message queue put-back and backtracking

by Samer Abdallah :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Just to set the record straight and in case anyone else tries to
implement this, I had to introduce an extra cut in ndet_getmsg1/2
to get this to work properly, because the choice-point created by
retract(pushed_message(Q,M)) was messing things up in a way that
I don't fully understand, but seems to be because of the interaction
between asserta/1 and retract/1 when asserta is called while retract
is active. This is all because I took the cut out of bt_call/2  
thinking it
was a good idea...

So, the solution in full is
----------------------------------------------------

:- dynamic pushed_message/2.

ndet_getmsg(Queue,Message) :-
        bt_call(ndet_getmsg1(Queue,Message),push_back(Queue,Message)).

ndet_getmsg1(Queue, Message) :-
    retract(pushed_message(Queue, Message)), !.   % This is the extra  
necessary cut.

ndet_getmsg1(Queue, Message) :-
    thread_get_message(Queue, Message), !. % This cut is probably not  
necessary.

push_back(Queue, Message) :-
    asserta(pushed_message(Queue, Message)).

bt_call(Do,Undo) :- Do, (true; once(Undo), fail).

---------------------------------------------------
With this it is possible to extract successive elements from the
queue and apply non-deterministic predicates to them in a
fully backtrackable way.

Richard, re your suggestion
> Why not simply represent the queue as a process,
> and let that process store the data any way it feels like?
Forgive me if I'm being dense but what exactly do you mean by
a process in this context? Do you have a particular Prolog  
implementation
in mind?

Cheers,
Samer



On 13 Jan 2007, at 17:11, Samer Abdallah wrote:

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


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

Re: 'not' as atomic symbol

by Richard A. O'Keefe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 10 Jan 2007, at 11:32 am, randy sharp wrote:

> How do I disable the predicate interpretation of 'not'?

Unless you are trying to define a predicate called 'not',
why do you want to?

> I have an NL application which involves the word 'not', but it seems  
> to be trying to interpret the word as a predicate rather than as an  
> atomic symbol.

Could you possibly mean "as an atomic symbol which is an operator"?
But no, in SWI 5.6.27, not _isn't_ an operator, there is nothing at
all special about the atom 'not'.
>
>
> In SICStus, this wasn't a problem. I used the following statement to  
> disable the prolog interpretation of the following words:
>
> :- op(0,fx,[(wait),(public),(mod),(dynamic)].

No, that DIDN'T disable the Prolog interpretation of ANY of those words.
All it did was change the SYNTAX.  Instead of writing
        :- dynamic p/1.
you would have to write
        :- dynamic(p/1).
but the SEMANTICS of 'dynamic' is in no way changed by cancelling its
operator properties.
>
>
> I thought the same might apply here:
>
> :- op(0,fx,[(not)].
>
> but this didn't work either.

'not' doesn't have any operator properties to start with.
        X = not,
        Y = [the,problem,is,not,obvious],
        Z = not(knotted(not))
all work perfectly fine out of the box.

What _exactly_ is happening that you don't want to happen?


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