point notation in Prolog 
Author Message
 point notation in Prolog

Hi,

I was trying to understand one of my old Lisp-programs when i saw
a Lisp instruction very usefull : The point notation in functions arguments
to build a function with a not-defined number of arguments.

How do you do that in Prolog ?

For example a 'add' predicat which adds all its arguments
(which are not in a list of course !) :
        add(R,1,2,3,4).
        R=10

In Lisp you should use something like that: (de add (R,A.L)) (...)

It is very usefull in a Meta-level when you use the same predicat differently
as in OOP if you use 'send' for sending a message to an object without
knowing the number of arguments !

PM

 ____________________________________________________________________________
|                                                  |                         |
| Philippe MATHIEU                                 | tel: (33) 20.43.45.04   |
| LIFL - URA 369 CNRS                              |                         |
| Bat. M3                                          | fax: (33) 20.43.65.66   |
| Universite des Sciences et Technologies de Lille |                         |

| FRANCE                                           |                         |
|_________________________________________________ |_________________________|



Fri, 09 Feb 1996 15:19:37 GMT  
 point notation in Prolog

Lisp   (a . b)  =   Prolog  [ a | b ]

Lisp   (a b)    =   Prolog  [ a, b ]

In Prolog you can also pick off more than one element before the bar:
[X,Y,Z|W] for instance.

Here's one way to sum the numbers in a list:

sum([],0).

sum([First|Rest],N) :- sum(Rest,M), N is M+First.
--
:-  Michael A. Covington, Associate Research Scientist        :    *****

:-  The University of Georgia              phone 706 542-0358 :   *  *  *
:-  Athens, Georgia 30602-7415 U.S.A.     amateur radio N4TMI :  ** *** **  <><



Fri, 09 Feb 1996 23:02:57 GMT  
 point notation in Prolog

   Hi,

   I was trying to understand one of my old Lisp-programs when i saw
   a Lisp instruction very usefull : The point notation in functions arguments
   to build a function with a not-defined number of arguments.

The point notation is used the same way in Prolog:  A.L = [A|L].
Or, if you prefer, in both cases, A is the car of the list and L
is the cdr.

   How do you do that in Prolog ?

   For example a 'add' predicat which adds all its arguments
   (which are not in a list of course !) :
           add(R,1,2,3,4).
           R=10

You say "which are not in a list of course!"  However, A.L is a list,
in both Lisp and Prolog.  You are confusing lists, which are the primary
syntactic structure in Lisp, and which have similar properties in Prolog,
with term arity.  The arguments of a Prolog predicate are not elements of
a list.

   In Lisp you should use something like that: (de add (R,A.L)) (...)

You can do the same thing in Prolog.  Consulting this:

        add(Sum, Addends) :-
                add(Addends, 0, Sum).

        add([], Sum, Sum).
        add(Term.Rest, So_far, Total) :-
                Next is Term + So_far,
                add(Rest, Next, Total) .

Allows you to query:

        ?- add(R, [1,2,3,4]).
        R = 10
        yes.

The only difference is the second argument is a list of unknown
length, instead of a predicate with an unknown number of arguments.

If you wanted this to look more like Lisp, where all the arguments
are the tail of a list whose head is the function name, you can do
it this way (going to extremes to avoid standard Prolog list notation):

        lisp_like_query(Function_name.Arguments) :-
                Call =.. (Function_name.Arguments.[]),
                Call.

        add(Sum.Addends) :-
                add(Addends, 0, Sum).

        add(Term.Rest, So_far, Total) :-
                Next is Term+So_far,
                add(Rest, Next, Total).
        add(Last, So_far, Sum) :-
                Sum is So_far+Last.

And query in a Lisp style (allowing for Prolog dot notation to separate
list elements instead of the Lisp space syntax):

        ?- lisp_like_query(add .R .1 .2 .3 .4).
        R = 10
        yes.

The lisp_like_query/1 predicate can be used for all your "defuns".

If you don't like the lisp_like_query/1, you can skip it by putting
the function symbol as the predicate funtor:

        ?- add(R .1 .2 .3 .4).
        R = 10
        yes.

