[comp.lang.prolog] PROLOG Digest V5 #87

PROLOG-REQUEST@SUSHI.STANFORD.EDU (Chuck Restivo, The Moderator) (11/17/87)

PROLOG Digest           Wednesday, 18 Nov 1987     Volume 5 : Issue 87

Today's Topics:
                       Announcement - Binding,
                  Query - SB Prolog & Wisdom Prolog,
                       Implementation - Badness
----------------------------------------------------------------------

Date: Tue 10 Nov 87 16:22:50-EST
From: vijay <Vijay.Saraswat@C.CS.CMU.EDU>
Subject: Bindings.

I have moved from the Computer Science Department at CMU to
the Intelligent Systems Lab at Xerox PARC. My new USMAIL and
net-address are:

Vijay Saraswat
Xerox PARC,
3333 Coyote Hill Road,
Palo Alto, Ca 9434.
(saraswat.pa@xerox.com)

------------------------------

Date: 12 Nov 87 04:52:33 GMT
From: cbosgd!cblpf!dtm@ucbvax.Berkeley.EDU  (Dattaram Mirvke)
Subject: Sys V version of SB-prolog.


        Recently I got a version SB-prolog. However it seems like it is
very much "in tune" with BSD UNIX. Has anyone hacked it to either get it
working on Sys V? May be you would like to save me and some others
here some work :-). Is there SysV version of this beast somewhere out there?
Thanks in advance..

------------------------------

Date: 12 Nov 87 21:41:19 GMT
From: ece-csc!drb@mcnc.org  (Dr. Dennis R. Bahler)
Subject: Needed: views on Wisdom Prolog

I would like to hear from people who have impressions/experiences -- the
good, the bad, the ugly, and the indifferent -- with the Wisdom Prolog
available from MIT in connection with Sterling and Shapiro's book
The Art of Prolog.  Specifically, (i) how suitable/friendly is it for advanced
undergraduates with no logic programming experience? (ii) how does it compare
with other such systems? (iii) any known major plusses/deficiencies?

Pointers to written reviews would also be appreciated.

We have someone here who is thinking about using this system in an
advanced undergrad languages course that also does LISP, Smalltalk-V, etc.
He has IBM PC's to play with.

-- Dennis Bahler

------------------------------

Date: 11 Nov 87 00:27:31 GMT
From: blenko@burdvax.prc.unisys.com  (Tom Blenko)
Subject: Re: Badness

