From: Matt
Subject: What to learn: Prolog or Lisp?
Date: 
Message-ID: <741972130wnr@bluebean.demon.co.uk>
Hi folks,

I'm planning, in the Autumn, to take a correspondence course in either Prolog 
or Lisp. Realistically I don't have the time or money to learn both so I have 
to choose.

I'm doing this because I want to start studying AI, which is plainly going to 
be a core technology of the future. My particular areas of interest are (likely 
to be) reasoning, cognition, intelligent and automous software and agents etc. 

On a more abstract level, I'm wamntto learn about realising relationships
between things, rather than just doing processing on things.

I realise that this is just a first step, but one has to start somewhere. I 
guess the most suitable language would be the one that gets me thinking most 
about AI, rather than the 'best' per se.

However I'm just starting out so don't know enough about AI to even start 
thinking about this decision.

So I'd appreciate some advice on what each language is most suitable for and 
which may the best for my circumstances. It would be helpful if you could avoid 
heavy AI jargon as I don't yet understand it - that's why I'm trying to learn.

I am an experienced professional programmer, specialising in C, C++ and Visual 
Basic, so I'm starting from a good solid computer science base. 

I will probably be using my PC for running compilers/interpreters so that may 
be a factor.

Thanks for your help.

From: Michael Jampel
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <31F355E6.C1D@info.fundp.ac.be>
Matt wrote:
> 
> Hi folks,
> 
> I'm planning, in the Autumn, to take a correspondence course in either Prolog
> or Lisp. 
> My particular areas of interest are (likely
> to be) reasoning, cognition, intelligent and automous software and agents etc.
> 
> On a more abstract level, I'm wamntto learn about realising relationships
> between things, rather than just doing processing on things.
> I am an experienced professional programmer, specialising in C, C++ and Visual
> Basic, so I'm starting from a good solid computer science base.

In general, LISP is deterministic, as are C, C++, Basic.
Prolog is no-deterministic, i.e. one program can have more
than one correct answer. So if you want to learn something
as different as possible from C etc, I suggest Prolog.

Also, LISP is to do with functions, whereas Prolog is concerned
with relations --- functions are a subset of relations, so Prolog
seems more general. (Of course, all computer languages are
equally expressive theoretically.)

Historically, I think LISP Was more USA-based and Prolog was more
Europe-based --- this might affect responses.

One more personal prejudice: Prolog is the basis of a new
class of languages to do with "Constraint Logic Programming"
which is wonderful,  and will be increasingly important in 
the future. So you should move to CLP via Prolog. (See
comp.constraints for more.)

=============================================================
Michael Jampel              Currently: ···@info.fundp.ac.be
(······@cs.city.ac.uk)         in    : phone +32 81 72.49.87
                             Belgium : fax   +32 81 72.49.67
From: P. Srinivas
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <4t0epc$m7g@tribune.usask.ca>
Michael Jampel (···@info.fundp.ac.be) wrote:
: > between things, rather than just doing processing on things.
: > I am an experienced professional programmer, specialising in C, C++ and Visual
: > Basic, so I'm starting from a good solid computer science base.

: In general, LISP is deterministic, as are C, C++, Basic.
: Prolog is no-deterministic, i.e. one program can have more
: than one correct answer. So if you want to learn something
: as different as possible from C etc, I suggest Prolog.