This could also be written in a single function (the "(...)" in your
"(de add (R,A.L)) (...)" above) and it wouldn't be too disimilar from
typical Lisp defun (or Scheme define, etc.) versions:

        add(Sum.Addends) :-
                Addends = (First.Rest)
                   -> add(Partial.Rest),
                      Sum is First+Partial
                   ;  Sum is 0 .

Some of the spaces are needed so that the dots (".") don't get
confused with decimal points.  You could also query:

        ?- add(R.(1).(2).(3).(4)).
        R = 10
        yes.

The querry "add(R.(1).2.(3).4)" works, too!


Motorola GSTG AI lab, Scottsdale, Arizona



Fri, 09 Feb 1996 16:51:13 GMT  
 point notation in Prolog

Yesterday I asked netters about a predicate which can be called with an unknown
number of arguments, as the point notation in Lisp.

Here is a solution:

:- op(500,xfy,#).

writeline(A # B) :- !, write(A), writeline(B).
writeline(A) :- write(A), nl.

you can now ask it like :

| ?- writeline(a # b # c).
abc

yes
| ?- writeline(a # b # c # d # e).
abcde

yes

I don't really enjoy this solution because it breaks the unity of the Prolog syntax.
You must know by advance how to call this sort of predicate.
The point notation in Lisp allows the user to call a clasical function as well as a function with an unknown number of args.

If you have any other idea ....

PM



Sat, 10 Feb 1996 15:21:40 GMT  
 point notation in Prolog
Quote:


>   Hi,

>   I was trying to understand one of my old Lisp-programs when i saw
>   a Lisp instruction very usefull : The point notation in functions arguments
>   to build a function with a not-defined number of arguments.

                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Quote:
>The point notation is used the same way in Prolog:  A.L = [A|L].
                                ^^^^^^^^
>Or, if you prefer, in both cases, A is the car of the list and L
>is the cdr.

>   How do you do that in Prolog ?

>   For example a 'add' predicat which adds all its arguments
>   (which are not in a list of course !) :
>       add(R,1,2,3,4).
>       R=10

>You say "which are not in a list of course!"  However, A.L is a list,
>in both Lisp and Prolog.  You are confusing lists, which are the primary
>syntactic structure in Lisp, and which have similar properties in Prolog,
>with term arity.  The arguments of a Prolog predicate are not elements of

                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Quote:
>a list.
 ^^^^^^

>   In Lisp you should use something like that: (de add (R,A.L)) (...)

>You can do the same thing in Prolog.  Consulting this:
> [Prolog code removed]

Actually, in the context in which the `.' occurs in the Lisp defun it
does not indicate the presence of a list of arguments with a variable
tail. To plagiarise the truism above ``The arguments of a Lisp
predicate are not elements of a list'' A parse of the defun form would
indeed return a list with a dotted tail but at call time arguments are
not supplied in a list they are supplied on a stack. This has been the
case with every real Lisp since McCarthy's Lisp 1.5. In the Prolog
code (deleted merely to preserve silica) lists of arguments must be
constructed by the *caller* and supplied at runtime. In the Lisp code
the caller does not supply a list of arguments, instead the call form
can have variable arity. In Common Lisp extra arguments are indicated
by the &REST keyword, not by a `.'.

The question here is to do with variable numbers of arguments to a
function, which should not be conflated with passing variable amounts
of data by supplying structures as arguments. The correct response to
Matthieu Philou is that you *cannot* define Prolog predicates with
variable arity but you can achieve the same effect in Prolog with much
the same runtime overheads as for Lisp by passing the variable
arguments in a (list) structure (note that the compiled version of the
*called* Lisp function conses any extra arguments supplied by the
caller into a list so it does the work done by the caller in Prolog).

Perhaps someone might like to argue the question whether it is a
*good* or *bad* thing to allow variable numbers of arguments rather
than require bundling of such arguments in some structure. Distinguish
carefully variable arity functions from *argument defaulting* (as in
C++ and various Lisps) where functions with *fixed* arity can have
trailing arguments omitted in calls and the omitted argument variables
take default values. Consider issues such as utility, reusability,
productivity, clarity, brevity, maintainability, correctness,
performance.  Candidates may appeal to their own logics (empirical or
theoretical) but all arguments must be quoted in full and reference to
scripture will be ignored. Write on one side of the screen only.

Andrew Dinn
-----------------------------
Our Motto - A Proper Lisp Now



Sat, 10 Feb 1996 17:35:07 GMT  
 point notation in Prolog


   >   Hi,
   >
   >   I was trying to understand one of my old Lisp-programs when i saw
   >   a Lisp instruction very usefull : The point notation in functions arguments
   >   to build a function with a not-defined number of arguments.
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   >The point notation is used the same way in Prolog:  A.L = [A|L].
                                   ^^^^^^^^
   >Or, if you prefer, in both cases, A is the car of the list and L
   >is the cdr.
   >
   >   How do you do that in Prolog ?
   >
   >   For example a 'add' predicat which adds all its arguments
   >   (which are not in a list of course !) :
   >    add(R,1,2,3,4).
   >    R=10
   >
   >You say "which are not in a list of course!"  However, A.L is a list,
   >in both Lisp and Prolog.  You are confusing lists, which are the primary
   >syntactic structure in Lisp, and which have similar properties in Prolog,
   >with term arity.  The arguments of a Prolog predicate are not elements of
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   >a list.
    ^^^^^^
   >
   >   In Lisp you should use something like that: (de add (R,A.L)) (...)
   >
   >You can do the same thing in Prolog.  Consulting this:
   > [Prolog code removed]

   Actually, in the context in which the `.' occurs in the Lisp defun it
   does not indicate the presence of a list of arguments with a variable
   tail. To plagiarise the truism above ``The arguments of a Lisp
   predicate are not elements of a list''

However, the arguments of a Lisp predicate are syntactically served by
source code in lists as list elements, with the first list element the
function name.  Prolog allows you to do exactly the same thing with a
simple little wrapper like the one you deleted from my post.  Prolog
also adds arity constraints on its basic syntax to support additional
builtin capabilities (such as resolution) at a cost of first order
restrictions.

                                          A parse of the defun form would
   indeed return a list with a dotted tail but at call time arguments are
   not supplied in a list they are supplied on a stack. This has been the
   case with every real Lisp since McCarthy's Lisp 1.5. In the Prolog
   code (deleted merely to preserve silica) lists of arguments must be
   constructed by the *caller* and supplied at runtime. In the Lisp code
   the caller does not supply a list of arguments, instead the call form
   can have variable arity. In Common Lisp extra arguments are indicated
   by the &REST keyword, not by a `.'.

The &REST and optional tokens are syntactical niceties.  This
discussion was started with a question that was not related to
implementation details.  The questions was "I was trying to
understand..." with no expressed concern about call time stacks,
etc.  Implementation issues are interesting in their own context,
but are dodging this question.

   The question here is to do with variable numbers of arguments to a
   function, which should not be conflated with passing variable amounts
   of data by supplying structures as arguments. The correct response to
   Matthieu Philou is that you *cannot* define Prolog predicates with
   variable arity but you can achieve the same effect in Prolog with much
   the same runtime overheads as for Lisp by passing the variable
   arguments in a (list) structure (note that the compiled version of the
   *called* Lisp function conses any extra arguments supplied by the
   caller into a list so it does the work done by the caller in Prolog).

The correct response to Andrew is you cannot pass any function call
or definition to Lisp without doing so in a list structure (S
expressions).  Prolog wraps a syntactic structure around its means of
expression that is different (but includes) the list structure of Lisp.
So what!  I think Mathieu asked an interesting question regarding his
perspective of programming in two different languages.  I think Andrew
is trying to start a pissing match which degrades the virtues of both
programming systems (or at least their adherents).  


Motorola GSTG, Scottsdale, Arizona



Sat, 10 Feb 1996 15:52:48 GMT  
 point notation in Prolog
In standard Prologs there is no way to define predicates that accept varying
numbers of arguments.  This is because the arity (= number of arguments) is
considered part of a predicate's name.

Bye,
        Jens.
--


---------------------------------+---------------------------------------------
As the air to a bird, or the sea to a fish, so is contempt to the contemptible.



Sun, 11 Feb 1996 01:53:42 GMT  
 point notation in Prolog


Quote:
>However, the arguments of a Lisp predicate are syntactically served by
>source code in lists as list elements, with the first list element the
>function name.  Prolog allows you to do exactly the same thing with a
>simple little wrapper like the one you deleted from my post.

If this is a syntactical problem, you can solve it in term_expansion/2.
For example, using following term_expansion, you can get
       | ?- sum(X,0,2,3,4,5).
       X = 14 ?
       yes

Quote:
>The &REST and optional tokens are syntactical niceties.  This
>discussion was started with a question that was not related to
>implementation details.  

As matter of fact, the implementation needs a list. Why not show
it explicitly? IMHO, I prefer sum([0,2,3,4,5],X) rather than
sum(X,0,2,3,4,5).

        my_term_expansion(A,A1) :- var(A),!,A=A1.
        my_term_expansion(A,A1) :- atomic(A),!,A=A1.
        my_term_expansion(Funarg,F) :-
            Funarg =.. [sum,Sum|Args],!,F = sum_up(Args,0,Sum).
        my_term_expansion(F,F1) :-
            functor(F,H,A),!,functor(F1,H,A),my_term_expansion(0,A,F,F1).
        my_term_expansion(I,I,_,_):-!.
        my_term_expansion(I,A,F,Fn):-
            J is I+1,
            arg(J,F,NX),arg(J,Fn,N),
            my_term_expansion(NX,N),!,
            my_term_expansion(J,A,F,Fn).
        term_expansion(F,F1) :- my_term_expansion(F,F1).

        sum_up([],N,N1) :- !,N=N1.
        sum_up([H|T],N,N1) :- N0 is N+H,sum_up(T,N0,N1).
---

Sony Computer Science Laboratory, Inc,Japan



Sun, 11 Feb 1996 11:19:19 GMT  
 point notation in Prolog


Quote:
>It is very usefull in a Meta-level when you use the same predicat differently
>as in OOP if you use 'send' for sending a message to an object without
>knowing the number of arguments !

If you need message passing there is another way.  In GM library in
SICStus Prolog, Object => Message is a syntax for message passing. Then
you have arbitrary number of argumets in (rather) good syntax, like
this:
        View=>circle(X,Y,R,font(7x14),color(red),filled).
The next thing is to define =>/2 predicate. If I were you I write a
compiler.

----

Sony Computer Science Laboratory, Inc,Japan



Sun, 11 Feb 1996 11:39:29 GMT  
 point notation in Prolog

Quote:

> [stuff about variable arity predicates, syntax etc]
>...                                                  I think Andrew
>is trying to start a pissing match which degrades the virtues of both
>programming systems (or at least their adherents).  

Sheesh!

I am very sorry to have trod on someone's corns here but I do resent
the {*filter*} theory overtones. I was actually trying to make a
distinction (passing variable amounts of data in a wrapper vs variable
arity functions) in order to pose the question ``Are variable arity
functions a good thing?''. I thought the discussion up to then was
merely talking about how to emulate a Lisp feature in Prolog rather
than the virtues of the feature per se.

I did not care to answer the question I posed because I don't think
there is *one correct answer* just like I don't think there is *one
correct language*. Far from denigrating the virtues of Lisp and Prolog
I only wish more people were aware of how well they cope with lots of
programming problems. Could Richard O'Keefe come in here and do his
``sometimes you need a screwdriver, sometimes a hammer'' bit now.

Andrew Dinn
-----------------------------
Our Motto - A Proper Lisp Now



Sun, 11 Feb 1996 16:58:49 GMT  
 point notation in Prolog

   I did not care to answer the question I posed because I don't think
   there is *one correct answer* just like I don't think there is *one
   correct language*. Far from denigrating the virtues of Lisp and Prolog
   I only wish more people were aware of how well they cope with lots of
   programming problems. Could Richard O'Keefe come in here and do his
   ``sometimes you need a screwdriver, sometimes a hammer'' bit now.

That you asked the question led me to believe you wanted an answer.
It didn't appear rhetorical to me.  Now that you have straightened
me out on what you think, I agree!  

Richard, your help is not needed, but, of course, always welcome.


Motorola GSTG AI lab
Scottsdale, Arizona



Sun, 11 Feb 1996 15:22:28 GMT  
 point notation in Prolog
In LIFE (an OO extension of Prolog with functions) all terms are dynamic,
so you can specify an arbitrary number of arguments on any predicate call.

One can write things like:

W:write :- map(display_one, feature_values(W)).

assuming "display_one" displays one term, this can be called using:

        write(hello,charley,catch,22) ?
        hellocharleycatch22

features(term) is a function which returns the list of features of a term.
feature_values(term) returns the list the values of the features, it can
be naively implemented as:

feature_values(X) -> map(project(2=>X),features(X)).
(this uses functions and currying).

Notice how for this to work we need to be able to reference the calling term
of a predicate (variable 'W' in the first example). We know how to compile this
efficiently so that fixed arity clauses or clauses which do not reference the head
from within the body incur no runtime penalty.

Likewise sum can be implemented as a function:

S:sum -> list_sum(feature_values(S)).

list_sum([H|T]) -> H+list_sum(T).
list_sum([]) -> 0.

So: 'A=sum(1,2,3,4)?'  yields 'A=10.', and 'A=sum?' yields 'A=0.'

_______________________________________________________________________________

                                                      Tel: (33) (1) 47.14.28.65
Digital Equipment Corporation                         Fax: (33) (1) 47.14.28.99
Paris Research Laboratory
85, avenue Victor Hugo
92500 Rueil-Malmaison Cedex
FRANCE
_______________________________________________________________________________



Tue, 13 Feb 1996 16:41:59 GMT  
 point notation in Prolog

   The question here is to do with variable numbers of arguments to a
   function, which should not be conflated with passing variable amounts
   of data by supplying structures as arguments. The correct response to
   Matthieu Philou is that you *cannot* define Prolog predicates with
   variable arity but you can achieve the same effect in Prolog with much
   the same runtime overheads as for Lisp by passing the variable
   arguments in a (list) structure (note that the compiled version of the
   *called* Lisp function conses any extra arguments supplied by the
   caller into a list so it does the work done by the caller in Prolog).

This could be implemented very easily, I think, using the translation
mechanism of modern prolog implementations. The idea is that you write
the call as having multiple parameters, but the translation put the
variable arguments (the &REST) in a list. So you write something like:

        :- varparam p/2.

        head :- ..., p(a,b,c,d,e,f), ...

Is translated into:

        head :- ..., p(a,b,[c,d,e,f]), ...

That is de declaration says that the first two parameters are
mandatory and follow by a variable amount of 0 or more extra args.
The implementation itself should be trivial. How useful this really is
from the soft-eng point of view is a diferent matter.

        Jose Alberto.
--
..........................................................................
:                                                                        :


:     University of Maryland   \  |  /  PHONE: (301) 405-2716            :
:       College Park, MD 20742  \ | / FAX/HOME: (202) 265-5784           :
:........................................................................:



Wed, 14 Feb 1996 03:28:00 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. PDC Prolog / Visual Prolog First Steps Edition +/- points

2. Question on monad notation (infix notation for monadic map)

3. Prolog and notation for implication

4. quintus prolog choice points

5. Integer/floating point type conversion in Prolog

6. Point-to-Point Comm in NT-Network

7. Point to point communication

8. Point to point communication over TCP/IP

9. Point to Point radio link

10. Take Forth's good points, chuck the bad point

11. Point to Point Communications

12. SPX point-to-point comm. in Clipper

 

 
Powered by phpBB® Forum Software