It isn't clear what the admonition to program declaratively means.
Programming declaratively, in the sense of pure PROLOG (without call(),
not(), and cut()) is not even powerful enough to express IF-THEN-ELSE,
which I am willing to assume is a _sine_qua_non_ for programming.  One
can get IF-THEN-ELSE back with call() and not(), but the
non-declarative character of PROLOG not() is also well known.  So I
don't think we can take "program declaratively" too seriously if it
means that we cannot express IF-THEN-ELSE (because it doesn't suffice
as programming), or if it means that we have to admit call() and not()
(because then it isn't declarative).

Just to save some time here, I also point out that not() restricted to,
or delayed to await, grounded arguments, as you and others have
proposed, does not get one out of the difficulty (of expressing
IF-THEN-ELSE declaratively when the condition requires more than
constructor matching).

I'm not sure we're disagreeing. I do recall a perfectly fine
declarative program for append3() that you cite in a paper as suffering
from non-termination, even though correct declarative solutions are
also possible, and other examples are not too hard to come by.  So I
think the "program declaratively" admonition is not even safe,
efficiency questions aside.

-- Tom

------------------------------

Date: Mon, 9 Nov 87 12:16:35 GMT
From: Fernando Pereira <pereira%cam.sri.com@drakes.ai.sri.com>
Subject: Blenko's defence of mediocrity

Tom Blenko says

> ... Most code, Prolog
> and otherwise, is good enough because it runs.  Programmers have
> neither the time nor the interest to engage in the pensive, reflective
> approach to programming that O'Keefe espouses.

Is he this understanding of mediocrity with respect to products he
may buy, a new car, say?  Is he happy enough with a car just because it
runs when he buys it? What about when it doesn't start in a particularly
wet/cold day? Will he accept an excuse from the manufacturer along the
lines ``do you expect us to test cars under conditions that only happen
once every two years?'' And what about economy, comfort, and so on?

``Good enough because it runs'' is the standard excuse of mediocre
engineering. We know what this attitude to quality has done to
US industry...

I don't see why a computer program should be any less well designed
than a [good] car. Yet software manufacturers as a matter of course
put out products of a standard of quality that consumers would not
tolerate in a car or VCR. No commercial program that I have bought
for myself or my company breaks down as rarely as my five-year-old
economy model German car. The thoughtful approach to quality that
Richard O'Keefe advocates is essential in good manufacturing, as
the many books and articles written recently about Japan's industrial
success make exceedingly clear.

As for append/3: if Tom's complaint is that it does not check whether
its second argument is a list, the real question is ``why should it?''
That definition of append satisfies the specification

        (forall x y z) (list(x) & list(y) & append(x,y,z) =>
                                list(z) & x::y = z)

where :: is the list concatenation function. What is the problem if
append(x,y,z) accepts certain nonlist arguments? IF what Tom wants is
the stricter specification

        (forall x y z) (append(x,y,z) => list(x) & list(y) & list(z) &
                                x::y = z)

he won't have any difficulty in implementing it (at a cost!).


-- Fernando Pereira

------------------------------

Date: 12 Nov 87 21:16:30 GMT
From: broome@smoke.brl.mil  (Paul Broome )
Subject: Badness

It's not clear that IF-THEN-ELSE is essential for programming.  In fact it's
often hazardous!  The ELSE part of an IF-THEN-ELSE is too all-enclosing.

A small example that immediately comes to mind is factorial, often written
something like

        fac(N) = if N=0 then  1
                        else  N*fac(N-1).

The danger comes from permitting an unbounded recursion for negative N.
It's much better, in this case at least, to say explicitly what cases
can be handled and fail for those outside.  E.g. something like

        fac(N) = if N=0 then 1
                 if N>0 then N*fac(N-1).

It would be interesting to see a small example that *requires* IF-THEN-ELSE?

-- Paul

------------------------------

Date: Mon, 9 Nov 87 22:22:33 PST
From: quintus!ok@Sun.COM (Richard A. O'Keefe)
Subject:  Badness


    Tom Blenko writes "Programmers have neither the time nor the
interest to engage in the pensive, reflective approach to
programming that O'Keefe espouses."  (It really is VERY kind of
kind to say that I "espouse" this approach, but how can he know
that?)  Let me paraphrase that:

        Programmers have neither the time nor the interest to do
        the job they are paid to do.  Let the customer pay!

    I bank with the XYZ bank.  Their computer seems to crash an
awful lot, and they told me that I couldn't add my father's name
to my account, I'd have to close the old account and open a new
one.  Sounds as though they have some programmers who have
neither the time nor the interest to think about their programs.

    I was once given a piece of advice about flying: "[when something
goes wrong] don't just DO something, SIT THERE [and think about it
first]".  If this is good advice for someone whose plane has started
spinning towards the ground, can the pressures on programmers really
be so much worse that they have to do something without thinking?
There *is* a difference: if a pilot crashes his plane, HE suffers,
but if a programmer's program crashes, it's often someone ELSE who
suffers.

    Surely someone who is paid to write programs has a duty to think
about what s/he is doing.  And with respect to textbooks, someone
who is paid to tell other people how to write programs also has a
duty to think about what s/he is doing.

    Tom Blenko says that "goodness (and even correctness) of software