: Also, LISP is to do with functions, whereas Prolog is concerned
: with relations --- functions are a subset of relations, so Prolog
: seems more general. (Of course, all computer languages are
**********************


 This is, I think a misconception as far as programming languages
 are concerned.

  The above statement is true in a strict mathematical sense. But 
 function in a program are not matehmatical functions. They
 are, what can be called, "evaluable" functions. Prolog predicates
 can not be more general because of this nature. That is why
 Prolog also have non-logical, non-relational constructs called
 evaluable predicates like "is" predicate. Though in theory
 every langauge is Turing Comlete, in practice LISP seems to be more
 general as you can easily write a prolog interpretor in LISP
 than otherway round. Also, in LISP programmar has the control
 over his program, where as the control in prolog is fixed in built
 (dept first, SNLD resolution??). For some problems this will
 be good, but for some other it might not suite. You will get frustrated in
 the canse of later.

: Historically, I think LISP Was more USA-based and Prolog was more
: Europe-based --- this might affect responses.

: One more personal prejudice: Prolog is the basis of a new
: class of languages to do with "Constraint Logic Programming"
: which is wonderful,  and will be increasingly important in 
: the future. So you should move to CLP via Prolog. (See
: comp.constraints for more.)

This is the class of problems you migth what to use logic languages.
But for general purpose AI or anything else, LISP is more powerful
and flexible.


My $0.01 worth,


Srini

   URL http://www.cs.usask.ca/homepages/grads/srini/
--------------------
Srinivas Palthepu                             Email: ·····@cs.usask.ca
ARIES laboratory,                            Phones: (306) 966-8654 (lab)
Department of Computer Science,                      (306) 966-4759 (office)
University of Saskatchewan,                          (306) 373-6724 (home)    
57 Campus Dr, Saskatoon, SK, S7N 5A9            Fax: (306) 966-4884
From: 'Enrico, of course...'
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <4t0sc7$b09@bubba.NMSU.Edu>
In article ···@tribune.usask.ca, ·····@alfresco.usask.ca (P. Srinivas) writes:
> : Also, LISP is to do with functions, whereas Prolog is concerned
> : with relations --- functions are a subset of relations, so Prolog
> : seems more general. (Of course, all computer languages are
> **********************
> 
> 
>  This is, I think a misconception as far as programming languages
>  are concerned.
> 
>   The above statement is true in a strict mathematical sense. But 
>  function in a program are not matehmatical functions. They
>  are, what can be called, "evaluable" functions. Prolog predicates
>  can not be more general because of this nature. That is why

Well, also Prolog predicates in this sense are not mathematical relations
but evaluable ones. You should properly justify an assertion like
"prolog predicates cannot be more general". It is a quite straightforward
exercise to rewrite a functional program into a prolog one. I would say
that the opposite is quite not true.

>  Prolog also have non-logical, non-relational constructs called
>  evaluable predicates like "is" predicate. Though in theory
>  every langauge is Turing Comlete, in practice LISP seems to be more
>  general as you can easily write a prolog interpretor in LISP

Can you ? But you need to implement backtracking, you need to implement
full unification... it seems to me that the other way round is MUCH
easier...

>  than otherway round. Also, in LISP programmar has the control
>  over his program, where as the control in prolog is fixed in built
>  (dept first, SNLD resolution??). For some problems this will
>  be good, but for some other it might not suite. You will get frustrated in
>  the canse of later.

Well, can you again justify the assertion that makes control in LISP more
flexible ? In Prolog execution is based on resolution steps (take subgoal,
reduce subgoal), in LISP you have execution based on function applications. Again,
at the intuitive level I don't see this big difference.

> 
> : Historically, I think LISP Was more USA-based and Prolog was more
> : Europe-based --- this might affect responses.
> 

I deeply agree with this. Just consider the amount of applications in logic 
programming developed in Europe.

> : One more personal prejudice: Prolog is the basis of a new
> : class of languages to do with "Constraint Logic Programming"
> : which is wonderful,  and will be increasingly important in 
> : the future. So you should move to CLP via Prolog. (See
> : comp.constraints for more.)
> 
> This is the class of problems you migth what to use logic languages.
> But for general purpose AI or anything else, LISP is more powerful
> and flexible.

My experience is showing that more and more people are actually using
Prolog for AI applications. Unification and backtracking are very precious
in a lot of AI applications (e.g. search problems).


The only reason that in the past made functional languages slightly superior
to logic ones is probably execution speed. But with the current implementation
technology (abstract interpretation, native-code compilation, implicit
parallelization) I would say that also this does not stand true anymore.

My $0.25


					Rico

-------------------------------------------------------------------------
Laboratory for Logic, Databases,|   email: ········@cs.nmsu.edu
and Advanced Programming	|	   ······@getafix.cineca.it
Department of Computer Science	|   www: http://www.cs.nmsu.edu/~epontell
Box 30001, Dept. CS		|
New Mexico State University	|   Ph:  +1 (505) 646 6239 
Las Cruces, NM 88003-0001	|   Fax: +1 (505) 646 1002 
USA				|
-------------------------------------------------------------------------
From: P. Srinivas
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <4t30ej$7m@tribune.usask.ca>
'Enrico, of course...' (········@nmsu.edu) wrote:
: In article ···@tribune.usask.ca, ·····@alfresco.usask.ca (P. Srinivas) writes:
: > : Also, LISP is to do with functions, whereas Prolog is concerned
: > : with relations --- functions are a subset of relations, so Prolog
: > : seems more general. (Of course, all computer languages are
: > **********************
: > 
: > 
: >  This is, I think a misconception as far as programming languages
: >  are concerned.
: > 
: >   The above statement is true in a strict mathematical sense. But 
: >  function in a program are not matehmatical functions. They
: >  are, what can be called, "evaluable" functions. Prolog predicates
: >  can not be more general because of this nature. That is why

: Well, also Prolog predicates in this sense are not mathematical relations
: but evaluable ones. You should properly justify an assertion like
: "prolog predicates cannot be more general". It is a quite straightforward
: exercise to rewrite a functional program into a prolog one. I would say
: that the opposite is quite not true.


Oh no. Take a look at Harlequin Lispworks, A commercial common lisp
system that comes with a FULL industry standard prolog writen 
completely in common LISP. More over, any AI textbook worth its price
will include an implementation of Unification algorithm and resolution
in LISP. One can easily take this two and turn them into a prolog
interpretor.

Can you show me any prolog program that implements LISP like
language?

: >  Prolog also have non-logical, non-relational constructs called
: >  evaluable predicates like "is" predicate. Though in theory
: >  every langauge is Turing Comlete, in practice LISP seems to be more
: >  general as you can easily write a prolog interpretor in LISP

: Can you ? But you need to implement backtracking, you need to implement
: full unification... it seems to me that the other way round is MUCH
: easier...

Yes, I can. You also can. It is easy. Ofcourse one has to
be careful if you want an efficient prolog. You need to buy a
commercial one.

: >  than otherway round. Also, in LISP programmar has the control
: >  over his program, where as the control in prolog is fixed in built
: >  (dept first, SNLD resolution??). For some problems this will
: >  be good, but for some other it might not suite. You will get frustrated in
: >  the canse of later.

: Well, can you again justify the assertion that makes control in LISP more
: flexible ? In Prolog execution is based on resolution steps (take subgoal,
: reduce subgoal), in LISP you have execution based on function applications. 
: Again, at the intuitive level I don't see this big difference.

Wll, what I mean to say was the level of abstraction one has
to program at is much higher in prolog. You mostly do declarative style
programming. One can also give a procedural interpretation
of declarative description. After all that is what computer does
after you submit your program. But when you program you need to
think more declaratively (comprared to languages like LISP).
That is the reason why prolog fixed control mechanism comes in your way
and LISP execution mechanism does not come in your way.
Try to similate simple for loops in prolog and you will know
what I am talking about. (I am not saying that loops are 
that important, but that example is good for bringing out the
point I am making).

: > 
: > : Historically, I think LISP Was more USA-based and Prolog was more
: > : Europe-based --- this might affect responses.
: > 

: I deeply agree with this. Just consider the amount of applications in logic 
: programming developed in Europe.

No comment.

: > : One more personal prejudice: Prolog is the basis of a new
: > : class of languages to do with "Constraint Logic Programming"
: > : which is wonderful,  and will be increasingly important in 
: > : the future. So you should move to CLP via Prolog. (See
: > : comp.constraints for more.)
: > 
: > This is the class of problems you migth what to use logic languages.
: > But for general purpose AI or anything else, LISP is more powerful
: > and flexible.

: My experience is showing that more and more people are actually using
: Prolog for AI applications. Unification and backtracking are very precious
: in a lot of AI applications (e.g. search problems).

AS I said, prolog might be suited for certain class of problems
where problem is well specified and everything is crystal clear before you
write programming. Modern software systems are rarely like that,
especially large ones and AI ones. It migth be easy to
code well known A* algorithm in prolog. but
prolog is simply not for any exploratory programming.

: The only reason that in the past made functional languages slightly superior
: to logic ones is probably execution speed. But with the current implementation
: technology (abstract interpretation, native-code compilation, implicit
: parallelization) I would say that also this does not stand true anymore.

I have not even mentioned the efficiency. I was juts giving reasons 
based on technicalities of two languages. Efficiency also
might throw in a couple of points aggainst Prolog (I am just
guessing from your article, I do not know about current implementation and
their efficency)

Srini

--
   URL http://www.cs.usask.ca/homepages/grads/srini/
--------------------
Srinivas Palthepu                             Email: ·····@cs.usask.ca
ARIES laboratory,                            Phones: (306) 966-8654 (lab)
Department of Computer Science,                      (306) 966-4759 (office)
University of Saskatchewan,                          (306) 373-6724 (home)    
57 Campus Dr, Saskatoon, SK, S7N 5A9            Fax: (306) 966-4884
From: Jamie Andrews
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <4t75lf$bqh@ceres.cs.sfu.ca>
     Well, great minds apparently run in the same channel --
or is that "fools think alike"?... I hacked up a quick Lisp
interpreter too; this one has exprs and nexprs and some
primitive error handling, and it uses no cuts, disjunctions or
database predicates, so it is purely declarative and should work
in any vaguely Edinburgh Prolog. 

    I don't know where this bizarre idea that you can't write a
Lisp interpreter in Prolog came from, but I've seen it on the
Net a few times.  Best to lay it to rest.  But as for the rest
of the Prolog vs. Lisp debate, I've always maintained that such
discussions usually generate more heat than light.

% Simple pure Lisp interpreter, v. 1.0.
% Jamie Andrews (·····@cs.sfu.ca), July 1996.
%
% Each Lisp s-expression (a b c) encoded as [a,b,c];
%   thus [append,x,y] for (append x y).
% Quoting must be done explicitly, as [quote,[a,b]] for '(a b).
%   Could add operator definitions and/or term_expansion hooks
%   to get around this.
% Thus, to evaluate expressions, e.g. give goal
%   eval([append,[quote,[a,b]],[quote,[b,c]]], Result).
% Regular functions defined by adding clauses of the form
%   defun(Funcname, Arglist, Funcbody).
%   (See examples at the end of the code.)  Could instead build
%   a parser, read code from file, etc.
% Nexpr functions defined in the same way but with
%   defun_nexpr(Funcname, Arglist, Funcbody).
% No setq; could add by adding another argument (the "returned
%   environment") to most predicates, and adding some code for
%   setq to eval_appl1.
% No cuts in this Prolog code, but could make much more efficient
%   by putting them in in the obvious places.

% Main predicate.
eval(S, Result) :-
  eval1(S, [], Result).

eval1([F|Args], Env, Result) :-
  eval_appl(F, Args, Env, Result).
eval1(A, Env, Result) :-
  \+ (A = [_|_]),
  eval_atom(A, Env, Result).

% Preds for evaluating function applications

eval_appl(F, Args, Env, Result) :-
  defined_func(F, Nargs),
  length(Args, Nargs),
  eval_appl1(F, Args, Env, Result).
% For errors, as in rest of code, return nil
% but write an error message.
eval_appl(F, _, _, nil) :-
  \+ defined_func(F, _),
  write('Undefined function: '), write(F), nl.
eval_appl(F, Args, _, nil) :-
  defined_func(F, Nargs),
  \+ length(Args, Nargs),
  write('Wrong number of arguments: '), write([F|Args]), nl.

% Defined functions, and their numbers of arguments.
% Builtins...
defined_func(eq, 2).
defined_func(car, 1).
defined_func(cdr, 1).
defined_func(cons, 2).
defined_func(cond, _).
defined_func(quote, 1).
defined_func(eval, 1).
% ...and user-defined functions.
defined_func(Func, Nargs) :-
  defun(Func, Args, _),
  length(Args, Nargs).
defined_func(Func, Nargs) :-
  defun_nexpr(Func, Args, _),
  length(Args, Nargs).

% Evaluate a function with the right number of arguments.
% Builtins...
eval_appl1(eq, [S,T], Env, Result) :-
  eval1(S, Env, Sval),
  eval1(T, Env, Tval),
  decide_eq(Sval, Tval, Result).
eval_appl1(car, [S], Env, Result) :-
  eval1(S, Env, Sval),
  decide_car(Sval, Result).
eval_appl1(cdr, [S], Env, Result) :-
  eval1(S, Env, Sval),
  decide_cdr(Sval, Result).
eval_appl1(cons, [S,T], Env, [Sval|Tval]) :-
  eval1(S, Env, Sval),
  eval1(T, Env, Tval).
eval_appl1(cond, Clauses, Env, Result) :-
  eval_cond(Clauses, Env, Result).
eval_appl1(quote, [S], _, S).
eval_appl1(eval, [S], Env, Result) :-
  eval1(S, Env, Sval),
  eval1(Sval, Env, Result).
% ... and user-defined functions.
eval_appl1(Func, Aparams, Env, Result) :-
  defun(Func, Fparams, Body),
  map_eval1(Aparams, Env, Evalparams),
  build_env(Fparams, Evalparams, Newenv),
  eval1(Body, Newenv, Result).
eval_appl1(Func, Aparams, Env, Result) :-
  defun_nexpr(Func, Fparams, Body),
  build_env(Fparams, Aparams, Newenv),
  eval1(Body, Newenv, Result).

% Decide on the result of an eq
decide_eq(S, S, t).
decide_eq([], nil, t).
decide_eq(nil, [], t).
decide_eq(S, T, nil) :-
  \+ (S = T),
  \+ (S = [], T = nil),
  \+ (S = nil, T = []).

decide_car([S|_], S).
decide_car(S, nil) :-
  \+ (S = [_|_]).

decide_cdr([_|S], S).
decide_cdr(S, nil) :-
  \+ (S = [_|_]).

% eval_cond(Cond_clauses, Env, Result).
% If have reached end of cond, return nil.
eval_cond([], _, nil).
% Otherwise, evaluate the test and decide on the result.
eval_cond([[Test,S]|Clauses], Env, Result) :-
  eval1(Test, Env, Testval),
  eval_cond1(Testval, S, Clauses, Env, Result).
% We could consider a list after the test in a cond clause
% to be correct, and return the last one evaluated, but in
% a pure Lisp this is probably erroneous.
eval_cond([[Head|Rest]|_], _, nil) :-
  \+ ([Head|Rest] = [_,_]),
  write('Error: list after cond test: '), write(Rest), nl.
eval_cond([Atom|_], _, nil) :-
  \+ (Atom = [_|_]),
  write('Error: atom instead of cond clause: '), write(Atom), nl.

% Interpret nil as false, non-nil as true.
% If test value is nil, go on with other clauses
eval_cond1(nil, _, Clauses, Env, Result) :-
  eval_cond(Clauses, Env, Result).
% If test value is not nil but rest of clause is empty, return test value
eval_cond1(Testval, [], _, _, Testval) :-
  \+ (Testval = nil).
% Otherwise, evaluate rest of clause
eval_cond1(Testval, S, _, Env, Result) :-
  \+ (Testval = nil),
  \+ (S = []),
  eval1(S, Env, Result).

map_eval1([], _, []).
map_eval1([S|Ss], Env, [T|Ts]) :-
  eval1(S, Env, T),
  map_eval1(Ss, Env, Ts).

build_env([], [], []).
build_env([F|Fs], [A|As], [bind(F,A)|Env]) :-
  build_env(Fs, As, Env).

% Preds for evaluating atoms

eval_atom(t, _, t).
eval_atom(nil, _, nil).
eval_atom(S, Env, Result) :-
  \+ (S = t),
  \+ (S = nil),
  getval(Env, S, Result).

getval([], S, nil) :-
  write('Undefined atom: '), write(S), nl.
getval([bind(S,T)|_], S, T).
getval([bind(S1,_)|Env], S, Result) :-
  \+ (S = S1),
  getval(Env, S, Result).



% Some function definitions

defun(null, [x],
  [eq,x,nil]
).

defun(append, [x,y],
  [cond,[[null,x],y],
        [t,[cons,[car,x],[append,[cdr,x],y]]]]
).

defun(member, [x,y],
  [cond,[[null,y],nil],
        [[eq,x,[car,y]],t],
        [t,[member,x,[cdr,y]]]]
).

--Jamie.             "It was on one of my journeys between the EDSAC room and
  ·····@cs.sfu.ca     the punching equipment [c. 1950] that... the realization
came over me with full force that a good part of the remainder of my life was
going to be spent in finding errors in my own programs." -- Maurice V. Wilkes
From: Leon Sterling
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <leon-2407960905490001@leonmac.cs.mu.oz.au>
In article <·········@tribune.usask.ca>, ·····@alfresco.usask.ca (P.
Srinivas) wrote:
 
> Can you show me any prolog program that implements LISP like
> language?

I have seen several. It is an easy thing to build a protoype.

> AS I said, prolog might be suited for certain class of problems
> where problem is well specified and everything is crystal clear before you
> write programming. Modern software systems are rarely like that,
> especially large ones and AI ones. It migth be easy to
> code well known A* algorithm in prolog. but
> prolog is simply not for any exploratory programming.

Quite wrong. Prolog is excellent for exploratory programming.
This kind of misinformation is annoying.

-- 
Leon Sterling                        ····@cs.mu.oz.au
Department of Computer Science       Phone: +61 3 9287 9100
University of Melbourne,             Fax: +61 3 9348 1184 
Parkville, Vic. 3052                 Office, L.2.21, 221 Bouverie St.
AUSTRALIA
From: Ralph Becket
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <4t4tat$qv7@lyra.csx.cam.ac.uk>
In article <·········@tribune.usask.ca>,
P. Srinivas <·····@alfresco.usask.ca> wrote:
>
> [...snippy snip]
>
>Oh no. Take a look at Harlequin Lispworks, A commercial common lisp
>system that comes with a FULL industry standard prolog writen 
>completely in common LISP. More over, any AI textbook worth its price
>will include an implementation of Unification algorithm and resolution
>in LISP. One can easily take this two and turn them into a prolog
>interpretor.
>
>Can you show me any prolog program that implements LISP like
>language?

A five-minute hack produces...


eval([Fn | Args], Result, StateIn-StateOut) :-
	eval_args(Args, EvalArgs, StateIn-State0),
	apply(Fn, EvalArgs, Result, State0-StateOut).


eval_args([], [], State-State).

eval_args([Arg | Args], [EvalArg | EvalArgs], StateIn-StateOut) :-
	eval(Arg, EvalArg, StateIn-State0),
	eval_args(Args, EvalArgs, State0-StateOut).


apply(setf, [Sym, Value], t, State-[Sym=Value | State]).

apply(defun, [Sym, Args, Body], t, State-[Sym=fn(Args, Body) | State]).

apply(quote, Form, Form, State-State).

...

apply(Sym, [], Value, State-State) :-
	member(Sym=Value, State),
	!.

apply(Fn, Args, Result, StateIn-StateOut) :-
	member(Fn=fn(FnArgs, FnBody), StateIn),
	!,
	copy_term((FnArgs, FnBody), (Args, Body)),
	eval(Body, Result, StateIn-StateOut).


A bit on the light side, a tad inefficient, but the guts of Lisp are
there.  I'm sorry, but I cannot see a Lisp implementation of Prolog
being this easy.

But this is all rather beside the point.  Ease of implementation of
various languages in Lisp/Prolog is not the issue.  What is being
debated here is expressive power.  For my money, Prolog wins hands
down here with its full unification and its ability to manipulate
structures; Lisp has at best weak pattern matching and a truly gross
quoting facility.  On the other hand, it is often easier to keep
persistent state in a Lisp program and if your problem is more
naturally suited to the functional paradigm then Lisp has a clear
advantage (although why one would then use Lisp rather than a
civilised language like ML is beyond me...)

>: Well, can you again justify the assertion that makes control in LISP more
>: flexible ? In Prolog execution is based on resolution steps (take subgoal,
>: reduce subgoal), in LISP you have execution based on function applications. 
>: Again, at the intuitive level I don't see this big difference.
>
>Wll, what I mean to say was the level of abstraction one has
>to program at is much higher in prolog. You mostly do declarative style
>programming. One can also give a procedural interpretation
>of declarative description. After all that is what computer does
>after you submit your program. But when you program you need to
>think more declaratively (comprared to languages like LISP).
>That is the reason why prolog fixed control mechanism comes in your way
>and LISP execution mechanism does not come in your way.
>Try to similate simple for loops in prolog and you will know
>what I am talking about. (I am not saying that loops are 
>that important, but that example is good for bringing out the
>point I am making).

What's the problem here?  Prolog essentially follows left-to-right
execution just as Lisp does (otherwise IO would be a major pain).
Viewed this way, backtracking is a boon.  Without it, one is either
forced to implement potentially much more costly breadth-first style
programs or maintain state to keep track of choice-points in the
search, as is the case with Lisp.

>AS I said, prolog might be suited for certain class of problems
>where problem is well specified and everything is crystal clear before you
>write programming. Modern software systems are rarely like that,
>especially large ones and AI ones. It migth be easy to
>code well known A* algorithm in prolog. but
>prolog is simply not for any exploratory programming.

I suspect you have had little experience with Prolog (to deter claims
that I'm in a my-favourite-language debate, I would point out that I
have also used Lisp extensively).

>I have not even mentioned the efficiency. I was juts giving reasons 
>based on technicalities of two languages. Efficiency also
>might throw in a couple of points aggainst Prolog (I am just
>guessing from your article, I do not know about current implementation and
>their efficency)

Indeed.  Interested parties should look at the Mercury stuff.  Let us
all hope this one takes off.

>
>Srini
>

Ralph
--
············@cl.cam.ac.uk                    http://www.cl.cam.ac.uk/users/rwab1
From: Ray Nickson
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <v58d91mfv86.fsf@isa.cs.uq.oz.au>
In article <·········@tribune.usask.ca> ·····@alfresco.usask.ca (P. Srinivas) writes:

   Can you show me any prolog program that implements LISP like
   language?

I called this interpreter for a Lisp-like language `scheme', I think
because it doesn't distinguish symbols' apvals from their expr values.
But it is dynamically scoped.  I implemented it when I was playing
with lazy evaluation; it has a `lazy cons' operator as (which doesn't
evaluate its arguments) as well as ordinary cons.

Yes, it is a toy, of course, but it was only about four hours' work.
I've implemented similar-quality Prolog interpreters in Lisp with
somewhat more effort, but I'm more fluent with Prolog than I am with
Lisp so that doesn't say much about their relative powers.

Ray

%% Toy `scheme' interpreter with lazy lists.
%% Ray Nickson (·······@cs.uq.edu.au)
%% Written some time around 1990.  Tested in Qu-Prolog in 1995.
%% Posted to comp.lang.prolog in July 1996.

%% Do with this as you wish.
%% Especially polite people will keep my name on it and let me know of
%% any interesting changes.

?- add_global_exception_handler(signal(_,_,_,'SIGINT'),
                                scheme_error('interrupt')),
   set_signals_flag(on).

main(_) :- scheme.

%%%%%%%%%%%%%%%%%%%%%%%%%%
%% read-eval-print loop %%
%%%%%%%%%%%%%%%%%%%%%%%%%%
scheme :-
    scheme_default_assoc(A0),
    ( access('stdlib.scm', 4, 0) ->
        open('stdlib.scm', read, Strm),
        scheme_load_stream(Strm, [], E, A0, A)
    ;
        E = [], A = A0
    ),
    scheme(E, _, A, _).

scheme(Env0, Env, Assoc0, Assoc) :-
    catch(scheme_read_eval_print(Env0, Env1, Assoc0, Assoc1, Cont),
          scheme_error,
          ( Cont = yes, Env1 = Env0, Assoc1 = Assoc0 )),
    Cont = yes,
    !,
    scheme(Env1, Env, Assoc1, Assoc).
scheme(_, _, _, _) :-
    write(goodbye),
    nl.

scheme_read_eval_print(Env0, Env, Assoc0, Assoc, Cont) :-
    write('scheme> '),
    scheme_read(Form, user_input),
    !,
    scheme_eval(Form, Env0, Env1, Assoc0, Assoc1, Val),
    scheme_write(Val),
    nl,
    scheme_lookup(values, Env1, Assoc1, Vals),
    scheme_update(Env1, Env, Assoc1, Assoc, values, [Val|Vals]),
    Cont = yes.
scheme_read_eval_print(_,_,_,_, no).

scheme_eval(Form, Env0, Env, Assoc0, Assoc, Val) :-
    ( number(Form) ->
        Env = Env0,
        Assoc = Assoc0,
        Val = Form
    ; atom(Form) ->
        Env = Env0,
        Assoc = Assoc0,
        scheme_lookup(Form, Env0, Assoc0, Val)
    ; Form = [Fun|Args] ->
        scheme_eval(Fun, Env0, Env1, Assoc0, Assoc1, FunVal),
        scheme_apply(FunVal, Args, Env1, Env, Assoc1, Assoc, Val)
    ; Form = lcons(_,_,_) ->
        Env = Env0,
        Assoc = Assoc0,
        Val = Form
    ; Form = string(Str) ->
        Env = Env0,
        Assoc = Assoc0,
        Val = Form
    ; Form = subr(_) ->
        Env = Env0,
        Assoc = Assoc0,
        Val = Form
    ; Form = fsubr(_) ->
        Env = Env0,
        Assoc = Assoc0,
        Val = Form
    ;
        scheme_error('bad scheme form', [Form])
    ).

scheme_lookup(Name, Env, Assoc, Val) :-
    ( member(Bnd, Env),
      member(Name-Val0, Bnd) ->
        Val = Val0
    ; member(Name-Val0, Assoc) ->
        Val = Val0
    ;
        scheme_error('undefined scheme variable', [Name])
    ).

scheme_apply([lambda,Formals,Form|Name], Args,
             Env0, Env, Assoc0, Assoc, Val) :-
    scheme_eval_list(Args, Env0, Env1, Assoc0, Assoc1, ArgVals),
    scheme_bind(Formals, ArgVals, Name, Binding),
    scheme_eval(Form, [Binding|Env1], [_|Env], Assoc1, Assoc, Val).
scheme_apply([flambda,Formals,Form|Name], Args,
             Env0, Env, Assoc0, Assoc, Val) :-
    scheme_bind(Formals, Args, Name, Binding),
    scheme_eval(Form, [Binding|Env0], [_|Env], Assoc0, Assoc, Val).
scheme_apply(subr(Name), Args, Env0, Env, Assoc0, Assoc, Val) :-
    scheme_eval_list(Args, Env0, Env1, Assoc0, Assoc1, ArgVals),
    ( call(Name(ArgVals,Env1,Env,Assoc1,Assoc,Val)) ->
        true
    ;
        Error =.. [Name|ArgVals],
        scheme_error('scheme subr failed', [Error])
    ).
scheme_apply(fsubr(Name), Args, Env0, Env, Assoc0, Assoc, Val) :-
    ( call(Name(Args,Env0,Env,Assoc0,Assoc,Val)) ->
        true
    ;
        Error =.. [Name|Args],
        scheme_error('scheme fsubr failed', [Error])
    ).

scheme_bind([], [], _, []) :-
    !.
scheme_bind([Formal|Formals], [Arg|Args], Name, [Formal-Arg|Bnd]) :-
    !,
    scheme_bind(Formals, Args, Name, Bnd).
scheme_bind([], [_|_], Name, bad) :-
    !,
    scheme_error('too many arguments', Name).
scheme_bind([_|_], [], Name, bad) :-
    !,
    scheme_error('not enough arguments', Name).
scheme_bind(ListFormal, Args, _, [ListFormal-Args]).

scheme_eval_list([], Env0, Env, Assoc0, Assoc, []) :-
    !,
    Env = Env0,
    Assoc = Assoc0.
scheme_eval_list([Arg|Args], Env0, Env, Assoc0, Assoc, [Val|Vals]) :-
    !,
    scheme_eval(Arg, Env0, Env1, Assoc0, Assoc1, Val),
    scheme_eval_list(Args, Env1, Env, Assoc1, Assoc, Vals).

scheme_update([Bnd0|Env], [Bnd|Env], Assoc, Assoc, X, Y) :-
    scheme_update_bnd(Bnd0, Bnd, X, Y),
    !.
scheme_update([Bnd|Env0], [Bnd|Env], Assoc0, Assoc, X, Y) :-
    !,
    scheme_update(Env0, Env, Assoc0, Assoc, X, Y).
scheme_update([], [], A0, A, X, Y) :-
    scheme_update_assoc(A0, A, X, Y).

scheme_update_bnd([X-_|Bs], [X-Y|Bs], X, Y) :-
    !.
scheme_update_bnd([B|Bs0], [B|Bs], X, Y) :-
    scheme_update_bnd(Bs0, Bs, X, Y).

scheme_update_assoc([], [X-Y], X, Y).
scheme_update_assoc([X-_|Bs], [X-Y|Bs], X, Y) :-
    !.
scheme_update_assoc([B|Bs0], [B|Bs], X, Y) :-
    scheme_update_assoc(Bs0, Bs, X, Y).

scheme_error(Kind, Value) :-
    set_signals_flag(on),
    write_term_list([w(Kind), ': ', w(Value), nl]),
    throw(scheme_error).
scheme_error(Kind) :-
    set_signals_flag(on),
    write_term_list([w(Kind), nl]),
    throw(scheme_error).

%%%%%%%%%%%%%%%%%%%%%%%
%% SCHEME PRIMITIVES %%
%%%%%%%%%%%%%%%%%%%%%%%


scheme_default_assoc(
    [
     nil     - [],
     []      - [],
     t       - t,
     values  - [],
     eval    - subr(scheme_eval1),
     quote   - fsubr(scheme_quote),
     lambda  - fsubr(scheme_lambda),
     flambda - fsubr(scheme_flambda),
     (+)     - subr(scheme_plus),
     (-)     - subr(scheme_minus),
     (*)     - subr(scheme_times),
     (/)     - subr(scheme_divide),
     ('%')   - subr(scheme_mod),
     (=)     - subr(scheme_equal),
     (<)     - subr(scheme_lessp),
     set     - subr(scheme_set),
     cons    - subr(scheme_cons),
     lcons   - fsubr(scheme_lcons),
     car     - subr(scheme_car),
     cdr     - subr(scheme_cdr),
     if      - fsubr(scheme_if),
     read    - subr(scheme_read),
     write   - subr(scheme_write),
     load    - subr(scheme_load),
     xyzzy   - subr(scheme_xyzzy)
    ]).

scheme_eval1([X], E0, E, A0, A, Z) :-
    scheme_eval(X, E0, E, A0, A, Z).

scheme_quote([X], E, E, A, A, X).

scheme_lambda([Args,Form|Name], E, E, A, A, [lambda,Args,Form|Name]).

scheme_flambda([Args,Form|Name], E, E, A, A, [flambda,Args,Form|Name]).

scheme_plus([], E, E, A, A, 0).
scheme_plus([X|Xs], E, E, A, A, Z) :-
    scheme_plus(Xs, E, E, A, A, Y),
    Z is X+Y.

scheme_minus([X], E, E, A, A, Z) :-
    Z is -X.
scheme_minus([X,Y], E, E, A, A, Z) :-
    Z is X-Y.

scheme_times([], E, E, A, A, 1).
scheme_times([X|Xs], E, E, A, A, Z) :-
    scheme_times(Xs, E, E, A, A, Y),
    Z is X*Y.

scheme_divide([X,Y], E, E, A, A, Z) :-
    Z is X//Y.

scheme_mod([X,Y], E, E, A, A, Z) :-
    Z is X mod Y.

scheme_equal([X,Y], E, E, A, A, Z) :-
    ( X == Y ->
        Z = t
    ;
        Z = []
    ).

scheme_lessp([X,Y], E, E, A, A, Z) :-
    ( X < Y ->
        Z = t
    ;
        Z = []
    ).

scheme_set([X,Y], E0, E, A0, A, Y) :-
    scheme_update(E0, E, A0, A, X, Y).

scheme_cons([X,Y], E, E, A, A, [X|Y]).

scheme_lcons([X,Y], E, E, A, A, lcons(E,X,Y)).

scheme_car([[X|_]], E, E, A, A, X).
scheme_car([lcons(E,X,_)], E0, E0, A0, A, Z) :-
    scheme_eval(X, E, _, A0, A, Z).

scheme_cdr([[_|X]], E, E, A, A, X).
scheme_cdr([lcons(E,_,X)], E0, E0, A0, A, Z) :-
    scheme_eval(X, E, _, A0, A, Z).

scheme_if([Cond,Then,Else], E0, E, A0, A, Z) :-
    scheme_eval(Cond, E0, E1, A0, A1, CondVal),
    ( CondVal = [] ->
        scheme_eval(Else, E1, E, A1, A, Z)
    ;
        scheme_eval(Then, E1, E, A1, A, Z)
    ).

scheme_read([], E, E, A, A, Term) :-
    scheme_read(Term, user_input).

scheme_read([Strm], E, E, A, A, Term) :-
    scheme_read(Term, Strm).

scheme_write([Term], E, E, A, A, Term) :-
    scheme_write(Term).

scheme_load([string(File)], E0, E, A0, A, t) :-
    atom_codes(FN, File),
    open(FN, read, Strm),
    scheme_load_stream(Strm, E0, E, A0, A),
    close(Strm).

scheme_load_stream(Strm, E0, E, A0, A) :-
    scheme_read(Form, Strm),
    scheme_eval(Form, E0, E1, A0, A1, _),
    !,
    scheme_load_stream(Strm, E1, E, A1, A).
scheme_load_stream(_, E, E, A, A).

scheme_xyzzy([], E, E, A, A, []) :-
    break.

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Reading scheme syntax %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
scheme_read(Term, Strm) :-
    scheme_read(Term, _Unread, Strm).

scheme_read(Term, Unread, Strm) :-
    get1(Strm, C),
    scheme_read(C, Term, Unread, Strm).

scheme_read(0'(, Term, Unread, Strm) :-
    !,
    scheme_read_list(Term, Unread, Strm).
scheme_read(0'-, Term, Unread, Strm) :-
    !,
    scheme_read_number(-, 0, Num, Unread1, Strm),
    ( Num < 0 ->
        Term = Num,
        Unread = Unread1
    ;
        scheme_read_atom(Unread1, Chars, Unread, Strm),
        atom_codes(Term, [0'-|Chars])
    ).
scheme_read(0'", Term, Unread, Strm) :-
    !,
    scheme_read_string(String, Strm),
    Term = string(String),
    Unread = 0' .
scheme_read(0'', Term, Unread, Strm) :-
    !,
    scheme_read(Term1, Unread, Strm),
    Term = [quote, Term1].
scheme_read(N, Term, Unread, Strm) :-
    between(0'0, 0'9, N),
    !,
    V is N - 0'0,
    scheme_read_number(+, V, Term, Unread, Strm).
scheme_read(A, Term, Unread, Strm) :-
    % \+ is_number_char(A),
    is_atom_char(A),
    !,
    scheme_read_atom(Chars, Unread, Strm),
    atom_codes(Term, [A|Chars]).
scheme_read(C, Term, Unread, Strm) :-
    C =< 0' ,
    !,
    scheme_read(Term, Unread, Strm).
scheme_read(C, Term, C, _) :-
    scheme_error('unexpected character in read', [C]).

scheme_read_list(List, Unread, Strm) :-
    scheme_read_list(0' , List, Unread, Strm).

scheme_read_list(0' , List, Unread, Strm) :-
    !,
    get1(Strm, C),
    scheme_read_list(C, List, Unread, Strm).
scheme_read_list(0'., List, 0' , Strm) :-
    !,
    scheme_read(List, Unread, Strm),
    scheme_expect(Unread, 0'), Strm).
scheme_read_list(0'), List, 0' , _) :-
    !,
    List = [].
scheme_read_list(C, List, Unread, Strm) :-
    scheme_read(C, Head, Unread0, Strm),
    scheme_read_list(Unread0, Rest, Unread, Strm),
    List = [Head|Rest].

scheme_read_string(Str, Strm) :-
    get0(Strm, C),
    scheme_read_string(C, Str, Strm).

scheme_read_string(0'", Str, _) :-
    !,
    Str = [].
scheme_read_string(0'\\, Str, Strm) :-
    !,
    get0(Strm, C),
    Str = [C|Str1],
    scheme_read_string(Str1, Strm).
scheme_read_string(C, Str, Strm) :-
    % C is not " or \,
    Str = [C|Str1],
    scheme_read_string(Str1, Strm).

scheme_read_number(Sign, V0, V, Unread, Strm) :-
    get0(Strm, C),
    scheme_read_number(C, Sign, V0, V, Unread, Strm).

scheme_read_number(C, Sign, V0, V, Unread, Strm) :-
    between(0'0, 0'9, C),
    !,
    V1 is V0*10 + C - 0'0,
    scheme_read_number(Sign, V1, V, Unread, Strm).
scheme_read_number(C, +, V0, V, Unread, _) :-
    % \+ between(0'0, 0'9, C),
    V = V0,
    Unread = C.
scheme_read_number(C, -, V0, V, Unread, _) :-
    % \+ between(0'0, 0'9, C),
    V is - V0,
    Unread = C.

scheme_read_atom(Chars, Unread, Strm) :-
    get0(Strm, C),
    scheme_read_atom(C, Chars, Unread, Strm).

scheme_read_atom(C, Chars, Unread, Strm) :-
    is_atom_char(C),
    !,
    Chars = [C|Chars1],
    scheme_read_atom(Chars1, Unread, Strm).
scheme_read_atom(C, Chars, Unread, _) :-
    % \+ is_atom_char(C),
    Chars = [],
    Unread = C.

scheme_expect(Unread, Expect, Strm) :-
    ( Unread = Expect ->
        true
    ; Unread =< 32 ->
        get1(Strm, C),
        scheme_expect(C, Expect, Strm)
    ;
        scheme_error('unexpected character in read', [Unread])
    ).

is_atom_char(0'!).
%Xis_atom_char(0'").
%Xis_atom_char(0'#).
is_atom_char(0'$).
is_atom_char(0'%).
is_atom_char(0'&).
%Xis_atom_char(0'').
%Xis_atom_char(0'().
%Xis_atom_char(0')).
is_atom_char(0'*).
is_atom_char(0'+).
is_atom_char(0',).
is_atom_char(0'-).
%Xis_atom_char(0'.).
is_atom_char(0'/).
is_atom_char(0'0).
is_atom_char(0'1).
is_atom_char(0'2).
is_atom_char(0'3).
is_atom_char(0'4).
is_atom_char(0'5).
is_atom_char(0'6).
is_atom_char(0'7).
is_atom_char(0'8).
is_atom_char(0'9).
is_atom_char(0':).
%Xis_atom_char(0';).
is_atom_char(0'<).
is_atom_char(0'=).
is_atom_char(0'>).
%Xis_atom_char(0'?).
is_atom_char(··@).
is_atom_char(0'A).
is_atom_char(0'B).
is_atom_char(0'C).
is_atom_char(0'D).
is_atom_char(0'E).
is_atom_char(0'F).
is_atom_char(0'G).
is_atom_char(0'H).
is_atom_char(0'I).
is_atom_char(0'J).
is_atom_char(0'K).
is_atom_char(0'L).
is_atom_char(0'M).
is_atom_char(0'N).
is_atom_char(0'O).
is_atom_char(0'P).
is_atom_char(0'Q).
is_atom_char(0'R).
is_atom_char(0'S).
is_atom_char(0'T).
is_atom_char(0'U).
is_atom_char(0'V).
is_atom_char(0'W).
is_atom_char(0'X).
is_atom_char(0'Y).
is_atom_char(0'Z).
%Xis_atom_char(0'[).
%Xis_atom_char(0'\).
%Xis_atom_char(0']).
is_atom_char(0'^).
is_atom_char(0'_).
is_atom_char(0'`).
is_atom_char(0'a).
is_atom_char(0'b).
is_atom_char(0'c).
is_atom_char(0'd).
is_atom_char(0'e).
is_atom_char(0'f).
is_atom_char(0'g).
is_atom_char(0'h).
is_atom_char(0'i).
is_atom_char(0'j).
is_atom_char(0'k).
is_atom_char(0'l).
is_atom_char(0'm).
is_atom_char(0'n).
is_atom_char(0'o).
is_atom_char(0'p).
is_atom_char(0'q).
is_atom_char(0'r).
is_atom_char(0's).
is_atom_char(0't).
is_atom_char(0'u).
is_atom_char(0'v).
is_atom_char(0'w).
is_atom_char(0'x).
is_atom_char(0'y).
is_atom_char(0'z).
is_atom_char(0'{).
is_atom_char(0'|).
is_atom_char(0'}).
is_atom_char(0'~).

get1(Strm, C) :-
    get0(Strm, X),
    ( X =:= 0'; ->
        scan_to_eol(Strm),
        get1(Strm, C)
    ; X > 0'  ->
        C = X
    ; X > 0   ->
        get1(Strm, C)
    ).

scan_to_eol(Strm) :-
    repeat,
      get0(Strm, C),
      member(C, [0'\n, -1]),
    !,
    C = 0'\n.

scheme_write([quote,A]) :-
    !,
    write(''''),
    scheme_write(A).
scheme_write([]) :-
    !,
    write(nil).
scheme_write([A|B]) :-
    !,
    write('('),
    scheme_write(A),
    scheme_write_list_end(B).
scheme_write(string(Str)) :-
    !,
    write('"'),
    scheme_write_chars(Str),
    write('"').
scheme_write(X) :-
    % default
    write(X).

scheme_write_list_end([]) :-
    !,
    write(')').
scheme_write_list_end([A|B]) :-
    !,
    write(' '),
    scheme_write(A),
    scheme_write_list_end(B).
scheme_write_list_end(B) :-
    write(' . '),
    scheme_write(B),
    write(')').

scheme_write_chars([]).
scheme_write_chars([C|Cs]) :-
    ( C = 0'" ->
        put_code(0'\\)
    ; C = 0'\\ ->
        put_code(0'\\)
    ;
        true
    ),
    put_code(C),
    scheme_write_chars(Cs).
From: Stephen Cranefield
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <STEPHEN.96Jul26121000@eros.otago.ac.nz>
In article <·········@tribune.usask.ca> ·····@alfresco.usask.ca (P. Srinivas) writes:

>   Oh no. Take a look at Harlequin Lispworks, A commercial common lisp
>   system that comes with a FULL industry standard prolog writen 
>   completely in common LISP. 

I wouldn't call the Harlequin Lispworks version of Prolog "industry
standard".  It has one glaring flaw: all variables are considered
equal in the standard ordering of Prolog terms.  I wouldn't mind too
much if their documentation didn't insist on saying it "conforms
closely to Edinburgh Prolog" and that the term comparison operators
@<, @>, @=< and @>= have the "standard Edinburgh definitions".
It's a shame; otherwise the Lispworks version of Prolog does seem very
good.

- Stephen

-------------------------------------------------------------------------
Stephen Cranefield                                  Phone: +64 3 479 8083
Department of Information Science                   Fax:         479 8311
University of Otago                                 
Dunedin, New Zealand             E-mail: ···········@commerce.otago.ac.nz    
-------------------------------------------------------------------------
From: Stephan Kepser
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <4t24i8$4ck@sparcserver.lrz-muenchen.de>
In article <··········@tribune.usask.ca> ·····@alfresco.usask.ca (P.  
Srinivas) writes:
[...]
>  than otherway round. Also, in LISP programmar has the control
>  over his program, where as the control in prolog is fixed in built
>  (dept first, SNLD resolution??). For some problems this will
>  be good, but for some other it might not suite. You will get frustrated  
>   in the canse of later.

This is a common misconception that needs correction. The fact that Prolog  
has depth first as built-in search strategy does not preclude you from  
implementing breadth first, best first or whatever search strategy you  
prefer. It just means that you get depth first for free, while you have to  
write a few lines of code to get, say, breadth first.

> Srini
> 
>    URL http://www.cs.usask.ca/homepages/grads/srini/
> --------------------
> Srinivas Palthepu                             Email: ·····@cs.usask.ca
> ARIES laboratory,                            Phones: (306) 966-8654  
(lab)
> Department of Computer Science,                      (306) 966-4759  
(office)
> University of Saskatchewan,                          (306) 373-6724  
(home)    
> 57 Campus Dr, Saskatoon, SK, S7N 5A9            Fax: (306) 966-4884

--
Stephan Kepser           ······@cis.uni-muenchen.de
CIS   Centrum fuer Informations- und Sprachverarbeitung
LMU Muenchen, Oettingenstr. 67, D-80538 Muenchen,  Germany
Tel: +49 89 2178 2716     Fax: +49 89 2178 2701
From: John Dowding
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <DOWDING.96Jul22133904@Gansett.ai.sri.com>
    Palthepu> predicates like "is" predicate. Though in theory every
    Palthepu> langauge is Turing Comlete, in practice LISP seems to be
    Palthepu> more general as you can easily write a prolog
    Palthepu> interpretor in LISP than otherway round.


Really?  What is so difficult about writting a LISP interpreter in
Prolog?  I can't say to have written one myself, but I have written
lambda-reducers, and that was no big deal.  Extending that to a decent
subset of lisp doesn't sound terribly hard.

If anything, I would expect handling cut and backtracking correctly in
a Prolog implementation in LISP would take some effort.
--
John Dowding
·······@ai.sri.com
From: Jeffrey Mark Siskind
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <QOBI.96Jul25152924@eesun.technion.ac.il>
In article <············@info.fundp.ac.be> Michael Jampel <···@info.fundp.ac.be> writes:

   In general, LISP is deterministic, as are C, C++, Basic.
   Prolog is no-deterministic, i.e. one program can have more
   than one correct answer. So if you want to learn something
   as different as possible from C etc, I suggest Prolog.

See Screamer, available from my home page, for an extension of CommonLisp that
supports nondetereminism. See QobiScheme, also available from my home page,
for an extension of Scheme that supports nondeterminism.

   One more personal prejudice: Prolog is the basis of a new
   class of languages to do with "Constraint Logic Programming"
   which is wonderful,  and will be increasingly important in 
   the future. So you should move to CLP via Prolog. (See
   comp.constraints for more.)

Both Screamer and QobiScheme support constraint-based programming in a Scheme
or CommonLisp framework. QobiScheme supports finite domain constraints via
generalized forward checking and arc consistency as well as unification.
Screamer supports all of these as well as arbitrary numeric constraints over
integers/rationals/floats using bounds propagation coupled with divide and
conquer interval splitting. Nothing about constraint-based programming is
particularly better suited to Prolog, Scheme, Lisp, or any other language.
The generic lifting transformation to derive CLP languages from Prolog could
be applied to almost any language.
-- 

    Jeff (home page http://tochna.technion.ac.il/~qobi)
From: Will Hartung
Subject: WAY over my head (Was Re: What to learn: Prolog or Lisp?)
Date: 
Message-ID: <vfr750Dv4C5v.KAL@netcom.com>
····@eesun.technion.ac.il (Jeffrey Mark Siskind) writes:

>Both Screamer and QobiScheme support constraint-based programming in a Scheme
>or CommonLisp framework. QobiScheme supports finite domain constraints via
>generalized forward checking and arc consistency as well as unification.
>Screamer supports all of these as well as arbitrary numeric constraints over
>integers/rationals/floats using bounds propagation coupled with divide and
>conquer interval splitting. Nothing about constraint-based programming is
>particularly better suited to Prolog, Scheme, Lisp, or any other language.
>The generic lifting transformation to derive CLP languages from Prolog could
>be applied to almost any language.

I love hanging out and lurking in these groups.  I don't think I
understood 50% of this paragraph. I know what the words mean, but
arranged in this particular way, I'm lost. :-)

This isn't a flame, or a troll, or anything else, it's just my
observation. Hanging out here is like sitting in with wine collectors,
another area of complete vocabulary starvation.

But, eventually, I'll learn what was said here, so I can judge later
on whether it's important to me and how I work.

So, if anyone out there is actually feeling unappreciated by "The
Masses(tm)", there are some folks out here who are listening.

Meanwhile, this bit of mass will sit down, shut down, put the blank
look back on my face, and nod enthusiastically when it seems
appropiate.

I'm just glad you're not taking this stuff to E-Mail, and I get to
listen in.

Thanx again for sharing..
-- 
Will Hartung - Rancho Santa Margarita. It's a dry heat. ······@netcom.com
1990 VFR750 - VFR=Very Red    "Ho, HaHa, Dodge, Parry, Spin, HA! THRUST!"
1993 Explorer - Cage? Hell, it's a prison.                    -D. Duck
From: Joachim Schimpf
Subject: Re: What to learn: Prolog or Lisp?
Date: 
Message-ID: <4tid3j$809@penguin.doc.ic.ac.uk>
In article <··················@eesun.technion.ac.il>,
	····@eesun.technion.ac.il (Jeffrey Mark Siskind) writes:
>In article <············@info.fundp.ac.be> Michael Jampel <···@info.fundp.ac.be> writes:
>   One more personal prejudice: Prolog is the basis of a new
>   class of languages to do with "Constraint Logic Programming"
>   which is wonderful,  and will be increasingly important in 
>   the future. So you should move to CLP via Prolog. (See
>   comp.constraints for more.)
>
>Both Screamer and QobiScheme support constraint-based programming in a Scheme
>or CommonLisp framework. QobiScheme supports finite domain constraints via
>generalized forward checking and arc consistency as well as unification.
>Screamer supports all of these as well as arbitrary numeric constraints over
>integers/rationals/floats using bounds propagation coupled with divide and
>conquer interval splitting. Nothing about constraint-based programming is
>particularly better suited to Prolog, Scheme, Lisp, or any other language.

I had a look at Screamer and saw that the first thing you did in order
to implement constraints was to add backtracking and logical variables
to Lisp! Now, that seems to me the best proof for the claim that Prolog
is a more suitable basis for CLP since it has these things already.

Of course you can use any language as an _implementation_ language
for CLP (ILOG has done that quite successfully with C++), but with
a logic-based, relational language like Prolog you can get a completely
natural embedding.


>The generic lifting transformation to derive CLP languages from Prolog could
>be applied to almost any language.

I'm not sure know which transformation you are talking about. In my
view, when you start from Prolog, you don't have to change the language
at all, just execute it more cleverly and you have a CLP system.


------------------------------------------------------------------------
 Joachim Schimpf                       /   phone:      +44 171 594 8187
 IC-Parc, William Penney Laboratory   /   ················@doc.ic.ac.uk
 Imperial College, London SW7 2AZ    /   http://www-icparc.doc.ic.ac.uk