depends upon one's perspective."  Sure.  Just like whether 1+2 = 3
depends on one's perspective.  A piece of software is correct if and
only if it satisfies its specification.  In the case of Lagache's
library, for example, the specification was the documentation written
in English.  And the code did not satisfy its specification.  I was
able to show that there were calls (such as calling the sort routine
with a variable as first argument) which the documentation did not
prohibit which did not behave sensibly.  I did say that the code
probably worked in the context that Lagache intended, but it is a
plain matter of fact that his documentation did not say what all the
restrictions on his code were.  Either the code or the specification
could be changed to produce correct software, but that does not mean
that the incompatibility of the code and specification that existed
depends on anyone's perspective.  Similarly, goodness is objective.
A tool (and a subroutine library is a tool) is good to the extent
that it is fit for its intended purpose.  In the case of software,
we can measure
        size of program
        speed
        space use
quite easily.  With some effort, we can measure (on an ordinal scale)
how easy the code is to read, maintain, or adapt to a slightly
different task.

    Blenko claims that the usual definition of append/3 is
"erroneous Prolog software" and gibes that he has never "seen a
correct version (even in the Quintus library!)".  Wrong.  The
definition of append/3 simply IS.  It can only be correct or
erroneous with respect to a particular specification.  I'm not
contradicting myself here: correctness is a relation between a
program and a specification, and for a given specification the
correctness or otherwise of a program is an objective fact.
The specification we at Quintus use is that append/3 is only
defined when the arguments are lists.  (In fact the DEC-10
Prolog type checker has the meta-fact
        :- pred append(list(T),list(T),list(T)).
which makes this explicit.)  The usual definition of append/3
is correct with respect to that specification.  It is easy to
give a specification with respect to which it is incorrect:
        "append(X, Y, Z) is true when X, Y, and Z are integers
         and Z is congruent to (X+Y) modulo 42".
There's nothing special about append/3:  the usual definition
of member/1 entails the satisfiability of member(1, .(1,fred)).
So what?  It's correct if that behaviour is consistent with the
specification, and if the specification only says what happens
when the second argument is (or may become) a list, fine.

    With respect to Blenko's numbered points, I have to agree.
Though his point 1 really amounts to saying that some people
writing "Prolog" are really writing Lisp and neither know nor care.
But I must take issue with this point 5, which I repeat here.
        5. It is well known that O'Keefe's and Naish's exhortations
           to Lagache (for sensitivity to efficiencies in the
           implementation and for conformity to simple declarative
           interpretations) will sometimes conflict.  This presents
           the programmer with a dilemma that he or she may not
           (indeed may not be able to) escape.
One of the files in the public-domain DEC-10 Prolog library is
called ORDSET.PL.  It defines set operations, using lists in standard
order without duplicates as the representation of sets.  The Quintus
library includes a file ordsets.pl which adds some operations and
fixes some bugs, but was essentially the same.  I have just finished
rewriting nearly every predicate in that file.  The new code
        contains no cuts
        has no overlapping clause heads
        is 15% to 20% faster.
Conflict?  Dilemma?  Not this time.  Not often, either.

    I'm beginning to think that it may not be Prolog after all.  Someone
recently sent me a draft of a paper.  The paper compares versions of a
program in four declarative languages (including Prolog) and Pascal.
It was most illuminating.  I wouldn't describe any of the versions as
"bad".  But there was a subtle difference between the declarative
versions and the Pascal version which rendered the (storage cost)
comparison invalid.  I'm not going to go into details; that's for the
author of the paper to do.  But a key lesson I learned from it is that
it can be appallingly hard to get any idea of what a program in a
lazy functional language or a language like FP is up to.  Subtle
differences in the code can have dramatic effects on efficiency (I
identified a *possible* time factor of 20 in one program and an
*actual* space factor of 30 in another).  There is a new book by Simon
Peyton-Jones about functional languages.  He has a chapter on pragmatics,
and there are some really unpleasant subtleties.  I'm inclined to think
that lazy evaluation is much harder to understand than backtracking.
The difference between a lazy program which constructs only part of an
infinite data structure and one which races off to infinity may be very
hard to see in the source code.

    Is there a greater tendency for Prolog programmers to write bad
Prolog than for Scheme programmers to write bad Scheme?  Than for
Miranda programmers (or KRC or SASL or whatever)?  What we need here
is some input from people who are teaching at least two declarative
languages.

------------------------------

End of PROLOG Digest
********************